Wrapped WorldUpdater into `EVMWorldupdater` (#7434)

* wrapped WorldUpdater into `EVMWorldupdater` to remove the authority code injection from the implementation of the actual world updaters

Signed-off-by: Daniel Lehrner <daniel.lehrner@consensys.net>

* add CHANGELOG entry

Signed-off-by: Daniel Lehrner <daniel.lehrner@consensys.net>

---------

Signed-off-by: Daniel Lehrner <daniel.lehrner@consensys.net>
Co-authored-by: Justin Florentine <justin+github@florentine.us>
Co-authored-by: Sally MacFarlane <macfarla.github@gmail.com>
pull/7452/head
daniellehrner 4 months ago committed by GitHub
parent 6623b2d693
commit b53db47dab
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 1
      CHANGELOG.md
  2. 20
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/AuthorityProcessor.java
  3. 34
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java
  4. 20
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateMutableWorldStateUpdater.java
  5. 6
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/worldview/accumulator/DiffBasedWorldStateUpdateAccumulator.java
  6. 23
      evm/src/main/java/org/hyperledger/besu/evm/fluent/SimpleWorld.java
  7. 36
      evm/src/main/java/org/hyperledger/besu/evm/frame/MessageFrame.java
  8. 1
      evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCallOperation.java
  9. 1
      evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCreateOperation.java
  10. 1
      evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractExtCallOperation.java
  11. 22
      evm/src/main/java/org/hyperledger/besu/evm/worldstate/AbstractWorldUpdater.java
  12. 127
      evm/src/main/java/org/hyperledger/besu/evm/worldstate/EVMWorldUpdater.java
  13. 22
      evm/src/main/java/org/hyperledger/besu/evm/worldstate/JournaledUpdater.java
  14. 8
      evm/src/main/java/org/hyperledger/besu/evm/worldstate/WorldUpdater.java
  15. 22
      evm/src/test/java/org/hyperledger/besu/evm/toy/ToyWorld.java

@ -15,6 +15,7 @@
### Additions and Improvements ### Additions and Improvements
- Expose set finalized/safe block in plugin api BlockchainService. These method can be used by plugins to set finalized/safe block for a PoA network (such as QBFT, IBFT and Clique).[#7382](https://github.com/hyperledger/besu/pull/7382) - Expose set finalized/safe block in plugin api BlockchainService. These method can be used by plugins to set finalized/safe block for a PoA network (such as QBFT, IBFT and Clique).[#7382](https://github.com/hyperledger/besu/pull/7382)
- In process RPC service [#7395](https://github.com/hyperledger/besu/pull/7395) - In process RPC service [#7395](https://github.com/hyperledger/besu/pull/7395)
- Wrap WorldUpdater into EVMWorldupdater [#7434](https://github.com/hyperledger/besu/pull/7434)
### Bug fixes ### Bug fixes
- Correct entrypoint in Docker evmtool [#7430](https://github.com/hyperledger/besu/pull/7430) - Correct entrypoint in Docker evmtool [#7430](https://github.com/hyperledger/besu/pull/7430)

@ -18,8 +18,7 @@ import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.evm.account.Account; import org.hyperledger.besu.evm.account.Account;
import org.hyperledger.besu.evm.account.AccountState; import org.hyperledger.besu.evm.account.AccountState;
import org.hyperledger.besu.evm.account.MutableAccount; import org.hyperledger.besu.evm.account.MutableAccount;
import org.hyperledger.besu.evm.worldstate.AuthorizedCodeService; import org.hyperledger.besu.evm.worldstate.EVMWorldUpdater;
import org.hyperledger.besu.evm.worldstate.WorldUpdater;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.Optional; import java.util.Optional;
@ -38,10 +37,7 @@ public class AuthorityProcessor {
} }
public void addContractToAuthority( public void addContractToAuthority(
final WorldUpdater worldState, final EVMWorldUpdater evmWorldUpdater, final Transaction transaction) {
final AuthorizedCodeService authorizedCodeService,
final Transaction transaction) {
transaction transaction
.getAuthorizationList() .getAuthorizationList()
.get() .get()
@ -60,7 +56,7 @@ public class AuthorityProcessor {
} }
final Optional<MutableAccount> maybeAccount = final Optional<MutableAccount> maybeAccount =
Optional.ofNullable(worldState.getAccount(authorityAddress)); Optional.ofNullable(evmWorldUpdater.getAccount(authorityAddress));
final long accountNonce = final long accountNonce =
maybeAccount.map(AccountState::getNonce).orElse(0L); maybeAccount.map(AccountState::getNonce).orElse(0L);
@ -69,12 +65,14 @@ public class AuthorityProcessor {
return; return;
} }
if (authorizedCodeService.hasAuthorizedCode(authorityAddress)) { if (evmWorldUpdater
.authorizedCodeService()
.hasAuthorizedCode(authorityAddress)) {
return; return;
} }
Optional<Account> codeAccount = Optional<Account> codeAccount =
Optional.ofNullable(worldState.get(payload.address())); Optional.ofNullable(evmWorldUpdater.get(payload.address()));
final Bytes code; final Bytes code;
if (codeAccount.isPresent()) { if (codeAccount.isPresent()) {
code = codeAccount.get().getCode(); code = codeAccount.get().getCode();
@ -82,7 +80,9 @@ public class AuthorityProcessor {
code = Bytes.EMPTY; code = Bytes.EMPTY;
} }
authorizedCodeService.addAuthorizedCode(authorityAddress, code); evmWorldUpdater
.authorizedCodeService()
.addAuthorizedCode(authorityAddress, code);
})); }));
} }
} }

@ -42,7 +42,7 @@ import org.hyperledger.besu.evm.frame.MessageFrame;
import org.hyperledger.besu.evm.gascalculator.GasCalculator; import org.hyperledger.besu.evm.gascalculator.GasCalculator;
import org.hyperledger.besu.evm.processor.AbstractMessageProcessor; import org.hyperledger.besu.evm.processor.AbstractMessageProcessor;
import org.hyperledger.besu.evm.tracing.OperationTracer; import org.hyperledger.besu.evm.tracing.OperationTracer;
import org.hyperledger.besu.evm.worldstate.AuthorizedCodeService; import org.hyperledger.besu.evm.worldstate.EVMWorldUpdater;
import org.hyperledger.besu.evm.worldstate.WorldUpdater; import org.hyperledger.besu.evm.worldstate.WorldUpdater;
import java.util.Deque; import java.util.Deque;
@ -286,9 +286,8 @@ public class MainnetTransactionProcessor {
final TransactionValidationParams transactionValidationParams, final TransactionValidationParams transactionValidationParams,
final PrivateMetadataUpdater privateMetadataUpdater, final PrivateMetadataUpdater privateMetadataUpdater,
final Wei blobGasPrice) { final Wei blobGasPrice) {
final EVMWorldUpdater evmWorldUpdater = new EVMWorldUpdater(worldState);
try { try {
final AuthorizedCodeService authorizedCodeService = new AuthorizedCodeService();
worldState.setAuthorizedCodeService(authorizedCodeService);
final var transactionValidator = transactionValidatorFactory.get(); final var transactionValidator = transactionValidatorFactory.get();
LOG.trace("Starting execution of {}", transaction); LOG.trace("Starting execution of {}", transaction);
ValidationResult<TransactionInvalidReason> validationResult = ValidationResult<TransactionInvalidReason> validationResult =
@ -306,7 +305,7 @@ public class MainnetTransactionProcessor {
} }
final Address senderAddress = transaction.getSender(); final Address senderAddress = transaction.getSender();
final MutableAccount sender = worldState.getOrCreateSenderAccount(senderAddress); final MutableAccount sender = evmWorldUpdater.getOrCreateSenderAccount(senderAddress);
validationResult = validationResult =
transactionValidator.validateForSender(transaction, sender, transactionValidationParams); transactionValidator.validateForSender(transaction, sender, transactionValidationParams);
@ -315,7 +314,7 @@ public class MainnetTransactionProcessor {
return TransactionProcessingResult.invalid(validationResult); return TransactionProcessingResult.invalid(validationResult);
} }
operationTracer.tracePrepareTransaction(worldState, transaction); operationTracer.tracePrepareTransaction(evmWorldUpdater, transaction);
final Set<Address> addressList = new BytesTrieSet<>(Address.SIZE); final Set<Address> addressList = new BytesTrieSet<>(Address.SIZE);
@ -324,10 +323,8 @@ public class MainnetTransactionProcessor {
throw new RuntimeException("Authority processor is required for 7702 transactions"); throw new RuntimeException("Authority processor is required for 7702 transactions");
} }
maybeAuthorityProcessor maybeAuthorityProcessor.get().addContractToAuthority(evmWorldUpdater, transaction);
.get() addressList.addAll(evmWorldUpdater.authorizedCodeService().getAuthorities());
.addContractToAuthority(worldState, authorizedCodeService, transaction);
addressList.addAll(authorizedCodeService.getAuthorities());
} }
final long previousNonce = sender.incrementNonce(); final long previousNonce = sender.incrementNonce();
@ -384,8 +381,7 @@ public class MainnetTransactionProcessor {
accessListGas, accessListGas,
setCodeGas); setCodeGas);
final WorldUpdater worldUpdater = worldState.updater(); final WorldUpdater worldUpdater = evmWorldUpdater.updater();
worldUpdater.setAuthorizedCodeService(authorizedCodeService);
final ImmutableMap.Builder<String, Object> contextVariablesBuilder = final ImmutableMap.Builder<String, Object> contextVariablesBuilder =
ImmutableMap.<String, Object>builder() ImmutableMap.<String, Object>builder()
.put(KEY_IS_PERSISTING_PRIVATE_STATE, isPersistingPrivateState) .put(KEY_IS_PERSISTING_PRIVATE_STATE, isPersistingPrivateState)
@ -437,12 +433,11 @@ public class MainnetTransactionProcessor {
.contract(contractAddress) .contract(contractAddress)
.inputData(initCodeBytes.slice(code.getSize())) .inputData(initCodeBytes.slice(code.getSize()))
.code(code) .code(code)
.authorizedCodeService(authorizedCodeService)
.build(); .build();
} else { } else {
@SuppressWarnings("OptionalGetWithoutIsPresent") // isContractCall tests isPresent @SuppressWarnings("OptionalGetWithoutIsPresent") // isContractCall tests isPresent
final Address to = transaction.getTo().get(); final Address to = transaction.getTo().get();
final Optional<Account> maybeContract = Optional.ofNullable(worldState.get(to)); final Optional<Account> maybeContract = Optional.ofNullable(evmWorldUpdater.get(to));
initialFrame = initialFrame =
commonMessageFrameBuilder commonMessageFrameBuilder
.type(MessageFrame.Type.MESSAGE_CALL) .type(MessageFrame.Type.MESSAGE_CALL)
@ -453,7 +448,6 @@ public class MainnetTransactionProcessor {
maybeContract maybeContract
.map(c -> messageCallProcessor.getCodeFromEVM(c.getCodeHash(), c.getCode())) .map(c -> messageCallProcessor.getCodeFromEVM(c.getCodeHash(), c.getCode()))
.orElse(CodeV0.EMPTY_CODE)) .orElse(CodeV0.EMPTY_CODE))
.authorizedCodeService(authorizedCodeService)
.build(); .build();
} }
Deque<MessageFrame> messageFrameStack = initialFrame.getMessageFrameStack(); Deque<MessageFrame> messageFrameStack = initialFrame.getMessageFrameStack();
@ -532,9 +526,9 @@ public class MainnetTransactionProcessor {
operationTracer.traceBeforeRewardTransaction(worldUpdater, transaction, coinbaseWeiDelta); operationTracer.traceBeforeRewardTransaction(worldUpdater, transaction, coinbaseWeiDelta);
final var coinbase = worldState.getOrCreate(miningBeneficiary); final var coinbase = evmWorldUpdater.getOrCreate(miningBeneficiary);
coinbase.incrementBalance(coinbaseWeiDelta); coinbase.incrementBalance(coinbaseWeiDelta);
authorizedCodeService.resetAuthorities(); evmWorldUpdater.authorizedCodeService().resetAuthorities();
operationTracer.traceEndTransaction( operationTracer.traceEndTransaction(
worldUpdater, worldUpdater,
@ -546,10 +540,10 @@ public class MainnetTransactionProcessor {
initialFrame.getSelfDestructs(), initialFrame.getSelfDestructs(),
0L); 0L);
initialFrame.getSelfDestructs().forEach(worldState::deleteAccount); initialFrame.getSelfDestructs().forEach(evmWorldUpdater::deleteAccount);
if (clearEmptyAccounts) { if (clearEmptyAccounts) {
worldState.clearAccountsThatAreEmpty(); evmWorldUpdater.clearAccountsThatAreEmpty();
} }
if (initialFrame.getState() == MessageFrame.State.COMPLETED_SUCCESS) { if (initialFrame.getState() == MessageFrame.State.COMPLETED_SUCCESS) {
@ -577,7 +571,7 @@ public class MainnetTransactionProcessor {
} }
} catch (final MerkleTrieException re) { } catch (final MerkleTrieException re) {
operationTracer.traceEndTransaction( operationTracer.traceEndTransaction(
worldState.updater(), evmWorldUpdater.updater(),
transaction, transaction,
false, false,
Bytes.EMPTY, Bytes.EMPTY,
@ -590,7 +584,7 @@ public class MainnetTransactionProcessor {
throw re; throw re;
} catch (final RuntimeException re) { } catch (final RuntimeException re) {
operationTracer.traceEndTransaction( operationTracer.traceEndTransaction(
worldState.updater(), evmWorldUpdater.updater(),
transaction, transaction,
false, false,
Bytes.EMPTY, Bytes.EMPTY,

@ -18,7 +18,6 @@ import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.evm.account.Account; import org.hyperledger.besu.evm.account.Account;
import org.hyperledger.besu.evm.account.MutableAccount; import org.hyperledger.besu.evm.account.MutableAccount;
import org.hyperledger.besu.evm.worldstate.AuthorizedCodeService;
import org.hyperledger.besu.evm.worldstate.WorldUpdater; import org.hyperledger.besu.evm.worldstate.WorldUpdater;
import java.util.Collection; import java.util.Collection;
@ -31,39 +30,35 @@ public class PrivateMutableWorldStateUpdater implements WorldUpdater {
protected final WorldUpdater publicWorldUpdater; protected final WorldUpdater publicWorldUpdater;
protected final WorldUpdater privateWorldUpdater; protected final WorldUpdater privateWorldUpdater;
private AuthorizedCodeService authorizedCodeService;
public PrivateMutableWorldStateUpdater( public PrivateMutableWorldStateUpdater(
final WorldUpdater publicWorldUpdater, final WorldUpdater privateWorldUpdater) { final WorldUpdater publicWorldUpdater, final WorldUpdater privateWorldUpdater) {
this.publicWorldUpdater = publicWorldUpdater; this.publicWorldUpdater = publicWorldUpdater;
this.privateWorldUpdater = privateWorldUpdater; this.privateWorldUpdater = privateWorldUpdater;
this.authorizedCodeService = new AuthorizedCodeService();
} }
@Override @Override
public MutableAccount createAccount(final Address address, final long nonce, final Wei balance) { public MutableAccount createAccount(final Address address, final long nonce, final Wei balance) {
return authorizedCodeService.processMutableAccount( return privateWorldUpdater.createAccount(address, nonce, balance);
this, privateWorldUpdater.createAccount(address, nonce, balance), address);
} }
@Override @Override
public MutableAccount createAccount(final Address address) { public MutableAccount createAccount(final Address address) {
return authorizedCodeService.processMutableAccount( return privateWorldUpdater.createAccount(address);
this, privateWorldUpdater.createAccount(address), address);
} }
@Override @Override
public MutableAccount getAccount(final Address address) { public MutableAccount getAccount(final Address address) {
final MutableAccount privateAccount = privateWorldUpdater.getAccount(address); final MutableAccount privateAccount = privateWorldUpdater.getAccount(address);
if (privateAccount != null && !privateAccount.isEmpty()) { if (privateAccount != null && !privateAccount.isEmpty()) {
return authorizedCodeService.processMutableAccount(this, privateAccount, address); return privateAccount;
} }
final MutableAccount publicAccount = publicWorldUpdater.getAccount(address); final MutableAccount publicAccount = publicWorldUpdater.getAccount(address);
if (publicAccount != null && !publicAccount.isEmpty()) { if (publicAccount != null && !publicAccount.isEmpty()) {
publicAccount.becomeImmutable(); publicAccount.becomeImmutable();
return authorizedCodeService.processMutableAccount(this, publicAccount, address); return publicAccount;
} }
return authorizedCodeService.processMutableAccount(this, privateAccount, address); return privateAccount;
} }
@Override @Override
@ -109,9 +104,4 @@ public class PrivateMutableWorldStateUpdater implements WorldUpdater {
public Optional<WorldUpdater> parentUpdater() { public Optional<WorldUpdater> parentUpdater() {
return privateWorldUpdater.parentUpdater(); return privateWorldUpdater.parentUpdater();
} }
@Override
public void setAuthorizedCodeService(final AuthorizedCodeService authorizedCodeService) {
this.authorizedCodeService = authorizedCodeService;
}
} }

@ -250,8 +250,7 @@ public abstract class DiffBasedWorldStateUpdateAccumulator<ACCOUNT extends DiffB
accountsToUpdate.put(address, diffBasedValue); accountsToUpdate.put(address, diffBasedValue);
} else if (diffBasedValue.getUpdated() != null) { } else if (diffBasedValue.getUpdated() != null) {
if (diffBasedValue.getUpdated().isEmpty()) { if (diffBasedValue.getUpdated().isEmpty()) {
return authorizedCodeService.processMutableAccount( return track(new UpdateTrackingAccount<>(diffBasedValue.getUpdated()));
this, track(new UpdateTrackingAccount<>(diffBasedValue.getUpdated())), address);
} else { } else {
throw new IllegalStateException("Cannot create an account when one already exists"); throw new IllegalStateException("Cannot create an account when one already exists");
} }
@ -268,8 +267,7 @@ public abstract class DiffBasedWorldStateUpdateAccumulator<ACCOUNT extends DiffB
Hash.EMPTY, Hash.EMPTY,
true); true);
diffBasedValue.setUpdated(newAccount); diffBasedValue.setUpdated(newAccount);
return authorizedCodeService.processMutableAccount( return track(new UpdateTrackingAccount<>(newAccount));
this, track(new UpdateTrackingAccount<>(newAccount)), address);
} }
@Override @Override

@ -18,7 +18,6 @@ import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.evm.account.Account; import org.hyperledger.besu.evm.account.Account;
import org.hyperledger.besu.evm.account.MutableAccount; import org.hyperledger.besu.evm.account.MutableAccount;
import org.hyperledger.besu.evm.worldstate.AuthorizedCodeService;
import org.hyperledger.besu.evm.worldstate.WorldUpdater; import org.hyperledger.besu.evm.worldstate.WorldUpdater;
import java.util.Collection; import java.util.Collection;
@ -35,8 +34,6 @@ public class SimpleWorld implements WorldUpdater {
/** The Accounts. */ /** The Accounts. */
Map<Address, SimpleAccount> accounts = new HashMap<>(); Map<Address, SimpleAccount> accounts = new HashMap<>();
private AuthorizedCodeService authorizedCodeService;
/** Instantiates a new Simple world. */ /** Instantiates a new Simple world. */
public SimpleWorld() { public SimpleWorld() {
this(null); this(null);
@ -49,7 +46,6 @@ public class SimpleWorld implements WorldUpdater {
*/ */
public SimpleWorld(final SimpleWorld parent) { public SimpleWorld(final SimpleWorld parent) {
this.parent = parent; this.parent = parent;
this.authorizedCodeService = new AuthorizedCodeService();
} }
@Override @Override
@ -60,11 +56,11 @@ public class SimpleWorld implements WorldUpdater {
@Override @Override
public Account get(final Address address) { public Account get(final Address address) {
if (accounts.containsKey(address)) { if (accounts.containsKey(address)) {
return authorizedCodeService.processAccount(this, accounts.get(address), address); return accounts.get(address);
} else if (parent != null) { } else if (parent != null) {
return authorizedCodeService.processAccount(this, parent.get(address), address); return parent.get(address);
} else { } else {
return authorizedCodeService.processAccount(this, null, address); return null;
} }
} }
@ -75,14 +71,14 @@ public class SimpleWorld implements WorldUpdater {
} }
SimpleAccount account = new SimpleAccount(address, nonce, balance); SimpleAccount account = new SimpleAccount(address, nonce, balance);
accounts.put(address, account); accounts.put(address, account);
return authorizedCodeService.processMutableAccount(this, account, address); return account;
} }
@Override @Override
public MutableAccount getAccount(final Address address) { public MutableAccount getAccount(final Address address) {
SimpleAccount account = accounts.get(address); SimpleAccount account = accounts.get(address);
if (account != null) { if (account != null) {
return authorizedCodeService.processMutableAccount(this, account, address); return account;
} }
Account parentAccount = parent == null ? null : parent.getAccount(address); Account parentAccount = parent == null ? null : parent.getAccount(address);
if (parentAccount != null) { if (parentAccount != null) {
@ -94,9 +90,9 @@ public class SimpleWorld implements WorldUpdater {
parentAccount.getBalance(), parentAccount.getBalance(),
parentAccount.getCode()); parentAccount.getCode());
accounts.put(address, account); accounts.put(address, account);
return authorizedCodeService.processMutableAccount(this, account, address); return account;
} }
return authorizedCodeService.processMutableAccount(this, null, address); return null;
} }
@Override @Override
@ -136,9 +132,4 @@ public class SimpleWorld implements WorldUpdater {
public Optional<WorldUpdater> parentUpdater() { public Optional<WorldUpdater> parentUpdater() {
return Optional.ofNullable(parent); return Optional.ofNullable(parent);
} }
@Override
public void setAuthorizedCodeService(final AuthorizedCodeService authorizedCodeService) {
this.authorizedCodeService = authorizedCodeService;
}
} }

@ -33,7 +33,6 @@ import org.hyperledger.besu.evm.internal.UnderflowException;
import org.hyperledger.besu.evm.log.Log; import org.hyperledger.besu.evm.log.Log;
import org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup; import org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup;
import org.hyperledger.besu.evm.operation.Operation; import org.hyperledger.besu.evm.operation.Operation;
import org.hyperledger.besu.evm.worldstate.AuthorizedCodeService;
import org.hyperledger.besu.evm.worldstate.WorldUpdater; import org.hyperledger.besu.evm.worldstate.WorldUpdater;
import java.util.ArrayDeque; import java.util.ArrayDeque;
@ -202,7 +201,6 @@ public class MessageFrame {
// Global data fields. // Global data fields.
private final WorldUpdater worldUpdater; private final WorldUpdater worldUpdater;
private final AuthorizedCodeService authorizedCodeService;
// Metadata fields. // Metadata fields.
private final Type type; private final Type type;
@ -272,8 +270,7 @@ public class MessageFrame {
final Consumer<MessageFrame> completer, final Consumer<MessageFrame> completer,
final Map<String, Object> contextVariables, final Map<String, Object> contextVariables,
final Optional<Bytes> revertReason, final Optional<Bytes> revertReason,
final TxValues txValues, final TxValues txValues) {
final AuthorizedCodeService authorizedCodeService) {
this.txValues = txValues; this.txValues = txValues;
this.type = type; this.type = type;
@ -293,7 +290,6 @@ public class MessageFrame {
this.completer = completer; this.completer = completer;
this.contextVariables = contextVariables; this.contextVariables = contextVariables;
this.revertReason = revertReason; this.revertReason = revertReason;
this.authorizedCodeService = authorizedCodeService;
this.undoMark = txValues.transientStorage().mark(); this.undoMark = txValues.transientStorage().mark();
} }
@ -427,15 +423,6 @@ public class MessageFrame {
return returnData; return returnData;
} }
/**
* Return the authorized account service.
*
* @return the authorized account service
*/
public AuthorizedCodeService getAuthorizedCodeService() {
return authorizedCodeService;
}
/** /**
* Set the return data. * Set the return data.
* *
@ -1360,7 +1347,6 @@ public class MessageFrame {
private Optional<Bytes> reason = Optional.empty(); private Optional<Bytes> reason = Optional.empty();
private Set<Address> accessListWarmAddresses = emptySet(); private Set<Address> accessListWarmAddresses = emptySet();
private Multimap<Address, Bytes32> accessListWarmStorage = HashMultimap.create(); private Multimap<Address, Bytes32> accessListWarmStorage = HashMultimap.create();
private AuthorizedCodeService authorizedCodeService;
private Optional<List<VersionedHash>> versionedHashes = Optional.empty(); private Optional<List<VersionedHash>> versionedHashes = Optional.empty();
@ -1645,17 +1631,6 @@ public class MessageFrame {
return this; return this;
} }
/**
* Sets authorized account service.
*
* @param authorizedCodeService the authorized account service
* @return the builder
*/
public Builder authorizedCodeService(final AuthorizedCodeService authorizedCodeService) {
this.authorizedCodeService = authorizedCodeService;
return this;
}
private void validate() { private void validate() {
if (parentMessageFrame == null) { if (parentMessageFrame == null) {
checkState(worldUpdater != null, "Missing message frame world updater"); checkState(worldUpdater != null, "Missing message frame world updater");
@ -1690,10 +1665,6 @@ public class MessageFrame {
boolean newStatic; boolean newStatic;
TxValues newTxValues; TxValues newTxValues;
if (authorizedCodeService == null) {
authorizedCodeService = new AuthorizedCodeService();
}
if (parentMessageFrame == null) { if (parentMessageFrame == null) {
newTxValues = newTxValues =
new TxValues( new TxValues(
@ -1721,8 +1692,6 @@ public class MessageFrame {
parentMessageFrame.warmUpAddress(contract); parentMessageFrame.warmUpAddress(contract);
} }
updater.setAuthorizedCodeService(authorizedCodeService);
MessageFrame messageFrame = MessageFrame messageFrame =
new MessageFrame( new MessageFrame(
type, type,
@ -1739,8 +1708,7 @@ public class MessageFrame {
completer, completer,
contextVariables == null ? Map.of() : contextVariables, contextVariables == null ? Map.of() : contextVariables,
reason, reason,
newTxValues, newTxValues);
authorizedCodeService);
newTxValues.messageFrameStack().addFirst(messageFrame); newTxValues.messageFrameStack().addFirst(messageFrame);
messageFrame.warmUpAddress(sender); messageFrame.warmUpAddress(sender);
messageFrame.warmUpAddress(contract); messageFrame.warmUpAddress(contract);

@ -230,7 +230,6 @@ public abstract class AbstractCallOperation extends AbstractOperation {
.code(code) .code(code)
.isStatic(isStatic(frame)) .isStatic(isStatic(frame))
.completer(child -> complete(frame, child)) .completer(child -> complete(frame, child))
.authorizedCodeService(frame.getAuthorizedCodeService())
.build(); .build();
// see note in stack depth check about incrementing cost // see note in stack depth check about incrementing cost
frame.incrementRemainingGas(cost); frame.incrementRemainingGas(cost);

@ -195,7 +195,6 @@ public abstract class AbstractCreateOperation extends AbstractOperation {
.apparentValue(value) .apparentValue(value)
.code(code) .code(code)
.completer(child -> complete(parent, child, evm)) .completer(child -> complete(parent, child, evm))
.authorizedCodeService(parent.getAuthorizedCodeService())
.build(); .build();
parent.setState(MessageFrame.State.CODE_SUSPENDED); parent.setState(MessageFrame.State.CODE_SUSPENDED);

@ -180,7 +180,6 @@ public abstract class AbstractExtCallOperation extends AbstractCallOperation {
.code(code) .code(code)
.isStatic(isStatic(frame)) .isStatic(isStatic(frame))
.completer(child -> complete(frame, child)) .completer(child -> complete(frame, child))
.authorizedCodeService(frame.getAuthorizedCodeService())
.build(); .build();
frame.setState(MessageFrame.State.CODE_SUSPENDED); frame.setState(MessageFrame.State.CODE_SUSPENDED);

@ -43,9 +43,6 @@ public abstract class AbstractWorldUpdater<W extends WorldView, A extends Accoun
private final W world; private final W world;
private final EvmConfiguration evmConfiguration; private final EvmConfiguration evmConfiguration;
/** The authorized code service. */
protected AuthorizedCodeService authorizedCodeService;
/** The Updated accounts. */ /** The Updated accounts. */
protected Map<Address, UpdateTrackingAccount<A>> updatedAccounts = new ConcurrentHashMap<>(); protected Map<Address, UpdateTrackingAccount<A>> updatedAccounts = new ConcurrentHashMap<>();
@ -62,7 +59,6 @@ public abstract class AbstractWorldUpdater<W extends WorldView, A extends Accoun
protected AbstractWorldUpdater(final W world, final EvmConfiguration evmConfiguration) { protected AbstractWorldUpdater(final W world, final EvmConfiguration evmConfiguration) {
this.world = world; this.world = world;
this.evmConfiguration = evmConfiguration; this.evmConfiguration = evmConfiguration;
this.authorizedCodeService = new AuthorizedCodeService();
} }
/** /**
@ -91,7 +87,7 @@ public abstract class AbstractWorldUpdater<W extends WorldView, A extends Accoun
final UpdateTrackingAccount<A> account = new UpdateTrackingAccount<>(address); final UpdateTrackingAccount<A> account = new UpdateTrackingAccount<>(address);
account.setNonce(nonce); account.setNonce(nonce);
account.setBalance(balance); account.setBalance(balance);
return authorizedCodeService.processMutableAccount(this, track(account), address); return track(account);
} }
@Override @Override
@ -99,12 +95,12 @@ public abstract class AbstractWorldUpdater<W extends WorldView, A extends Accoun
// We may have updated it already, so check that first. // We may have updated it already, so check that first.
final MutableAccount existing = updatedAccounts.get(address); final MutableAccount existing = updatedAccounts.get(address);
if (existing != null) { if (existing != null) {
return authorizedCodeService.processAccount(this, existing, address); return existing;
} }
if (deletedAccounts.contains(address)) { if (deletedAccounts.contains(address)) {
return null; return null;
} }
return authorizedCodeService.processAccount(this, getForMutation(address), address); return getForMutation(address);
} }
@Override @Override
@ -112,7 +108,7 @@ public abstract class AbstractWorldUpdater<W extends WorldView, A extends Accoun
// We may have updated it already, so check that first. // We may have updated it already, so check that first.
final MutableAccount existing = updatedAccounts.get(address); final MutableAccount existing = updatedAccounts.get(address);
if (existing != null) { if (existing != null) {
return authorizedCodeService.processMutableAccount(this, existing, address); return existing;
} }
if (deletedAccounts.contains(address)) { if (deletedAccounts.contains(address)) {
return null; return null;
@ -121,10 +117,9 @@ public abstract class AbstractWorldUpdater<W extends WorldView, A extends Accoun
// Otherwise, get it from our wrapped view and create a new update tracker. // Otherwise, get it from our wrapped view and create a new update tracker.
final A origin = getForMutation(address); final A origin = getForMutation(address);
if (origin == null) { if (origin == null) {
return authorizedCodeService.processMutableAccount(this, null, address); return null;
} else { } else {
return authorizedCodeService.processMutableAccount( return track(new UpdateTrackingAccount<>(origin));
this, track(new UpdateTrackingAccount<>(origin)), address);
} }
} }
@ -170,11 +165,6 @@ public abstract class AbstractWorldUpdater<W extends WorldView, A extends Accoun
} }
} }
@Override
public void setAuthorizedCodeService(final AuthorizedCodeService authorizedCodeService) {
this.authorizedCodeService = authorizedCodeService;
}
/** /**
* The accounts modified in this updater. * The accounts modified in this updater.
* *

@ -0,0 +1,127 @@
/*
* Copyright contributors to Hyperledger Besu.
*
* 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.Wei;
import org.hyperledger.besu.evm.account.Account;
import org.hyperledger.besu.evm.account.MutableAccount;
import org.hyperledger.besu.evm.frame.MessageFrame;
import java.util.Collection;
import java.util.Optional;
/**
* The EVM world updater. This class is a wrapper around a WorldUpdater that provides an
* AuthorizedCodeService to manage the authorized code for accounts.
*/
public class EVMWorldUpdater implements WorldUpdater {
private final WorldUpdater rootWorldUpdater;
private final AuthorizedCodeService authorizedCodeService;
/**
* Instantiates a new EVM world updater.
*
* @param rootWorldUpdater the root world updater
*/
public EVMWorldUpdater(final WorldUpdater rootWorldUpdater) {
this(rootWorldUpdater, new AuthorizedCodeService());
}
private EVMWorldUpdater(
final WorldUpdater rootWorldUpdater, final AuthorizedCodeService authorizedCodeService) {
this.rootWorldUpdater = rootWorldUpdater;
this.authorizedCodeService = authorizedCodeService;
}
/**
* Authorized code service.
*
* @return the authorized code service
*/
public AuthorizedCodeService authorizedCodeService() {
return authorizedCodeService;
}
@Override
public MutableAccount createAccount(final Address address, final long nonce, final Wei balance) {
return authorizedCodeService.processMutableAccount(
this, rootWorldUpdater.createAccount(address, nonce, balance), address);
}
@Override
public MutableAccount getAccount(final Address address) {
return authorizedCodeService.processMutableAccount(
this, rootWorldUpdater.getAccount(address), address);
}
@Override
public MutableAccount getOrCreate(final Address address) {
return authorizedCodeService.processMutableAccount(
this, rootWorldUpdater.getOrCreate(address), address);
}
@Override
public MutableAccount getOrCreateSenderAccount(final Address address) {
return authorizedCodeService.processMutableAccount(
this, rootWorldUpdater.getOrCreateSenderAccount(address), address);
}
@Override
public MutableAccount getSenderAccount(final MessageFrame frame) {
return authorizedCodeService.processMutableAccount(
this, rootWorldUpdater.getSenderAccount(frame), frame.getSenderAddress());
}
@Override
public void deleteAccount(final Address address) {
rootWorldUpdater.deleteAccount(address);
}
@Override
public Collection<? extends Account> getTouchedAccounts() {
return rootWorldUpdater.getTouchedAccounts();
}
@Override
public Collection<Address> getDeletedAccountAddresses() {
return rootWorldUpdater.getDeletedAccountAddresses();
}
@Override
public void revert() {
rootWorldUpdater.revert();
}
@Override
public void commit() {
rootWorldUpdater.commit();
}
@Override
public Optional<WorldUpdater> parentUpdater() {
return rootWorldUpdater.parentUpdater();
}
@Override
public WorldUpdater updater() {
return new EVMWorldUpdater(rootWorldUpdater.updater(), authorizedCodeService);
}
@Override
public Account get(final Address address) {
return authorizedCodeService.processAccount(this, rootWorldUpdater.get(address), address);
}
}

@ -41,7 +41,6 @@ public class JournaledUpdater<W extends WorldView> implements WorldUpdater {
final UndoMap<Address, JournaledAccount> accounts; final UndoMap<Address, JournaledAccount> accounts;
final UndoSet<Address> deleted; final UndoSet<Address> deleted;
final long undoMark; final long undoMark;
private AuthorizedCodeService authorizedCodeService;
/** /**
* Instantiates a new Stacked updater. * Instantiates a new Stacked updater.
@ -67,7 +66,6 @@ public class JournaledUpdater<W extends WorldView> implements WorldUpdater {
"WorldUpdater must be a JournaledWorldUpdater or an AbstractWorldUpdater"); "WorldUpdater must be a JournaledWorldUpdater or an AbstractWorldUpdater");
} }
undoMark = accounts.mark(); undoMark = accounts.mark();
this.authorizedCodeService = new AuthorizedCodeService();
} }
/** /**
@ -128,18 +126,12 @@ public class JournaledUpdater<W extends WorldView> implements WorldUpdater {
accounts.values().forEach(JournaledAccount::markTransactionBoundary); accounts.values().forEach(JournaledAccount::markTransactionBoundary);
} }
@Override
public void setAuthorizedCodeService(final AuthorizedCodeService authorizedCodeService) {
this.authorizedCodeService = authorizedCodeService;
}
@Override @Override
public MutableAccount createAccount(final Address address, final long nonce, final Wei balance) { public MutableAccount createAccount(final Address address, final long nonce, final Wei balance) {
JournaledAccount journaledAccount = JournaledAccount journaledAccount =
new JournaledAccount(rootWorld.createAccount(address, nonce, balance)); new JournaledAccount(rootWorld.createAccount(address, nonce, balance));
accounts.put(address, journaledAccount); accounts.put(address, journaledAccount);
return authorizedCodeService.processMutableAccount( return new JournaledAccount(journaledAccount);
this, new JournaledAccount(journaledAccount), address);
} }
@Override @Override
@ -147,7 +139,7 @@ public class JournaledUpdater<W extends WorldView> implements WorldUpdater {
// We may have updated it already, so check that first. // We may have updated it already, so check that first.
final JournaledAccount existing = accounts.get(address); final JournaledAccount existing = accounts.get(address);
if (existing != null) { if (existing != null) {
return authorizedCodeService.processMutableAccount(this, existing, address); return existing;
} }
if (deleted.contains(address)) { if (deleted.contains(address)) {
return null; return null;
@ -156,11 +148,11 @@ public class JournaledUpdater<W extends WorldView> implements WorldUpdater {
// Otherwise, get it from our wrapped view and create a new update tracker. // Otherwise, get it from our wrapped view and create a new update tracker.
final MutableAccount origin = rootWorld.getAccount(address); final MutableAccount origin = rootWorld.getAccount(address);
if (origin == null) { if (origin == null) {
return authorizedCodeService.processMutableAccount(this, null, address); return null;
} else { } else {
var newAccount = new JournaledAccount(origin); var newAccount = new JournaledAccount(origin);
accounts.put(address, newAccount); accounts.put(address, newAccount);
return authorizedCodeService.processMutableAccount(this, newAccount, address); return newAccount;
} }
} }
@ -177,12 +169,12 @@ public class JournaledUpdater<W extends WorldView> implements WorldUpdater {
public Account get(final Address address) { public Account get(final Address address) {
final MutableAccount existing = accounts.get(address); final MutableAccount existing = accounts.get(address);
if (existing != null) { if (existing != null) {
return authorizedCodeService.processAccount(this, existing, address); return existing;
} }
if (deleted.contains(address)) { if (deleted.contains(address)) {
return authorizedCodeService.processAccount(this, null, address); return null;
} }
return authorizedCodeService.processAccount(this, rootWorld.get(address), address); return rootWorld.get(address);
} }
@Override @Override

@ -179,12 +179,4 @@ public interface WorldUpdater extends MutableWorldView {
default void markTransactionBoundary() { default void markTransactionBoundary() {
// default is to ignore // default is to ignore
} }
/**
* Sets the {@link AuthorizedCodeService} associated with this {@link WorldUpdater}.
*
* @param authorizedCodeService the {@link AuthorizedCodeService} to associate with this {@link
* WorldUpdater}
*/
void setAuthorizedCodeService(AuthorizedCodeService authorizedCodeService);
} }

@ -18,7 +18,6 @@ import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.evm.account.Account; import org.hyperledger.besu.evm.account.Account;
import org.hyperledger.besu.evm.account.MutableAccount; import org.hyperledger.besu.evm.account.MutableAccount;
import org.hyperledger.besu.evm.worldstate.AuthorizedCodeService;
import org.hyperledger.besu.evm.worldstate.WorldUpdater; import org.hyperledger.besu.evm.worldstate.WorldUpdater;
import java.util.Collection; import java.util.Collection;
@ -33,7 +32,6 @@ public class ToyWorld implements WorldUpdater {
ToyWorld parent; ToyWorld parent;
Map<Address, ToyAccount> accounts = new HashMap<>(); Map<Address, ToyAccount> accounts = new HashMap<>();
private AuthorizedCodeService authorizedCodeService;
public ToyWorld() { public ToyWorld() {
this(null); this(null);
@ -41,7 +39,6 @@ public class ToyWorld implements WorldUpdater {
public ToyWorld(final ToyWorld parent) { public ToyWorld(final ToyWorld parent) {
this.parent = parent; this.parent = parent;
this.authorizedCodeService = new AuthorizedCodeService();
} }
@Override @Override
@ -52,11 +49,11 @@ public class ToyWorld implements WorldUpdater {
@Override @Override
public Account get(final Address address) { public Account get(final Address address) {
if (accounts.containsKey(address)) { if (accounts.containsKey(address)) {
return authorizedCodeService.processAccount(this, accounts.get(address), address); return accounts.get(address);
} else if (parent != null) { } else if (parent != null) {
return authorizedCodeService.processAccount(this, parent.get(address), address); return parent.get(address);
} else { } else {
return authorizedCodeService.processAccount(this, null, address); return null;
} }
} }
@ -73,17 +70,17 @@ public class ToyWorld implements WorldUpdater {
final Bytes code) { final Bytes code) {
ToyAccount account = new ToyAccount(parentAccount, address, nonce, balance, code); ToyAccount account = new ToyAccount(parentAccount, address, nonce, balance, code);
accounts.put(address, account); accounts.put(address, account);
return authorizedCodeService.processMutableAccount(this, account, address); return account;
} }
@Override @Override
public MutableAccount getAccount(final Address address) { public MutableAccount getAccount(final Address address) {
if (accounts.containsKey(address)) { if (accounts.containsKey(address)) {
return authorizedCodeService.processMutableAccount(this, accounts.get(address), address); return accounts.get(address);
} else if (parent != null) { } else if (parent != null) {
Account parentAccount = parent.getAccount(address); Account parentAccount = parent.getAccount(address);
if (parentAccount == null) { if (parentAccount == null) {
return authorizedCodeService.processMutableAccount(this, null, address); return null;
} else { } else {
return createAccount( return createAccount(
parentAccount, parentAccount,
@ -93,7 +90,7 @@ public class ToyWorld implements WorldUpdater {
parentAccount.getCode()); parentAccount.getCode());
} }
} else { } else {
return authorizedCodeService.processMutableAccount(this, null, address); return null;
} }
} }
@ -131,9 +128,4 @@ public class ToyWorld implements WorldUpdater {
public Optional<WorldUpdater> parentUpdater() { public Optional<WorldUpdater> parentUpdater() {
return Optional.empty(); return Optional.empty();
} }
@Override
public void setAuthorizedCodeService(final AuthorizedCodeService authorizedCodeService) {
this.authorizedCodeService = authorizedCodeService;
}
} }

Loading…
Cancel
Save