use of org.hyperledger.besu.evm.account.MutableAccount in project hedera-services by hashgraph.
the class AbstractRecordingCreateOperation method execute.
@Override
public Operation.OperationResult execute(final MessageFrame frame, final EVM evm) {
// We have a feature flag for CREATE2
if (!isEnabled()) {
return INVALID_RESPONSE;
}
// manual check because some reads won't come until the "complete" step.
if (frame.stackSize() < getStackItemsConsumed()) {
return UNDERFLOW_RESPONSE;
}
final Gas cost = cost(frame);
final Optional<Gas> optionalCost = Optional.ofNullable(cost);
if (cost != null) {
if (frame.isStatic()) {
return haltWith(optionalCost, ILLEGAL_STATE_CHANGE);
} else if (frame.getRemainingGas().compareTo(cost) < 0) {
return new Operation.OperationResult(optionalCost, Optional.of(ExceptionalHaltReason.INSUFFICIENT_GAS));
}
final Wei value = Wei.wrap(frame.getStackItem(0));
final Address address = frame.getRecipientAddress();
final MutableAccount account = frame.getWorldUpdater().getAccount(address).getMutable();
frame.clearReturnData();
if (value.compareTo(account.getBalance()) > 0 || frame.getMessageStackDepth() >= MAX_STACK_DEPTH) {
fail(frame);
} else {
spawnChildMessage(frame);
}
}
return new Operation.OperationResult(optionalCost, Optional.empty());
}
use of org.hyperledger.besu.evm.account.MutableAccount in project hedera-services by hashgraph.
the class AbstractRecordingCreateOperation method spawnChildMessage.
private void spawnChildMessage(final MessageFrame frame) {
// memory cost needs to be calculated prior to memory expansion
final Gas cost = cost(frame);
frame.decrementRemainingGas(cost);
final Address address = frame.getRecipientAddress();
final MutableAccount account = frame.getWorldUpdater().getAccount(address).getMutable();
account.incrementNonce();
final Wei value = Wei.wrap(frame.getStackItem(0));
final long inputOffset = clampedToLong(frame.getStackItem(1));
final long inputSize = clampedToLong(frame.getStackItem(2));
final Bytes inputData = frame.readMemory(inputOffset, inputSize);
final Address contractAddress = targetContractAddress(frame);
final Gas childGasStipend = gasCalculator().gasAvailableForChildCreate(frame.getRemainingGas());
frame.decrementRemainingGas(childGasStipend);
final MessageFrame childFrame = MessageFrame.builder().type(MessageFrame.Type.CONTRACT_CREATION).messageFrameStack(frame.getMessageFrameStack()).worldUpdater(frame.getWorldUpdater().updater()).initialGas(childGasStipend).address(contractAddress).originator(frame.getOriginatorAddress()).contract(contractAddress).gasPrice(frame.getGasPrice()).inputData(Bytes.EMPTY).sender(frame.getRecipientAddress()).value(value).apparentValue(value).code(new Code(inputData, Hash.EMPTY)).blockValues(frame.getBlockValues()).depth(frame.getMessageStackDepth() + 1).completer(child -> complete(frame, child)).miningBeneficiary(frame.getMiningBeneficiary()).blockHashLookup(frame.getBlockHashLookup()).maxStackSize(frame.getMaxStackSize()).build();
frame.incrementRemainingGas(cost);
frame.getMessageFrameStack().addFirst(childFrame);
frame.setState(MessageFrame.State.CODE_SUSPENDED);
}
use of org.hyperledger.besu.evm.account.MutableAccount in project hedera-services by hashgraph.
the class HederaSStoreOperation method execute.
@Override
public Operation.OperationResult execute(final MessageFrame frame, final EVM evm) {
final UInt256 key = UInt256.fromBytes(frame.popStackItem());
final UInt256 value = UInt256.fromBytes(frame.popStackItem());
final MutableAccount account = frame.getWorldUpdater().getAccount(frame.getRecipientAddress()).getMutable();
if (account == null) {
return ILLEGAL_STATE_CHANGE;
}
UInt256 currentValue = account.getStorageValue(key);
boolean currentZero = currentValue.isZero();
boolean newZero = value.isZero();
boolean checkCalculator = checkSuperCost;
Gas gasCost = Gas.ZERO;
if (currentZero && !newZero) {
final var updater = (HederaWorldUpdater) frame.getWorldUpdater();
HederaWorldState.WorldStateAccount hederaAccount = updater.getHederaAccount(frame.getRecipientAddress());
long durationInSeconds = Math.max(0, (hederaAccount != null ? hederaAccount.getExpiry() : HederaOperationUtil.newContractExpiryIn(frame)) - frame.getBlockValues().getTimestamp());
long sbh = frame.getMessageFrameStack().getLast().getContextVariable("sbh");
Wei gasPrice = frame.getGasPrice();
gasCost = Gas.of(calculateStorageGasNeeded(64, /*two 256-bit words*/
durationInSeconds, sbh, gasPrice.toLong()));
((HederaWorldUpdater) frame.getWorldUpdater()).addSbhRefund(gasCost);
} else {
checkCalculator = true;
}
if (checkCalculator) {
Address address = account.getAddress();
boolean slotIsWarm = frame.warmUpStorage(address, key);
gasCost = gasCost.max(gasCalculator().calculateStorageCost(account, key, value).plus(slotIsWarm ? Gas.ZERO : this.gasCalculator().getColdSloadCost()));
frame.incrementGasRefund(gasCalculator().calculateStorageRefundAmount(account, key, value));
}
Optional<Gas> optionalCost = Optional.of(gasCost);
final Gas remainingGas = frame.getRemainingGas();
if (frame.isStatic()) {
return new OperationResult(optionalCost, Optional.of(ExceptionalHaltReason.ILLEGAL_STATE_CHANGE));
} else if (remainingGas.compareTo(gasCost) < 0) {
return new OperationResult(optionalCost, Optional.of(ExceptionalHaltReason.INSUFFICIENT_GAS));
}
if (dynamicProperties.shouldEnableTraceability()) {
HederaOperationUtil.cacheExistingValue(frame, account.getAddress(), key, currentValue);
}
account.setStorageValue(key, value);
frame.storageWasUpdated(key, value);
return new Operation.OperationResult(optionalCost, Optional.empty());
}
use of org.hyperledger.besu.evm.account.MutableAccount in project besu by hyperledger.
the class PrivacyBlockProcessorTest method mockPrivateStateArchive.
private MutableWorldState mockPrivateStateArchive() {
final MutableWorldState mockPrivateState = mock(MutableWorldState.class);
final WorldUpdater mockWorldUpdater = mock(WorldUpdater.class);
final WrappedEvmAccount mockWrappedEvmAccount = mock(WrappedEvmAccount.class);
final MutableAccount mockMutableAccount = mock(MutableAccount.class);
when(mockWrappedEvmAccount.getMutable()).thenReturn(mockMutableAccount);
when(mockWorldUpdater.createAccount(any())).thenReturn(mockWrappedEvmAccount);
when(mockPrivateState.updater()).thenReturn(mockWorldUpdater);
when(mockPrivateState.rootHash()).thenReturn(Hash.ZERO);
return mockPrivateState;
}
use of org.hyperledger.besu.evm.account.MutableAccount in project besu by hyperledger.
the class LogRollingTests method rollBackOnce.
@Test
public void rollBackOnce() {
final BonsaiPersistedWorldState worldState = new BonsaiPersistedWorldState(archive, new BonsaiWorldStateKeyValueStorage(accountStorage, codeStorage, storageStorage, trieBranchStorage, trieLogStorage));
final WorldUpdater updater = worldState.updater();
final MutableAccount mutableAccount = updater.createAccount(addressOne, 1, Wei.of(1L)).getMutable();
mutableAccount.setCode(Bytes.of(0, 1, 2));
mutableAccount.setStorageValue(UInt256.ONE, UInt256.ONE);
updater.commit();
worldState.persist(headerOne);
final WorldUpdater updater2 = worldState.updater();
final MutableAccount mutableAccount2 = updater2.getAccount(addressOne).getMutable();
mutableAccount2.setStorageValue(UInt256.ONE, UInt256.valueOf(2));
updater2.commit();
worldState.persist(headerTwo);
final BonsaiWorldStateUpdater firstRollbackUpdater = (BonsaiWorldStateUpdater) worldState.updater();
final TrieLogLayer layerTwo = getTrieLogLayer(trieLogStorage, headerTwo.getHash());
firstRollbackUpdater.rollBack(layerTwo);
worldState.persist(headerOne);
final BonsaiPersistedWorldState secondWorldState = new BonsaiPersistedWorldState(secondArchive, new BonsaiWorldStateKeyValueStorage(secondAccountStorage, secondCodeStorage, secondStorageStorage, secondTrieBranchStorage, secondTrieLogStorage));
final WorldUpdater secondUpdater = secondWorldState.updater();
final MutableAccount secondMutableAccount = secondUpdater.createAccount(addressOne, 1, Wei.of(1L)).getMutable();
secondMutableAccount.setCode(Bytes.of(0, 1, 2));
secondMutableAccount.setStorageValue(UInt256.ONE, UInt256.ONE);
secondUpdater.commit();
secondWorldState.persist(null);
assertKeyValueStorageEqual(accountStorage, secondAccountStorage);
assertKeyValueStorageEqual(codeStorage, secondCodeStorage);
assertKeyValueStorageEqual(storageStorage, secondStorageStorage);
final KeyValueStorageTransaction tx = trieBranchStorage.startTransaction();
tx.remove(BonsaiWorldStateKeyValueStorage.WORLD_BLOCK_HASH_KEY);
tx.commit();
assertKeyValueStorageEqual(trieBranchStorage, secondTrieBranchStorage);
// trie logs won't be the same, we don't delete the roll back log
assertKeyValueSubset(trieLogStorage, secondTrieLogStorage);
assertThat(secondWorldState.rootHash()).isEqualByComparingTo(worldState.rootHash());
}
Aggregations