diff --git a/besu/src/main/java/org/hyperledger/besu/services/TransactionSimulationServiceImpl.java b/besu/src/main/java/org/hyperledger/besu/services/TransactionSimulationServiceImpl.java index 54cce205a36..4dc411ee0be 100644 --- a/besu/src/main/java/org/hyperledger/besu/services/TransactionSimulationServiceImpl.java +++ b/besu/src/main/java/org/hyperledger/besu/services/TransactionSimulationServiceImpl.java @@ -14,6 +14,7 @@ */ package org.hyperledger.besu.services; +import org.hyperledger.besu.datatypes.AccountOverrideMap; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.Transaction; import org.hyperledger.besu.ethereum.chain.Blockchain; @@ -62,6 +63,17 @@ public Optional simulate( final Hash blockHash, final OperationTracer operationTracer, final boolean isAllowExceedingBalance) { + return simulate( + transaction, Optional.empty(), blockHash, operationTracer, isAllowExceedingBalance); + } + + @Override + public Optional simulate( + final Transaction transaction, + final Optional maybeAccountOverrides, + final Hash blockHash, + final OperationTracer operationTracer, + final boolean isAllowExceedingBalance) { final CallParameter callParameter = CallParameter.fromTransaction(transaction); @@ -79,6 +91,7 @@ public Optional simulate( return transactionSimulator .process( callParameter, + maybeAccountOverrides, isAllowExceedingBalance ? SIMULATOR_ALLOWING_EXCEEDING_BALANCE : TransactionValidationParams.transactionSimulator(), diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/util/AccountOverride.java b/datatypes/src/main/java/org/hyperledger/besu/datatypes/AccountOverride.java similarity index 76% rename from ethereum/core/src/main/java/org/hyperledger/besu/ethereum/util/AccountOverride.java rename to datatypes/src/main/java/org/hyperledger/besu/datatypes/AccountOverride.java index 3bae4af1d84..e414e97eb5d 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/util/AccountOverride.java +++ b/datatypes/src/main/java/org/hyperledger/besu/datatypes/AccountOverride.java @@ -12,9 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.ethereum.util; - -import org.hyperledger.besu.datatypes.Wei; +package org.hyperledger.besu.datatypes; import java.util.Map; import java.util.Objects; @@ -26,11 +24,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -// similar to AccountDiff -// BUT -// there are more fields that need to be added -// stateDiff -// movePrecompileToAddress +/** Account Override parameter class */ @JsonIgnoreProperties(ignoreUnknown = true) @JsonDeserialize(builder = AccountOverride.Builder.class) public class AccountOverride { @@ -52,22 +46,43 @@ private AccountOverride( this.stateDiff = stateDiff; } + /** + * Gets the balance override + * + * @return the balance if present + */ public Optional getBalance() { return balance; } + /** + * Gets the nonce override + * + * @return the nonce if present + */ public Optional getNonce() { return nonce; } + /** + * Gets the code override + * + * @return the code if present + */ public Optional getCode() { return code; } + /** + * Gets the state override map + * + * @return the state override map if present + */ public Optional> getStateDiff() { return stateDiff; } + /** Builder class for Account overrides */ public static class Builder { private Optional balance = Optional.empty(); private Optional nonce = Optional.empty(); @@ -77,31 +92,66 @@ public static class Builder { /** Default constructor. */ public Builder() {} + /** + * Sets the balance override + * + * @param balance the balance override + * @return the builder + */ public Builder withBalance(final Wei balance) { this.balance = Optional.ofNullable(balance); return this; } + /** + * Sets the nonce override + * + * @param nonce the nonce override + * @return the builder + */ public Builder withNonce(final Long nonce) { this.nonce = Optional.ofNullable(nonce); return this; } + /** + * Sets the code override + * + * @param code the code override + * @return the builder + */ public Builder withCode(final String code) { this.code = Optional.ofNullable(code); return this; } + /** + * Sets the state diff override + * + * @param stateDiff the map of state overrides + * @return the builder + */ public Builder withStateDiff(final Map stateDiff) { this.stateDiff = Optional.ofNullable(stateDiff); return this; } + /** + * build the account override from the builder + * + * @return account override + */ public AccountOverride build() { return new AccountOverride(balance, nonce, code, stateDiff); } } + /** + * utility method to log unknown properties + * + * @param key key for the unrecognized value + * @param value the unrecognized value + */ @JsonAnySetter public void withUnknownProperties(final String key, final Object value) { LOG.debug( diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/util/AccountOverrideMap.java b/datatypes/src/main/java/org/hyperledger/besu/datatypes/AccountOverrideMap.java similarity index 87% rename from ethereum/core/src/main/java/org/hyperledger/besu/ethereum/util/AccountOverrideMap.java rename to datatypes/src/main/java/org/hyperledger/besu/datatypes/AccountOverrideMap.java index 30fc808c9bb..20aee461859 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/util/AccountOverrideMap.java +++ b/datatypes/src/main/java/org/hyperledger/besu/datatypes/AccountOverrideMap.java @@ -12,16 +12,16 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.ethereum.util; - -import org.hyperledger.besu.datatypes.Address; +package org.hyperledger.besu.datatypes; import java.util.HashMap; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +/** Map of account overrides, indexed by address */ @JsonIgnoreProperties(ignoreUnknown = true) public class AccountOverrideMap extends HashMap { + /** Default constructor */ public AccountOverrideMap() {} } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCall.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCall.java index 5f736e8d5a9..ef5c8c7a6cf 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCall.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCall.java @@ -17,6 +17,7 @@ import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType.BLOCK_NOT_FOUND; import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType.INTERNAL_ERROR; +import org.hyperledger.besu.datatypes.AccountOverrideMap; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcErrorConverter; @@ -41,7 +42,6 @@ import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason; import org.hyperledger.besu.ethereum.transaction.TransactionSimulator; import org.hyperledger.besu.ethereum.transaction.TransactionSimulatorResult; -import org.hyperledger.besu.ethereum.util.AccountOverrideMap; import org.hyperledger.besu.evm.tracing.OperationTracer; import java.util.Optional; diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthEstimateGas.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthEstimateGas.java index ab758dadec7..2352a5a8c37 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthEstimateGas.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthEstimateGas.java @@ -14,6 +14,7 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; +import org.hyperledger.besu.datatypes.AccountOverrideMap; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcRequestException; @@ -29,7 +30,6 @@ import org.hyperledger.besu.ethereum.transaction.CallParameter; import org.hyperledger.besu.ethereum.transaction.TransactionSimulator; import org.hyperledger.besu.ethereum.transaction.TransactionSimulatorResult; -import org.hyperledger.besu.ethereum.util.AccountOverrideMap; import org.hyperledger.besu.evm.tracing.EstimateGasOperationTracer; import java.util.Optional; diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCallTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCallTest.java index d16de7d9943..7de6f65aae2 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCallTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCallTest.java @@ -27,6 +27,8 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; +import org.hyperledger.besu.datatypes.AccountOverride; +import org.hyperledger.besu.datatypes.AccountOverrideMap; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.Wei; @@ -51,8 +53,6 @@ import org.hyperledger.besu.ethereum.transaction.PreCloseStateHandler; import org.hyperledger.besu.ethereum.transaction.TransactionSimulator; import org.hyperledger.besu.ethereum.transaction.TransactionSimulatorResult; -import org.hyperledger.besu.ethereum.util.AccountOverride; -import org.hyperledger.besu.ethereum.util.AccountOverrideMap; import java.util.Optional; diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthEstimateGasTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthEstimateGasTest.java index 9f321e00502..7c770f08a2d 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthEstimateGasTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthEstimateGasTest.java @@ -21,6 +21,8 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import org.hyperledger.besu.datatypes.AccountOverride; +import org.hyperledger.besu.datatypes.AccountOverrideMap; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest; @@ -44,8 +46,6 @@ import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason; import org.hyperledger.besu.ethereum.transaction.TransactionSimulator; import org.hyperledger.besu.ethereum.transaction.TransactionSimulatorResult; -import org.hyperledger.besu.ethereum.util.AccountOverride; -import org.hyperledger.besu.ethereum.util.AccountOverrideMap; import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; import org.hyperledger.besu.evm.tracing.OperationTracer; diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/TransactionSimulator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/TransactionSimulator.java index 3f35492b2b4..1c6140f1d1f 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/TransactionSimulator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/TransactionSimulator.java @@ -19,6 +19,8 @@ import org.hyperledger.besu.crypto.SECPSignature; import org.hyperledger.besu.crypto.SignatureAlgorithm; import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; +import org.hyperledger.besu.datatypes.AccountOverride; +import org.hyperledger.besu.datatypes.AccountOverrideMap; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.BlobGas; import org.hyperledger.besu.datatypes.Hash; @@ -34,8 +36,6 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; import org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams; import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult; -import org.hyperledger.besu.ethereum.util.AccountOverride; -import org.hyperledger.besu.ethereum.util.AccountOverrideMap; import org.hyperledger.besu.ethereum.vm.CachingBlockHashLookup; import org.hyperledger.besu.ethereum.vm.DebugOperationTracer; import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; @@ -105,6 +105,7 @@ public Optional process( final BlockHeader header = blockchain.getBlockHeader(blockNumber).orElse(null); return process( callParams, + Optional.empty(), transactionValidationParams, operationTracer, (mutableWorldState, transactionSimulatorResult) -> transactionSimulatorResult, @@ -118,6 +119,7 @@ public Optional process( final BlockHeader blockHeader) { return process( callParams, + Optional.empty(), transactionValidationParams, operationTracer, (mutableWorldState, transactionSimulatorResult) -> transactionSimulatorResult, diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/transaction/TransactionSimulatorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/transaction/TransactionSimulatorTest.java index 0dfa7e924fa..e0715e58477 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/transaction/TransactionSimulatorTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/transaction/TransactionSimulatorTest.java @@ -26,6 +26,7 @@ import org.hyperledger.besu.crypto.SECPSignature; import org.hyperledger.besu.crypto.SignatureAlgorithm; import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; +import org.hyperledger.besu.datatypes.AccountOverride; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.BlobsWithCommitments; import org.hyperledger.besu.datatypes.Hash; @@ -48,7 +49,6 @@ import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult; import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult.Status; -import org.hyperledger.besu.ethereum.util.AccountOverride; import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; import org.hyperledger.besu.evm.account.Account; import org.hyperledger.besu.evm.account.MutableAccount; diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/util/AccountOverrideParameterTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/util/AccountOverrideParameterTest.java index 8e7b5c3f0eb..1b6d8c1cbe3 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/util/AccountOverrideParameterTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/util/AccountOverrideParameterTest.java @@ -18,6 +18,8 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; +import org.hyperledger.besu.datatypes.AccountOverride; +import org.hyperledger.besu.datatypes.AccountOverrideMap; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest; diff --git a/plugin-api/build.gradle b/plugin-api/build.gradle index 333cac59268..dfdf20bff21 100644 --- a/plugin-api/build.gradle +++ b/plugin-api/build.gradle @@ -71,7 +71,7 @@ Calculated : ${currentHash} tasks.register('checkAPIChanges', FileStateChecker) { description = "Checks that the API for the Plugin-API project does not change without deliberate thought" files = sourceSets.main.allJava.files - knownHash = 'wOjR3/uPElPs1GonuLMBWStn1zukFMyy/GfQ9OYChpI=' + knownHash = 'IPpTJJxjDbjW08c3Cm8GbBhULYFy0jq9m3BzliGzrf8=' } check.dependsOn('checkAPIChanges') diff --git a/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/TransactionSimulationService.java b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/TransactionSimulationService.java index dffdb0cfe51..d5fc0a34979 100644 --- a/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/TransactionSimulationService.java +++ b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/TransactionSimulationService.java @@ -14,6 +14,7 @@ */ package org.hyperledger.besu.plugin.services; +import org.hyperledger.besu.datatypes.AccountOverrideMap; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.Transaction; import org.hyperledger.besu.evm.tracing.OperationTracer; @@ -39,4 +40,21 @@ Optional simulate( Hash blockHash, OperationTracer operationTracer, boolean isAllowExceedingBalance); + + /** + * Simulate transaction execution at the block identified by the hash + * + * @param transaction tx + * @param accountOverrides state overrides to apply to this simulation + * @param blockHash the hash of the block + * @param operationTracer the tracer + * @param isAllowExceedingBalance should ignore the sender balance during the simulation? + * @return the result of the simulation + */ + Optional simulate( + Transaction transaction, + Optional accountOverrides, + Hash blockHash, + OperationTracer operationTracer, + boolean isAllowExceedingBalance); }