Search in sources :

Example 1 with MutableAccount

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());
}
Also used : Address(org.hyperledger.besu.datatypes.Address) Gas(org.hyperledger.besu.evm.Gas) Wei(org.hyperledger.besu.datatypes.Wei) MutableAccount(org.hyperledger.besu.evm.account.MutableAccount) AbstractOperation(org.hyperledger.besu.evm.operation.AbstractOperation) Operation(org.hyperledger.besu.evm.operation.Operation)

Example 2 with MutableAccount

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);
}
Also used : Bytes(org.apache.tuweni.bytes.Bytes) Address(org.hyperledger.besu.datatypes.Address) MessageFrame(org.hyperledger.besu.evm.frame.MessageFrame) Gas(org.hyperledger.besu.evm.Gas) MutableAccount(org.hyperledger.besu.evm.account.MutableAccount) Wei(org.hyperledger.besu.datatypes.Wei) Code(org.hyperledger.besu.evm.Code)

Example 3 with MutableAccount

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());
}
Also used : Address(org.hyperledger.besu.datatypes.Address) HederaWorldState(com.hedera.services.store.contracts.HederaWorldState) HederaWorldUpdater(com.hedera.services.store.contracts.HederaWorldUpdater) Gas(org.hyperledger.besu.evm.Gas) MutableAccount(org.hyperledger.besu.evm.account.MutableAccount) Wei(org.hyperledger.besu.datatypes.Wei) UInt256(org.apache.tuweni.units.bigints.UInt256)

Example 4 with MutableAccount

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;
}
Also used : MutableWorldState(org.hyperledger.besu.ethereum.core.MutableWorldState) WorldUpdater(org.hyperledger.besu.evm.worldstate.WorldUpdater) WrappedEvmAccount(org.hyperledger.besu.evm.worldstate.WrappedEvmAccount) MutableAccount(org.hyperledger.besu.evm.account.MutableAccount)

Example 5 with MutableAccount

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());
}
Also used : WorldUpdater(org.hyperledger.besu.evm.worldstate.WorldUpdater) KeyValueStorageTransaction(org.hyperledger.besu.plugin.services.storage.KeyValueStorageTransaction) MutableAccount(org.hyperledger.besu.evm.account.MutableAccount) Test(org.junit.Test)

Aggregations

MutableAccount (org.hyperledger.besu.evm.account.MutableAccount)49 WorldUpdater (org.hyperledger.besu.evm.worldstate.WorldUpdater)33 Test (org.junit.Test)23 MutableWorldState (org.hyperledger.besu.ethereum.core.MutableWorldState)19 Address (org.hyperledger.besu.datatypes.Address)14 Wei (org.hyperledger.besu.datatypes.Wei)14 UInt256 (org.apache.tuweni.units.bigints.UInt256)10 Bytes (org.apache.tuweni.bytes.Bytes)9 MessageFrame (org.hyperledger.besu.evm.frame.MessageFrame)7 Bytes32 (org.apache.tuweni.bytes.Bytes32)5 Hash (org.hyperledger.besu.datatypes.Hash)5 ProcessableBlockHeader (org.hyperledger.besu.ethereum.core.ProcessableBlockHeader)5 ArrayDeque (java.util.ArrayDeque)4 ArrayList (java.util.ArrayList)4 BlockHeader (org.hyperledger.besu.ethereum.core.BlockHeader)4 Code (org.hyperledger.besu.evm.Code)4 Gas (org.hyperledger.besu.evm.Gas)4 Account (org.hyperledger.besu.evm.account.Account)4 Map (java.util.Map)3 TreeMap (java.util.TreeMap)3