diff --git a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java index cde0b95bbb7..80037c8c6c1 100644 --- a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java +++ b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java @@ -50,7 +50,7 @@ import org.hyperledger.besu.ethereum.mainnet.feemarket.BaseFeeMarket; import org.hyperledger.besu.ethereum.mainnet.feemarket.ExcessBlobGasCalculator; import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; -import org.hyperledger.besu.evm.account.EvmAccount; +import org.hyperledger.besu.evm.account.MutableAccount; import org.hyperledger.besu.evm.worldstate.WorldUpdater; import org.hyperledger.besu.plugin.services.exception.StorageException; import org.hyperledger.besu.plugin.services.securitymodule.SecurityModuleException; @@ -190,10 +190,10 @@ protected BlockCreationResult createBlock( final List ommers = maybeOmmers.orElse(selectOmmers()); - if (maybeParentBeaconBlockRoot.isPresent()) { - ParentBeaconBlockRootHelper.storeParentBeaconBlockRoot( - disposableWorldState.updater(), timestamp, maybeParentBeaconBlockRoot.get()); - } + maybeParentBeaconBlockRoot.ifPresent( + bytes32 -> + ParentBeaconBlockRootHelper.storeParentBeaconBlockRoot( + disposableWorldState.updater(), timestamp, bytes32)); throwIfStopped(); final TransactionSelectionResults transactionResults = @@ -466,9 +466,9 @@ boolean rewardBeneficiary( .getBlockProcessor() .getCoinbaseReward(blockReward, header.getNumber(), ommers.size()); final WorldUpdater updater = worldState.updater(); - final EvmAccount beneficiary = updater.getOrCreate(miningBeneficiary); + final MutableAccount beneficiary = updater.getOrCreate(miningBeneficiary); - beneficiary.getMutable().incrementBalance(coinbaseReward); + beneficiary.incrementBalance(coinbaseReward); for (final BlockHeader ommerHeader : ommers) { if (ommerHeader.getNumber() - header.getNumber() > MAX_GENERATION) { LOG.trace( @@ -479,12 +479,12 @@ boolean rewardBeneficiary( return false; } - final EvmAccount ommerCoinbase = updater.getOrCreate(ommerHeader.getCoinbase()); + final MutableAccount ommerCoinbase = updater.getOrCreate(ommerHeader.getCoinbase()); final Wei ommerReward = protocolSpec .getBlockProcessor() .getOmmerReward(blockReward, header.getNumber(), ommerHeader.getNumber()); - ommerCoinbase.getMutable().incrementBalance(ommerReward); + ommerCoinbase.incrementBalance(ommerReward); } updater.commit(); diff --git a/ethereum/core/src/integration-test/java/org/hyperledger/besu/ethereum/vm/EntriesFromIntegrationTest.java b/ethereum/core/src/integration-test/java/org/hyperledger/besu/ethereum/vm/EntriesFromIntegrationTest.java index e139d69352d..fcfd71f206e 100644 --- a/ethereum/core/src/integration-test/java/org/hyperledger/besu/ethereum/vm/EntriesFromIntegrationTest.java +++ b/ethereum/core/src/integration-test/java/org/hyperledger/besu/ethereum/vm/EntriesFromIntegrationTest.java @@ -39,7 +39,7 @@ public class EntriesFromIntegrationTest { public void shouldCollectStateEntries() { final MutableWorldState worldState = createInMemoryWorldStateArchive().getMutable(); final WorldUpdater updater = worldState.updater(); - MutableAccount account = updater.getOrCreate(Address.fromHexString("0x56")).getMutable(); + MutableAccount account = updater.getOrCreate(Address.fromHexString("0x56")); final Map expectedValues = new TreeMap<>(); final int nodeCount = 100_000; final Random random = new Random(42989428249L); @@ -49,19 +49,19 @@ public void shouldCollectStateEntries() { addExpectedValue( account, expectedValues, - UInt256.valueOf(Math.abs(random.nextLong())), - UInt256.valueOf(i * 10 + 1)); + UInt256.valueOf(random.nextLong(Long.MAX_VALUE)), + UInt256.valueOf(i * 10 + 1L)); } updater.commit(); // Add some changes on top that AbstractWorldUpdater.UpdateTrackingAccount will have to merge. - account = worldState.updater().getOrCreate(Address.fromHexString("0x56")).getMutable(); + account = worldState.updater().getOrCreate(Address.fromHexString("0x56")); for (int i = 0; i <= nodeCount; i++) { addExpectedValue( account, expectedValues, - UInt256.valueOf(Math.abs(random.nextLong())), - UInt256.valueOf(i * 10 + 1)); + UInt256.valueOf(random.nextLong(Long.MAX_VALUE)), + UInt256.valueOf(i * 10 + 1L)); } final Map values = diff --git a/ethereum/core/src/jmh/java/org/hyperledger/besu/ethereum/vm/operations/TransientStorageOperationBenchmark.java b/ethereum/core/src/jmh/java/org/hyperledger/besu/ethereum/vm/operations/TransientStorageOperationBenchmark.java index 612bedc2c74..19d3c8b45ca 100644 --- a/ethereum/core/src/jmh/java/org/hyperledger/besu/ethereum/vm/operations/TransientStorageOperationBenchmark.java +++ b/ethereum/core/src/jmh/java/org/hyperledger/besu/ethereum/vm/operations/TransientStorageOperationBenchmark.java @@ -59,7 +59,7 @@ private MessageFrame createMessageFrame(final Address address) { .blockHeader(blockHeader) .blockchain(blockchain) .build(); - worldStateUpdater.getOrCreate(address).getMutable().setBalance(Wei.of(1)); + worldStateUpdater.getOrCreate(address).setBalance(Wei.of(1)); worldStateUpdater.commit(); return benchmarkFrame; diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/bonsai/BonsaiAccount.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/bonsai/BonsaiAccount.java index 14be477a07d..a5488cb9a2e 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/bonsai/BonsaiAccount.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/bonsai/BonsaiAccount.java @@ -28,7 +28,6 @@ import org.hyperledger.besu.ethereum.rlp.RLPOutput; import org.hyperledger.besu.evm.ModificationNotAllowedException; import org.hyperledger.besu.evm.account.AccountStorageEntry; -import org.hyperledger.besu.evm.account.EvmAccount; import org.hyperledger.besu.evm.account.MutableAccount; import org.hyperledger.besu.evm.worldstate.UpdateTrackingAccount; @@ -41,9 +40,9 @@ import org.apache.tuweni.bytes.Bytes32; import org.apache.tuweni.units.bigints.UInt256; -public class BonsaiAccount implements MutableAccount, EvmAccount, AccountValue { +public class BonsaiAccount implements MutableAccount, AccountValue { private final BonsaiWorldView context; - private final boolean mutable; + private boolean mutable; private final Address address; private final Hash addressHash; @@ -163,7 +162,7 @@ public long getNonce() { @Override public void setNonce(final long value) { if (!mutable) { - throw new UnsupportedOperationException("Account is immutable"); + throw new ModificationNotAllowedException(); } nonce = value; } @@ -176,7 +175,7 @@ public Wei getBalance() { @Override public void setBalance(final Wei value) { if (!mutable) { - throw new UnsupportedOperationException("Account is immutable"); + throw new ModificationNotAllowedException(); } balance = value; } @@ -192,7 +191,7 @@ public Bytes getCode() { @Override public void setCode(final Bytes code) { if (!mutable) { - throw new UnsupportedOperationException("Account is immutable"); + throw new ModificationNotAllowedException(); } this.code = code; if (code == null || code.isEmpty()) { @@ -244,7 +243,7 @@ public void writeTo(final RLPOutput out) { @Override public void setStorageValue(final UInt256 key, final UInt256 value) { if (!mutable) { - throw new UnsupportedOperationException("Account is immutable"); + throw new ModificationNotAllowedException(); } updatedStorage.put(key, value); } @@ -259,15 +258,6 @@ public Map getUpdatedStorage() { return updatedStorage; } - @Override - public MutableAccount getMutable() throws ModificationNotAllowedException { - if (mutable) { - return this; - } else { - throw new ModificationNotAllowedException(); - } - } - @Override public Hash getStorageRoot() { return storageRoot; @@ -275,11 +265,16 @@ public Hash getStorageRoot() { public void setStorageRoot(final Hash storageRoot) { if (!mutable) { - throw new UnsupportedOperationException("Account is immutable"); + throw new ModificationNotAllowedException(); } this.storageRoot = storageRoot; } + @Override + public void becomeImmutable() { + mutable = false; + } + @Override public String toString() { return "AccountState{" diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/bonsai/worldview/BonsaiWorldStateUpdateAccumulator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/bonsai/worldview/BonsaiWorldStateUpdateAccumulator.java index 2a04f92fb19..b1cd64378b9 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/bonsai/worldview/BonsaiWorldStateUpdateAccumulator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/bonsai/worldview/BonsaiWorldStateUpdateAccumulator.java @@ -27,10 +27,9 @@ import org.hyperledger.besu.ethereum.rlp.RLP; import org.hyperledger.besu.ethereum.trie.MerkleTrieException; import org.hyperledger.besu.evm.account.Account; -import org.hyperledger.besu.evm.account.EvmAccount; +import org.hyperledger.besu.evm.account.MutableAccount; import org.hyperledger.besu.evm.worldstate.AbstractWorldUpdater; import org.hyperledger.besu.evm.worldstate.UpdateTrackingAccount; -import org.hyperledger.besu.evm.worldstate.WrappedEvmAccount; import org.hyperledger.besu.plugin.services.trielogs.TrieLog; import org.hyperledger.besu.plugin.services.trielogs.TrieLogAccumulator; @@ -44,6 +43,7 @@ import java.util.Set; import java.util.TreeSet; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; import java.util.function.Function; import com.google.common.collect.ForwardingMap; @@ -115,12 +115,12 @@ protected UpdateTrackingAccount track( } @Override - public EvmAccount getAccount(final Address address) { + public MutableAccount getAccount(final Address address) { return super.getAccount(address); } @Override - public EvmAccount createAccount(final Address address, final long nonce, final Wei balance) { + public MutableAccount createAccount(final Address address, final long nonce, final Wei balance) { BonsaiValue bonsaiValue = accountsToUpdate.get(address); if (bonsaiValue == null) { @@ -141,7 +141,7 @@ public EvmAccount createAccount(final Address address, final long nonce, final W Hash.EMPTY, true); bonsaiValue.setUpdated(newAccount); - return new WrappedEvmAccount(track(new UpdateTrackingAccount<>(newAccount))); + return track(new UpdateTrackingAccount<>(newAccount)); } @Override @@ -176,17 +176,15 @@ protected BonsaiAccount loadAccount( final BonsaiValue bonsaiValue = accountsToUpdate.get(address); if (bonsaiValue == null) { final Account account; - if (wrappedWorldView() instanceof BonsaiWorldStateUpdateAccumulator) { - account = - ((BonsaiWorldStateUpdateAccumulator) wrappedWorldView()) - .loadAccount(address, bonsaiAccountFunction); + if (wrappedWorldView() + instanceof BonsaiWorldStateUpdateAccumulator bonsaiWorldStateUpdateAccumulator) { + account = bonsaiWorldStateUpdateAccumulator.loadAccount(address, bonsaiAccountFunction); } else { account = wrappedWorldView().get(address); } - BonsaiAccount mutableAccount = null; - if (account instanceof BonsaiAccount) { - mutableAccount = new BonsaiAccount((BonsaiAccount) account, this, true); - accountsToUpdate.put(address, new BonsaiValue<>((BonsaiAccount) account, mutableAccount)); + if (account instanceof BonsaiAccount bonsaiAccount) { + BonsaiAccount mutableAccount = new BonsaiAccount(bonsaiAccount, this, true); + accountsToUpdate.put(address, new BonsaiValue<>(bonsaiAccount, mutableAccount)); return mutableAccount; } else { // add the empty read in accountsToUpdate @@ -418,14 +416,13 @@ public Optional getStorageValueByStorageSlotKey( } try { final Optional valueUInt = - (wrappedWorldView() instanceof BonsaiWorldState) - ? ((BonsaiWorldState) wrappedWorldView()) - .getStorageValueByStorageSlotKey( - () -> - Optional.ofNullable(loadAccount(address, BonsaiValue::getPrior)) - .map(BonsaiAccount::getStorageRoot), - address, - storageSlotKey) + (wrappedWorldView() instanceof BonsaiWorldState bonsaiWorldState) + ? bonsaiWorldState.getStorageValueByStorageSlotKey( + () -> + Optional.ofNullable(loadAccount(address, BonsaiValue::getPrior)) + .map(BonsaiAccount::getStorageRoot), + address, + storageSlotKey) : wrappedWorldView().getStorageValueByStorageSlotKey(address, storageSlotKey); storageToUpdate .computeIfAbsent( @@ -495,53 +492,43 @@ public BonsaiWorldStateKeyValueStorage getWorldStateStorage() { } public void rollForward(final TrieLog layer) { - layer.getAccountChanges().entrySet().stream() + layer + .getAccountChanges() .forEach( - entry -> - rollAccountChange( - entry.getKey(), entry.getValue().getPrior(), entry.getValue().getUpdated())); - layer.getCodeChanges().entrySet().stream() + (address, change) -> + rollAccountChange(address, change.getPrior(), change.getUpdated())); + layer + .getCodeChanges() .forEach( - entry -> - rollCodeChange( - entry.getKey(), entry.getValue().getPrior(), entry.getValue().getUpdated())); - layer.getStorageChanges().entrySet().stream() + (address, change) -> rollCodeChange(address, change.getPrior(), change.getUpdated())); + layer + .getStorageChanges() .forEach( - entry -> - entry - .getValue() - .forEach( - (storageSlotKey, value) -> - rollStorageChange( - entry.getKey(), - storageSlotKey, - value.getPrior(), - value.getUpdated()))); + (address, storage) -> + storage.forEach( + (storageSlotKey, value) -> + rollStorageChange( + address, storageSlotKey, value.getPrior(), value.getUpdated()))); } public void rollBack(final TrieLog layer) { - layer.getAccountChanges().entrySet().stream() + layer + .getAccountChanges() .forEach( - entry -> - rollAccountChange( - entry.getKey(), entry.getValue().getUpdated(), entry.getValue().getPrior())); - layer.getCodeChanges().entrySet().stream() + (address, change) -> + rollAccountChange(address, change.getUpdated(), change.getPrior())); + layer + .getCodeChanges() .forEach( - entry -> - rollCodeChange( - entry.getKey(), entry.getValue().getUpdated(), entry.getValue().getPrior())); - layer.getStorageChanges().entrySet().stream() + (address, change) -> rollCodeChange(address, change.getUpdated(), change.getPrior())); + layer + .getStorageChanges() .forEach( - entry -> - entry - .getValue() - .forEach( - (storageSlotKey, value) -> - rollStorageChange( - entry.getKey(), - storageSlotKey, - value.getUpdated(), - value.getPrior()))); + (address, storage) -> + storage.forEach( + (storageSlotKey, value) -> + rollStorageChange( + address, storageSlotKey, value.getUpdated(), value.getPrior()))); } private void rollAccountChange( @@ -598,8 +585,7 @@ private BonsaiValue loadAccountFromParent( final Address address, final BonsaiValue defaultValue) { try { final Account parentAccount = wrappedWorldView().get(address); - if (parentAccount instanceof BonsaiAccount) { - final BonsaiAccount account = (BonsaiAccount) parentAccount; + if (parentAccount instanceof BonsaiAccount account) { final BonsaiValue loadedAccountValue = new BonsaiValue<>(new BonsaiAccount(account), account); accountsToUpdate.put(address, loadedAccountValue); @@ -634,7 +620,7 @@ private void rollCodeChange( } if (codeValue == null) { - if ((expectedCode == null || expectedCode.size() == 0) && replacementCode != null) { + if ((expectedCode == null || expectedCode.isEmpty()) && replacementCode != null) { codeToUpdate.put(address, new BonsaiValue<>(null, replacementCode)); } else { throw new IllegalStateException( @@ -772,11 +758,11 @@ public void reset() { public static class AccountConsumingMap extends ForwardingMap { - private final ConcurrentHashMap accounts; + private final ConcurrentMap accounts; private final Consumer consumer; public AccountConsumingMap( - final ConcurrentHashMap accounts, final Consumer consumer) { + final ConcurrentMap accounts, final Consumer consumer) { this.accounts = accounts; this.consumer = consumer; } @@ -801,11 +787,11 @@ public static class StorageConsumingMap extends ForwardingMap { private final Address address; - private final ConcurrentHashMap storages; + private final ConcurrentMap storages; private final Consumer consumer; public StorageConsumingMap( - final Address address, final ConcurrentHashMap storages, final Consumer consumer) { + final Address address, final ConcurrentMap storages, final Consumer consumer) { this.address = address; this.storages = storages; this.consumer = consumer; diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/chain/GenesisState.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/chain/GenesisState.java index b873161976a..f6c969d58b2 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/chain/GenesisState.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/chain/GenesisState.java @@ -48,7 +48,6 @@ import java.util.Optional; import java.util.OptionalLong; import java.util.function.Function; -import java.util.stream.Collectors; import java.util.stream.Stream; import com.google.common.base.MoreObjects; @@ -86,8 +85,7 @@ public static GenesisState fromJson(final String json, final ProtocolSchedule pr */ public static GenesisState fromConfig( final GenesisConfigFile config, final ProtocolSchedule protocolSchedule) { - final List genesisAccounts = - parseAllocations(config).collect(Collectors.toList()); + final List genesisAccounts = parseAllocations(config).toList(); final Block block = new Block( buildHeader(config, calculateGenesisStateHash(genesisAccounts), protocolSchedule), @@ -124,7 +122,7 @@ private static void writeAccountsTo( final WorldUpdater updater = target.updater(); genesisAccounts.forEach( genesisAccount -> { - final MutableAccount account = updater.getOrCreate(genesisAccount.address).getMutable(); + final MutableAccount account = updater.getOrCreate(genesisAccount.address); account.setNonce(genesisAccount.nonce); account.setBalance(genesisAccount.balance); account.setCode(genesisAccount.code); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ClassicBlockProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ClassicBlockProcessor.java index 5079c0763be..044017b8728 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ClassicBlockProcessor.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ClassicBlockProcessor.java @@ -64,7 +64,7 @@ boolean rewardCoinbase( } final Wei coinbaseReward = getCoinbaseReward(blockReward, header.getNumber(), ommers.size()); final WorldUpdater updater = worldState.updater(); - final MutableAccount coinbase = updater.getOrCreate(header.getCoinbase()).getMutable(); + final MutableAccount coinbase = updater.getOrCreate(header.getCoinbase()); coinbase.incrementBalance(coinbaseReward); for (final BlockHeader ommerHeader : ommers) { @@ -77,8 +77,7 @@ boolean rewardCoinbase( return false; } - final MutableAccount ommerCoinbase = - updater.getOrCreate(ommerHeader.getCoinbase()).getMutable(); + final MutableAccount ommerCoinbase = updater.getOrCreate(ommerHeader.getCoinbase()); final Wei ommerReward = getOmmerReward(blockReward, header.getNumber(), ommerHeader.getNumber()); ommerCoinbase.incrementBalance(ommerReward); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockProcessor.java index ae1187eb6bb..9f2096f63d2 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockProcessor.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockProcessor.java @@ -59,8 +59,7 @@ protected boolean rewardCoinbase( final Wei coinbaseReward = getCoinbaseReward(blockReward, header.getNumber(), ommers.size()); final WorldUpdater updater = worldState.updater(); final Address miningBeneficiary = getMiningBeneficiaryCalculator().calculateBeneficiary(header); - final MutableAccount miningBeneficiaryAccount = - updater.getOrCreate(miningBeneficiary).getMutable(); + final MutableAccount miningBeneficiaryAccount = updater.getOrCreate(miningBeneficiary); miningBeneficiaryAccount.incrementBalance(coinbaseReward); for (final BlockHeader ommerHeader : ommers) { @@ -73,8 +72,7 @@ protected boolean rewardCoinbase( return false; } - final MutableAccount ommerCoinbase = - updater.getOrCreate(ommerHeader.getCoinbase()).getMutable(); + final MutableAccount ommerCoinbase = updater.getOrCreate(ommerHeader.getCoinbase()); final Wei ommerReward = getOmmerReward(blockReward, header.getNumber(), ommerHeader.getNumber()); ommerCoinbase.incrementBalance(ommerReward); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecs.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecs.java index dd94e60b5bd..02f757483df 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecs.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecs.java @@ -870,9 +870,9 @@ private void updateWorldStateForDao(final MutableWorldState worldState) { .toList(); final WorldUpdater worldUpdater = worldState.updater(); final MutableAccount daoRefundContract = - worldUpdater.getOrCreate(DAO_REFUND_CONTRACT_ADDRESS).getMutable(); + worldUpdater.getOrCreate(DAO_REFUND_CONTRACT_ADDRESS); for (final Address address : addresses) { - final MutableAccount account = worldUpdater.getOrCreate(address).getMutable(); + final MutableAccount account = worldUpdater.getOrCreate(address); final Wei balance = account.getBalance(); account.decrementBalance(balance); daoRefundContract.incrementBalance(balance); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java index 6dbd3b4c3db..7d235fb3a39 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java @@ -33,7 +33,6 @@ import org.hyperledger.besu.ethereum.trie.MerkleTrieException; import org.hyperledger.besu.ethereum.vm.BlockHashLookup; import org.hyperledger.besu.evm.account.Account; -import org.hyperledger.besu.evm.account.EvmAccount; import org.hyperledger.besu.evm.account.MutableAccount; import org.hyperledger.besu.evm.code.CodeV0; import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; @@ -285,7 +284,7 @@ public TransactionProcessingResult processTransaction( final Address senderAddress = transaction.getSender(); - final EvmAccount sender = worldState.getOrCreateSenderAccount(senderAddress); + final MutableAccount sender = worldState.getOrCreateSenderAccount(senderAddress); validationResult = transactionValidator.validateForSender(transaction, sender, transactionValidationParams); @@ -294,8 +293,7 @@ public TransactionProcessingResult processTransaction( return TransactionProcessingResult.invalid(validationResult); } - final MutableAccount senderMutableAccount = sender.getMutable(); - final long previousNonce = senderMutableAccount.incrementNonce(); + final long previousNonce = sender.incrementNonce(); LOG.trace( "Incremented sender {} nonce ({} -> {})", senderAddress, @@ -309,7 +307,7 @@ public TransactionProcessingResult processTransaction( final Wei upfrontGasCost = transaction.getUpfrontGasCost(transactionGasPrice, blobGasPrice, blobGas); - final Wei previousBalance = senderMutableAccount.decrementBalance(upfrontGasCost); + final Wei previousBalance = sender.decrementBalance(upfrontGasCost); LOG.trace( "Deducted sender {} upfront gas cost {} ({} -> {})", senderAddress, @@ -386,7 +384,7 @@ public TransactionProcessingResult processTransaction( final MessageFrame initialFrame; if (transaction.isContractCreation()) { final Address contractAddress = - Address.contractAddress(senderAddress, senderMutableAccount.getNonce() - 1L); + Address.contractAddress(senderAddress, sender.getNonce() - 1L); final Bytes initCodeBytes = transaction.getPayload(); initialFrame = @@ -443,7 +441,7 @@ public TransactionProcessingResult processTransaction( final long refundedGas = refunded(transaction, initialFrame.getRemainingGas(), baseRefundGas); final Wei refundedWei = transactionGasPrice.multiply(refundedGas); final Wei balancePriorToRefund = sender.getBalance(); - senderMutableAccount.incrementBalance(refundedWei); + sender.incrementBalance(refundedWei); LOG.atTrace() .setMessage("refunded sender {} {} wei ({} -> {})") .addArgument(senderAddress) @@ -454,7 +452,7 @@ public TransactionProcessingResult processTransaction( final long gasUsedByTransaction = transaction.getGasLimit() - initialFrame.getRemainingGas(); // update the coinbase - final var coinbase = worldState.getOrCreate(miningBeneficiary).getMutable(); + final var coinbase = worldState.getOrCreate(miningBeneficiary); final long usedGas = transaction.getGasLimit() - refundedGas; final CoinbaseFeePriceCalculator coinbaseCalculator; if (blockHeader.getBaseFee().isPresent()) { diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ParentBeaconBlockRootHelper.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ParentBeaconBlockRootHelper.java index 7d110fb425b..669815f7d52 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ParentBeaconBlockRootHelper.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ParentBeaconBlockRootHelper.java @@ -22,14 +22,14 @@ import org.apache.tuweni.units.bigints.UInt256; /** A helper class to store the parent beacon block root. */ -public class ParentBeaconBlockRootHelper { +public interface ParentBeaconBlockRootHelper { // Modulus use to for the timestamp to store the root public static final long HISTORICAL_ROOTS_MODULUS = 8191; public static final Address BEACON_ROOTS_ADDRESS = Address.fromHexString("0xBEaC020001c6C8B69E5257f4754e46e25f5dc9cB"); - public static void storeParentBeaconBlockRoot( + static void storeParentBeaconBlockRoot( final WorldUpdater worldUpdater, final long timestamp, final Bytes32 root) { /* see EIP-4788: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-4788.md @@ -40,7 +40,7 @@ public static void storeParentBeaconBlockRoot( final UInt256 timestampIndex = UInt256.valueOf(timestampReduced); final UInt256 rootIndex = UInt256.valueOf(timestampExtended); - final MutableAccount account = worldUpdater.getOrCreate(BEACON_ROOTS_ADDRESS).getMutable(); + final MutableAccount account = worldUpdater.getOrCreate(BEACON_ROOTS_ADDRESS); account.setStorageValue(timestampIndex, UInt256.valueOf(timestamp)); account.setStorageValue(rootIndex, UInt256.fromBytes(root)); worldUpdater.commit(); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/WithdrawalsProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/WithdrawalsProcessor.java index b91f81208a6..d2b0f8edf78 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/WithdrawalsProcessor.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/WithdrawalsProcessor.java @@ -15,7 +15,7 @@ package org.hyperledger.besu.ethereum.mainnet; import org.hyperledger.besu.ethereum.core.Withdrawal; -import org.hyperledger.besu.evm.account.EvmAccount; +import org.hyperledger.besu.evm.account.MutableAccount; import org.hyperledger.besu.evm.worldstate.WorldUpdater; import java.util.List; @@ -25,8 +25,8 @@ public class WithdrawalsProcessor { public void processWithdrawals( final List withdrawals, final WorldUpdater worldUpdater) { for (final Withdrawal withdrawal : withdrawals) { - final EvmAccount account = worldUpdater.getOrCreate(withdrawal.getAddress()); - account.getMutable().incrementBalance(withdrawal.getAmount().getAsWei()); + final MutableAccount account = worldUpdater.getOrCreate(withdrawal.getAddress()); + account.incrementBalance(withdrawal.getAmount().getAsWei()); } worldUpdater.clearAccountsThatAreEmpty(); worldUpdater.commit(); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateGroupRehydrationBlockProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateGroupRehydrationBlockProcessor.java index 713d73c48e5..462bd9c6619 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateGroupRehydrationBlockProcessor.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateGroupRehydrationBlockProcessor.java @@ -231,7 +231,7 @@ private boolean rewardCoinbase( final Wei coinbaseReward = blockReward.add(blockReward.multiply(ommers.size()).divide(32)); final WorldUpdater updater = worldState.updater(); - final MutableAccount coinbase = updater.getOrCreate(header.getCoinbase()).getMutable(); + final MutableAccount coinbase = updater.getOrCreate(header.getCoinbase()); coinbase.incrementBalance(coinbaseReward); for (final BlockHeader ommerHeader : ommers) { @@ -245,8 +245,7 @@ private boolean rewardCoinbase( return false; } - final MutableAccount ommerCoinbase = - updater.getOrCreate(ommerHeader.getCoinbase()).getMutable(); + final MutableAccount ommerCoinbase = updater.getOrCreate(ommerHeader.getCoinbase()); final long distance = header.getNumber() - ommerHeader.getNumber(); final Wei ommerReward = blockReward.subtract(blockReward.multiply(distance).divide(8)); ommerCoinbase.incrementBalance(ommerReward); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateStateGenesisAllocator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateStateGenesisAllocator.java index 1f84f210b92..f1a022fa7c2 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateStateGenesisAllocator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateStateGenesisAllocator.java @@ -56,7 +56,7 @@ public void applyGenesisToPrivateWorldState( final PrivacyGenesis genesis = privacyGroupGenesisProvider.getPrivacyGenesis(privacyGroupId, blockNumber); - if (genesis.getAccounts().size() > 0) { + if (!genesis.getAccounts().isEmpty()) { LOG.debug( "Applying {} privacy accounts onto {} private state genesis at {}", @@ -67,15 +67,14 @@ public void applyGenesisToPrivateWorldState( genesis .getAccounts() .forEach( - (genesisAccount) -> { + genesisAccount -> { final Address address = genesisAccount.getAddress(); if (address.toBigInteger().compareTo(BigInteger.valueOf(Byte.MAX_VALUE)) < 0) { LOG.warn( "Genesis address {} is in reserved range and may be overwritten", address); } - final MutableAccount account = - privateWorldStateUpdater.createAccount(address).getMutable(); + final MutableAccount account = privateWorldStateUpdater.createAccount(address); LOG.debug("{} applied to genesis", address.toHexString()); @@ -90,14 +89,14 @@ public void applyGenesisToPrivateWorldState( if (isFlexiblePrivacyEnabled) { // inject management final MutableAccount managementContract = - privateWorldStateUpdater.createAccount(DEFAULT_FLEXIBLE_PRIVACY_MANAGEMENT).getMutable(); + privateWorldStateUpdater.createAccount(DEFAULT_FLEXIBLE_PRIVACY_MANAGEMENT); // this is the code for the simple management contract managementContract.setCode(FlexibleGroupManagement.DEFAULT_GROUP_MANAGEMENT_RUNTIME_BYTECODE); // inject proxy final MutableAccount procyContract = - privateWorldStateUpdater.createAccount(FLEXIBLE_PRIVACY_PROXY).getMutable(); + privateWorldStateUpdater.createAccount(FLEXIBLE_PRIVACY_PROXY); // this is the code for the proxy contract procyContract.setCode(FlexibleGroupManagement.PROXY_RUNTIME_BYTECODE); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateTransactionProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateTransactionProcessor.java index 2eeb29cf32b..c953ed93d1d 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateTransactionProcessor.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateTransactionProcessor.java @@ -26,7 +26,6 @@ import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason; import org.hyperledger.besu.ethereum.worldstate.DefaultMutablePrivateWorldStateUpdater; import org.hyperledger.besu.evm.account.Account; -import org.hyperledger.besu.evm.account.EvmAccount; import org.hyperledger.besu.evm.account.MutableAccount; import org.hyperledger.besu.evm.code.CodeV0; import org.hyperledger.besu.evm.frame.MessageFrame; @@ -90,11 +89,11 @@ public TransactionProcessingResult processTransaction( LOG.trace("Starting private execution of {}", transaction); final Address senderAddress = transaction.getSender(); - final EvmAccount maybePrivateSender = privateWorldState.getAccount(senderAddress); + final MutableAccount maybePrivateSender = privateWorldState.getAccount(senderAddress); final MutableAccount sender = maybePrivateSender != null - ? maybePrivateSender.getMutable() - : privateWorldState.createAccount(senderAddress, 0, Wei.ZERO).getMutable(); + ? maybePrivateSender + : privateWorldState.createAccount(senderAddress, 0, Wei.ZERO); final ValidationResult validationResult = privateTransactionValidator.validate(transaction, sender.getNonce(), false); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/storage/migration/PrivateMigrationBlockProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/storage/migration/PrivateMigrationBlockProcessor.java index 73ebea34384..0310700e1f5 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/storage/migration/PrivateMigrationBlockProcessor.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/storage/migration/PrivateMigrationBlockProcessor.java @@ -141,7 +141,7 @@ private boolean rewardCoinbase( final Wei coinbaseReward = blockReward.add(blockReward.multiply(ommers.size()).divide(32)); final WorldUpdater updater = worldState.updater(); - final MutableAccount coinbase = updater.getOrCreate(header.getCoinbase()).getMutable(); + final MutableAccount coinbase = updater.getOrCreate(header.getCoinbase()); coinbase.incrementBalance(coinbaseReward); for (final BlockHeader ommerHeader : ommers) { @@ -155,8 +155,7 @@ private boolean rewardCoinbase( return false; } - final MutableAccount ommerCoinbase = - updater.getOrCreate(ommerHeader.getCoinbase()).getMutable(); + final MutableAccount ommerCoinbase = updater.getOrCreate(ommerHeader.getCoinbase()); final long distance = header.getNumber() - ommerHeader.getNumber(); final Wei ommerReward = blockReward.subtract(blockReward.multiply(distance).divide(8)); ommerCoinbase.incrementBalance(ommerReward); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/DebugOperationTracer.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/DebugOperationTracer.java index 07a10e218ab..b1ef1bc0b1c 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/DebugOperationTracer.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/DebugOperationTracer.java @@ -199,11 +199,8 @@ private Optional> captureStorage(final MessageFrame frame) try { final Map storageContents = new TreeMap<>( - frame - .getWorldUpdater() - .getAccount(frame.getRecipientAddress()) - .getMutable() - .getUpdatedStorage()); + frame.getWorldUpdater().getAccount(frame.getRecipientAddress()).getUpdatedStorage()); + return Optional.of(storageContents); } catch (final ModificationNotAllowedException e) { return Optional.of(new TreeMap<>()); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/worldstate/DefaultMutablePrivateWorldStateUpdater.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/worldstate/DefaultMutablePrivateWorldStateUpdater.java index fe1bf39ecbd..e52319463cc 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/worldstate/DefaultMutablePrivateWorldStateUpdater.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/worldstate/DefaultMutablePrivateWorldStateUpdater.java @@ -17,9 +17,8 @@ import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.evm.account.Account; -import org.hyperledger.besu.evm.account.EvmAccount; +import org.hyperledger.besu.evm.account.MutableAccount; import org.hyperledger.besu.evm.worldstate.WorldUpdater; -import org.hyperledger.besu.evm.worldstate.WrappedEvmAccount; import java.util.Collection; import java.util.Optional; @@ -39,24 +38,24 @@ public DefaultMutablePrivateWorldStateUpdater( } @Override - public EvmAccount createAccount(final Address address, final long nonce, final Wei balance) { + public MutableAccount createAccount(final Address address, final long nonce, final Wei balance) { return privateWorldUpdater.createAccount(address, nonce, balance); } @Override - public EvmAccount createAccount(final Address address) { + public MutableAccount createAccount(final Address address) { return privateWorldUpdater.createAccount(address); } @Override - public EvmAccount getAccount(final Address address) { - final EvmAccount privateAccount = privateWorldUpdater.getAccount(address); + public MutableAccount getAccount(final Address address) { + final MutableAccount privateAccount = privateWorldUpdater.getAccount(address); if (privateAccount != null && !privateAccount.isEmpty()) { return privateAccount; } - final EvmAccount publicAccount = publicWorldUpdater.getAccount(address); + final MutableAccount publicAccount = publicWorldUpdater.getAccount(address); if (publicAccount != null && !publicAccount.isEmpty()) { - ((WrappedEvmAccount) publicAccount).setImmutable(true); // FIXME + publicAccount.becomeImmutable(); return publicAccount; } return privateAccount; diff --git a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlockDataGenerator.java b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlockDataGenerator.java index e02406927fc..3b2b8e30958 100644 --- a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlockDataGenerator.java +++ b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlockDataGenerator.java @@ -15,7 +15,6 @@ package org.hyperledger.besu.ethereum.core; import static com.google.common.base.Preconditions.checkArgument; -import static java.util.stream.Collectors.toUnmodifiableList; import static java.util.stream.Collectors.toUnmodifiableSet; import static org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider.createInMemoryWorldStateArchive; @@ -58,7 +57,6 @@ import java.util.Random; import java.util.Set; import java.util.function.Supplier; -import java.util.stream.Collectors; import java.util.stream.Stream; import org.apache.tuweni.bytes.Bytes; @@ -141,7 +139,7 @@ private List blockSequence( // Mutate accounts accountsToSetup.forEach( hash -> { - final MutableAccount a = stateUpdater.getAccount(hash).getMutable(); + final MutableAccount a = stateUpdater.getAccount(hash); a.incrementNonce(); a.setBalance(Wei.of(positiveLong())); storageKeys.forEach(key -> a.setStorageValue(key, UInt256.ONE)); @@ -181,7 +179,7 @@ private List createRandomAccounts( final WorldUpdater updater = worldState.updater(); final List accounts = new ArrayList<>(count); for (int i = 0; i < count; i++) { - final MutableAccount account = updater.getOrCreate(address()).getMutable(); + final MutableAccount account = updater.getOrCreate(address()); if (random.nextFloat() < percentContractAccounts) { // Some percentage of accounts are contract accounts account.setCode(bytesValue(5, 50)); @@ -373,21 +371,13 @@ public Transaction transaction(final TransactionType transactionType, final Byte public Transaction transaction( final TransactionType transactionType, final Bytes payload, final Address to) { - switch (transactionType) { - case FRONTIER: - return frontierTransaction(payload, to); - case EIP1559: - return eip1559Transaction(payload, to); - case ACCESS_LIST: - return accessListTransaction(payload, to); - case BLOB: - return blobTransaction(payload, to); - default: - throw new RuntimeException( - String.format( - "Developer Error. No random transaction generator defined for %s", - transactionType)); - } + return switch (transactionType) { + case FRONTIER -> frontierTransaction(payload, to); + case EIP1559 -> eip1559Transaction(payload, to); + case ACCESS_LIST -> accessListTransaction(payload, to); + case BLOB -> blobTransaction(payload, to); + // no default, all types accounted for. + }; } private Transaction accessListTransaction(final Bytes payload, final Address to) { @@ -406,13 +396,12 @@ private Transaction accessListTransaction(final Bytes payload, final Address to) private List accessList() { final List
accessedAddresses = - Stream.generate(this::address).limit(1L + random.nextInt(3)).collect(toUnmodifiableList()); + Stream.generate(this::address).limit(1L + random.nextInt(3)).toList(); final List accessedStorage = new ArrayList<>(); for (int i = 0; i < accessedAddresses.size(); ++i) { accessedStorage.add( new AccessListEntry( - accessedAddresses.get(i), - Stream.generate(this::bytes32).limit(2L * i).collect(toUnmodifiableList()))); + accessedAddresses.get(i), Stream.generate(this::bytes32).limit(2L * i).toList())); } return accessedStorage; } @@ -469,10 +458,7 @@ public Set transactions(final int n, final TransactionType... trans public Set transactions(final int n) { return transactions( - n, - new TransactionType[] { - TransactionType.FRONTIER, TransactionType.ACCESS_LIST, TransactionType.EIP1559 - }); + n, TransactionType.FRONTIER, TransactionType.ACCESS_LIST, TransactionType.EIP1559); } public Set transactionsWithAllTypes() { @@ -483,10 +469,7 @@ public Set transactionsWithAllTypes(final int atLeast) { checkArgument(atLeast >= 0); final HashSet remainingTransactionTypes = new HashSet<>( - Set.of( - new TransactionType[] { - TransactionType.FRONTIER, TransactionType.ACCESS_LIST, TransactionType.EIP1559 - })); + Set.of(TransactionType.FRONTIER, TransactionType.ACCESS_LIST, TransactionType.EIP1559)); final HashSet transactions = new HashSet<>(); while (transactions.size() < atLeast || !remainingTransactionTypes.isEmpty()) { final Transaction newTransaction = transaction(); @@ -540,7 +523,7 @@ public List receipts(final Block block) { } public List logs(final int logsCount, final int topicsPerLog) { - return Stream.generate(() -> log(topicsPerLog)).limit(logsCount).collect(Collectors.toList()); + return Stream.generate(() -> log(topicsPerLog)).limit(logsCount).toList(); } public Log log() { @@ -548,8 +531,7 @@ public Log log() { } public Log log(final int topicCount) { - final List topics = - Stream.generate(this::logTopic).limit(topicCount).collect(Collectors.toList()); + final List topics = Stream.generate(this::logTopic).limit(topicCount).toList(); return new Log(address(), bytesValue(5, 15), topics); } diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/bonsai/LogRollingTests.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/bonsai/LogRollingTests.java index b26120e69fb..0e2fb0c0d1a 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/bonsai/LogRollingTests.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/bonsai/LogRollingTests.java @@ -53,7 +53,7 @@ import org.mockito.junit.jupiter.MockitoExtension; @ExtendWith(MockitoExtension.class) -public class LogRollingTests { +class LogRollingTests { private BonsaiWorldStateProvider archive; @@ -126,7 +126,7 @@ public class LogRollingTests { new MainnetBlockHeaderFunctions()); @BeforeEach - public void createStorage() { + void createStorage() { provider = new InMemoryKeyValueStorageProvider(); final CachedMerkleTrieLoader cachedMerkleTrieLoader = new CachedMerkleTrieLoader(new NoOpMetricsSystem()); @@ -167,15 +167,14 @@ public void createStorage() { } @Test - public void simpleRollForwardTest() { + void simpleRollForwardTest() { final BonsaiWorldState worldState = new BonsaiWorldState( archive, new BonsaiWorldStateKeyValueStorage(provider, new NoOpMetricsSystem())); final WorldUpdater updater = worldState.updater(); - final MutableAccount mutableAccount = - updater.createAccount(addressOne, 1, Wei.of(1L)).getMutable(); + final MutableAccount mutableAccount = updater.createAccount(addressOne, 1, Wei.of(1L)); mutableAccount.setCode(Bytes.of(0, 1, 2)); mutableAccount.setStorageValue(UInt256.ONE, UInt256.ONE); updater.commit(); @@ -210,14 +209,13 @@ public void simpleRollForwardTest() { } @Test - public void rollForwardTwice() { + void rollForwardTwice() { final BonsaiWorldState worldState = new BonsaiWorldState( archive, new BonsaiWorldStateKeyValueStorage(provider, new NoOpMetricsSystem())); final WorldUpdater updater = worldState.updater(); - final MutableAccount mutableAccount = - updater.createAccount(addressOne, 1, Wei.of(1L)).getMutable(); + final MutableAccount mutableAccount = updater.createAccount(addressOne, 1, Wei.of(1L)); mutableAccount.setCode(Bytes.of(0, 1, 2)); mutableAccount.setStorageValue(UInt256.ONE, UInt256.ONE); updater.commit(); @@ -225,7 +223,7 @@ public void rollForwardTwice() { worldState.persist(headerOne); final WorldUpdater updater2 = worldState.updater(); - final MutableAccount mutableAccount2 = updater2.getAccount(addressOne).getMutable(); + final MutableAccount mutableAccount2 = updater2.getAccount(addressOne); mutableAccount2.setStorageValue(UInt256.ONE, UInt256.valueOf(2)); updater2.commit(); @@ -261,14 +259,13 @@ public void rollForwardTwice() { } @Test - public void rollBackOnce() { + void rollBackOnce() { final BonsaiWorldState worldState = new BonsaiWorldState( archive, new BonsaiWorldStateKeyValueStorage(provider, new NoOpMetricsSystem())); final WorldUpdater updater = worldState.updater(); - final MutableAccount mutableAccount = - updater.createAccount(addressOne, 1, Wei.of(1L)).getMutable(); + final MutableAccount mutableAccount = updater.createAccount(addressOne, 1, Wei.of(1L)); mutableAccount.setCode(Bytes.of(0, 1, 2)); mutableAccount.setStorageValue(UInt256.ONE, UInt256.ONE); updater.commit(); @@ -276,7 +273,7 @@ public void rollBackOnce() { worldState.persist(headerOne); final WorldUpdater updater2 = worldState.updater(); - final MutableAccount mutableAccount2 = updater2.getAccount(addressOne).getMutable(); + final MutableAccount mutableAccount2 = updater2.getAccount(addressOne); mutableAccount2.setStorageValue(UInt256.ONE, UInt256.valueOf(2)); updater2.commit(); @@ -296,7 +293,7 @@ public void rollBackOnce() { final WorldUpdater secondUpdater = secondWorldState.updater(); final MutableAccount secondMutableAccount = - secondUpdater.createAccount(addressOne, 1, Wei.of(1L)).getMutable(); + secondUpdater.createAccount(addressOne, 1, Wei.of(1L)); secondMutableAccount.setCode(Bytes.of(0, 1, 2)); secondMutableAccount.setStorageValue(UInt256.ONE, UInt256.ONE); secondUpdater.commit(); diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessorTest.java index 2fe864a5c90..4bc2c6944e2 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessorTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessorTest.java @@ -29,7 +29,6 @@ import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason; import org.hyperledger.besu.ethereum.vm.BlockHashLookup; -import org.hyperledger.besu.evm.account.EvmAccount; import org.hyperledger.besu.evm.account.MutableAccount; import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.gascalculator.GasCalculator; @@ -49,7 +48,7 @@ import org.mockito.junit.jupiter.MockitoExtension; @ExtendWith(MockitoExtension.class) -public class MainnetTransactionProcessorTest { +class MainnetTransactionProcessorTest { private static final int MAX_STACK_SIZE = 1024; @@ -67,8 +66,7 @@ public class MainnetTransactionProcessorTest { @Mock private Transaction transaction; @Mock private BlockHashLookup blockHashLookup; - @Mock private EvmAccount senderAccount; - @Mock private MutableAccount mutableSenderAccount; + @Mock private MutableAccount senderAccount; MainnetTransactionProcessor createTransactionProcessor(final boolean warmCoinbase) { return new MainnetTransactionProcessor( @@ -84,14 +82,13 @@ MainnetTransactionProcessor createTransactionProcessor(final boolean warmCoinbas } @Test - public void shouldWarmCoinbaseIfRequested() { + void shouldWarmCoinbaseIfRequested() { Optional
toAddresss = Optional.of(Address.fromHexString("0x2222222222222222222222222222222222222222")); when(transaction.getTo()).thenReturn(toAddresss); Address senderAddress = Address.fromHexString("0x5555555555555555555555555555555555555555"); Address coinbaseAddress = Address.fromHexString("0x4242424242424242424242424242424242424242"); - when(senderAccount.getMutable()).thenReturn(mutableSenderAccount); when(transaction.getHash()).thenReturn(Hash.EMPTY); when(transaction.getPayload()).thenReturn(Bytes.EMPTY); when(transaction.getSender()).thenReturn(senderAddress); @@ -145,7 +142,7 @@ public void shouldWarmCoinbaseIfRequested() { } @Test - public void shouldCallTransactionValidatorWithExpectedTransactionValidationParams() { + void shouldCallTransactionValidatorWithExpectedTransactionValidationParams() { final ArgumentCaptor txValidationParamCaptor = transactionValidationParamCaptor(); diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/PrivacyBlockProcessorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/PrivacyBlockProcessorTest.java index 8835854ee05..4711e456cf0 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/PrivacyBlockProcessorTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/PrivacyBlockProcessorTest.java @@ -45,7 +45,6 @@ import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; import org.hyperledger.besu.evm.account.MutableAccount; import org.hyperledger.besu.evm.worldstate.WorldUpdater; -import org.hyperledger.besu.evm.worldstate.WrappedEvmAccount; import org.hyperledger.besu.services.kvstore.InMemoryKeyValueStorage; import java.util.Collections; @@ -59,7 +58,7 @@ import org.mockito.junit.jupiter.MockitoExtension; @ExtendWith(MockitoExtension.class) -public class PrivacyBlockProcessorTest { +class PrivacyBlockProcessorTest { private PrivacyBlockProcessor privacyBlockProcessor; private PrivateStateStorage privateStateStorage; @@ -91,7 +90,7 @@ public void setUp() { } @Test - public void mustCopyPreviousPrivacyGroupBlockHeadMap() { + void mustCopyPreviousPrivacyGroupBlockHeadMap() { final BlockDataGenerator blockDataGenerator = new BlockDataGenerator(); final Blockchain blockchain = mock(Blockchain.class); final MutableWorldState mutableWorldState = mock(MutableWorldState.class); @@ -132,7 +131,7 @@ public void mustCopyPreviousPrivacyGroupBlockHeadMap() { } @Test - public void mustPerformRehydration() { + void mustPerformRehydration() { final BlockDataGenerator blockDataGenerator = new BlockDataGenerator(); final Blockchain blockchain = mock(Blockchain.class); final MutableWorldState mutableWorldState = mock(MutableWorldState.class); @@ -191,9 +190,7 @@ public void mustPerformRehydration() { 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); + final MutableAccount mockWrappedEvmAccount = mock(MutableAccount.class); when(mockWorldUpdater.createAccount(any())).thenReturn(mockWrappedEvmAccount); when(mockPrivateState.updater()).thenReturn(mockWorldUpdater); when(mockPrivateState.rootHash()).thenReturn(Hash.ZERO); diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/vm/DebugOperationTracerTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/vm/DebugOperationTracerTest.java index 48fe26af187..146213722b5 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/vm/DebugOperationTracerTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/vm/DebugOperationTracerTest.java @@ -33,7 +33,6 @@ import org.hyperledger.besu.evm.operation.Operation; import org.hyperledger.besu.evm.operation.Operation.OperationResult; import org.hyperledger.besu.evm.worldstate.WorldUpdater; -import org.hyperledger.besu.evm.worldstate.WrappedEvmAccount; import java.util.Map; import java.util.TreeMap; @@ -47,7 +46,7 @@ import org.mockito.junit.jupiter.MockitoExtension; @ExtendWith(MockitoExtension.class) -public class DebugOperationTracerTest { +class DebugOperationTracerTest { private static final int DEPTH = 4; private static final long INITIAL_GAS = 1000L; @@ -65,7 +64,7 @@ public OperationResult execute(final MessageFrame frame, final EVM evm) { }; @Test - public void shouldRecordProgramCounter() { + void shouldRecordProgramCounter() { final MessageFrame frame = validMessageFrame(); frame.setPC(10); final TraceFrame traceFrame = traceFrame(frame); @@ -74,14 +73,14 @@ public void shouldRecordProgramCounter() { } @Test - public void shouldRecordOpcode() { + void shouldRecordOpcode() { final MessageFrame frame = validMessageFrame(); final TraceFrame traceFrame = traceFrame(frame); assertThat(traceFrame.getOpcode()).isEqualTo("MUL"); } @Test - public void shouldRecordDepth() { + void shouldRecordDepth() { final MessageFrame frame = validMessageFrame(); // simulate 4 calls frame.getMessageFrameStack().add(frame); @@ -93,7 +92,7 @@ public void shouldRecordDepth() { } @Test - public void shouldRecordRemainingGas() { + void shouldRecordRemainingGas() { final MessageFrame frame = validMessageFrame(); // final Gas currentGasCost = Gas.of(50); final TraceFrame traceFrame = traceFrame(frame); @@ -101,7 +100,7 @@ public void shouldRecordRemainingGas() { } @Test - public void shouldRecordStackWhenEnabled() { + void shouldRecordStackWhenEnabled() { final MessageFrame frame = validMessageFrame(); final UInt256 stackItem1 = UInt256.fromHexString("0x01"); final UInt256 stackItem2 = UInt256.fromHexString("0x02"); @@ -115,14 +114,14 @@ public void shouldRecordStackWhenEnabled() { } @Test - public void shouldNotRecordStackWhenDisabled() { + void shouldNotRecordStackWhenDisabled() { final TraceFrame traceFrame = traceFrame(validMessageFrame(), new TraceOptions(false, false, false)); assertThat(traceFrame.getStack()).isEmpty(); } @Test - public void shouldRecordMemoryWhenEnabled() { + void shouldRecordMemoryWhenEnabled() { final MessageFrame frame = validMessageFrame(); final Bytes32 word1 = Bytes32.fromHexString("0x01"); final Bytes32 word2 = Bytes32.fromHexString("0x02"); @@ -136,14 +135,14 @@ public void shouldRecordMemoryWhenEnabled() { } @Test - public void shouldNotRecordMemoryWhenDisabled() { + void shouldNotRecordMemoryWhenDisabled() { final TraceFrame traceFrame = traceFrame(validMessageFrame(), new TraceOptions(false, false, false)); assertThat(traceFrame.getMemory()).isEmpty(); } @Test - public void shouldRecordStorageWhenEnabled() { + void shouldRecordStorageWhenEnabled() { final MessageFrame frame = validMessageFrame(); final Map updatedStorage = setupStorageForCapture(frame); final TraceFrame traceFrame = traceFrame(frame, new TraceOptions(true, false, false)); @@ -152,14 +151,14 @@ public void shouldRecordStorageWhenEnabled() { } @Test - public void shouldNotRecordStorageWhenDisabled() { + void shouldNotRecordStorageWhenDisabled() { final TraceFrame traceFrame = traceFrame(validMessageFrame(), new TraceOptions(false, false, false)); assertThat(traceFrame.getStorage()).isEmpty(); } @Test - public void shouldCaptureFrameWhenExceptionalHaltOccurs() { + void shouldCaptureFrameWhenExceptionalHaltOccurs() { final MessageFrame frame = validMessageFrame(); final Map updatedStorage = setupStorageForCapture(frame); @@ -210,15 +209,13 @@ private MessageFrameTestFixture validMessageFrameBuilder() { } private Map setupStorageForCapture(final MessageFrame frame) { - final WrappedEvmAccount account = mock(WrappedEvmAccount.class); - final MutableAccount mutableAccount = mock(MutableAccount.class); - when(account.getMutable()).thenReturn(mutableAccount); + final MutableAccount account = mock(MutableAccount.class); when(worldUpdater.getAccount(frame.getRecipientAddress())).thenReturn(account); final Map updatedStorage = new TreeMap<>(); updatedStorage.put(UInt256.ZERO, UInt256.valueOf(233)); updatedStorage.put(UInt256.ONE, UInt256.valueOf(2424)); - when(mutableAccount.getUpdatedStorage()).thenReturn(updatedStorage); + when(account.getUpdatedStorage()).thenReturn(updatedStorage); final Bytes32 word1 = Bytes32.fromHexString("0x01"); final Bytes32 word2 = Bytes32.fromHexString("0x02"); final Bytes32 word3 = Bytes32.fromHexString("0x03"); diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/worldstate/DefaultMutableWorldStateTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/worldstate/DefaultMutableWorldStateTest.java index 7f910364511..bc632e0f62a 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/worldstate/DefaultMutableWorldStateTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/worldstate/DefaultMutableWorldStateTest.java @@ -46,7 +46,7 @@ // TODO: make that an abstract mutable world state test, and create sub-class for all world state // implementations. -public class DefaultMutableWorldStateTest { +class DefaultMutableWorldStateTest { // The following test cases are loosely derived from the testTransactionToItself // GeneralStateReferenceTest. @@ -64,7 +64,7 @@ private static MutableWorldState createEmpty() { } @Test - public void rootHash_Empty() { + void rootHash_Empty() { final MutableWorldState worldState = createEmpty(); assertThat(worldState.rootHash()).isEqualTo(MerkleTrie.EMPTY_TRIE_NODE_HASH); @@ -73,16 +73,16 @@ public void rootHash_Empty() { } @Test - public void containsAccount_AccountDoesNotExist() { + void containsAccount_AccountDoesNotExist() { final WorldState worldState = createEmpty(); assertThat(worldState.get(ADDRESS)).isNull(); } @Test - public void containsAccount_AccountExists() { + void containsAccount_AccountExists() { final MutableWorldState worldState = createEmpty(); final WorldUpdater updater = worldState.updater(); - updater.createAccount(ADDRESS).getMutable().setBalance(Wei.of(100000)); + updater.createAccount(ADDRESS).setBalance(Wei.of(100000)); updater.commit(); assertThat(worldState.get(ADDRESS)).isNotNull(); assertThat(worldState.rootHash()) @@ -92,7 +92,7 @@ public void containsAccount_AccountExists() { } @Test - public void removeAccount_AccountDoesNotExist() { + void removeAccount_AccountDoesNotExist() { final MutableWorldState worldState = createEmpty(); final WorldUpdater updater = worldState.updater(); updater.deleteAccount(ADDRESS); @@ -104,10 +104,10 @@ public void removeAccount_AccountDoesNotExist() { } @Test - public void removeAccount_UpdatedAccount() { + void removeAccount_UpdatedAccount() { final MutableWorldState worldState = createEmpty(); final WorldUpdater updater = worldState.updater(); - updater.createAccount(ADDRESS).getMutable().setBalance(Wei.of(100000)); + updater.createAccount(ADDRESS).setBalance(Wei.of(100000)); updater.deleteAccount(ADDRESS); updater.commit(); assertThat(worldState.rootHash()).isEqualTo(MerkleTrie.EMPTY_TRIE_NODE_HASH); @@ -117,11 +117,11 @@ public void removeAccount_UpdatedAccount() { } @Test - public void removeAccount_AccountExists() { + void removeAccount_AccountExists() { // Create a world state with one account final MutableWorldState worldState = createEmpty(); WorldUpdater updater = worldState.updater(); - updater.createAccount(ADDRESS).getMutable().setBalance(Wei.of(100000)); + updater.createAccount(ADDRESS).setBalance(Wei.of(100000)); updater.commit(); assertThat(worldState.get(ADDRESS)).isNotNull(); assertThat(worldState.rootHash()).isNotEqualTo(MerkleTrie.EMPTY_TRIE_NODE_HASH); @@ -138,11 +138,11 @@ public void removeAccount_AccountExists() { } @Test - public void removeAccount_AccountExistsAndIsPersisted() { + void removeAccount_AccountExistsAndIsPersisted() { // Create a world state with one account final MutableWorldState worldState = createEmpty(); WorldUpdater updater = worldState.updater(); - updater.createAccount(ADDRESS).getMutable().setBalance(Wei.of(100000)); + updater.createAccount(ADDRESS).setBalance(Wei.of(100000)); updater.commit(); worldState.persist(null); assertThat(worldState.get(ADDRESS)).isNotNull(); @@ -164,35 +164,35 @@ public void removeAccount_AccountExistsAndIsPersisted() { } @Test - public void streamAccounts_empty() { + void streamAccounts_empty() { final MutableWorldState worldState = createEmpty(); final Stream accounts = worldState.streamAccounts(Bytes32.ZERO, 10); - assertThat(accounts.count()).isEqualTo(0L); + assertThat(accounts.count()).isZero(); } @Test - public void streamAccounts_singleAccount() { + void streamAccounts_singleAccount() { final MutableWorldState worldState = createEmpty(); final WorldUpdater updater = worldState.updater(); - updater.createAccount(ADDRESS).getMutable().setBalance(Wei.of(100000)); + updater.createAccount(ADDRESS).setBalance(Wei.of(100000)); updater.commit(); List accounts = worldState.streamAccounts(Bytes32.ZERO, 10).collect(Collectors.toList()); - assertThat(accounts.size()).isEqualTo(1L); + assertThat(accounts).hasSize(1); assertThat(accounts.get(0).getAddress()).hasValue(ADDRESS); assertThat(accounts.get(0).getBalance()).isEqualTo(Wei.of(100000)); // Check again after persisting worldState.persist(null); accounts = worldState.streamAccounts(Bytes32.ZERO, 10).collect(Collectors.toList()); - assertThat(accounts.size()).isEqualTo(1L); + assertThat(accounts).hasSize(1); assertThat(accounts.get(0).getAddress()).hasValue(ADDRESS); assertThat(accounts.get(0).getBalance()).isEqualTo(Wei.of(100000)); } @Test - public void streamAccounts_multipleAccounts() { + void streamAccounts_multipleAccounts() { final Address addr1 = Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"); final Address addr2 = Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0c"); @@ -200,10 +200,10 @@ public void streamAccounts_multipleAccounts() { final WorldUpdater updater = worldState.updater(); // Create an account - final MutableAccount accountA = updater.createAccount(addr1).getMutable(); + final MutableAccount accountA = updater.createAccount(addr1); accountA.setBalance(Wei.of(100000)); // Create another - final MutableAccount accountB = updater.createAccount(addr2).getMutable(); + final MutableAccount accountB = updater.createAccount(addr2); accountB.setNonce(1); // Commit changes updater.commit(); @@ -217,16 +217,14 @@ public void streamAccounts_multipleAccounts() { final Hash startHash = accountAIsFirst ? accountA.getAddressHash() : accountB.getAddressHash(); // Get first account - final List firstAccount = - worldState.streamAccounts(startHash, 1).collect(Collectors.toList()); - assertThat(firstAccount.size()).isEqualTo(1L); + final List firstAccount = worldState.streamAccounts(startHash, 1).toList(); + assertThat(firstAccount).hasSize(1); assertThat(firstAccount.get(0).getAddress()) .hasValue(accountAIsFirst ? accountA.getAddress() : accountB.getAddress()); // Get both accounts - final List allAccounts = - worldState.streamAccounts(Bytes32.ZERO, 2).collect(Collectors.toList()); - assertThat(allAccounts.size()).isEqualTo(2L); + final List allAccounts = worldState.streamAccounts(Bytes32.ZERO, 2).toList(); + assertThat(allAccounts).hasSize(2); assertThat(allAccounts.get(0).getAddress()) .hasValue(accountAIsFirst ? accountA.getAddress() : accountB.getAddress()); assertThat(allAccounts.get(1).getAddress()) @@ -235,14 +233,14 @@ public void streamAccounts_multipleAccounts() { // Get second account final Bytes32 startHashForSecondAccount = UInt256.fromBytes(startHash).add(1L); final List secondAccount = - worldState.streamAccounts(startHashForSecondAccount, 100).collect(Collectors.toList()); - assertThat(secondAccount.size()).isEqualTo(1L); + worldState.streamAccounts(startHashForSecondAccount, 100).toList(); + assertThat(secondAccount).hasSize(1); assertThat(secondAccount.get(0).getAddress()) .hasValue(accountAIsFirst ? accountB.getAddress() : accountA.getAddress()); } @Test - public void commitAndPersist() { + void commitAndPersist() { final KeyValueStorage storage = new InMemoryKeyValueStorage(); final WorldStateKeyValueStorage kvWorldStateStorage = new WorldStateKeyValueStorage(storage); final MutableWorldState worldState = createEmpty(kvWorldStateStorage); @@ -252,7 +250,7 @@ public void commitAndPersist() { Hash.fromHexString("0xa3e1c133a5a51b03399ed9ad0380f3182e9e18322f232b816dd4b9094f871e1b"); // Update account and assert we get the expected response from updater - updater.createAccount(ADDRESS).getMutable().setBalance(newBalance); + updater.createAccount(ADDRESS).setBalance(newBalance); assertThat(updater.get(ADDRESS)).isNotNull(); assertThat(updater.get(ADDRESS).getBalance()).isEqualTo(newBalance); @@ -285,10 +283,10 @@ public void commitAndPersist() { } @Test - public void getAccountNonce_AccountExists() { + void getAccountNonce_AccountExists() { final MutableWorldState worldState = createEmpty(); final WorldUpdater updater = worldState.updater(); - updater.createAccount(ADDRESS).getMutable().setNonce(1L); + updater.createAccount(ADDRESS).setNonce(1L); updater.commit(); assertThat(worldState.get(ADDRESS).getNonce()).isEqualTo(1L); assertThat(worldState.rootHash()) @@ -298,10 +296,10 @@ public void getAccountNonce_AccountExists() { } @Test - public void replaceAccountNonce() { + void replaceAccountNonce() { final MutableWorldState worldState = createEmpty(); final WorldUpdater updater = worldState.updater(); - final MutableAccount account = updater.createAccount(ADDRESS).getMutable(); + final MutableAccount account = updater.createAccount(ADDRESS); account.setNonce(1L); account.setNonce(2L); updater.commit(); @@ -313,19 +311,19 @@ public void replaceAccountNonce() { } @Test - public void getAccountBalance_AccountExists() { + void getAccountBalance_AccountExists() { final MutableWorldState worldState = createEmpty(); final WorldUpdater updater = worldState.updater(); - updater.createAccount(ADDRESS).getMutable().setBalance(Wei.of(100000)); + updater.createAccount(ADDRESS).setBalance(Wei.of(100000)); updater.commit(); assertThat(worldState.get(ADDRESS).getBalance()).isEqualTo(Wei.of(100000)); } @Test - public void replaceAccountBalance() { + void replaceAccountBalance() { final MutableWorldState worldState = createEmpty(); final WorldUpdater updater = worldState.updater(); - final MutableAccount account = updater.createAccount(ADDRESS).getMutable(); + final MutableAccount account = updater.createAccount(ADDRESS); account.setBalance(Wei.of(100000)); account.setBalance(Wei.of(200000)); updater.commit(); @@ -337,10 +335,10 @@ public void replaceAccountBalance() { } @Test - public void setStorageValue_ZeroValue() { + void setStorageValue_ZeroValue() { final MutableWorldState worldState = createEmpty(); final WorldUpdater updater = worldState.updater(); - final MutableAccount account = updater.createAccount(ADDRESS).getMutable(); + final MutableAccount account = updater.createAccount(ADDRESS); account.setBalance(Wei.of(100000)); account.setStorageValue(UInt256.ZERO, UInt256.ZERO); updater.commit(); @@ -352,10 +350,10 @@ public void setStorageValue_ZeroValue() { } @Test - public void setStorageValue_NonzeroValue() { + void setStorageValue_NonzeroValue() { final MutableWorldState worldState = createEmpty(); final WorldUpdater updater = worldState.updater(); - final MutableAccount account = updater.createAccount(ADDRESS).getMutable(); + final MutableAccount account = updater.createAccount(ADDRESS); account.setBalance(Wei.of(100000)); account.setStorageValue(UInt256.ONE, UInt256.valueOf(2)); updater.commit(); @@ -367,10 +365,10 @@ public void setStorageValue_NonzeroValue() { } @Test - public void replaceStorageValue_NonzeroValue() { + void replaceStorageValue_NonzeroValue() { final MutableWorldState worldState = createEmpty(); final WorldUpdater updater = worldState.updater(); - final MutableAccount account = updater.createAccount(ADDRESS).getMutable(); + final MutableAccount account = updater.createAccount(ADDRESS); account.setBalance(Wei.of(100000)); account.setStorageValue(UInt256.ONE, UInt256.valueOf(2)); account.setStorageValue(UInt256.ONE, UInt256.valueOf(3)); @@ -383,10 +381,10 @@ public void replaceStorageValue_NonzeroValue() { } @Test - public void replaceStorageValue_ZeroValue() { + void replaceStorageValue_ZeroValue() { final MutableWorldState worldState = createEmpty(); final WorldUpdater updater = worldState.updater(); - final MutableAccount account = updater.createAccount(ADDRESS).getMutable(); + final MutableAccount account = updater.createAccount(ADDRESS); account.setBalance(Wei.of(100000)); account.setStorageValue(UInt256.ONE, UInt256.valueOf(2)); account.setStorageValue(UInt256.ONE, UInt256.ZERO); @@ -398,15 +396,15 @@ public void replaceStorageValue_ZeroValue() { } @Test - public void getOriginalStorageValue() { + void getOriginalStorageValue() { final MutableWorldState worldState = createEmpty(); final WorldUpdater setupUpdater = worldState.updater(); - final MutableAccount setupAccount = setupUpdater.createAccount(ADDRESS).getMutable(); + final MutableAccount setupAccount = setupUpdater.createAccount(ADDRESS); setupAccount.setStorageValue(UInt256.ONE, UInt256.valueOf(2)); setupUpdater.commit(); final WorldUpdater updater = worldState.updater(); - final MutableAccount account = updater.getOrCreate(ADDRESS).getMutable(); + final MutableAccount account = updater.getOrCreate(ADDRESS); assertThat(account.getOriginalStorageValue(UInt256.ONE)).isEqualTo(UInt256.valueOf(2)); account.setStorageValue(UInt256.ONE, UInt256.valueOf(3)); @@ -414,35 +412,35 @@ public void getOriginalStorageValue() { } @Test - public void originalStorageValueIsAlwaysZeroIfStorageWasCleared() { + void originalStorageValueIsAlwaysZeroIfStorageWasCleared() { final MutableWorldState worldState = createEmpty(); final WorldUpdater setupUpdater = worldState.updater(); - final MutableAccount setupAccount = setupUpdater.createAccount(ADDRESS).getMutable(); + final MutableAccount setupAccount = setupUpdater.createAccount(ADDRESS); setupAccount.setStorageValue(UInt256.ONE, UInt256.valueOf(2)); setupUpdater.commit(); final WorldUpdater updater = worldState.updater(); - final MutableAccount account = updater.getOrCreate(ADDRESS).getMutable(); + final MutableAccount account = updater.getOrCreate(ADDRESS); account.clearStorage(); assertThat(account.getOriginalStorageValue(UInt256.ONE)).isEqualTo(UInt256.ZERO); } @Test - public void clearStorage() { + void clearStorage() { final UInt256 storageKey = UInt256.ONE; final UInt256 storageValue = UInt256.valueOf(2L); // Create a world state with one account final MutableWorldState worldState = createEmpty(); final WorldUpdater updater = worldState.updater(); - MutableAccount account = updater.createAccount(ADDRESS).getMutable(); + MutableAccount account = updater.createAccount(ADDRESS); account.setBalance(Wei.of(100000)); account.setStorageValue(storageKey, storageValue); assertThat(account.getStorageValue(storageKey)).isEqualTo(storageValue); // Clear storage - account = updater.getAccount(ADDRESS).getMutable(); + account = updater.getAccount(ADDRESS); assertThat(account).isNotNull(); assertThat(account.getStorageValue(storageKey)).isEqualTo(storageValue); account.clearStorage(); @@ -462,14 +460,14 @@ public void clearStorage() { } @Test - public void clearStorage_AfterPersisting() { + void clearStorage_AfterPersisting() { final UInt256 storageKey = UInt256.ONE; final UInt256 storageValue = UInt256.valueOf(2L); // Create a world state with one account final MutableWorldState worldState = createEmpty(); final WorldUpdater updater = worldState.updater(); - MutableAccount account = updater.createAccount(ADDRESS).getMutable(); + MutableAccount account = updater.createAccount(ADDRESS); account.setBalance(Wei.of(100000)); account.setStorageValue(storageKey, storageValue); updater.commit(); @@ -478,7 +476,7 @@ public void clearStorage_AfterPersisting() { assertThat(worldState.rootHash()).isNotEqualTo(MerkleTrie.EMPTY_TRIE_NODE_HASH); // Clear storage - account = updater.getAccount(ADDRESS).getMutable(); + account = updater.getAccount(ADDRESS); assertThat(account).isNotNull(); assertThat(account.getStorageValue(storageKey)).isEqualTo(storageValue); account.clearStorage(); @@ -499,7 +497,7 @@ public void clearStorage_AfterPersisting() { } @Test - public void clearStorageThenEdit() { + void clearStorageThenEdit() { final UInt256 storageKey = UInt256.ONE; final UInt256 originalStorageValue = UInt256.valueOf(2L); final UInt256 newStorageValue = UInt256.valueOf(3L); @@ -507,13 +505,13 @@ public void clearStorageThenEdit() { // Create a world state with one account final MutableWorldState worldState = createEmpty(); final WorldUpdater updater = worldState.updater(); - MutableAccount account = updater.createAccount(ADDRESS).getMutable(); + MutableAccount account = updater.createAccount(ADDRESS); account.setBalance(Wei.of(100000)); account.setStorageValue(storageKey, originalStorageValue); assertThat(account.getStorageValue(storageKey)).isEqualTo(originalStorageValue); // Clear storage then edit - account = updater.getAccount(ADDRESS).getMutable(); + account = updater.getAccount(ADDRESS); assertThat(account).isNotNull(); assertThat(account.getStorageValue(storageKey)).isEqualTo(originalStorageValue); assertThat(updater.get(ADDRESS).getStorageValue(storageKey)).isEqualTo(originalStorageValue); @@ -534,7 +532,7 @@ public void clearStorageThenEdit() { } @Test - public void clearStorageThenEditAfterPersisting() { + void clearStorageThenEditAfterPersisting() { final UInt256 storageKey = UInt256.ONE; final UInt256 originalStorageValue = UInt256.valueOf(2L); final UInt256 newStorageValue = UInt256.valueOf(3L); @@ -542,7 +540,7 @@ public void clearStorageThenEditAfterPersisting() { // Create a world state with one account final MutableWorldState worldState = createEmpty(); final WorldUpdater updater = worldState.updater(); - MutableAccount account = updater.createAccount(ADDRESS).getMutable(); + MutableAccount account = updater.createAccount(ADDRESS); account.setBalance(Wei.of(100000)); account.setStorageValue(storageKey, originalStorageValue); assertThat(account.getStorageValue(storageKey)).isEqualTo(originalStorageValue); @@ -550,7 +548,7 @@ public void clearStorageThenEditAfterPersisting() { worldState.persist(null); // Clear storage then edit - account = updater.getAccount(ADDRESS).getMutable(); + account = updater.getAccount(ADDRESS); assertThat(account).isNotNull(); assertThat(account.getStorageValue(storageKey)).isEqualTo(originalStorageValue); assertThat(updater.get(ADDRESS).getStorageValue(storageKey)).isEqualTo(originalStorageValue); @@ -572,10 +570,10 @@ public void clearStorageThenEditAfterPersisting() { } @Test - public void replaceAccountCode() { + void replaceAccountCode() { final MutableWorldState worldState = createEmpty(); final WorldUpdater updater = worldState.updater(); - final MutableAccount account = updater.createAccount(ADDRESS).getMutable(); + final MutableAccount account = updater.createAccount(ADDRESS); account.setBalance(Wei.of(100000)); account.setCode(Bytes.of(1, 2, 3)); account.setCode(Bytes.of(3, 2, 1)); @@ -588,15 +586,15 @@ public void replaceAccountCode() { } @Test - public void revert() { + void revert() { final MutableWorldState worldState = createEmpty(); final WorldUpdater updater1 = worldState.updater(); - final MutableAccount account1 = updater1.createAccount(ADDRESS).getMutable(); + final MutableAccount account1 = updater1.createAccount(ADDRESS); account1.setBalance(Wei.of(200000)); updater1.commit(); final WorldUpdater updater2 = worldState.updater(); - final MutableAccount account2 = updater2.getAccount(ADDRESS).getMutable(); + final MutableAccount account2 = updater2.getAccount(ADDRESS); account2.setBalance(Wei.of(300000)); assertThat(updater2.get(ADDRESS).getBalance()).isEqualTo(Wei.of(300000)); @@ -613,27 +611,27 @@ public void revert() { } @Test - public void shouldReturnNullForGetMutableWhenAccountDeletedInAncestor() { + void shouldReturnNullForGetMutableWhenAccountDeletedInAncestor() { final MutableWorldState worldState = createEmpty(); final WorldUpdater updater1 = worldState.updater(); - final MutableAccount account1 = updater1.createAccount(ADDRESS).getMutable(); + final MutableAccount account1 = updater1.createAccount(ADDRESS); updater1.commit(); assertThat(updater1.get(ADDRESS)) .isEqualToComparingOnlyGivenFields(account1, "address", "nonce", "balance", "codeHash"); updater1.deleteAccount(ADDRESS); final WorldUpdater updater2 = updater1.updater(); - assertThat(updater2.get(ADDRESS)).isEqualTo(null); + assertThat(updater2.get(ADDRESS)).isNull(); final WorldUpdater updater3 = updater2.updater(); - assertThat(updater3.getAccount(ADDRESS)).isEqualTo(null); + assertThat(updater3.getAccount(ADDRESS)).isNull(); } @Test - public void shouldCombineUnchangedAndChangedValuesWhenRetrievingStorageEntries() { + void shouldCombineUnchangedAndChangedValuesWhenRetrievingStorageEntries() { final MutableWorldState worldState = createEmpty(); WorldUpdater updater = worldState.updater(); - MutableAccount account = updater.createAccount(ADDRESS).getMutable(); + MutableAccount account = updater.createAccount(ADDRESS); account.setBalance(Wei.of(100000)); account.setStorageValue(UInt256.ONE, UInt256.valueOf(2)); account.setStorageValue(UInt256.valueOf(2), UInt256.valueOf(5)); @@ -647,7 +645,7 @@ public void shouldCombineUnchangedAndChangedValuesWhenRetrievingStorageEntries() initialSetOfEntries.forEach(entry -> initialEntries.put(entry.getKeyHash(), entry)); updater = worldState.updater(); - account = updater.getAccount(ADDRESS).getMutable(); + account = updater.getAccount(ADDRESS); account.setStorageValue(UInt256.ONE, UInt256.valueOf(3)); account.setStorageValue(UInt256.valueOf(3), UInt256.valueOf(6)); diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/T8nExecutor.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/T8nExecutor.java index 63005b81140..9d2faeb7dc8 100644 --- a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/T8nExecutor.java +++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/T8nExecutor.java @@ -354,7 +354,6 @@ static T8nResult runTest( : Wei.of(Long.decode(rewardString)); worldStateUpdater .getOrCreateSenderAccount(blockHeader.getCoinbase()) - .getMutable() .incrementBalance(reward); } diff --git a/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/ReferenceTestWorldState.java b/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/ReferenceTestWorldState.java index 9518d2c99d4..659847c1211 100644 --- a/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/ReferenceTestWorldState.java +++ b/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/ReferenceTestWorldState.java @@ -81,7 +81,7 @@ public Map getStorage() { static void insertAccount( final WorldUpdater updater, final Address address, final AccountMock toCopy) { - final MutableAccount account = updater.getOrCreate(address).getMutable(); + final MutableAccount account = updater.getOrCreate(address); account.setNonce(toCopy.getNonce()); account.setBalance(toCopy.getBalance()); account.setCode(toCopy.getCode()); diff --git a/evm/src/main/java/org/hyperledger/besu/evm/account/EvmAccount.java b/evm/src/main/java/org/hyperledger/besu/evm/account/EvmAccount.java deleted file mode 100644 index ecd3cf3ceaf..00000000000 --- a/evm/src/main/java/org/hyperledger/besu/evm/account/EvmAccount.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright ConsenSys AG. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - */ -package org.hyperledger.besu.evm.account; - -import org.hyperledger.besu.evm.ModificationNotAllowedException; - -/** The interface Evm account. */ -public interface EvmAccount extends Account { - /** - * Gets mutable account. - * - * @return the mutable account - * @throws ModificationNotAllowedException the modification not allowed exception - */ - public MutableAccount getMutable() throws ModificationNotAllowedException; -} diff --git a/evm/src/main/java/org/hyperledger/besu/evm/account/MutableAccount.java b/evm/src/main/java/org/hyperledger/besu/evm/account/MutableAccount.java index a4caf35c288..455df4a8b3f 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/account/MutableAccount.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/account/MutableAccount.java @@ -105,4 +105,9 @@ default Wei decrementBalance(final Wei value) { * @return a map of storage that has been modified. */ Map getUpdatedStorage(); + + /** + * Make this instance immutable. Used for private world state interactions with public contracts. + */ + void becomeImmutable(); } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/fluent/SimpleAccount.java b/evm/src/main/java/org/hyperledger/besu/evm/fluent/SimpleAccount.java index 75c86070950..b8a4db21eab 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/fluent/SimpleAccount.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/fluent/SimpleAccount.java @@ -21,7 +21,6 @@ import org.hyperledger.besu.evm.ModificationNotAllowedException; import org.hyperledger.besu.evm.account.Account; import org.hyperledger.besu.evm.account.AccountStorageEntry; -import org.hyperledger.besu.evm.account.EvmAccount; import org.hyperledger.besu.evm.account.MutableAccount; import java.util.HashMap; @@ -35,10 +34,12 @@ import org.apache.tuweni.units.bigints.UInt256; /** The Simple account. */ -public class SimpleAccount implements EvmAccount, MutableAccount { +public class SimpleAccount implements MutableAccount { private final Account parent; + private boolean mutable = true; + private Address address; private final Supplier addressHash = Suppliers.memoize(() -> address == null ? Hash.ZERO : address.addressHash()); @@ -137,34 +138,44 @@ public NavigableMap storageEntriesFrom( "Storage iteration not supported in simple account facade"); } - @Override - public MutableAccount getMutable() throws ModificationNotAllowedException { - return this; - } - @Override public void setNonce(final long value) { + if (!mutable) { + throw new ModificationNotAllowedException(); + } nonce = value; } @Override public void setBalance(final Wei value) { + if (!mutable) { + throw new ModificationNotAllowedException(); + } balance = value; } @Override public void setCode(final Bytes code) { + if (!mutable) { + throw new ModificationNotAllowedException(); + } this.code = code; codeHash = Suppliers.memoize(() -> this.code == null ? Hash.EMPTY : Hash.hash(this.code)); } @Override public void setStorageValue(final UInt256 key, final UInt256 value) { + if (!mutable) { + throw new ModificationNotAllowedException(); + } storage.put(key, value); } @Override public void clearStorage() { + if (!mutable) { + throw new ModificationNotAllowedException(); + } storage.clear(); } @@ -172,4 +183,9 @@ public void clearStorage() { public Map getUpdatedStorage() { return storage; } + + @Override + public void becomeImmutable() { + mutable = false; + } } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/fluent/SimpleWorld.java b/evm/src/main/java/org/hyperledger/besu/evm/fluent/SimpleWorld.java index a7288602083..6bc19ca0dae 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/fluent/SimpleWorld.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/fluent/SimpleWorld.java @@ -18,14 +18,13 @@ import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.evm.account.Account; -import org.hyperledger.besu.evm.account.EvmAccount; +import org.hyperledger.besu.evm.account.MutableAccount; import org.hyperledger.besu.evm.worldstate.WorldUpdater; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Optional; -import java.util.stream.Collectors; /** The Simple world. */ public class SimpleWorld implements WorldUpdater { @@ -66,14 +65,14 @@ public Account get(final Address address) { } @Override - public EvmAccount createAccount(final Address address, final long nonce, final Wei balance) { + public MutableAccount createAccount(final Address address, final long nonce, final Wei balance) { SimpleAccount account = new SimpleAccount(address, nonce, balance); accounts.put(address, account); return account; } @Override - public EvmAccount getAccount(final Address address) { + public MutableAccount getAccount(final Address address) { if (accounts.containsKey(address)) { return accounts.get(address); } else if (parent != null) { @@ -98,7 +97,7 @@ public Collection
getDeletedAccountAddresses() { return accounts.entrySet().stream() .filter(e -> e.getValue() == null) .map(Map.Entry::getKey) - .collect(Collectors.toList()); + .toList(); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCreateOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCreateOperation.java index 50ced6fd8b7..d695edf1c8c 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCreateOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCreateOperation.java @@ -79,7 +79,7 @@ public OperationResult execute(final MessageFrame frame, final EVM evm) { final Wei value = Wei.wrap(frame.getStackItem(0)); final Address address = frame.getRecipientAddress(); - final MutableAccount account = frame.getWorldUpdater().getAccount(address).getMutable(); + final MutableAccount account = frame.getWorldUpdater().getAccount(address); frame.clearReturnData(); final long inputOffset = clampedToLong(frame.getStackItem(1)); diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/SStoreOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/SStoreOperation.java index b4fa49751e4..d5055e0bd81 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/SStoreOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/SStoreOperation.java @@ -66,8 +66,7 @@ public OperationResult execute(final MessageFrame frame, final EVM evm) { final UInt256 key = UInt256.fromBytes(frame.popStackItem()); final UInt256 newValue = UInt256.fromBytes(frame.popStackItem()); - final MutableAccount account = - frame.getWorldUpdater().getAccount(frame.getRecipientAddress()).getMutable(); + final MutableAccount account = frame.getWorldUpdater().getAccount(frame.getRecipientAddress()); if (account == null) { return ILLEGAL_STATE_CHANGE; } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/SelfDestructOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/SelfDestructOperation.java index 98807652034..3f29fcea57e 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/SelfDestructOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/SelfDestructOperation.java @@ -75,10 +75,9 @@ public OperationResult execute(final MessageFrame frame, final EVM evm) { } // We passed preliminary checks, get mutable accounts. - final MutableAccount originatorAccount = - frame.getWorldUpdater().getAccount(originatorAddress).getMutable(); + final MutableAccount originatorAccount = frame.getWorldUpdater().getAccount(originatorAddress); final MutableAccount beneficiaryAccount = - frame.getWorldUpdater().getOrCreate(beneficiaryAddress).getMutable(); + frame.getWorldUpdater().getOrCreate(beneficiaryAddress); // Do the "sweep," all modes send all originator balance to the beneficiary account. originatorAccount.decrementBalance(originatorBalance); diff --git a/evm/src/main/java/org/hyperledger/besu/evm/processor/ContractCreationProcessor.java b/evm/src/main/java/org/hyperledger/besu/evm/processor/ContractCreationProcessor.java index 17fa4da60b8..7acea893724 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/processor/ContractCreationProcessor.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/processor/ContractCreationProcessor.java @@ -108,12 +108,11 @@ public void start(final MessageFrame frame, final OperationTracer operationTrace } try { - final MutableAccount sender = frame.getWorldUpdater().getSenderAccount(frame).getMutable(); + final MutableAccount sender = frame.getWorldUpdater().getSenderAccount(frame); sender.decrementBalance(frame.getValue()); Address contractAddress = frame.getContractAddress(); - final MutableAccount contract = - frame.getWorldUpdater().getOrCreate(contractAddress).getMutable(); + final MutableAccount contract = frame.getWorldUpdater().getOrCreate(contractAddress); if (accountExists(contract)) { LOG.trace( "Contract creation error: account has already been created for address {}", @@ -169,7 +168,7 @@ public void codeSuccess(final MessageFrame frame, final OperationTracer operatio // Finalize contract creation, setting the contract code. final MutableAccount contract = - frame.getWorldUpdater().getOrCreate(frame.getContractAddress()).getMutable(); + frame.getWorldUpdater().getOrCreate(frame.getContractAddress()); contract.setCode(contractCode); LOG.trace( "Successful creation of contract {} with code of size {} (Gas remaining: {})", diff --git a/evm/src/main/java/org/hyperledger/besu/evm/processor/MessageCallProcessor.java b/evm/src/main/java/org/hyperledger/besu/evm/processor/MessageCallProcessor.java index b1d41da97a1..0c100e33407 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/processor/MessageCallProcessor.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/processor/MessageCallProcessor.java @@ -18,7 +18,7 @@ import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.evm.EVM; import org.hyperledger.besu.evm.ModificationNotAllowedException; -import org.hyperledger.besu.evm.account.EvmAccount; +import org.hyperledger.besu.evm.account.MutableAccount; import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.precompile.PrecompileContractRegistry; @@ -28,8 +28,8 @@ import java.util.Collection; import java.util.Objects; import java.util.Optional; +import java.util.Set; -import com.google.common.collect.ImmutableSet; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -61,7 +61,7 @@ public MessageCallProcessor( * @param precompiles the precompiles */ public MessageCallProcessor(final EVM evm, final PrecompileContractRegistry precompiles) { - super(evm, ImmutableSet.of()); + super(evm, Set.of()); this.precompiles = precompiles; } @@ -102,11 +102,11 @@ protected void codeSuccess(final MessageFrame frame, final OperationTracer opera * of the world state of this executor. */ private void transferValue(final MessageFrame frame) { - final EvmAccount senderAccount = frame.getWorldUpdater().getSenderAccount(frame); + final MutableAccount senderAccount = frame.getWorldUpdater().getSenderAccount(frame); // The yellow paper explicitly states that if the recipient account doesn't exist at this // point, it is created. Even if the value is zero we are still creating an account with 0x! - final EvmAccount recipientAccount = + final MutableAccount recipientAccount = frame.getWorldUpdater().getOrCreate(frame.getRecipientAddress()); if (Objects.equals(frame.getValue(), Wei.ZERO)) { @@ -125,9 +125,8 @@ private void transferValue(final MessageFrame frame) { if (frame.getRecipientAddress().equals(frame.getSenderAddress())) { LOG.trace("Message call of {} to itself: no fund transferred", frame.getSenderAddress()); } else { - final Wei prevSenderBalance = senderAccount.getMutable().decrementBalance(frame.getValue()); - final Wei prevRecipientBalance = - recipientAccount.getMutable().incrementBalance(frame.getValue()); + final Wei prevSenderBalance = senderAccount.decrementBalance(frame.getValue()); + final Wei prevRecipientBalance = recipientAccount.incrementBalance(frame.getValue()); LOG.trace( "Transferred value {} for message call from {} ({} -> {}) to {} ({} -> {})", diff --git a/evm/src/main/java/org/hyperledger/besu/evm/worldstate/AbstractWorldUpdater.java b/evm/src/main/java/org/hyperledger/besu/evm/worldstate/AbstractWorldUpdater.java index fde3aa8c244..41cacdbea06 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/worldstate/AbstractWorldUpdater.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/worldstate/AbstractWorldUpdater.java @@ -17,7 +17,6 @@ import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.evm.account.Account; -import org.hyperledger.besu.evm.account.EvmAccount; import org.hyperledger.besu.evm.account.MutableAccount; import java.util.Collection; @@ -78,11 +77,11 @@ protected UpdateTrackingAccount track(final UpdateTrackingAccount account) } @Override - public EvmAccount createAccount(final Address address, final long nonce, final Wei balance) { + public MutableAccount createAccount(final Address address, final long nonce, final Wei balance) { final UpdateTrackingAccount account = new UpdateTrackingAccount<>(address); account.setNonce(nonce); account.setBalance(balance); - return new WrappedEvmAccount(track(account)); + return track(account); } @Override @@ -99,11 +98,11 @@ public Account get(final Address address) { } @Override - public EvmAccount getAccount(final Address address) { + public MutableAccount getAccount(final Address address) { // We may have updated it already, so check that first. final MutableAccount existing = updatedAccounts.get(address); if (existing != null) { - return new WrappedEvmAccount(existing); + return existing; } if (deletedAccounts.contains(address)) { return null; @@ -114,7 +113,7 @@ public EvmAccount getAccount(final Address address) { if (origin == null) { return null; } else { - return new WrappedEvmAccount(track(new UpdateTrackingAccount<>(origin))); + return track(new UpdateTrackingAccount<>(origin)); } } @@ -150,8 +149,8 @@ protected W wrappedWorldView() { @Override public Optional parentUpdater() { - if (world instanceof WorldUpdater) { - return Optional.of((WorldUpdater) world); + if (world instanceof WorldUpdater worldUpdater) { + return Optional.of(worldUpdater); } else { return Optional.empty(); } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/worldstate/UpdateTrackingAccount.java b/evm/src/main/java/org/hyperledger/besu/evm/worldstate/UpdateTrackingAccount.java index 9b9f5e2a127..bc8a0fdfcd5 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/worldstate/UpdateTrackingAccount.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/worldstate/UpdateTrackingAccount.java @@ -24,7 +24,6 @@ import org.hyperledger.besu.evm.ModificationNotAllowedException; import org.hyperledger.besu.evm.account.Account; import org.hyperledger.besu.evm.account.AccountStorageEntry; -import org.hyperledger.besu.evm.account.EvmAccount; import org.hyperledger.besu.evm.account.MutableAccount; import java.util.Map; @@ -47,12 +46,14 @@ * * @param the type parameter */ -public class UpdateTrackingAccount implements MutableAccount, EvmAccount { +public class UpdateTrackingAccount implements MutableAccount { private final Address address; private final Hash addressHash; @Nullable private A account; // null if this is a new account. + private boolean mutable = true; + private long nonce; private Wei balance; @@ -172,6 +173,9 @@ public long getNonce() { @Override public void setNonce(final long value) { + if (!mutable) { + throw new ModificationNotAllowedException(); + } this.nonce = value; } @@ -182,6 +186,9 @@ public Wei getBalance() { @Override public void setBalance(final Wei value) { + if (!mutable) { + throw new ModificationNotAllowedException(); + } this.balance = value; } @@ -214,6 +221,9 @@ public boolean hasCode() { @Override public void setCode(final Bytes code) { + if (!mutable) { + throw new ModificationNotAllowedException(); + } this.updatedCode = code; this.updatedCodeHash = null; } @@ -271,15 +281,26 @@ public NavigableMap storageEntriesFrom( @Override public void setStorageValue(final UInt256 key, final UInt256 value) { + if (!mutable) { + throw new ModificationNotAllowedException(); + } updatedStorage.put(key, value); } @Override public void clearStorage() { + if (!mutable) { + throw new ModificationNotAllowedException(); + } storageWasCleared = true; updatedStorage.clear(); } + @Override + public void becomeImmutable() { + mutable = false; + } + /** * Gets storage was cleared. * @@ -308,9 +329,4 @@ public String toString() { "%s -> {nonce: %s, balance:%s, code:%s, storage:%s }", address, nonce, balance, updatedCode == null ? "[not updated]" : updatedCode, storage); } - - @Override - public MutableAccount getMutable() throws ModificationNotAllowedException { - return this; - } } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/worldstate/WorldUpdater.java b/evm/src/main/java/org/hyperledger/besu/evm/worldstate/WorldUpdater.java index a9b012facbf..fe88c86a7df 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/worldstate/WorldUpdater.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/worldstate/WorldUpdater.java @@ -17,7 +17,6 @@ import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.evm.account.Account; -import org.hyperledger.besu.evm.account.EvmAccount; import org.hyperledger.besu.evm.account.MutableAccount; import org.hyperledger.besu.evm.frame.MessageFrame; @@ -48,7 +47,7 @@ public interface WorldUpdater extends MutableWorldView { * @return the account {@code address}, which will have nonce {@code nonce}, balance {@code * balance} and empty code and storage. */ - EvmAccount createAccount(Address address, long nonce, Wei balance); + MutableAccount createAccount(Address address, long nonce, Wei balance); /** * Creates a new account, or reset it (that is, act as if it was deleted and created anew) if it @@ -61,7 +60,7 @@ public interface WorldUpdater extends MutableWorldView { * @return the account {@code address}, which will have 0 for the nonce and balance and empty code * and storage. */ - default EvmAccount createAccount(final Address address) { + default MutableAccount createAccount(final Address address) { return createAccount(address, Account.DEFAULT_NONCE, Account.DEFAULT_BALANCE); } @@ -73,8 +72,8 @@ default EvmAccount createAccount(final Address address) { * #getAccount(Address)}, otherwise, it is created and returned as if by {@link * #createAccount(Address)} (and thus all his fields will be zero/empty). */ - default EvmAccount getOrCreate(final Address address) { - final EvmAccount account = getAccount(address); + default MutableAccount getOrCreate(final Address address) { + final MutableAccount account = getAccount(address); return account == null ? createAccount(address) : account; } @@ -85,7 +84,7 @@ default EvmAccount getOrCreate(final Address address) { * @param address the address of the account. * @return the account of the sender for {@code address} */ - default EvmAccount getOrCreateSenderAccount(final Address address) { + default MutableAccount getOrCreateSenderAccount(final Address address) { return getOrCreate(address); } @@ -96,7 +95,7 @@ default EvmAccount getOrCreateSenderAccount(final Address address) { * @param address the address of the account. * @return the account {@code address}, or {@code null} if the account does not exist. */ - EvmAccount getAccount(Address address); + MutableAccount getAccount(Address address); /** * Retrieves the senders account, returning a modifiable object (whose updates are accumulated by @@ -105,7 +104,7 @@ default EvmAccount getOrCreateSenderAccount(final Address address) { * @param frame the current message frame. * @return the account {@code address}, or {@code null} if the account does not exist. */ - default EvmAccount getSenderAccount(final MessageFrame frame) { + default MutableAccount getSenderAccount(final MessageFrame frame) { return getAccount(frame.getSenderAddress()); } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/worldstate/WrappedEvmAccount.java b/evm/src/main/java/org/hyperledger/besu/evm/worldstate/WrappedEvmAccount.java deleted file mode 100644 index 8d644d9650d..00000000000 --- a/evm/src/main/java/org/hyperledger/besu/evm/worldstate/WrappedEvmAccount.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright ConsenSys AG. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - */ -package org.hyperledger.besu.evm.worldstate; - -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.datatypes.Wei; -import org.hyperledger.besu.evm.ModificationNotAllowedException; -import org.hyperledger.besu.evm.account.AccountStorageEntry; -import org.hyperledger.besu.evm.account.EvmAccount; -import org.hyperledger.besu.evm.account.MutableAccount; - -import java.util.NavigableMap; - -import org.apache.tuweni.bytes.Bytes; -import org.apache.tuweni.bytes.Bytes32; -import org.apache.tuweni.units.bigints.UInt256; - -/** The Wrapped evm account. */ -public class WrappedEvmAccount implements EvmAccount { - private final MutableAccount mutableAccount; - - /** - * Is immutable. - * - * @return the boolean - */ - public boolean isImmutable() { - return isImmutable; - } - - /** - * Sets immutable. - * - * @param immutable the immutable - */ - public void setImmutable(final boolean immutable) { - isImmutable = immutable; - } - - private boolean isImmutable; - - /** - * Instantiates a new Wrapped evm account. - * - * @param mutableAccount the mutable account - */ - public WrappedEvmAccount(final MutableAccount mutableAccount) { - - this.mutableAccount = mutableAccount; - this.isImmutable = false; - } - - @Override - public MutableAccount getMutable() throws ModificationNotAllowedException { - if (isImmutable) { - throw new ModificationNotAllowedException(); - } - return mutableAccount; - } - - @Override - public Address getAddress() { - return mutableAccount.getAddress(); - } - - @Override - public Hash getAddressHash() { - return mutableAccount.getAddressHash(); - } - - @Override - public long getNonce() { - return mutableAccount.getNonce(); - } - - @Override - public Wei getBalance() { - return mutableAccount.getBalance(); - } - - @Override - public Bytes getCode() { - return mutableAccount.getCode(); - } - - @Override - public Hash getCodeHash() { - return mutableAccount.getCodeHash(); - } - - @Override - public UInt256 getStorageValue(final UInt256 key) { - return mutableAccount.getStorageValue(key); - } - - @Override - public UInt256 getOriginalStorageValue(final UInt256 key) { - return mutableAccount.getOriginalStorageValue(key); - } - - @Override - public NavigableMap storageEntriesFrom( - final Bytes32 startKeyHash, final int limit) { - return mutableAccount.storageEntriesFrom(startKeyHash, limit); - } -} diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operation/AbstractCreateOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operation/AbstractCreateOperationTest.java index aa3dfd40217..1a703f489d7 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operation/AbstractCreateOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operation/AbstractCreateOperationTest.java @@ -39,7 +39,6 @@ import org.hyperledger.besu.evm.processor.ContractCreationProcessor; import org.hyperledger.besu.evm.tracing.OperationTracer; import org.hyperledger.besu.evm.worldstate.WorldUpdater; -import org.hyperledger.besu.evm.worldstate.WrappedEvmAccount; import java.util.Deque; import java.util.List; @@ -52,10 +51,8 @@ class AbstractCreateOperationTest { private final WorldUpdater worldUpdater = mock(WorldUpdater.class); - private final WrappedEvmAccount account = mock(WrappedEvmAccount.class); - private final WrappedEvmAccount newAccount = mock(WrappedEvmAccount.class); - private final MutableAccount mutableAccount = mock(MutableAccount.class); - private final MutableAccount newMutableAccount = mock(MutableAccount.class); + private final MutableAccount account = mock(MutableAccount.class); + private final MutableAccount newAccount = mock(MutableAccount.class); private final FakeCreateOperation operation = new FakeCreateOperation(new ConstantinopleGasCalculator(), Integer.MAX_VALUE); @@ -169,15 +166,13 @@ private void executeOperation(final Bytes contract, final EVM evm) { messageFrame.expandMemory(0, 500); messageFrame.writeMemory(memoryOffset.trimLeadingZeros().toInt(), contract.size(), contract); - when(account.getMutable()).thenReturn(mutableAccount); when(account.getNonce()).thenReturn(55L); - when(mutableAccount.getBalance()).thenReturn(Wei.ZERO); + when(account.getBalance()).thenReturn(Wei.ZERO); when(worldUpdater.getAccount(any())).thenReturn(account); when(worldUpdater.get(any())).thenReturn(account); when(worldUpdater.getSenderAccount(any())).thenReturn(account); when(worldUpdater.getOrCreate(any())).thenReturn(newAccount); - when(newAccount.getMutable()).thenReturn(newMutableAccount); - when(newMutableAccount.getCode()).thenReturn(Bytes.EMPTY); + when(newAccount.getCode()).thenReturn(Bytes.EMPTY); when(worldUpdater.updater()).thenReturn(worldUpdater); operation.execute(messageFrame, evm); diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operations/Create2OperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operations/Create2OperationTest.java index 5590cd09b4f..d9b41d4681e 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operations/Create2OperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operations/Create2OperationTest.java @@ -40,7 +40,6 @@ import org.hyperledger.besu.evm.testutils.TestMessageFrameBuilder; import org.hyperledger.besu.evm.tracing.OperationTracer; import org.hyperledger.besu.evm.worldstate.WorldUpdater; -import org.hyperledger.besu.evm.worldstate.WrappedEvmAccount; import java.util.Deque; import java.util.List; @@ -56,11 +55,9 @@ public class Create2OperationTest { private MessageFrame messageFrame; private final WorldUpdater worldUpdater = mock(WorldUpdater.class); - private final WrappedEvmAccount account = mock(WrappedEvmAccount.class); - private final MutableAccount mutableAccount = mock(MutableAccount.class); + private final MutableAccount account = mock(MutableAccount.class); private final EVM evm = mock(EVM.class); - private final WrappedEvmAccount newAccount = mock(WrappedEvmAccount.class); - private final MutableAccount newMutableAccount = mock(MutableAccount.class); + private final MutableAccount newAccount = mock(MutableAccount.class); private final Create2Operation operation = new Create2Operation(new ConstantinopleGasCalculator(), Integer.MAX_VALUE); @@ -147,7 +144,6 @@ public void setUp(final String sender, final String salt, final String code) { final UInt256 memoryOffset = UInt256.fromHexString("0xFF"); final Bytes codeBytes = Bytes.fromHexString(code); final UInt256 memoryLength = UInt256.valueOf(codeBytes.size()); - when(account.getMutable()).thenReturn(mutableAccount); messageFrame = MessageFrame.builder() .type(MessageFrame.Type.CONTRACT_CREATION) @@ -174,7 +170,7 @@ public void setUp(final String sender, final String salt, final String code) { messageFrame.expandMemory(0, 500); messageFrame.writeMemory(memoryOffset.trimLeadingZeros().toInt(), code.length(), codeBytes); - when(mutableAccount.getBalance()).thenReturn(Wei.ZERO); + when(account.getBalance()).thenReturn(Wei.ZERO); when(worldUpdater.getAccount(any())).thenReturn(account); when(worldUpdater.updater()).thenReturn(worldUpdater); when(evm.getCode(any(), any())) @@ -214,15 +210,13 @@ void shanghaiMaxInitCodeSizeCreate() { final UInt256 memoryLength = UInt256.fromHexString("0xc000"); final MessageFrame messageFrame = testMemoryFrame(memoryOffset, memoryLength, UInt256.ZERO, 1); - when(account.getMutable()).thenReturn(mutableAccount); when(account.getNonce()).thenReturn(55L); - when(mutableAccount.getBalance()).thenReturn(Wei.ZERO); + when(account.getBalance()).thenReturn(Wei.ZERO); when(worldUpdater.getAccount(any())).thenReturn(account); when(worldUpdater.get(any())).thenReturn(account); when(worldUpdater.getSenderAccount(any())).thenReturn(account); when(worldUpdater.getOrCreate(any())).thenReturn(newAccount); - when(newAccount.getMutable()).thenReturn(newMutableAccount); - when(newMutableAccount.getCode()).thenReturn(Bytes.EMPTY); + when(newAccount.getCode()).thenReturn(Bytes.EMPTY); when(worldUpdater.updater()).thenReturn(worldUpdater); final EVM evm = MainnetEVMs.shanghai(DEV_NET_CHAIN_ID, EvmConfiguration.DEFAULT); @@ -244,15 +238,13 @@ void shanghaiMaxInitCodeSizePlus1Create() { final UInt256 memoryLength = UInt256.fromHexString("0xc001"); final MessageFrame messageFrame = testMemoryFrame(memoryOffset, memoryLength, UInt256.ZERO, 1); - when(account.getMutable()).thenReturn(mutableAccount); when(account.getNonce()).thenReturn(55L); - when(mutableAccount.getBalance()).thenReturn(Wei.ZERO); + when(account.getBalance()).thenReturn(Wei.ZERO); when(worldUpdater.getAccount(any())).thenReturn(account); when(worldUpdater.get(any())).thenReturn(account); when(worldUpdater.getSenderAccount(any())).thenReturn(account); when(worldUpdater.getOrCreate(any())).thenReturn(newAccount); - when(newAccount.getMutable()).thenReturn(newMutableAccount); - when(newMutableAccount.getCode()).thenReturn(Bytes.EMPTY); + when(newAccount.getCode()).thenReturn(Bytes.EMPTY); when(worldUpdater.updater()).thenReturn(worldUpdater); final EVM evm = MainnetEVMs.shanghai(DEV_NET_CHAIN_ID, EvmConfiguration.DEFAULT); @@ -314,8 +306,7 @@ void eofV1CannotCreateLegacy() { .build(); messageFrame.writeMemory(memoryOffset.toLong(), memoryLength.toLong(), SIMPLE_CREATE); - when(account.getMutable()).thenReturn(mutableAccount); - when(mutableAccount.getBalance()).thenReturn(Wei.ZERO); + when(account.getBalance()).thenReturn(Wei.ZERO); when(worldUpdater.getAccount(any())).thenReturn(account); final EVM evm = MainnetEVMs.cancun(DEV_NET_CHAIN_ID, EvmConfiguration.DEFAULT); @@ -339,9 +330,8 @@ void legacyCanCreateEOFv1() { .build(); messageFrame.writeMemory(memoryOffset.toLong(), memoryLength.toLong(), SIMPLE_EOF); - when(account.getMutable()).thenReturn(mutableAccount); when(account.getNonce()).thenReturn(55L); - when(mutableAccount.getBalance()).thenReturn(Wei.ZERO); + when(account.getBalance()).thenReturn(Wei.ZERO); when(worldUpdater.getAccount(any())).thenReturn(account); when(worldUpdater.get(any())).thenReturn(account); when(worldUpdater.getSenderAccount(any())).thenReturn(account); diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operations/CreateOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operations/CreateOperationTest.java index b685b8702ff..822f515741e 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operations/CreateOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operations/CreateOperationTest.java @@ -40,7 +40,6 @@ import org.hyperledger.besu.evm.testutils.TestMessageFrameBuilder; import org.hyperledger.besu.evm.tracing.OperationTracer; import org.hyperledger.besu.evm.worldstate.WorldUpdater; -import org.hyperledger.besu.evm.worldstate.WrappedEvmAccount; import java.util.Deque; import java.util.List; @@ -53,10 +52,8 @@ class CreateOperationTest { private final WorldUpdater worldUpdater = mock(WorldUpdater.class); - private final WrappedEvmAccount account = mock(WrappedEvmAccount.class); - private final WrappedEvmAccount newAccount = mock(WrappedEvmAccount.class); - private final MutableAccount mutableAccount = mock(MutableAccount.class); - private final MutableAccount newMutableAccount = mock(MutableAccount.class); + private final MutableAccount account = mock(MutableAccount.class); + private final MutableAccount newAccount = mock(MutableAccount.class); private final CreateOperation operation = new CreateOperation(new ConstantinopleGasCalculator(), Integer.MAX_VALUE); private final CreateOperation maxInitCodeOperation = @@ -91,15 +88,13 @@ void createFromMemoryMutationSafe() { final UInt256 memoryLength = UInt256.valueOf(SIMPLE_CREATE.size()); final MessageFrame messageFrame = testMemoryFrame(memoryOffset, memoryLength, UInt256.ZERO, 1); - when(account.getMutable()).thenReturn(mutableAccount); when(account.getNonce()).thenReturn(55L); - when(mutableAccount.getBalance()).thenReturn(Wei.ZERO); + when(account.getBalance()).thenReturn(Wei.ZERO); when(worldUpdater.getAccount(any())).thenReturn(account); when(worldUpdater.get(any())).thenReturn(account); when(worldUpdater.getSenderAccount(any())).thenReturn(account); when(worldUpdater.getOrCreate(any())).thenReturn(newAccount); - when(newAccount.getMutable()).thenReturn(newMutableAccount); - when(newMutableAccount.getCode()).thenReturn(Bytes.EMPTY); + when(newAccount.getCode()).thenReturn(Bytes.EMPTY); when(worldUpdater.updater()).thenReturn(worldUpdater); final EVM evm = MainnetEVMs.london(EvmConfiguration.DEFAULT); @@ -131,9 +126,8 @@ void nonceTooLarge() { final MessageFrame messageFrame = testMemoryFrame(memoryOffset, memoryLength, UInt256.ZERO, 1); when(worldUpdater.getAccount(any())).thenReturn(account); - when(account.getMutable()).thenReturn(mutableAccount); - when(mutableAccount.getBalance()).thenReturn(Wei.ZERO); - when(mutableAccount.getNonce()).thenReturn(-1L); + when(account.getBalance()).thenReturn(Wei.ZERO); + when(account.getNonce()).thenReturn(-1L); final EVM evm = MainnetEVMs.london(EvmConfiguration.DEFAULT); operation.execute(messageFrame, evm); @@ -149,9 +143,8 @@ void messageFrameStackTooDeep() { testMemoryFrame(memoryOffset, memoryLength, UInt256.ZERO, 1025); when(worldUpdater.getAccount(any())).thenReturn(account); - when(account.getMutable()).thenReturn(mutableAccount); - when(mutableAccount.getBalance()).thenReturn(Wei.ZERO); - when(mutableAccount.getNonce()).thenReturn(55L); + when(account.getBalance()).thenReturn(Wei.ZERO); + when(account.getNonce()).thenReturn(55L); final EVM evm = MainnetEVMs.london(EvmConfiguration.DEFAULT); operation.execute(messageFrame, evm); @@ -171,9 +164,8 @@ void notEnoughValue() { } when(worldUpdater.getAccount(any())).thenReturn(account); - when(account.getMutable()).thenReturn(mutableAccount); - when(mutableAccount.getBalance()).thenReturn(Wei.ZERO); - when(mutableAccount.getNonce()).thenReturn(55L); + when(account.getBalance()).thenReturn(Wei.ZERO); + when(account.getNonce()).thenReturn(55L); final EVM evm = MainnetEVMs.london(EvmConfiguration.DEFAULT); operation.execute(messageFrame, evm); @@ -187,15 +179,13 @@ void shanghaiMaxInitCodeSizeCreate() { final UInt256 memoryLength = UInt256.fromHexString("0xc000"); final MessageFrame messageFrame = testMemoryFrame(memoryOffset, memoryLength, UInt256.ZERO, 1); - when(account.getMutable()).thenReturn(mutableAccount); when(account.getNonce()).thenReturn(55L); - when(mutableAccount.getBalance()).thenReturn(Wei.ZERO); + when(account.getBalance()).thenReturn(Wei.ZERO); when(worldUpdater.getAccount(any())).thenReturn(account); when(worldUpdater.get(any())).thenReturn(account); when(worldUpdater.getSenderAccount(any())).thenReturn(account); when(worldUpdater.getOrCreate(any())).thenReturn(newAccount); - when(newAccount.getMutable()).thenReturn(newMutableAccount); - when(newMutableAccount.getCode()).thenReturn(Bytes.EMPTY); + when(newAccount.getCode()).thenReturn(Bytes.EMPTY); when(worldUpdater.updater()).thenReturn(worldUpdater); final EVM evm = MainnetEVMs.shanghai(DEV_NET_CHAIN_ID, EvmConfiguration.DEFAULT); @@ -217,15 +207,13 @@ void shanghaiMaxInitCodeSizePlus1Create() { final UInt256 memoryLength = UInt256.fromHexString("0xc001"); final MessageFrame messageFrame = testMemoryFrame(memoryOffset, memoryLength, UInt256.ZERO, 1); - when(account.getMutable()).thenReturn(mutableAccount); when(account.getNonce()).thenReturn(55L); - when(mutableAccount.getBalance()).thenReturn(Wei.ZERO); + when(account.getBalance()).thenReturn(Wei.ZERO); when(worldUpdater.getAccount(any())).thenReturn(account); when(worldUpdater.get(any())).thenReturn(account); when(worldUpdater.getSenderAccount(any())).thenReturn(account); when(worldUpdater.getOrCreate(any())).thenReturn(newAccount); - when(newAccount.getMutable()).thenReturn(newMutableAccount); - when(newMutableAccount.getCode()).thenReturn(Bytes.EMPTY); + when(newAccount.getCode()).thenReturn(Bytes.EMPTY); when(worldUpdater.updater()).thenReturn(worldUpdater); final EVM evm = MainnetEVMs.shanghai(DEV_NET_CHAIN_ID, EvmConfiguration.DEFAULT); @@ -247,8 +235,7 @@ void eofV1CannotCreateLegacy() { .build(); messageFrame.writeMemory(memoryOffset.toLong(), memoryLength.toLong(), SIMPLE_CREATE); - when(account.getMutable()).thenReturn(mutableAccount); - when(mutableAccount.getBalance()).thenReturn(Wei.ZERO); + when(account.getBalance()).thenReturn(Wei.ZERO); when(worldUpdater.getAccount(any())).thenReturn(account); final EVM evm = MainnetEVMs.cancun(DEV_NET_CHAIN_ID, EvmConfiguration.DEFAULT); @@ -271,9 +258,8 @@ void legacyCanCreateEOFv1() { .build(); messageFrame.writeMemory(memoryOffset.toLong(), memoryLength.toLong(), SIMPLE_EOF); - when(account.getMutable()).thenReturn(mutableAccount); when(account.getNonce()).thenReturn(55L); - when(mutableAccount.getBalance()).thenReturn(Wei.ZERO); + when(account.getBalance()).thenReturn(Wei.ZERO); when(worldUpdater.getAccount(any())).thenReturn(account); when(worldUpdater.get(any())).thenReturn(account); when(worldUpdater.getSenderAccount(any())).thenReturn(account); diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operations/ExtCodeHashOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operations/ExtCodeHashOperationTest.java index 3127970c3b9..a7ca5eefe67 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operations/ExtCodeHashOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operations/ExtCodeHashOperationTest.java @@ -69,7 +69,7 @@ void shouldReturnZeroWhenAccountDoesNotExist() { @Test void shouldReturnHashOfEmptyDataWhenAccountExistsButDoesNotHaveCode() { - worldStateUpdater.getOrCreate(REQUESTED_ADDRESS).getMutable().setBalance(Wei.of(1)); + worldStateUpdater.getOrCreate(REQUESTED_ADDRESS).setBalance(Wei.of(1)); assertThat(executeOperation(REQUESTED_ADDRESS)).isEqualTo(Hash.EMPTY); } @@ -87,14 +87,14 @@ void shouldReturnZeroWhenPrecompiledContractHasNoBalance() { @Test void shouldReturnEmptyCodeHashWhenPrecompileHasBalance() { // Sending money to a precompile causes it to exist in the world state archive. - worldStateUpdater.getOrCreate(Address.ECREC).getMutable().setBalance(Wei.of(10)); + worldStateUpdater.getOrCreate(Address.ECREC).setBalance(Wei.of(10)); assertThat(executeOperation(Address.ECREC)).isEqualTo(Hash.EMPTY); } @Test void shouldGetHashOfAccountCodeWhenCodeIsPresent() { final Bytes code = Bytes.fromHexString("0xabcdef"); - final MutableAccount account = worldStateUpdater.getOrCreate(REQUESTED_ADDRESS).getMutable(); + final MutableAccount account = worldStateUpdater.getOrCreate(REQUESTED_ADDRESS); account.setCode(code); assertThat(executeOperation(REQUESTED_ADDRESS)).isEqualTo(Hash.hash(code)); } @@ -103,7 +103,7 @@ void shouldGetHashOfAccountCodeWhenCodeIsPresent() { void shouldZeroOutLeftMostBitsToGetAddress() { // If EXTCODEHASH of A is X, then EXTCODEHASH of A + 2**160 is X. final Bytes code = Bytes.fromHexString("0xabcdef"); - final MutableAccount account = worldStateUpdater.getOrCreate(REQUESTED_ADDRESS).getMutable(); + final MutableAccount account = worldStateUpdater.getOrCreate(REQUESTED_ADDRESS); account.setCode(code); final UInt256 value = UInt256.fromBytes(Words.fromAddress(REQUESTED_ADDRESS)) diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operations/SStoreOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operations/SStoreOperationTest.java index fbf21ab5102..e2f14dbdb2a 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operations/SStoreOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operations/SStoreOperationTest.java @@ -64,7 +64,7 @@ private MessageFrame createMessageFrame( .blockValues(blockHeader) .initialGas(initialGas) .build(); - worldStateUpdater.getOrCreate(address).getMutable().setBalance(Wei.of(1)); + worldStateUpdater.getOrCreate(address).setBalance(Wei.of(1)); worldStateUpdater.commit(); frame.setGasRemaining(remainingGas); diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operations/SelfDestructOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operations/SelfDestructOperationTest.java index f596bed8aad..6c178dda2a9 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operations/SelfDestructOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operations/SelfDestructOperationTest.java @@ -33,7 +33,6 @@ import org.hyperledger.besu.evm.operation.Operation; import org.hyperledger.besu.evm.operation.SelfDestructOperation; import org.hyperledger.besu.evm.worldstate.WorldUpdater; -import org.hyperledger.besu.evm.worldstate.WrappedEvmAccount; import org.apache.tuweni.bytes.Bytes; import org.junit.jupiter.api.extension.ExtendWith; @@ -54,10 +53,8 @@ public class SelfDestructOperationTest { private MessageFrame messageFrame; @Mock private WorldUpdater worldUpdater; - @Mock private WrappedEvmAccount accountOriginator; - @Mock private WrappedEvmAccount accountBeneficiary; - @Mock private MutableAccount mutableAccountOriginator; - @Mock private MutableAccount mutableAccountBeneficiary; + @Mock private MutableAccount accountOriginator; + @Mock private MutableAccount accountBeneficiary; @Mock private EVM evm; private final SelfDestructOperation frontierOperation = @@ -104,9 +101,7 @@ void checkContractDeletionCommon( when(worldUpdater.get(beneficiaryAddress)).thenReturn(accountBeneficiary); } when(worldUpdater.getOrCreate(beneficiaryAddress)).thenReturn(accountBeneficiary); - when(accountOriginator.getMutable()).thenReturn(mutableAccountOriginator); when(accountOriginator.getBalance()).thenReturn(Wei.fromHexString(balanceHex)); - when(accountBeneficiary.getMutable()).thenReturn(mutableAccountBeneficiary); final Operation.OperationResult operationResult = operation.execute(messageFrame, evm); assertThat(operationResult).isNotNull(); @@ -115,10 +110,10 @@ void checkContractDeletionCommon( // some subset of these calls. verify(accountOriginator, atLeast(0)).getBalance(); verify(accountBeneficiary, atLeast(0)).getBalance(); - verify(mutableAccountOriginator, atLeast(0)).getBalance(); - verify(mutableAccountOriginator).decrementBalance(Wei.fromHexString(balanceHex)); - verify(mutableAccountOriginator, atLeast(0)).setBalance(Wei.ZERO); - verify(mutableAccountBeneficiary).incrementBalance(Wei.fromHexString(balanceHex)); + verify(accountOriginator, atLeast(0)).getBalance(); + verify(accountOriginator).decrementBalance(Wei.fromHexString(balanceHex)); + verify(accountOriginator, atLeast(0)).setBalance(Wei.ZERO); + verify(accountBeneficiary).incrementBalance(Wei.fromHexString(balanceHex)); } public static Object[][] params() { diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operations/TStoreOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operations/TStoreOperationTest.java index 403bd68a7a6..fed95ec0820 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operations/TStoreOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operations/TStoreOperationTest.java @@ -60,7 +60,7 @@ private MessageFrame createMessageFrame( .blockValues(blockHeader) .initialGas(initialGas) .build(); - worldStateUpdater.getOrCreate(address).getMutable().setBalance(Wei.of(1)); + worldStateUpdater.getOrCreate(address).setBalance(Wei.of(1)); worldStateUpdater.commit(); frame.setGasRemaining(remainingGas); diff --git a/evm/src/test/java/org/hyperledger/besu/evm/testutils/TestCodeExecutor.java b/evm/src/test/java/org/hyperledger/besu/evm/testutils/TestCodeExecutor.java index 02f6ffba191..7cc12b5867f 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/testutils/TestCodeExecutor.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/testutils/TestCodeExecutor.java @@ -83,7 +83,7 @@ public MessageFrame executeCode( public static void deployContract( final WorldUpdater worldUpdater, final Address contractAddress, final String codeHexString) { var updater = worldUpdater.updater(); - final MutableAccount contract = updater.getOrCreate(contractAddress).getMutable(); + final MutableAccount contract = updater.getOrCreate(contractAddress); contract.setNonce(0); contract.clearStorage(); @@ -95,8 +95,7 @@ public static WorldUpdater createInitialWorldState(final Consumer addressHash = Suppliers.memoize(() -> address == null ? Hash.ZERO : address.addressHash()); @@ -117,34 +118,44 @@ public NavigableMap storageEntriesFrom( throw new UnsupportedOperationException("Storage iteration not supported in toy evm"); } - @Override - public MutableAccount getMutable() throws ModificationNotAllowedException { - return this; - } - @Override public void setNonce(final long value) { + if (!mutable) { + throw new ModificationNotAllowedException(); + } nonce = value; } @Override public void setBalance(final Wei value) { + if (!mutable) { + throw new ModificationNotAllowedException(); + } balance = value; } @Override public void setCode(final Bytes code) { + if (!mutable) { + throw new ModificationNotAllowedException(); + } this.code = code; codeHash = Suppliers.memoize(() -> this.code == null ? Hash.EMPTY : Hash.hash(this.code)); } @Override public void setStorageValue(final UInt256 key, final UInt256 value) { + if (!mutable) { + throw new ModificationNotAllowedException(); + } storage.put(key, value); } @Override public void clearStorage() { + if (!mutable) { + throw new ModificationNotAllowedException(); + } storage.clear(); } @@ -152,4 +163,9 @@ public void clearStorage() { public Map getUpdatedStorage() { return storage; } + + @Override + public void becomeImmutable() { + mutable = false; + } } diff --git a/evm/src/test/java/org/hyperledger/besu/evm/toy/ToyWorld.java b/evm/src/test/java/org/hyperledger/besu/evm/toy/ToyWorld.java index b49d4930e5f..06aa833bcd2 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/toy/ToyWorld.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/toy/ToyWorld.java @@ -18,7 +18,7 @@ import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.evm.account.Account; -import org.hyperledger.besu.evm.account.EvmAccount; +import org.hyperledger.besu.evm.account.MutableAccount; import org.hyperledger.besu.evm.worldstate.WorldUpdater; import java.util.Collection; @@ -59,11 +59,11 @@ public Account get(final Address address) { } @Override - public EvmAccount createAccount(final Address address, final long nonce, final Wei balance) { + public MutableAccount createAccount(final Address address, final long nonce, final Wei balance) { return createAccount(null, address, nonce, balance, Bytes.EMPTY); } - public EvmAccount createAccount( + public MutableAccount createAccount( final Account parentAccount, final Address address, final long nonce, @@ -75,7 +75,7 @@ public EvmAccount createAccount( } @Override - public EvmAccount getAccount(final Address address) { + public MutableAccount getAccount(final Address address) { if (accounts.containsKey(address)) { return accounts.get(address); } else if (parent != null) { diff --git a/evm/src/test/java/org/hyperledger/besu/evm/tracing/ExtendedOperationTracerTest.java b/evm/src/test/java/org/hyperledger/besu/evm/tracing/ExtendedOperationTracerTest.java index e74d43d8ec4..9b57bd938f4 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/tracing/ExtendedOperationTracerTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/tracing/ExtendedOperationTracerTest.java @@ -20,7 +20,6 @@ import static org.mockito.Mockito.when; import org.hyperledger.besu.evm.EVM; -import org.hyperledger.besu.evm.account.EvmAccount; import org.hyperledger.besu.evm.account.MutableAccount; import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; import org.hyperledger.besu.evm.frame.MessageFrame; @@ -45,7 +44,6 @@ class ExtendedOperationTracerTest { @Mock EVM evm; @Mock MessageFrame frame; @Mock WorldUpdater worldUpdater; - @Mock EvmAccount evmAccount; @Mock MutableAccount mutableAccount; @BeforeEach @@ -55,8 +53,7 @@ void setUp() { when(frame.getRemainingGas()).thenReturn(1L); when(frame.getWorldUpdater()).thenReturn(worldUpdater); - when(worldUpdater.getOrCreate(any())).thenReturn(evmAccount); - when(evmAccount.getMutable()).thenReturn(mutableAccount); + when(worldUpdater.getOrCreate(any())).thenReturn(mutableAccount); } @Test @@ -69,7 +66,6 @@ void shouldCallTraceAccountCreationResultIfIsExtendedTracing() { // traceAccountCreationResult has been called and values have been set assertThat(tracer.frame).isNotNull(); - assertThat(tracer.haltReason).isNotNull(); assertThat(tracer.haltReason).isEmpty(); }