Merge branch 'main' into errors

pull/7881/head
Pavel Zaborskii 1 day ago committed by GitHub
commit 07dc6020a1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 10
      CHANGELOG.md
  2. 4
      acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/BadCLIOptionsPlugin.java
  3. 6
      acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestBesuEventsPlugin.java
  4. 8
      acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestBlockchainServiceFinalizedPlugin.java
  5. 4
      acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestInProcessRpcServicePlugin.java
  6. 10
      acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestMetricsPlugin.java
  7. 4
      acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestPermissioningPlugin.java
  8. 4
      acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestPicoCLIPlugin.java
  9. 6
      acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestPrivacyServicePlugin.java
  10. 4
      acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestRpcEndpointServicePlugin.java
  11. 4
      besu/src/main/java/org/hyperledger/besu/services/BesuPluginContextImpl.java
  12. 13
      besu/src/main/java/org/hyperledger/besu/services/TransactionSimulationServiceImpl.java
  13. 66
      datatypes/src/main/java/org/hyperledger/besu/datatypes/AccountOverride.java
  14. 6
      datatypes/src/main/java/org/hyperledger/besu/datatypes/AccountOverrideMap.java
  15. 2
      docs/README.md
  16. 2
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCall.java
  17. 25
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthEstimateGas.java
  18. 7
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCallTest.java
  19. 47
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthEstimateGasTest.java
  20. 21
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/TransactionSimulator.java
  21. 4
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/BonsaiWorldStateProvider.java
  22. 4
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/DiffBasedWorldStateProvider.java
  23. 6
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/trielog/TrieLogManager.java
  24. 2
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/transaction/TransactionSimulatorTest.java
  25. 2
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/util/AccountOverrideParameterTest.java
  26. 2
      plugin-api/build.gradle
  27. 42
      plugin-api/src/main/java/org/hyperledger/besu/plugin/BesuContext.java
  28. 2
      plugin-api/src/main/java/org/hyperledger/besu/plugin/BesuPlugin.java
  29. 55
      plugin-api/src/main/java/org/hyperledger/besu/plugin/ServiceManager.java
  30. 6
      plugin-api/src/main/java/org/hyperledger/besu/plugin/services/BesuService.java
  31. 18
      plugin-api/src/main/java/org/hyperledger/besu/plugin/services/TransactionSimulationService.java
  32. 6
      plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/RocksDBPlugin.java
  33. 6
      services/kvstore/src/main/java/org/hyperledger/besu/services/kvstore/InMemoryStoragePlugin.java

@ -6,7 +6,15 @@
- Removed Retesteth rpc service and commands [#7833](https://github.com/hyperledger/besu/pull/7783)
### Upcoming Breaking Changes
- Plugin API will be deprecating the BesuContext interface to be replaced with the ServiceManager interface.
- `MetricSystem::createLabelledGauge` is deprecated and will be removed in a future release, replace it with `MetricSystem::createLabelledSuppliedGauge`
- k8s (KUBERNETES) Nat method is now deprecated and will be removed in a future release
- `--host-whitelist` has been deprecated in favor of `--host-allowlist` since 2020 and will be removed in a future release
- Sunsetting features - for more context on the reasoning behind the deprecation of these features, including alternative options, read [this blog post](https://www.lfdecentralizedtrust.org/blog/sunsetting-tessera-and-simplifying-hyperledger-besu)
- Tessera privacy
- Smart-contract-based permissioning
- Proof of Work consensus
- Fast Sync
### Additions and Improvements
- Fine tune already seen txs tracker when a tx is removed from the pool [#7755](https://github.com/hyperledger/besu/pull/7755)
@ -15,8 +23,8 @@
- Update Java dependencies [#7786](https://github.com/hyperledger/besu/pull/7786)
- Add a method to get all the transaction in the pool, to the `TransactionPoolService`, to easily access the transaction pool content from plugins [#7813](https://github.com/hyperledger/besu/pull/7813)
- Add a method to check if a metric category is enabled to the plugin API [#7832](https://github.com/hyperledger/besu/pull/7832)
- Add account and state overrides to `eth_call` and `eth_estimateGas` [#7801](https://github.com/hyperledger/besu/pull/7801)
- Add a new metric collector for counters which get their value from suppliers [#7894](https://github.com/hyperledger/besu/pull/7894)
- Add account and state overrides to `eth_call` [#7801](https://github.com/hyperledger/besu/pull/7801) and `eth_estimateGas` [#7890](https://github.com/hyperledger/besu/pull/7890)
### Bug fixes
- Fix registering new metric categories from plugins [#7825](https://github.com/hyperledger/besu/pull/7825)

@ -16,8 +16,8 @@ package org.hyperledger.besu.tests.acceptance.plugins;
import static java.nio.charset.StandardCharsets.UTF_8;
import org.hyperledger.besu.plugin.BesuContext;
import org.hyperledger.besu.plugin.BesuPlugin;
import org.hyperledger.besu.plugin.ServiceManager;
import org.hyperledger.besu.plugin.services.PicoCLIOptions;
import java.io.File;
@ -39,7 +39,7 @@ public class BadCLIOptionsPlugin implements BesuPlugin {
private File callbackDir;
@Override
public void register(final BesuContext context) {
public void register(final ServiceManager context) {
LOG.info("Registering BadCliOptionsPlugin");
callbackDir = new File(System.getProperty("besu.plugins.dir", "plugins"));
writeStatus("init");

@ -14,8 +14,8 @@
*/
package org.hyperledger.besu.tests.acceptance.plugins;
import org.hyperledger.besu.plugin.BesuContext;
import org.hyperledger.besu.plugin.BesuPlugin;
import org.hyperledger.besu.plugin.ServiceManager;
import org.hyperledger.besu.plugin.data.BlockHeader;
import org.hyperledger.besu.plugin.data.PropagatedBlockContext;
import org.hyperledger.besu.plugin.services.BesuEvents;
@ -35,14 +35,14 @@ import org.slf4j.LoggerFactory;
public class TestBesuEventsPlugin implements BesuPlugin {
private static final Logger LOG = LoggerFactory.getLogger(TestBesuEventsPlugin.class);
private BesuContext context;
private ServiceManager context;
private Optional<Long> subscriptionId;
private final AtomicInteger blockCounter = new AtomicInteger();
private File callbackDir;
@Override
public void register(final BesuContext context) {
public void register(final ServiceManager context) {
this.context = context;
LOG.info("Registered");
callbackDir = new File(System.getProperty("besu.plugins.dir", "plugins"));

@ -17,8 +17,8 @@ package org.hyperledger.besu.tests.acceptance.plugins;
import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType;
import org.hyperledger.besu.plugin.BesuContext;
import org.hyperledger.besu.plugin.BesuPlugin;
import org.hyperledger.besu.plugin.ServiceManager;
import org.hyperledger.besu.plugin.data.BlockContext;
import org.hyperledger.besu.plugin.services.BlockchainService;
import org.hyperledger.besu.plugin.services.RpcEndpointService;
@ -40,11 +40,11 @@ public class TestBlockchainServiceFinalizedPlugin implements BesuPlugin {
private static final String RPC_METHOD_SAFE_BLOCK = "updateSafeBlockV1";
@Override
public void register(final BesuContext besuContext) {
public void register(final ServiceManager serviceManager) {
LOG.trace("Registering plugin ...");
final RpcEndpointService rpcEndpointService =
besuContext
serviceManager
.getService(RpcEndpointService.class)
.orElseThrow(
() ->
@ -52,7 +52,7 @@ public class TestBlockchainServiceFinalizedPlugin implements BesuPlugin {
"Failed to obtain RpcEndpointService from the BesuContext."));
final BlockchainService blockchainService =
besuContext
serviceManager
.getService(BlockchainService.class)
.orElseThrow(
() ->

@ -15,8 +15,8 @@
package org.hyperledger.besu.tests.acceptance.plugins;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.plugin.BesuContext;
import org.hyperledger.besu.plugin.BesuPlugin;
import org.hyperledger.besu.plugin.ServiceManager;
import org.hyperledger.besu.plugin.services.PicoCLIOptions;
import org.hyperledger.besu.plugin.services.RpcEndpointService;
import org.hyperledger.besu.plugin.services.rpc.RpcResponseType;
@ -36,7 +36,7 @@ public class TestInProcessRpcServicePlugin implements BesuPlugin {
long minGasPrice = -1;
@Override
public void register(final BesuContext context) {
public void register(final ServiceManager context) {
final PicoCLIOptions cmdlineOptions =
context
.getService(PicoCLIOptions.class)

@ -14,8 +14,8 @@
*/
package org.hyperledger.besu.tests.acceptance.plugins;
import org.hyperledger.besu.plugin.BesuContext;
import org.hyperledger.besu.plugin.BesuPlugin;
import org.hyperledger.besu.plugin.ServiceManager;
import org.hyperledger.besu.plugin.services.MetricsSystem;
import org.hyperledger.besu.plugin.services.metrics.MetricCategory;
import org.hyperledger.besu.plugin.services.metrics.MetricCategoryRegistry;
@ -30,12 +30,12 @@ import org.slf4j.LoggerFactory;
@AutoService(BesuPlugin.class)
public class TestMetricsPlugin implements BesuPlugin {
private static final Logger LOG = LoggerFactory.getLogger(TestMetricsPlugin.class);
private BesuContext besuContext;
private ServiceManager serviceManager;
@Override
public void register(final BesuContext context) {
public void register(final ServiceManager context) {
LOG.info("Registering TestMetricsPlugin");
besuContext = context;
serviceManager = context;
context
.getService(MetricCategoryRegistry.class)
.orElseThrow()
@ -45,7 +45,7 @@ public class TestMetricsPlugin implements BesuPlugin {
@Override
public void start() {
LOG.info("Starting TestMetricsPlugin");
besuContext
serviceManager
.getService(MetricsSystem.class)
.orElseThrow()
.createGauge(

@ -14,8 +14,8 @@
*/
package org.hyperledger.besu.tests.acceptance.plugins;
import org.hyperledger.besu.plugin.BesuContext;
import org.hyperledger.besu.plugin.BesuPlugin;
import org.hyperledger.besu.plugin.ServiceManager;
import org.hyperledger.besu.plugin.services.PermissioningService;
import org.hyperledger.besu.plugin.services.PicoCLIOptions;
@ -40,7 +40,7 @@ public class TestPermissioningPlugin implements BesuPlugin {
PermissioningService service;
@Override
public void register(final BesuContext context) {
public void register(final ServiceManager context) {
context.getService(PicoCLIOptions.class).orElseThrow().addPicoCLIOptions("permissioning", this);
service = context.getService(PermissioningService.class).orElseThrow();
}

@ -14,8 +14,8 @@
*/
package org.hyperledger.besu.tests.acceptance.plugins;
import org.hyperledger.besu.plugin.BesuContext;
import org.hyperledger.besu.plugin.BesuPlugin;
import org.hyperledger.besu.plugin.ServiceManager;
import org.hyperledger.besu.plugin.services.PicoCLIOptions;
import java.io.File;
@ -57,7 +57,7 @@ public class TestPicoCLIPlugin implements BesuPlugin {
private File callbackDir;
@Override
public void register(final BesuContext context) {
public void register(final ServiceManager context) {
LOG.info("Registering. Test Option is '{}'", testOption);
state = "registering";

@ -14,8 +14,8 @@
*/
package org.hyperledger.besu.tests.acceptance.plugins;
import org.hyperledger.besu.plugin.BesuContext;
import org.hyperledger.besu.plugin.BesuPlugin;
import org.hyperledger.besu.plugin.ServiceManager;
import org.hyperledger.besu.plugin.services.PicoCLIOptions;
import org.hyperledger.besu.plugin.services.PrivacyPluginService;
import org.hyperledger.besu.tests.acceptance.plugins.privacy.TestPrivacyGroupGenesisProvider;
@ -32,7 +32,7 @@ public class TestPrivacyServicePlugin implements BesuPlugin {
private static final Logger LOG = LoggerFactory.getLogger(TestPrivacyServicePlugin.class);
PrivacyPluginService pluginService;
BesuContext context;
ServiceManager context;
TestPrivacyGroupGenesisProvider privacyGroupGenesisProvider =
new TestPrivacyGroupGenesisProvider();
@ -40,7 +40,7 @@ public class TestPrivacyServicePlugin implements BesuPlugin {
new TestSigningPrivateMarkerTransactionFactory();
@Override
public void register(final BesuContext context) {
public void register(final ServiceManager context) {
this.context = context;
context

@ -16,8 +16,8 @@ package org.hyperledger.besu.tests.acceptance.plugins;
import static com.google.common.base.Preconditions.checkArgument;
import org.hyperledger.besu.plugin.BesuContext;
import org.hyperledger.besu.plugin.BesuPlugin;
import org.hyperledger.besu.plugin.ServiceManager;
import org.hyperledger.besu.plugin.services.RpcEndpointService;
import org.hyperledger.besu.plugin.services.rpc.PluginRpcRequest;
@ -51,7 +51,7 @@ public class TestRpcEndpointServicePlugin implements BesuPlugin {
}
@Override
public void register(final BesuContext context) {
public void register(final ServiceManager context) {
context
.getService(RpcEndpointService.class)
.ifPresent(

@ -18,8 +18,8 @@ import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState;
import org.hyperledger.besu.ethereum.core.plugins.PluginConfiguration;
import org.hyperledger.besu.plugin.BesuContext;
import org.hyperledger.besu.plugin.BesuPlugin;
import org.hyperledger.besu.plugin.ServiceManager;
import org.hyperledger.besu.plugin.services.BesuService;
import org.hyperledger.besu.plugin.services.PluginVersionsProvider;
@ -49,7 +49,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** The Besu plugin context implementation. */
public class BesuPluginContextImpl implements BesuContext, PluginVersionsProvider {
public class BesuPluginContextImpl implements ServiceManager, PluginVersionsProvider {
private static final Logger LOG = LoggerFactory.getLogger(BesuPluginContextImpl.class);

@ -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 class TransactionSimulationServiceImpl implements TransactionSimulationSe
final Hash blockHash,
final OperationTracer operationTracer,
final boolean isAllowExceedingBalance) {
return simulate(
transaction, Optional.empty(), blockHash, operationTracer, isAllowExceedingBalance);
}
@Override
public Optional<TransactionSimulationResult> simulate(
final Transaction transaction,
final Optional<AccountOverrideMap> maybeAccountOverrides,
final Hash blockHash,
final OperationTracer operationTracer,
final boolean isAllowExceedingBalance) {
final CallParameter callParameter = CallParameter.fromTransaction(transaction);
@ -79,6 +91,7 @@ public class TransactionSimulationServiceImpl implements TransactionSimulationSe
return transactionSimulator
.process(
callParameter,
maybeAccountOverrides,
isAllowExceedingBalance
? SIMULATOR_ALLOWING_EXCEEDING_BALANCE
: TransactionValidationParams.transactionSimulator(),

@ -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 com.fasterxml.jackson.databind.annotation.JsonDeserialize;
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 @@ public class AccountOverride {
this.stateDiff = stateDiff;
}
/**
* Gets the balance override
*
* @return the balance if present
*/
public Optional<Wei> getBalance() {
return balance;
}
/**
* Gets the nonce override
*
* @return the nonce if present
*/
public Optional<Long> getNonce() {
return nonce;
}
/**
* Gets the code override
*
* @return the code if present
*/
public Optional<String> getCode() {
return code;
}
/**
* Gets the state override map
*
* @return the state override map if present
*/
public Optional<Map<String, String>> getStateDiff() {
return stateDiff;
}
/** Builder class for Account overrides */
public static class Builder {
private Optional<Wei> balance = Optional.empty();
private Optional<Long> nonce = Optional.empty();
@ -77,31 +92,66 @@ public class AccountOverride {
/** 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<String, String> 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(

@ -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<Address, AccountOverride> {
/** Default constructor */
public AccountOverrideMap() {}
}

@ -1,4 +1,4 @@
Besu user documentation was moved to as separate repository to help manage versions and releases.
Besu user documentation was moved to a separate repository to help manage versions and releases.
If you want to contribute to the doc site, make a pull request against https://github.com/hyperledger/besu-docs

@ -17,6 +17,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods;
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.processing.TransactionProcessingResult;
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;

@ -14,9 +14,12 @@
*/
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;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonCallParameter;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.Quantity;
@ -31,6 +34,7 @@ import org.hyperledger.besu.evm.tracing.EstimateGasOperationTracer;
import java.util.Optional;
import com.google.common.annotations.VisibleForTesting;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -55,6 +59,8 @@ public class EthEstimateGas extends AbstractEstimateGas {
final CallParameter modifiedCallParams =
overrideGasLimitAndPrice(callParams, blockHeader.getGasLimit());
Optional<AccountOverrideMap> maybeStateOverrides = getAddressAccountOverrideMap(requestContext);
// TODO implement for block overrides
final boolean isAllowExceedingBalance = !callParams.isMaybeStrict().orElse(Boolean.FALSE);
@ -68,7 +74,11 @@ public class EthEstimateGas extends AbstractEstimateGas {
LOG.debug("Processing transaction with params: {}", modifiedCallParams);
final var maybeResult =
transactionSimulator.process(
modifiedCallParams, transactionValidationParams, operationTracer, blockHeader);
modifiedCallParams,
maybeStateOverrides,
transactionValidationParams,
operationTracer,
blockHeader);
final Optional<JsonRpcErrorResponse> maybeErrorResponse =
validateSimulationResult(requestContext, maybeResult);
@ -81,6 +91,7 @@ public class EthEstimateGas extends AbstractEstimateGas {
final var lowResult =
transactionSimulator.process(
overrideGasLimitAndPrice(callParams, low),
maybeStateOverrides,
transactionValidationParams,
operationTracer,
blockHeader);
@ -97,6 +108,7 @@ public class EthEstimateGas extends AbstractEstimateGas {
var binarySearchResult =
transactionSimulator.process(
overrideGasLimitAndPrice(callParams, mid),
maybeStateOverrides,
transactionValidationParams,
operationTracer,
blockHeader);
@ -127,4 +139,15 @@ public class EthEstimateGas extends AbstractEstimateGas {
}
return Optional.empty();
}
@VisibleForTesting
protected Optional<AccountOverrideMap> getAddressAccountOverrideMap(
final JsonRpcRequestContext request) {
try {
return request.getOptionalParameter(2, AccountOverrideMap.class);
} catch (JsonRpcParameter.JsonRpcParameterException e) {
throw new InvalidJsonRpcRequestException(
"Invalid account overrides parameter (index 2)", RpcErrorType.INVALID_CALL_PARAMS, e);
}
}
}

@ -27,6 +27,8 @@ import static org.mockito.Mockito.verify;
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.CallParameter;
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;
@ -342,7 +342,8 @@ public class EthCallTest {
public void shouldUseCorrectBlockNumberWhenEarliest() {
final JsonRpcRequestContext request = ethCallRequest(callParameter(), "earliest");
when(blockchainQueries.getBlockHashByNumber(anyLong())).thenReturn(Optional.of(Hash.ZERO));
when(transactionSimulator.process(any(), any(), any(), any(), any()))
when(transactionSimulator.process(
any(), any(), any(TransactionValidationParams.class), any(), any(BlockHeader.class)))
.thenReturn(Optional.empty());
when(blockchainQueries.getBlockHeaderByHash(Hash.ZERO))
.thenReturn(Optional.of(mock(BlockHeader.class)));

@ -21,6 +21,8 @@ import static org.mockito.Mockito.mock;
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;
@ -99,12 +101,44 @@ public class EthEstimateGasTest {
assertThat(method.getName()).isEqualTo("eth_estimateGas");
}
@Test
public void noAccountOverrides() {
final Wei gasPrice = Wei.of(1000);
final JsonRpcRequestContext request =
ethEstimateGasRequest(defaultLegacyTransactionCallParameter(gasPrice), "latest");
Optional<AccountOverrideMap> overrideMap = method.getAddressAccountOverrideMap(request);
assertThat(overrideMap.isPresent()).isFalse();
}
@Test
public void someAccountOverrides() {
AccountOverrideMap expectedOverrides = new AccountOverrideMap();
AccountOverride override = new AccountOverride.Builder().withNonce(88L).build();
final Address address = Address.fromHexString("0xd9c9cd5f6779558b6e0ed4e6acf6b1947e7fa1f3");
expectedOverrides.put(address, override);
final Wei gasPrice = Wei.of(1000);
final JsonRpcRequestContext request =
ethEstimateGasRequestWithStateOverrides(
defaultLegacyTransactionCallParameter(gasPrice), "latest", expectedOverrides);
Optional<AccountOverrideMap> maybeOverrideMap = method.getAddressAccountOverrideMap(request);
assertThat(maybeOverrideMap.isPresent()).isTrue();
AccountOverrideMap overrideMap = maybeOverrideMap.get();
assertThat(overrideMap.keySet()).hasSize(1);
assertThat(overrideMap.values()).hasSize(1);
assertThat(overrideMap).containsKey(address);
assertThat(overrideMap).containsValue(override);
}
@Test
public void shouldReturnErrorWhenTransientLegacyTransactionProcessorReturnsEmpty() {
final JsonRpcRequestContext request =
ethEstimateGasRequest(defaultLegacyTransactionCallParameter(Wei.ZERO));
when(transactionSimulator.process(
eq(modifiedLegacyTransactionCallParameter(Wei.ZERO)),
eq(Optional.empty()), // no account overrides
any(TransactionValidationParams.class),
any(OperationTracer.class),
eq(latestBlockHeader)))
@ -341,6 +375,7 @@ public class EthEstimateGasTest {
verify(transactionSimulator)
.process(
eq(modifiedLegacyTransactionCallParameter(Wei.ZERO)),
eq(Optional.empty()), // no account overrides
eq(
ImmutableTransactionValidationParams.builder()
.from(TransactionValidationParams.transactionSimulator())
@ -361,6 +396,7 @@ public class EthEstimateGasTest {
verify(transactionSimulator)
.process(
eq(modifiedLegacyTransactionCallParameter(Wei.ZERO)),
eq(Optional.empty()), // no account overrides
eq(
ImmutableTransactionValidationParams.builder()
.from(TransactionValidationParams.transactionSimulator())
@ -461,12 +497,14 @@ public class EthEstimateGasTest {
final TransactionSimulatorResult mockTxSimResult = mock(TransactionSimulatorResult.class);
when(transactionSimulator.process(
eq(modifiedLegacyTransactionCallParameter(gasPrice)),
eq(Optional.empty()), // no account overrides
any(TransactionValidationParams.class),
any(OperationTracer.class),
eq(blockHeader)))
.thenReturn(Optional.of(mockTxSimResult));
when(transactionSimulator.process(
eq(modifiedEip1559TransactionCallParameter()),
eq(Optional.empty()), // no account overrides
any(TransactionValidationParams.class),
any(OperationTracer.class),
eq(blockHeader)))
@ -551,4 +589,13 @@ public class EthEstimateGasTest {
return new JsonRpcRequestContext(
new JsonRpcRequest("2.0", "eth_estimateGas", new Object[] {callParameter, blockParam}));
}
private JsonRpcRequestContext ethEstimateGasRequestWithStateOverrides(
final CallParameter callParameter,
final String blockParam,
final AccountOverrideMap overrides) {
return new JsonRpcRequestContext(
new JsonRpcRequest(
"2.0", "eth_estimateGas", new Object[] {callParameter, blockParam, overrides}));
}
}

@ -19,6 +19,8 @@ import static org.hyperledger.besu.ethereum.mainnet.feemarket.ExcessBlobGasCalcu
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.ProtocolSchedule;
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 class TransactionSimulator {
final BlockHeader header = blockchain.getBlockHeader(blockNumber).orElse(null);
return process(
callParams,
Optional.empty(),
transactionValidationParams,
operationTracer,
(mutableWorldState, transactionSimulatorResult) -> transactionSimulatorResult,
@ -118,6 +119,22 @@ public class TransactionSimulator {
final BlockHeader blockHeader) {
return process(
callParams,
Optional.empty(),
transactionValidationParams,
operationTracer,
(mutableWorldState, transactionSimulatorResult) -> transactionSimulatorResult,
blockHeader);
}
public Optional<TransactionSimulatorResult> process(
final CallParameter callParams,
final Optional<AccountOverrideMap> maybeStateOverrides,
final TransactionValidationParams transactionValidationParams,
final OperationTracer operationTracer,
final BlockHeader blockHeader) {
return process(
callParams,
maybeStateOverrides,
transactionValidationParams,
operationTracer,
(mutableWorldState, transactionSimulatorResult) -> transactionSimulatorResult,

@ -28,7 +28,7 @@ import org.hyperledger.besu.ethereum.trie.diffbased.common.worldview.DiffBasedWo
import org.hyperledger.besu.ethereum.trie.patricia.StoredMerklePatriciaTrie;
import org.hyperledger.besu.ethereum.worldstate.StateTrieAccountValue;
import org.hyperledger.besu.evm.internal.EvmConfiguration;
import org.hyperledger.besu.plugin.BesuContext;
import org.hyperledger.besu.plugin.ServiceManager;
import java.util.HashSet;
import java.util.Optional;
@ -52,7 +52,7 @@ public class BonsaiWorldStateProvider extends DiffBasedWorldStateProvider {
final Blockchain blockchain,
final Optional<Long> maxLayersToLoad,
final BonsaiCachedMerkleTrieLoader bonsaiCachedMerkleTrieLoader,
final BesuContext pluginContext,
final ServiceManager pluginContext,
final EvmConfiguration evmConfiguration,
final Supplier<WorldStateHealer> worldStateHealerSupplier) {
super(worldStateKeyValueStorage, blockchain, maxLayersToLoad, pluginContext);

@ -31,7 +31,7 @@ import org.hyperledger.besu.ethereum.trie.diffbased.common.worldview.accumulator
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator;
import org.hyperledger.besu.evm.worldstate.WorldState;
import org.hyperledger.besu.plugin.BesuContext;
import org.hyperledger.besu.plugin.ServiceManager;
import org.hyperledger.besu.plugin.services.trielogs.TrieLog;
import java.util.ArrayList;
@ -61,7 +61,7 @@ public abstract class DiffBasedWorldStateProvider implements WorldStateArchive {
final DiffBasedWorldStateKeyValueStorage worldStateKeyValueStorage,
final Blockchain blockchain,
final Optional<Long> maxLayersToLoad,
final BesuContext pluginContext) {
final ServiceManager pluginContext) {
this.worldStateKeyValueStorage = worldStateKeyValueStorage;
// TODO: de-dup constructors

@ -21,7 +21,7 @@ import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.trielog.TrieLogFactor
import org.hyperledger.besu.ethereum.trie.diffbased.common.storage.DiffBasedWorldStateKeyValueStorage;
import org.hyperledger.besu.ethereum.trie.diffbased.common.worldview.DiffBasedWorldState;
import org.hyperledger.besu.ethereum.trie.diffbased.common.worldview.accumulator.DiffBasedWorldStateUpdateAccumulator;
import org.hyperledger.besu.plugin.BesuContext;
import org.hyperledger.besu.plugin.ServiceManager;
import org.hyperledger.besu.plugin.services.TrieLogService;
import org.hyperledger.besu.plugin.services.trielogs.TrieLog;
import org.hyperledger.besu.plugin.services.trielogs.TrieLogEvent;
@ -53,7 +53,7 @@ public class TrieLogManager {
final Blockchain blockchain,
final DiffBasedWorldStateKeyValueStorage worldStateKeyValueStorage,
final long maxLayersToLoad,
final BesuContext pluginContext) {
final ServiceManager pluginContext) {
this.blockchain = blockchain;
this.rootWorldStateStorage = worldStateKeyValueStorage;
this.maxLayersToLoad = maxLayersToLoad;
@ -133,7 +133,7 @@ public class TrieLogManager {
trieLogObservers.unsubscribe(id);
}
private TrieLogFactory setupTrieLogFactory(final BesuContext pluginContext) {
private TrieLogFactory setupTrieLogFactory(final ServiceManager pluginContext) {
// if we have a TrieLogService from pluginContext, use it.
var trieLogServicez =
Optional.ofNullable(pluginContext)

@ -26,6 +26,7 @@ import static org.mockito.Mockito.when;
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.blockhash.BlockHashProcessor;
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;

@ -18,6 +18,8 @@ import static org.assertj.core.api.Assertions.assertThat;
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;

@ -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 = 'ktVrmQXU7LMQi1ieb9OQ2vJNqZ0SVQ7Usauh1LMvUXY='
knownHash = 'IPpTJJxjDbjW08c3Cm8GbBhULYFy0jq9m3BzliGzrf8='
}
check.dependsOn('checkAPIChanges')

@ -14,42 +14,6 @@
*/
package org.hyperledger.besu.plugin;
import org.hyperledger.besu.plugin.services.BesuService;
import java.util.Optional;
/** Allows plugins to access Besu services. */
public interface BesuContext {
/**
* Add service.
*
* @param <T> the type parameter
* @param serviceType the service type
* @param service the service
*/
<T extends BesuService> void addService(final Class<T> serviceType, final T service);
/**
* Get the requested service, if it is available. There are a number of reasons that a service may
* not be available:
*
* <ul>
* <li>The service may not have started yet. Most services are not available before the {@link
* BesuPlugin#start()} method is called
* <li>The service is not supported by this version of Besu
* <li>The service may not be applicable to the current configuration. For example some services
* may only be available when a proof of authority network is in use
* </ul>
*
* <p>Since plugins are automatically loaded, unless the user has specifically requested
* functionality provided by the plugin, no error should be raised if required services are
* unavailable.
*
* @param serviceType the class defining the requested service.
* @param <T> the service type
* @return an optional containing the instance of the requested service, or empty if the service
* is unavailable
*/
<T extends BesuService> Optional<T> getService(Class<T> serviceType);
}
/** Deprecated in favor of the more precisely named ServiceManager interface. */
@Deprecated(since = "24.11.0", forRemoval = true)
public interface BesuContext extends ServiceManager {}

@ -48,7 +48,7 @@ public interface BesuPlugin {
*
* @param context the context that provides access to Besu services.
*/
void register(BesuContext context);
void register(ServiceManager context);
/**
* Called once when besu has loaded configuration but before external services have been started

@ -0,0 +1,55 @@
/*
* 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.plugin;
import org.hyperledger.besu.plugin.services.BesuService;
import java.util.Optional;
/** Adds and accesses BesuServices for plugins to provide or use. */
public interface ServiceManager {
/**
* Add service. Used by core besu or other plugins to add services to the service manager.
*
* @param <T> the type parameter
* @param serviceType the service type
* @param service the service
*/
<T extends BesuService> void addService(final Class<T> serviceType, final T service);
/**
* Get the requested service, if it is available. There are a number of reasons that a service may
* not be available:
*
* <ul>
* <li>The service may not have started yet. Most services are not available before the {@link
* BesuPlugin#start()} method is called
* <li>The service is not supported by this version of Besu
* <li>The service may not be applicable to the current configuration. For example some services
* may only be available when a proof of authority network is in use, or when user provided.
* </ul>
*
* <p>Since plugins are automatically loaded, unless the user has specifically requested
* functionality provided by the plugin, no error should be raised if required services are
* unavailable.
*
* @param serviceType the class defining the requested service.
* @param <T> the service type
* @return an optional containing the instance of the requested service, or empty if the service
* is unavailable
*/
<T extends BesuService> Optional<T> getService(Class<T> serviceType);
}

@ -14,10 +14,10 @@
*/
package org.hyperledger.besu.plugin.services;
import org.hyperledger.besu.plugin.BesuContext;
import org.hyperledger.besu.plugin.ServiceManager;
/**
* All services that can be resolved via {@link BesuContext#getService(Class)} must implement {@link
* BesuService}
* All services that can be resolved via {@link ServiceManager#getService(Class)} must implement
* {@link BesuService}
*/
public interface BesuService {}

@ -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 @@ public interface TransactionSimulationService extends BesuService {
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<TransactionSimulationResult> simulate(
Transaction transaction,
Optional<AccountOverrideMap> accountOverrides,
Hash blockHash,
OperationTracer operationTracer,
boolean isAllowExceedingBalance);
}

@ -14,8 +14,8 @@
*/
package org.hyperledger.besu.plugin.services.storage.rocksdb;
import org.hyperledger.besu.plugin.BesuContext;
import org.hyperledger.besu.plugin.BesuPlugin;
import org.hyperledger.besu.plugin.ServiceManager;
import org.hyperledger.besu.plugin.services.PicoCLIOptions;
import org.hyperledger.besu.plugin.services.StorageService;
import org.hyperledger.besu.plugin.services.storage.SegmentIdentifier;
@ -40,7 +40,7 @@ public class RocksDBPlugin implements BesuPlugin {
private final RocksDBCLIOptions options;
private final List<SegmentIdentifier> ignorableSegments = new ArrayList<>();
private BesuContext context;
private ServiceManager context;
private RocksDBKeyValueStorageFactory factory;
private RocksDBKeyValuePrivacyStorageFactory privacyFactory;
@ -59,7 +59,7 @@ public class RocksDBPlugin implements BesuPlugin {
}
@Override
public void register(final BesuContext context) {
public void register(final ServiceManager context) {
LOG.debug("Registering plugin");
this.context = context;

@ -14,8 +14,8 @@
*/
package org.hyperledger.besu.services.kvstore;
import org.hyperledger.besu.plugin.BesuContext;
import org.hyperledger.besu.plugin.BesuPlugin;
import org.hyperledger.besu.plugin.ServiceManager;
import org.hyperledger.besu.plugin.services.BesuConfiguration;
import org.hyperledger.besu.plugin.services.MetricsSystem;
import org.hyperledger.besu.plugin.services.StorageService;
@ -36,7 +36,7 @@ import org.slf4j.LoggerFactory;
public class InMemoryStoragePlugin implements BesuPlugin {
private static final Logger LOG = LoggerFactory.getLogger(InMemoryStoragePlugin.class);
private BesuContext context;
private ServiceManager context;
private InMemoryKeyValueStorageFactory factory;
private InMemoryKeyValueStorageFactory privacyFactory;
@ -44,7 +44,7 @@ public class InMemoryStoragePlugin implements BesuPlugin {
public InMemoryStoragePlugin() {}
@Override
public void register(final BesuContext context) {
public void register(final ServiceManager context) {
LOG.debug("Registering plugin");
this.context = context;

Loading…
Cancel
Save