Optimistic parallelization of transactions to improve performance (#7296)

Optimistic transaction parallelization execution during block processing to improve the performances. This feature can enabled with a flag --Xbonsai-parallel-tx-processing-enabled=true

Signed-off-by: Karim Taam <karim.t2am@gmail.com>
Co-authored-by: Ameziane H <ameziane.hamlat@consensys.net>
Co-authored-by: garyschulte <garyschulte@gmail.com>
pull/7374/head
Karim Taam 4 months ago committed by GitHub
parent 7a905f8b0a
commit 30c96c7a1d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 1
      CHANGELOG.md
  2. 2
      besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java
  3. 81
      besu/src/main/java/org/hyperledger/besu/cli/options/stable/DataStorageOptions.java
  4. 17
      besu/src/main/java/org/hyperledger/besu/controller/BesuControllerBuilder.java
  5. 4
      besu/src/main/java/org/hyperledger/besu/controller/CliqueBesuControllerBuilder.java
  6. 9
      besu/src/main/java/org/hyperledger/besu/controller/ConsensusScheduleBesuControllerBuilder.java
  7. 4
      besu/src/main/java/org/hyperledger/besu/controller/IbftBesuControllerBuilder.java
  8. 4
      besu/src/main/java/org/hyperledger/besu/controller/MainnetBesuControllerBuilder.java
  9. 4
      besu/src/main/java/org/hyperledger/besu/controller/MergeBesuControllerBuilder.java
  10. 4
      besu/src/main/java/org/hyperledger/besu/controller/QbftBesuControllerBuilder.java
  11. 7
      besu/src/main/java/org/hyperledger/besu/controller/TransitionBesuControllerBuilder.java
  12. 14
      besu/src/test/java/org/hyperledger/besu/ForkIdsNetworkConfigTest.java
  13. 2
      besu/src/test/java/org/hyperledger/besu/cli/CommandTestAbstract.java
  14. 23
      consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/CliqueProtocolSchedule.java
  15. 21
      consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/CliqueProtocolScheduleTest.java
  16. 4
      consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueBlockCreatorTest.java
  17. 4
      consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueMinerExecutorTest.java
  18. 12
      consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BaseBftProtocolScheduleBuilder.java
  19. 5
      consensus/common/src/test/java/org/hyperledger/besu/consensus/common/CombinedProtocolScheduleFactoryTest.java
  20. 5
      consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/BaseBftProtocolScheduleBuilderTest.java
  21. 4
      consensus/ibft/src/integration-test/java/org/hyperledger/besu/consensus/ibft/support/TestContextBuilder.java
  22. 23
      consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/IbftProtocolScheduleBuilder.java
  23. 5
      consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/IbftProtocolScheduleTest.java
  24. 4
      consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/blockcreation/BftBlockCreatorTest.java
  25. 5
      consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/statemachine/IbftBlockHeightManagerTest.java
  26. 19
      consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/MergeProtocolSchedule.java
  27. 20
      consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/TransitionProtocolSchedule.java
  28. 33
      consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/MergeProtocolScheduleTest.java
  29. 5
      consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeGenesisConfigHelper.java
  30. 4
      consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/TestContextBuilder.java
  31. 34
      consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/QbftProtocolScheduleBuilder.java
  32. 5
      consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/QbftProtocolScheduleTest.java
  33. 5
      consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftBlockHeightManagerTest.java
  34. 30
      crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/Blake2bfMessageDigest.java
  35. 50
      crypto/algorithms/src/test/java/org/hyperledger/besu/crypto/Blake2bfMessageDigestTest.java
  36. 2
      datatypes/src/main/java/org/hyperledger/besu/datatypes/StorageSlotKey.java
  37. 5
      ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/BlockchainImporter.java
  38. 4
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceHostAllowlistTest.java
  39. 6
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceLoginTest.java
  40. 4
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTestBase.java
  41. 4
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsClientAuthTest.java
  42. 4
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsMisconfigurationTest.java
  43. 4
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsTest.java
  44. 4
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/WebSocketServiceLoginTest.java
  45. 4
      ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreatorTest.java
  46. 4
      ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockTransactionSelectorTest.java
  47. 5
      ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/LegacyFeeMarketBlockTransactionSelectorTest.java
  48. 5
      ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/LondonFeeMarketBlockTransactionSelectorTest.java
  49. 24
      ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/PoWBlockCreatorTest.java
  50. 25
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/difficulty/fixed/FixedDifficultyProtocolSchedule.java
  51. 119
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/AbstractBlockProcessor.java
  52. 125
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ClassicProtocolSpecs.java
  53. 42
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSchedule.java
  54. 209
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecFactory.java
  55. 268
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecs.java
  56. 4
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java
  57. 32
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolScheduleBuilder.java
  58. 3
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolSpecBuilder.java
  59. 199
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/parallelization/MainnetParallelBlockProcessor.java
  60. 268
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/parallelization/ParallelizedConcurrentTransactionProcessor.java
  61. 133
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/parallelization/ParallelizedTransactionContext.java
  62. 114
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/parallelization/TransactionCollisionDetector.java
  63. 44
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/cache/NoopBonsaiCachedMerkleTrieLoader.java
  64. 12
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/worldview/BonsaiWorldState.java
  65. 126
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/worldview/accumulator/DiffBasedWorldStateUpdateAccumulator.java
  66. 7
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/worldstate/DataStorageConfiguration.java
  67. 4
      ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlockchainSetupUtil.java
  68. 4
      ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/ExecutionContextTestFixture.java
  69. 5
      ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/ProtocolScheduleFixture.java
  70. 6
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/BlockImportExceptionHandlingTest.java
  71. 5
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/difficulty/fixed/FixedProtocolScheduleTest.java
  72. 5
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/DefaultProtocolScheduleTest.java
  73. 13
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolScheduleTest.java
  74. 9
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/ProtocolScheduleBuilderTest.java
  75. 213
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/parallelization/ParallelizedConcurrentTransactionProcessorTest.java
  76. 290
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/parallelization/TransactionCollisionDetectorTest.java
  77. 4
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/AbstractIsolationTests.java
  78. 5
      ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/messages/BlockBodiesMessageTest.java
  79. 5
      ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/messages/BlockHeadersMessageTest.java
  80. 4
      ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/ChainHeadTrackerTest.java
  81. 7
      ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/backwardsync/BackwardSyncContextTest.java
  82. 7
      ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/backwardsync/BackwardSyncStepTest.java
  83. 7
      ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/backwardsync/ForwardSyncStepTest.java
  84. 4
      ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/AbstractTransactionPoolTest.java
  85. 4
      ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TestNode.java
  86. 4
      ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolFactoryTest.java
  87. 12
      ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/MainnetGenesisFileModule.java
  88. 1
      ethereum/referencetests/build.gradle
  89. 5
      ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/ReferenceTestProtocolSchedules.java
  90. 30
      ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/mainnet/DifficultyCalculatorTests.java
  91. 7
      ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/RetestethContext.java
  92. 12
      evm/src/main/java/org/hyperledger/besu/evm/tracing/OperationTracer.java
  93. 4
      metrics/core/src/main/java/org/hyperledger/besu/metrics/BesuMetricCategory.java

@ -23,6 +23,7 @@
- Added EIP-7702 [#7237](https://github.com/hyperledger/besu/pull/7237) - Added EIP-7702 [#7237](https://github.com/hyperledger/besu/pull/7237)
- Implement gnark-crypto for eip-196 [#7262](https://github.com/hyperledger/besu/pull/7262) - Implement gnark-crypto for eip-196 [#7262](https://github.com/hyperledger/besu/pull/7262)
- Add trie log pruner metrics [#7352](https://github.com/hyperledger/besu/pull/7352) - Add trie log pruner metrics [#7352](https://github.com/hyperledger/besu/pull/7352)
- `--Xbonsai-parallel-tx-processing-enabled` option enables executing transactions in parallel during block processing for Bonsai nodes
### Bug fixes ### Bug fixes
- Fix `eth_call` deserialization to correctly ignore unknown fields in the transaction object. [#7323](https://github.com/hyperledger/besu/pull/7323) - Fix `eth_call` deserialization to correctly ignore unknown fields in the transaction object. [#7323](https://github.com/hyperledger/besu/pull/7323)

@ -1901,6 +1901,8 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
.privacyParameters(privacyParameters()) .privacyParameters(privacyParameters())
.clock(Clock.systemUTC()) .clock(Clock.systemUTC())
.isRevertReasonEnabled(isRevertReasonEnabled) .isRevertReasonEnabled(isRevertReasonEnabled)
.isParallelTxProcessingEnabled(
dataStorageConfiguration.getUnstable().isParallelTxProcessingEnabled())
.storageProvider(storageProvider) .storageProvider(storageProvider)
.gasLimitCalculator( .gasLimitCalculator(
miningParametersSupplier.get().getTargetGasLimit().isPresent() miningParametersSupplier.get().getTargetGasLimit().isPresent()

@ -122,6 +122,14 @@ public class DataStorageOptions implements CLIOptions<DataStorageConfiguration>
"Enables code storage using code hash instead of by account hash. (default: ${DEFAULT-VALUE})") "Enables code storage using code hash instead of by account hash. (default: ${DEFAULT-VALUE})")
private boolean bonsaiCodeUsingCodeHashEnabled = DEFAULT_BONSAI_CODE_USING_CODE_HASH_ENABLED; private boolean bonsaiCodeUsingCodeHashEnabled = DEFAULT_BONSAI_CODE_USING_CODE_HASH_ENABLED;
@CommandLine.Option(
hidden = true,
names = {"--Xbonsai-parallel-tx-processing-enabled"},
arity = "1",
description =
"Enables parallelization of transactions to optimize processing speed by concurrently loading and executing necessary data in advance. (default: ${DEFAULT-VALUE})")
private Boolean isParallelTxProcessingEnabled = false;
/** Default Constructor. */ /** Default Constructor. */
Unstable() {} Unstable() {}
} }
@ -142,40 +150,48 @@ public class DataStorageOptions implements CLIOptions<DataStorageConfiguration>
* @param syncMode the sync mode * @param syncMode the sync mode
*/ */
public void validate(final CommandLine commandLine, final SyncMode syncMode) { public void validate(final CommandLine commandLine, final SyncMode syncMode) {
if (DataStorageFormat.BONSAI == dataStorageFormat && bonsaiLimitTrieLogsEnabled) { if (DataStorageFormat.BONSAI == dataStorageFormat) {
if (SyncMode.FULL == syncMode) { if (bonsaiLimitTrieLogsEnabled) {
throw new CommandLine.ParameterException( if (SyncMode.FULL == syncMode) {
commandLine, throw new CommandLine.ParameterException(
String.format( commandLine,
"Cannot enable %s with sync-mode %s. You must set %s or use a different sync-mode", String.format(
BONSAI_LIMIT_TRIE_LOGS_ENABLED, "Cannot enable %s with sync-mode %s. You must set %s or use a different sync-mode",
SyncMode.FULL, BONSAI_LIMIT_TRIE_LOGS_ENABLED,
BONSAI_LIMIT_TRIE_LOGS_ENABLED + "=false")); SyncMode.FULL,
} BONSAI_LIMIT_TRIE_LOGS_ENABLED + "=false"));
if (bonsaiMaxLayersToLoad < MINIMUM_BONSAI_TRIE_LOG_RETENTION_LIMIT) { }
throw new CommandLine.ParameterException( if (bonsaiMaxLayersToLoad < MINIMUM_BONSAI_TRIE_LOG_RETENTION_LIMIT) {
commandLine, throw new CommandLine.ParameterException(
String.format( commandLine,
BONSAI_STORAGE_FORMAT_MAX_LAYERS_TO_LOAD + " minimum value is %d", String.format(
MINIMUM_BONSAI_TRIE_LOG_RETENTION_LIMIT)); BONSAI_STORAGE_FORMAT_MAX_LAYERS_TO_LOAD + " minimum value is %d",
} MINIMUM_BONSAI_TRIE_LOG_RETENTION_LIMIT));
if (bonsaiTrieLogPruningWindowSize <= 0) { }
throw new CommandLine.ParameterException( if (bonsaiTrieLogPruningWindowSize <= 0) {
commandLine, throw new CommandLine.ParameterException(
String.format( commandLine,
BONSAI_TRIE_LOG_PRUNING_WINDOW_SIZE + "=%d must be greater than 0", String.format(
bonsaiTrieLogPruningWindowSize)); BONSAI_TRIE_LOG_PRUNING_WINDOW_SIZE + "=%d must be greater than 0",
bonsaiTrieLogPruningWindowSize));
}
if (bonsaiTrieLogPruningWindowSize <= bonsaiMaxLayersToLoad) {
throw new CommandLine.ParameterException(
commandLine,
String.format(
BONSAI_TRIE_LOG_PRUNING_WINDOW_SIZE
+ "=%d must be greater than "
+ BONSAI_STORAGE_FORMAT_MAX_LAYERS_TO_LOAD
+ "=%d",
bonsaiTrieLogPruningWindowSize,
bonsaiMaxLayersToLoad));
}
} }
if (bonsaiTrieLogPruningWindowSize <= bonsaiMaxLayersToLoad) { } else {
if (unstableOptions.isParallelTxProcessingEnabled) {
throw new CommandLine.ParameterException( throw new CommandLine.ParameterException(
commandLine, commandLine,
String.format( "Transaction parallelization is not supported unless operating in a 'diffbased' mode, such as Bonsai.");
BONSAI_TRIE_LOG_PRUNING_WINDOW_SIZE
+ "=%d must be greater than "
+ BONSAI_STORAGE_FORMAT_MAX_LAYERS_TO_LOAD
+ "=%d",
bonsaiTrieLogPruningWindowSize,
bonsaiMaxLayersToLoad));
} }
} }
} }
@ -198,6 +214,8 @@ public class DataStorageOptions implements CLIOptions<DataStorageConfiguration>
domainObject.getUnstable().getBonsaiFullFlatDbEnabled(); domainObject.getUnstable().getBonsaiFullFlatDbEnabled();
dataStorageOptions.unstableOptions.bonsaiCodeUsingCodeHashEnabled = dataStorageOptions.unstableOptions.bonsaiCodeUsingCodeHashEnabled =
domainObject.getUnstable().getBonsaiCodeStoredByCodeHashEnabled(); domainObject.getUnstable().getBonsaiCodeStoredByCodeHashEnabled();
dataStorageOptions.unstableOptions.isParallelTxProcessingEnabled =
domainObject.getUnstable().isParallelTxProcessingEnabled();
return dataStorageOptions; return dataStorageOptions;
} }
@ -214,6 +232,7 @@ public class DataStorageOptions implements CLIOptions<DataStorageConfiguration>
ImmutableDataStorageConfiguration.Unstable.builder() ImmutableDataStorageConfiguration.Unstable.builder()
.bonsaiFullFlatDbEnabled(unstableOptions.bonsaiFullFlatDbEnabled) .bonsaiFullFlatDbEnabled(unstableOptions.bonsaiFullFlatDbEnabled)
.bonsaiCodeStoredByCodeHashEnabled(unstableOptions.bonsaiCodeUsingCodeHashEnabled) .bonsaiCodeStoredByCodeHashEnabled(unstableOptions.bonsaiCodeUsingCodeHashEnabled)
.isParallelTxProcessingEnabled(unstableOptions.isParallelTxProcessingEnabled)
.build()) .build())
.build(); .build();
} }

@ -203,6 +203,9 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides
private int numberOfBlocksToCache = 0; private int numberOfBlocksToCache = 0;
/** whether parallel transaction processing is enabled or not */
protected boolean isParallelTxProcessingEnabled;
/** Instantiates a new Besu controller builder. */ /** Instantiates a new Besu controller builder. */
protected BesuControllerBuilder() {} protected BesuControllerBuilder() {}
@ -512,6 +515,20 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides
return this; return this;
} }
/**
* Sets whether parallel transaction processing is enabled. When parallel transaction processing
* is enabled, transactions within a block can be processed in parallel and potentially improving
* performance
*
* @param isParallelTxProcessingEnabled true to enable parallel transaction
* @return the besu controller
*/
public BesuControllerBuilder isParallelTxProcessingEnabled(
final boolean isParallelTxProcessingEnabled) {
this.isParallelTxProcessingEnabled = isParallelTxProcessingEnabled;
return this;
}
/** /**
* Build besu controller. * Build besu controller.
* *

@ -136,7 +136,9 @@ public class CliqueBesuControllerBuilder extends BesuControllerBuilder {
isRevertReasonEnabled, isRevertReasonEnabled,
evmConfiguration, evmConfiguration,
miningParameters, miningParameters,
badBlockManager); badBlockManager,
isParallelTxProcessingEnabled,
metricsSystem);
} }
@Override @Override

@ -358,6 +358,15 @@ public class ConsensusScheduleBesuControllerBuilder extends BesuControllerBuilde
return super.isRevertReasonEnabled(isRevertReasonEnabled); return super.isRevertReasonEnabled(isRevertReasonEnabled);
} }
@Override
public BesuControllerBuilder isParallelTxProcessingEnabled(
final boolean isParallelTxProcessingEnabled) {
besuControllerBuilderSchedule
.values()
.forEach(b -> b.isParallelTxProcessingEnabled(isParallelTxProcessingEnabled));
return super.isParallelTxProcessingEnabled(isParallelTxProcessingEnabled);
}
@Override @Override
public BesuControllerBuilder gasLimitCalculator(final GasLimitCalculator gasLimitCalculator) { public BesuControllerBuilder gasLimitCalculator(final GasLimitCalculator gasLimitCalculator) {
besuControllerBuilderSchedule.values().forEach(b -> b.gasLimitCalculator(gasLimitCalculator)); besuControllerBuilderSchedule.values().forEach(b -> b.gasLimitCalculator(gasLimitCalculator));

@ -291,7 +291,9 @@ public class IbftBesuControllerBuilder extends BftBesuControllerBuilder {
bftExtraDataCodec().get(), bftExtraDataCodec().get(),
evmConfiguration, evmConfiguration,
miningParameters, miningParameters,
badBlockManager); badBlockManager,
isParallelTxProcessingEnabled,
metricsSystem);
} }
@Override @Override

@ -99,7 +99,9 @@ public class MainnetBesuControllerBuilder extends BesuControllerBuilder {
isRevertReasonEnabled, isRevertReasonEnabled,
evmConfiguration, evmConfiguration,
miningParameters, miningParameters,
badBlockManager); badBlockManager,
isParallelTxProcessingEnabled,
metricsSystem);
} }
@Override @Override

@ -177,7 +177,9 @@ public class MergeBesuControllerBuilder extends BesuControllerBuilder {
privacyParameters, privacyParameters,
isRevertReasonEnabled, isRevertReasonEnabled,
miningParameters, miningParameters,
badBlockManager); badBlockManager,
isParallelTxProcessingEnabled,
metricsSystem);
} }
@Override @Override

@ -329,7 +329,9 @@ public class QbftBesuControllerBuilder extends BftBesuControllerBuilder {
bftExtraDataCodec().get(), bftExtraDataCodec().get(),
evmConfiguration, evmConfiguration,
miningParameters, miningParameters,
badBlockManager); badBlockManager,
isParallelTxProcessingEnabled,
metricsSystem);
} }
@Override @Override

@ -374,6 +374,13 @@ public class TransitionBesuControllerBuilder extends BesuControllerBuilder {
return propagateConfig(z -> z.isRevertReasonEnabled(isRevertReasonEnabled)); return propagateConfig(z -> z.isRevertReasonEnabled(isRevertReasonEnabled));
} }
@Override
public BesuControllerBuilder isParallelTxProcessingEnabled(
final boolean isParallelTxProcessingEnabled) {
super.isParallelTxProcessingEnabled(isParallelTxProcessingEnabled);
return propagateConfig(z -> z.isParallelTxProcessingEnabled(isParallelTxProcessingEnabled));
}
@Override @Override
public BesuControllerBuilder gasLimitCalculator(final GasLimitCalculator gasLimitCalculator) { public BesuControllerBuilder gasLimitCalculator(final GasLimitCalculator gasLimitCalculator) {
super.gasLimitCalculator(gasLimitCalculator); super.gasLimitCalculator(gasLimitCalculator);

@ -35,6 +35,7 @@ import org.hyperledger.besu.ethereum.forkid.ForkId;
import org.hyperledger.besu.ethereum.forkid.ForkIdManager; import org.hyperledger.besu.ethereum.forkid.ForkIdManager;
import org.hyperledger.besu.ethereum.mainnet.DefaultProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.DefaultProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.MainnetProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.MainnetProtocolSchedule;
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
@ -177,12 +178,21 @@ public class ForkIdsNetworkConfigTest {
new MilestoneStreamingProtocolSchedule( new MilestoneStreamingProtocolSchedule(
(DefaultProtocolSchedule) (DefaultProtocolSchedule)
MainnetProtocolSchedule.fromConfig( MainnetProtocolSchedule.fromConfig(
configOptions, MiningParameters.MINING_DISABLED, new BadBlockManager())); configOptions,
MiningParameters.MINING_DISABLED,
new BadBlockManager(),
false,
new NoOpMetricsSystem()));
MilestoneStreamingProtocolSchedule postMergeProtocolSchedule = MilestoneStreamingProtocolSchedule postMergeProtocolSchedule =
new MilestoneStreamingProtocolSchedule( new MilestoneStreamingProtocolSchedule(
(DefaultProtocolSchedule) (DefaultProtocolSchedule)
MergeProtocolSchedule.create( MergeProtocolSchedule.create(
configOptions, false, MiningParameters.MINING_DISABLED, new BadBlockManager())); configOptions,
false,
MiningParameters.MINING_DISABLED,
new BadBlockManager(),
false,
new NoOpMetricsSystem()));
final MilestoneStreamingTransitionProtocolSchedule schedule = final MilestoneStreamingTransitionProtocolSchedule schedule =
new MilestoneStreamingTransitionProtocolSchedule( new MilestoneStreamingTransitionProtocolSchedule(
preMergeProtocolSchedule, postMergeProtocolSchedule); preMergeProtocolSchedule, postMergeProtocolSchedule);

@ -276,6 +276,8 @@ public abstract class CommandTestAbstract {
when(mockControllerBuilder.privacyParameters(any())).thenReturn(mockControllerBuilder); when(mockControllerBuilder.privacyParameters(any())).thenReturn(mockControllerBuilder);
when(mockControllerBuilder.clock(any())).thenReturn(mockControllerBuilder); when(mockControllerBuilder.clock(any())).thenReturn(mockControllerBuilder);
when(mockControllerBuilder.isRevertReasonEnabled(false)).thenReturn(mockControllerBuilder); when(mockControllerBuilder.isRevertReasonEnabled(false)).thenReturn(mockControllerBuilder);
when(mockControllerBuilder.isParallelTxProcessingEnabled(false))
.thenReturn(mockControllerBuilder);
when(mockControllerBuilder.storageProvider(any())).thenReturn(mockControllerBuilder); when(mockControllerBuilder.storageProvider(any())).thenReturn(mockControllerBuilder);
when(mockControllerBuilder.gasLimitCalculator(any())).thenReturn(mockControllerBuilder); when(mockControllerBuilder.gasLimitCalculator(any())).thenReturn(mockControllerBuilder);
when(mockControllerBuilder.requiredBlocks(any())).thenReturn(mockControllerBuilder); when(mockControllerBuilder.requiredBlocks(any())).thenReturn(mockControllerBuilder);

@ -36,6 +36,7 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecBuilder;
import org.hyperledger.besu.ethereum.mainnet.feemarket.BaseFeeMarket; import org.hyperledger.besu.ethereum.mainnet.feemarket.BaseFeeMarket;
import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket;
import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.evm.internal.EvmConfiguration;
import org.hyperledger.besu.plugin.services.MetricsSystem;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.HashMap; import java.util.HashMap;
@ -64,6 +65,9 @@ public class CliqueProtocolSchedule {
* @param evmConfiguration the evm configuration * @param evmConfiguration the evm configuration
* @param miningParameters the mining parameters * @param miningParameters the mining parameters
* @param badBlockManager the cache to use to keep invalid blocks * @param badBlockManager the cache to use to keep invalid blocks
* @param isParallelTxProcessingEnabled indicates whether parallel transaction is enabled
* @param metricsSystem A metricSystem instance to be able to expose metrics in the underlying
* calls
* @return the protocol schedule * @return the protocol schedule
*/ */
public static ProtocolSchedule create( public static ProtocolSchedule create(
@ -74,7 +78,9 @@ public class CliqueProtocolSchedule {
final boolean isRevertReasonEnabled, final boolean isRevertReasonEnabled,
final EvmConfiguration evmConfiguration, final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters, final MiningParameters miningParameters,
final BadBlockManager badBlockManager) { final BadBlockManager badBlockManager,
final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
final CliqueConfigOptions cliqueConfig = config.getCliqueConfigOptions(); final CliqueConfigOptions cliqueConfig = config.getCliqueConfigOptions();
@ -110,7 +116,9 @@ public class CliqueProtocolSchedule {
isRevertReasonEnabled, isRevertReasonEnabled,
evmConfiguration, evmConfiguration,
miningParameters, miningParameters,
badBlockManager) badBlockManager,
isParallelTxProcessingEnabled,
metricsSystem)
.createProtocolSchedule(); .createProtocolSchedule();
} }
@ -124,6 +132,9 @@ public class CliqueProtocolSchedule {
* @param evmConfiguration the evm configuration * @param evmConfiguration the evm configuration
* @param miningParameters the mining parameters * @param miningParameters the mining parameters
* @param badBlockManager the cache to use to keep invalid blocks * @param badBlockManager the cache to use to keep invalid blocks
* @param isParallelTxProcessingEnabled indicates whether parallel transaction is enabled
* @param metricsSystem A metricSystem instance to be able to expose metrics in the underlying
* calls
* @return the protocol schedule * @return the protocol schedule
*/ */
@VisibleForTesting @VisibleForTesting
@ -134,7 +145,9 @@ public class CliqueProtocolSchedule {
final boolean isRevertReasonEnabled, final boolean isRevertReasonEnabled,
final EvmConfiguration evmConfiguration, final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters, final MiningParameters miningParameters,
final BadBlockManager badBlockManager) { final BadBlockManager badBlockManager,
final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
return create( return create(
config, config,
forksSchedule, forksSchedule,
@ -143,7 +156,9 @@ public class CliqueProtocolSchedule {
isRevertReasonEnabled, isRevertReasonEnabled,
evmConfiguration, evmConfiguration,
miningParameters, miningParameters,
badBlockManager); badBlockManager,
isParallelTxProcessingEnabled,
metricsSystem);
} }
private static ProtocolSpecBuilder applyCliqueSpecificModifications( private static ProtocolSpecBuilder applyCliqueSpecificModifications(

@ -37,6 +37,7 @@ import org.hyperledger.besu.ethereum.mainnet.HeaderValidationMode;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.evm.internal.EvmConfiguration;
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
import java.time.Instant; import java.time.Instant;
import java.util.List; import java.util.List;
@ -68,7 +69,9 @@ public class CliqueProtocolScheduleTest {
false, false,
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED, MiningParameters.MINING_DISABLED,
new BadBlockManager()); new BadBlockManager(),
false,
new NoOpMetricsSystem());
final ProtocolSpec homesteadSpec = protocolSchedule.getByBlockHeader(blockHeader(1)); final ProtocolSpec homesteadSpec = protocolSchedule.getByBlockHeader(blockHeader(1));
final ProtocolSpec tangerineWhistleSpec = protocolSchedule.getByBlockHeader(blockHeader(2)); final ProtocolSpec tangerineWhistleSpec = protocolSchedule.getByBlockHeader(blockHeader(2));
@ -92,7 +95,9 @@ public class CliqueProtocolScheduleTest {
false, false,
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED, MiningParameters.MINING_DISABLED,
new BadBlockManager()) new BadBlockManager(),
false,
new NoOpMetricsSystem())
.getByBlockHeader(blockHeader(0)); .getByBlockHeader(blockHeader(0));
assertThat(homestead.getName()).isEqualTo("Frontier"); assertThat(homestead.getName()).isEqualTo("Frontier");
@ -116,7 +121,9 @@ public class CliqueProtocolScheduleTest {
false, false,
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED, MiningParameters.MINING_DISABLED,
new BadBlockManager())) new BadBlockManager(),
false,
new NoOpMetricsSystem()))
.isInstanceOf(IllegalArgumentException.class) .isInstanceOf(IllegalArgumentException.class)
.hasMessage("Epoch length in config must be greater than zero"); .hasMessage("Epoch length in config must be greater than zero");
} }
@ -136,7 +143,9 @@ public class CliqueProtocolScheduleTest {
false, false,
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED, MiningParameters.MINING_DISABLED,
new BadBlockManager())) new BadBlockManager(),
false,
new NoOpMetricsSystem()))
.isInstanceOf(IllegalArgumentException.class) .isInstanceOf(IllegalArgumentException.class)
.hasMessage("Epoch length in config must be greater than zero"); .hasMessage("Epoch length in config must be greater than zero");
} }
@ -160,7 +169,9 @@ public class CliqueProtocolScheduleTest {
false, false,
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED, MiningParameters.MINING_DISABLED,
new BadBlockManager()); new BadBlockManager(),
false,
new NoOpMetricsSystem());
BlockHeader emptyFrontierParent = BlockHeader emptyFrontierParent =
headerBuilder headerBuilder

@ -106,7 +106,9 @@ public class CliqueBlockCreatorTest {
false, false,
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED, MiningParameters.MINING_DISABLED,
new BadBlockManager()); new BadBlockManager(),
false,
new NoOpMetricsSystem());
final Address otherAddress = Util.publicKeyToAddress(otherKeyPair.getPublicKey()); final Address otherAddress = Util.publicKeyToAddress(otherKeyPair.getPublicKey());
validatorList.add(otherAddress); validatorList.add(otherAddress);

@ -105,7 +105,9 @@ public class CliqueMinerExecutorTest {
false, false,
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED, MiningParameters.MINING_DISABLED,
new BadBlockManager()); new BadBlockManager(),
false,
new NoOpMetricsSystem());
cliqueEthContext = mock(EthContext.class, RETURNS_DEEP_STUBS); cliqueEthContext = mock(EthContext.class, RETURNS_DEEP_STUBS);
blockHeaderBuilder = new BlockHeaderTestFixture(); blockHeaderBuilder = new BlockHeaderTestFixture();
} }

@ -33,6 +33,7 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecBuilder;
import org.hyperledger.besu.ethereum.mainnet.WithdrawalsValidator; import org.hyperledger.besu.ethereum.mainnet.WithdrawalsValidator;
import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket;
import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.evm.internal.EvmConfiguration;
import org.hyperledger.besu.plugin.services.MetricsSystem;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.HashMap; import java.util.HashMap;
@ -58,6 +59,9 @@ public abstract class BaseBftProtocolScheduleBuilder {
* @param evmConfiguration the evm configuration * @param evmConfiguration the evm configuration
* @param miningParameters the mining parameters * @param miningParameters the mining parameters
* @param badBlockManager the cache to use to keep invalid blocks * @param badBlockManager the cache to use to keep invalid blocks
* @param isParallelTxProcessingEnabled indicates whether parallel transaction is enabled.
* @param metricsSystem metricsSystem A metricSystem instance to be able to expose metrics in the
* underlying calls
* @return the protocol schedule * @return the protocol schedule
*/ */
public BftProtocolSchedule createProtocolSchedule( public BftProtocolSchedule createProtocolSchedule(
@ -68,7 +72,9 @@ public abstract class BaseBftProtocolScheduleBuilder {
final BftExtraDataCodec bftExtraDataCodec, final BftExtraDataCodec bftExtraDataCodec,
final EvmConfiguration evmConfiguration, final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters, final MiningParameters miningParameters,
final BadBlockManager badBlockManager) { final BadBlockManager badBlockManager,
final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
final Map<Long, Function<ProtocolSpecBuilder, ProtocolSpecBuilder>> specMap = new HashMap<>(); final Map<Long, Function<ProtocolSpecBuilder, ProtocolSpecBuilder>> specMap = new HashMap<>();
forksSchedule forksSchedule
@ -90,7 +96,9 @@ public abstract class BaseBftProtocolScheduleBuilder {
isRevertReasonEnabled, isRevertReasonEnabled,
evmConfiguration, evmConfiguration,
miningParameters, miningParameters,
badBlockManager) badBlockManager,
isParallelTxProcessingEnabled,
metricsSystem)
.createProtocolSchedule(); .createProtocolSchedule();
return new BftProtocolSchedule((DefaultProtocolSchedule) protocolSchedule); return new BftProtocolSchedule((DefaultProtocolSchedule) protocolSchedule);
} }

@ -28,6 +28,7 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ProtocolScheduleBuilder; import org.hyperledger.besu.ethereum.mainnet.ProtocolScheduleBuilder;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecAdapters; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecAdapters;
import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.evm.internal.EvmConfiguration;
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.List; import java.util.List;
@ -177,7 +178,9 @@ public class CombinedProtocolScheduleFactoryTest {
false, false,
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED, MiningParameters.MINING_DISABLED,
new BadBlockManager()); new BadBlockManager(),
false,
new NoOpMetricsSystem());
return new BftProtocolSchedule( return new BftProtocolSchedule(
(DefaultProtocolSchedule) protocolScheduleBuilder.createProtocolSchedule()); (DefaultProtocolSchedule) protocolScheduleBuilder.createProtocolSchedule());

@ -39,6 +39,7 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket;
import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.evm.internal.EvmConfiguration;
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.List; import java.util.List;
@ -245,7 +246,9 @@ public class BaseBftProtocolScheduleBuilderTest {
bftExtraDataCodec, bftExtraDataCodec,
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED, MiningParameters.MINING_DISABLED,
new BadBlockManager()); new BadBlockManager(),
false,
new NoOpMetricsSystem());
} }
private BftConfigOptions createBftConfig(final BigInteger blockReward) { private BftConfigOptions createBftConfig(final BigInteger blockReward) {

@ -333,7 +333,9 @@ public class TestContextBuilder {
IBFT_EXTRA_DATA_ENCODER, IBFT_EXTRA_DATA_ENCODER,
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED, MiningParameters.MINING_DISABLED,
new BadBlockManager()); new BadBlockManager(),
false,
new NoOpMetricsSystem());
///////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////
// From here down is BASICALLY taken from IbftBesuController // From here down is BASICALLY taken from IbftBesuController

@ -27,6 +27,7 @@ import org.hyperledger.besu.ethereum.mainnet.BlockHeaderValidator;
import org.hyperledger.besu.ethereum.mainnet.feemarket.BaseFeeMarket; import org.hyperledger.besu.ethereum.mainnet.feemarket.BaseFeeMarket;
import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket;
import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.evm.internal.EvmConfiguration;
import org.hyperledger.besu.plugin.services.MetricsSystem;
import java.util.Optional; import java.util.Optional;
@ -46,6 +47,9 @@ public class IbftProtocolScheduleBuilder extends BaseBftProtocolScheduleBuilder
* @param evmConfiguration the evm configuration * @param evmConfiguration the evm configuration
* @param miningParameters the mining parameters * @param miningParameters the mining parameters
* @param badBlockManager the cache to use to keep invalid blocks * @param badBlockManager the cache to use to keep invalid blocks
* @param isParallelTxProcessingEnabled indicates whether parallel transaction is enabled
* @param metricsSystem A metricSystem instance to be able to expose metrics in the underlying
* calls
* @return the protocol schedule * @return the protocol schedule
*/ */
public static BftProtocolSchedule create( public static BftProtocolSchedule create(
@ -56,7 +60,9 @@ public class IbftProtocolScheduleBuilder extends BaseBftProtocolScheduleBuilder
final BftExtraDataCodec bftExtraDataCodec, final BftExtraDataCodec bftExtraDataCodec,
final EvmConfiguration evmConfiguration, final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters, final MiningParameters miningParameters,
final BadBlockManager badBlockManager) { final BadBlockManager badBlockManager,
final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
return new IbftProtocolScheduleBuilder() return new IbftProtocolScheduleBuilder()
.createProtocolSchedule( .createProtocolSchedule(
config, config,
@ -66,7 +72,9 @@ public class IbftProtocolScheduleBuilder extends BaseBftProtocolScheduleBuilder
bftExtraDataCodec, bftExtraDataCodec,
evmConfiguration, evmConfiguration,
miningParameters, miningParameters,
badBlockManager); badBlockManager,
isParallelTxProcessingEnabled,
metricsSystem);
} }
/** /**
@ -78,6 +86,9 @@ public class IbftProtocolScheduleBuilder extends BaseBftProtocolScheduleBuilder
* @param evmConfiguration the evm configuration * @param evmConfiguration the evm configuration
* @param miningParameters the mining parameters * @param miningParameters the mining parameters
* @param badBlockManager the cache to use to keep invalid blocks * @param badBlockManager the cache to use to keep invalid blocks
* @param isParallelTxProcessingEnabled indicates whether parallel transaction is enabled.
* @param metricsSystem A metricSystem instance to be able to expose metrics in the underlying
* calls
* @return the protocol schedule * @return the protocol schedule
*/ */
public static BftProtocolSchedule create( public static BftProtocolSchedule create(
@ -86,7 +97,9 @@ public class IbftProtocolScheduleBuilder extends BaseBftProtocolScheduleBuilder
final BftExtraDataCodec bftExtraDataCodec, final BftExtraDataCodec bftExtraDataCodec,
final EvmConfiguration evmConfiguration, final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters, final MiningParameters miningParameters,
final BadBlockManager badBlockManager) { final BadBlockManager badBlockManager,
final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
return create( return create(
config, config,
forksSchedule, forksSchedule,
@ -95,7 +108,9 @@ public class IbftProtocolScheduleBuilder extends BaseBftProtocolScheduleBuilder
bftExtraDataCodec, bftExtraDataCodec,
evmConfiguration, evmConfiguration,
miningParameters, miningParameters,
badBlockManager); badBlockManager,
isParallelTxProcessingEnabled,
metricsSystem);
} }
@Override @Override

@ -45,6 +45,7 @@ import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.ethereum.core.Util; import org.hyperledger.besu.ethereum.core.Util;
import org.hyperledger.besu.ethereum.mainnet.HeaderValidationMode; import org.hyperledger.besu.ethereum.mainnet.HeaderValidationMode;
import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.evm.internal.EvmConfiguration;
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.Collection; import java.util.Collection;
@ -103,7 +104,9 @@ public class IbftProtocolScheduleTest {
bftExtraDataCodec, bftExtraDataCodec,
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED, MiningParameters.MINING_DISABLED,
new BadBlockManager()); new BadBlockManager(),
false,
new NoOpMetricsSystem());
} }
private boolean validateHeader( private boolean validateHeader(

@ -121,7 +121,9 @@ public class BftBlockCreatorTest {
bftExtraDataEncoder, bftExtraDataEncoder,
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED, MiningParameters.MINING_DISABLED,
new BadBlockManager()); new BadBlockManager(),
false,
new NoOpMetricsSystem());
final ProtocolContext protContext = final ProtocolContext protContext =
new ProtocolContext( new ProtocolContext(
blockchain, blockchain,

@ -79,6 +79,7 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolScheduleBuilder;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecAdapters; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecAdapters;
import org.hyperledger.besu.ethereum.p2p.rlpx.wire.MessageData; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.MessageData;
import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.evm.internal.EvmConfiguration;
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
import org.hyperledger.besu.util.Subscribers; import org.hyperledger.besu.util.Subscribers;
import java.math.BigInteger; import java.math.BigInteger;
@ -184,7 +185,9 @@ public class IbftBlockHeightManagerTest {
false, false,
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED, MiningParameters.MINING_DISABLED,
new BadBlockManager()); new BadBlockManager(),
false,
new NoOpMetricsSystem());
ProtocolSchedule protocolSchedule = ProtocolSchedule protocolSchedule =
new BftProtocolSchedule( new BftProtocolSchedule(

@ -27,6 +27,7 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecBuilder;
import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket;
import org.hyperledger.besu.evm.MainnetEVMs; import org.hyperledger.besu.evm.MainnetEVMs;
import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.evm.internal.EvmConfiguration;
import org.hyperledger.besu.plugin.services.MetricsSystem;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.HashMap; import java.util.HashMap;
@ -49,19 +50,24 @@ public class MergeProtocolSchedule {
* @param isRevertReasonEnabled the is revert reason enabled * @param isRevertReasonEnabled the is revert reason enabled
* @param miningParameters the mining parameters * @param miningParameters the mining parameters
* @param badBlockManager the cache to use to keep invalid blocks * @param badBlockManager the cache to use to keep invalid blocks
* @param isParallelTxProcessingEnabled indicates whether parallel transaction is enabled.
* @return the protocol schedule * @return the protocol schedule
*/ */
public static ProtocolSchedule create( public static ProtocolSchedule create(
final GenesisConfigOptions config, final GenesisConfigOptions config,
final boolean isRevertReasonEnabled, final boolean isRevertReasonEnabled,
final MiningParameters miningParameters, final MiningParameters miningParameters,
final BadBlockManager badBlockManager) { final BadBlockManager badBlockManager,
final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
return create( return create(
config, config,
PrivacyParameters.DEFAULT, PrivacyParameters.DEFAULT,
isRevertReasonEnabled, isRevertReasonEnabled,
miningParameters, miningParameters,
badBlockManager); badBlockManager,
isParallelTxProcessingEnabled,
metricsSystem);
} }
/** /**
@ -72,6 +78,7 @@ public class MergeProtocolSchedule {
* @param isRevertReasonEnabled the is revert reason enabled * @param isRevertReasonEnabled the is revert reason enabled
* @param miningParameters the mining parameters * @param miningParameters the mining parameters
* @param badBlockManager the cache to use to keep invalid blocks * @param badBlockManager the cache to use to keep invalid blocks
* @param isParallelTxProcessingEnabled indicates whether parallel transaction is enabled.
* @return the protocol schedule * @return the protocol schedule
*/ */
public static ProtocolSchedule create( public static ProtocolSchedule create(
@ -79,7 +86,9 @@ public class MergeProtocolSchedule {
final PrivacyParameters privacyParameters, final PrivacyParameters privacyParameters,
final boolean isRevertReasonEnabled, final boolean isRevertReasonEnabled,
final MiningParameters miningParameters, final MiningParameters miningParameters,
final BadBlockManager badBlockManager) { final BadBlockManager badBlockManager,
final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
Map<Long, Function<ProtocolSpecBuilder, ProtocolSpecBuilder>> postMergeModifications = Map<Long, Function<ProtocolSpecBuilder, ProtocolSpecBuilder>> postMergeModifications =
new HashMap<>(); new HashMap<>();
@ -98,7 +107,9 @@ public class MergeProtocolSchedule {
isRevertReasonEnabled, isRevertReasonEnabled,
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
miningParameters, miningParameters,
badBlockManager) badBlockManager,
isParallelTxProcessingEnabled,
metricsSystem)
.createProtocolSchedule(); .createProtocolSchedule();
} }

@ -27,6 +27,7 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
import org.hyperledger.besu.ethereum.mainnet.ScheduledProtocolSpec; import org.hyperledger.besu.ethereum.mainnet.ScheduledProtocolSpec;
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
import org.hyperledger.besu.plugin.services.MetricsSystem;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.Optional; import java.util.Optional;
@ -65,17 +66,30 @@ public class TransitionProtocolSchedule implements ProtocolSchedule {
* milestone starting points * milestone starting points
* @param miningParameters the mining parameters * @param miningParameters the mining parameters
* @param badBlockManager the cache to use to keep invalid blocks * @param badBlockManager the cache to use to keep invalid blocks
* @param isParallelTxProcessingEnabled indicates whether parallel transaction is enabled.
* @return an initialised TransitionProtocolSchedule using post-merge defaults * @return an initialised TransitionProtocolSchedule using post-merge defaults
*/ */
public static TransitionProtocolSchedule fromConfig( public static TransitionProtocolSchedule fromConfig(
final GenesisConfigOptions genesisConfigOptions, final GenesisConfigOptions genesisConfigOptions,
final MiningParameters miningParameters, final MiningParameters miningParameters,
final BadBlockManager badBlockManager) { final BadBlockManager badBlockManager,
final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
ProtocolSchedule preMergeProtocolSchedule = ProtocolSchedule preMergeProtocolSchedule =
MainnetProtocolSchedule.fromConfig(genesisConfigOptions, miningParameters, badBlockManager); MainnetProtocolSchedule.fromConfig(
genesisConfigOptions,
miningParameters,
badBlockManager,
isParallelTxProcessingEnabled,
metricsSystem);
ProtocolSchedule postMergeProtocolSchedule = ProtocolSchedule postMergeProtocolSchedule =
MergeProtocolSchedule.create( MergeProtocolSchedule.create(
genesisConfigOptions, false, miningParameters, badBlockManager); genesisConfigOptions,
false,
miningParameters,
badBlockManager,
isParallelTxProcessingEnabled,
metricsSystem);
return new TransitionProtocolSchedule( return new TransitionProtocolSchedule(
preMergeProtocolSchedule, postMergeProtocolSchedule, PostMergeContext.get()); preMergeProtocolSchedule, postMergeProtocolSchedule, PostMergeContext.get());
} }

@ -29,6 +29,7 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
import org.hyperledger.besu.evm.operation.InvalidOperation; import org.hyperledger.besu.evm.operation.InvalidOperation;
import org.hyperledger.besu.evm.operation.PrevRanDaoOperation; import org.hyperledger.besu.evm.operation.PrevRanDaoOperation;
import org.hyperledger.besu.evm.operation.Push0Operation; import org.hyperledger.besu.evm.operation.Push0Operation;
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
import java.math.BigInteger; import java.math.BigInteger;
@ -48,7 +49,12 @@ public class MergeProtocolScheduleTest {
final GenesisConfigOptions config = GenesisConfigFile.fromConfig(jsonInput).getConfigOptions(); final GenesisConfigOptions config = GenesisConfigFile.fromConfig(jsonInput).getConfigOptions();
final ProtocolSchedule protocolSchedule = final ProtocolSchedule protocolSchedule =
MergeProtocolSchedule.create( MergeProtocolSchedule.create(
config, false, MiningParameters.MINING_DISABLED, new BadBlockManager()); config,
false,
MiningParameters.MINING_DISABLED,
new BadBlockManager(),
false,
new NoOpMetricsSystem());
final ProtocolSpec homesteadSpec = protocolSchedule.getByBlockHeader(blockHeader(1)); final ProtocolSpec homesteadSpec = protocolSchedule.getByBlockHeader(blockHeader(1));
final ProtocolSpec londonSpec = protocolSchedule.getByBlockHeader(blockHeader(1559)); final ProtocolSpec londonSpec = protocolSchedule.getByBlockHeader(blockHeader(1559));
@ -64,7 +70,12 @@ public class MergeProtocolScheduleTest {
final GenesisConfigOptions config = GenesisConfigFile.mainnet().getConfigOptions(); final GenesisConfigOptions config = GenesisConfigFile.mainnet().getConfigOptions();
final ProtocolSchedule protocolSchedule = final ProtocolSchedule protocolSchedule =
MergeProtocolSchedule.create( MergeProtocolSchedule.create(
config, false, MiningParameters.MINING_DISABLED, new BadBlockManager()); config,
false,
MiningParameters.MINING_DISABLED,
new BadBlockManager(),
false,
new NoOpMetricsSystem());
final long lastParisBlockNumber = 17034869L; final long lastParisBlockNumber = 17034869L;
final ProtocolSpec parisSpec = final ProtocolSpec parisSpec =
@ -100,7 +111,12 @@ public class MergeProtocolScheduleTest {
final GenesisConfigOptions config = GenesisConfigFile.fromConfig(jsonInput).getConfigOptions(); final GenesisConfigOptions config = GenesisConfigFile.fromConfig(jsonInput).getConfigOptions();
final ProtocolSchedule protocolSchedule = final ProtocolSchedule protocolSchedule =
MergeProtocolSchedule.create( MergeProtocolSchedule.create(
config, false, MiningParameters.MINING_DISABLED, new BadBlockManager()); config,
false,
MiningParameters.MINING_DISABLED,
new BadBlockManager(),
false,
new NoOpMetricsSystem());
final ProtocolSpec parisSpec = final ProtocolSpec parisSpec =
protocolSchedule.getByBlockHeader( protocolSchedule.getByBlockHeader(
@ -128,7 +144,12 @@ public class MergeProtocolScheduleTest {
final GenesisConfigOptions config = GenesisConfigFile.mainnet().getConfigOptions(); final GenesisConfigOptions config = GenesisConfigFile.mainnet().getConfigOptions();
final ProtocolSchedule protocolSchedule = final ProtocolSchedule protocolSchedule =
MergeProtocolSchedule.create( MergeProtocolSchedule.create(
config, false, MiningParameters.MINING_DISABLED, new BadBlockManager()); config,
false,
MiningParameters.MINING_DISABLED,
new BadBlockManager(),
false,
new NoOpMetricsSystem());
final long lastParisBlockNumber = 17034869L; final long lastParisBlockNumber = 17034869L;
final ProtocolSpec parisSpec = final ProtocolSpec parisSpec =
@ -160,7 +181,9 @@ public class MergeProtocolScheduleTest {
GenesisConfigFile.DEFAULT.getConfigOptions(), GenesisConfigFile.DEFAULT.getConfigOptions(),
false, false,
MiningParameters.MINING_DISABLED, MiningParameters.MINING_DISABLED,
new BadBlockManager()) new BadBlockManager(),
false,
new NoOpMetricsSystem())
.getByBlockHeader(blockHeader(0)); .getByBlockHeader(blockHeader(0));
assertThat(london.getName()).isEqualTo("Paris"); assertThat(london.getName()).isEqualTo("Paris");

@ -21,6 +21,7 @@ import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.ethereum.chain.BadBlockManager; import org.hyperledger.besu.ethereum.chain.BadBlockManager;
import org.hyperledger.besu.ethereum.core.MiningParameters; import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
import java.io.IOException; import java.io.IOException;
import java.net.URI; import java.net.URI;
@ -56,6 +57,8 @@ public interface MergeGenesisConfigHelper {
getPosGenesisConfigFile().getConfigOptions(), getPosGenesisConfigFile().getConfigOptions(),
false, false,
MiningParameters.MINING_DISABLED, MiningParameters.MINING_DISABLED,
new BadBlockManager()); new BadBlockManager(),
false,
new NoOpMetricsSystem());
} }
} }

@ -437,7 +437,9 @@ public class TestContextBuilder {
BFT_EXTRA_DATA_ENCODER, BFT_EXTRA_DATA_ENCODER,
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED, MiningParameters.MINING_DISABLED,
new BadBlockManager()); new BadBlockManager(),
false,
new NoOpMetricsSystem());
final BftValidatorOverrides validatorOverrides = convertBftForks(qbftForks); final BftValidatorOverrides validatorOverrides = convertBftForks(qbftForks);
final TransactionSimulator transactionSimulator = final TransactionSimulator transactionSimulator =

@ -31,6 +31,7 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.feemarket.BaseFeeMarket; import org.hyperledger.besu.ethereum.mainnet.feemarket.BaseFeeMarket;
import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket;
import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.evm.internal.EvmConfiguration;
import org.hyperledger.besu.plugin.services.MetricsSystem;
import java.util.Optional; import java.util.Optional;
@ -50,6 +51,9 @@ public class QbftProtocolScheduleBuilder extends BaseBftProtocolScheduleBuilder
* @param evmConfiguration the evm configuration * @param evmConfiguration the evm configuration
* @param miningParameters The mining parameters * @param miningParameters The mining parameters
* @param badBlockManager the cache to use to keep invalid blocks * @param badBlockManager the cache to use to keep invalid blocks
* @param isParallelTxProcessingEnabled indicates whether parallel transaction is enabled.
* @param metricsSystem A metricSystem instance to be able to expose metrics in the underlying
* calls
* @return the protocol schedule * @return the protocol schedule
*/ */
public static BftProtocolSchedule create( public static BftProtocolSchedule create(
@ -60,7 +64,9 @@ public class QbftProtocolScheduleBuilder extends BaseBftProtocolScheduleBuilder
final BftExtraDataCodec bftExtraDataCodec, final BftExtraDataCodec bftExtraDataCodec,
final EvmConfiguration evmConfiguration, final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters, final MiningParameters miningParameters,
final BadBlockManager badBlockManager) { final BadBlockManager badBlockManager,
final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
return new QbftProtocolScheduleBuilder() return new QbftProtocolScheduleBuilder()
.createProtocolSchedule( .createProtocolSchedule(
config, config,
@ -70,7 +76,9 @@ public class QbftProtocolScheduleBuilder extends BaseBftProtocolScheduleBuilder
bftExtraDataCodec, bftExtraDataCodec,
evmConfiguration, evmConfiguration,
miningParameters, miningParameters,
badBlockManager); badBlockManager,
isParallelTxProcessingEnabled,
metricsSystem);
} }
/** /**
@ -82,6 +90,9 @@ public class QbftProtocolScheduleBuilder extends BaseBftProtocolScheduleBuilder
* @param evmConfiguration the evm configuration * @param evmConfiguration the evm configuration
* @param miningParameters The mining parameters * @param miningParameters The mining parameters
* @param badBlockManager the cache to use to keep invalid blocks * @param badBlockManager the cache to use to keep invalid blocks
* @param isParallelTxProcessingEnabled indicates whether parallel transaction is enabled.
* @param metricsSystem A metricSystem instance to be able to expose metrics in the underlying
* calls
* @return the protocol schedule * @return the protocol schedule
*/ */
public static BftProtocolSchedule create( public static BftProtocolSchedule create(
@ -90,7 +101,9 @@ public class QbftProtocolScheduleBuilder extends BaseBftProtocolScheduleBuilder
final BftExtraDataCodec bftExtraDataCodec, final BftExtraDataCodec bftExtraDataCodec,
final EvmConfiguration evmConfiguration, final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters, final MiningParameters miningParameters,
final BadBlockManager badBlockManager) { final BadBlockManager badBlockManager,
final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
return create( return create(
config, config,
qbftForksSchedule, qbftForksSchedule,
@ -99,7 +112,9 @@ public class QbftProtocolScheduleBuilder extends BaseBftProtocolScheduleBuilder
bftExtraDataCodec, bftExtraDataCodec,
evmConfiguration, evmConfiguration,
miningParameters, miningParameters,
badBlockManager); badBlockManager,
isParallelTxProcessingEnabled,
metricsSystem);
} }
/** /**
@ -111,6 +126,9 @@ public class QbftProtocolScheduleBuilder extends BaseBftProtocolScheduleBuilder
* @param bftExtraDataCodec the bft extra data codec * @param bftExtraDataCodec the bft extra data codec
* @param miningParameters The mining parameters * @param miningParameters The mining parameters
* @param badBlockManager the cache to use to keep invalid blocks * @param badBlockManager the cache to use to keep invalid blocks
* @param isParallelTxProcessingEnabled indicates whether parallel transaction is enabled.
* @param metricsSystem A metricSystem instance to be able to expose metrics in the underlying
* calls
* @return the protocol schedule * @return the protocol schedule
*/ */
public static ProtocolSchedule create( public static ProtocolSchedule create(
@ -119,7 +137,9 @@ public class QbftProtocolScheduleBuilder extends BaseBftProtocolScheduleBuilder
final boolean isRevertReasonEnabled, final boolean isRevertReasonEnabled,
final BftExtraDataCodec bftExtraDataCodec, final BftExtraDataCodec bftExtraDataCodec,
final MiningParameters miningParameters, final MiningParameters miningParameters,
final BadBlockManager badBlockManager) { final BadBlockManager badBlockManager,
final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
return create( return create(
config, config,
qbftForksSchedule, qbftForksSchedule,
@ -128,7 +148,9 @@ public class QbftProtocolScheduleBuilder extends BaseBftProtocolScheduleBuilder
bftExtraDataCodec, bftExtraDataCodec,
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
miningParameters, miningParameters,
badBlockManager); badBlockManager,
isParallelTxProcessingEnabled,
metricsSystem);
} }
@Override @Override

@ -41,6 +41,7 @@ import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.ethereum.core.Util; import org.hyperledger.besu.ethereum.core.Util;
import org.hyperledger.besu.ethereum.mainnet.HeaderValidationMode; import org.hyperledger.besu.ethereum.mainnet.HeaderValidationMode;
import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.evm.internal.EvmConfiguration;
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.Collection; import java.util.Collection;
@ -138,7 +139,9 @@ public class QbftProtocolScheduleTest {
bftExtraDataCodec, bftExtraDataCodec,
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED, MiningParameters.MINING_DISABLED,
new BadBlockManager()); new BadBlockManager(),
false,
new NoOpMetricsSystem());
} }
private boolean validateHeader( private boolean validateHeader(

@ -78,6 +78,7 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolScheduleBuilder;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecAdapters; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecAdapters;
import org.hyperledger.besu.ethereum.p2p.rlpx.wire.MessageData; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.MessageData;
import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.evm.internal.EvmConfiguration;
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
import org.hyperledger.besu.util.Subscribers; import org.hyperledger.besu.util.Subscribers;
import java.math.BigInteger; import java.math.BigInteger;
@ -184,7 +185,9 @@ public class QbftBlockHeightManagerTest {
false, false,
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED, MiningParameters.MINING_DISABLED,
new BadBlockManager()); new BadBlockManager(),
false,
new NoOpMetricsSystem());
ProtocolSchedule protocolSchedule = ProtocolSchedule protocolSchedule =
new BftProtocolSchedule( new BftProtocolSchedule(

@ -34,6 +34,13 @@ public class Blake2bfMessageDigest extends BCMessageDigest implements Cloneable
super(new Blake2bfDigest()); super(new Blake2bfDigest());
} }
@Override
public Blake2bfMessageDigest clone() throws CloneNotSupportedException {
Blake2bfMessageDigest cloned = (Blake2bfMessageDigest) super.clone();
cloned.digest = ((Blake2bfDigest) this.digest).clone();
return cloned;
}
/** /**
* Implementation of the `F` compression function of the Blake2b cryptographic hash function. * Implementation of the `F` compression function of the Blake2b cryptographic hash function.
* *
@ -43,7 +50,7 @@ public class Blake2bfMessageDigest extends BCMessageDigest implements Cloneable
* *
* <p>Optimized for 64-bit platforms * <p>Optimized for 64-bit platforms
*/ */
public static class Blake2bfDigest implements Digest { public static class Blake2bfDigest implements Digest, Cloneable {
/** The constant MESSAGE_LENGTH_BYTES. */ /** The constant MESSAGE_LENGTH_BYTES. */
public static final int MESSAGE_LENGTH_BYTES = 213; public static final int MESSAGE_LENGTH_BYTES = 213;
@ -71,18 +78,18 @@ public class Blake2bfMessageDigest extends BCMessageDigest implements Cloneable
// buffer which holds serialized input for this compression function // buffer which holds serialized input for this compression function
// [ 4 bytes for rounds ][ 64 bytes for h ][ 128 bytes for m ] // [ 4 bytes for rounds ][ 64 bytes for h ][ 128 bytes for m ]
// [ 8 bytes for t_0 ][ 8 bytes for t_1 ][ 1 byte for f ] // [ 8 bytes for t_0 ][ 8 bytes for t_1 ][ 1 byte for f ]
private final byte[] buffer; private byte[] buffer;
private int bufferPos; private int bufferPos;
// deserialized inputs for f compression // deserialized inputs for f compression
private final long[] h; private long[] h;
private final long[] m; private long[] m;
private final long[] t; private long[] t;
private boolean f; private boolean f;
private long rounds; // unsigned integer represented as long private long rounds; // unsigned integer represented as long
private final long[] v; private long[] v;
private static boolean useNative; private static boolean useNative;
static { static {
@ -112,6 +119,17 @@ public class Blake2bfMessageDigest extends BCMessageDigest implements Cloneable
v = new long[16]; v = new long[16];
} }
@Override
public Blake2bfDigest clone() throws CloneNotSupportedException {
Blake2bfDigest cloned = (Blake2bfDigest) super.clone();
cloned.buffer = this.buffer.clone();
cloned.h = this.h.clone();
cloned.m = this.m.clone();
cloned.t = this.t.clone();
cloned.v = this.v.clone();
return cloned;
}
/** Disable native. */ /** Disable native. */
public static void disableNative() { public static void disableNative() {
useNative = false; useNative = false;

@ -17,6 +17,13 @@ package org.hyperledger.besu.crypto;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.Assertions.assertThatThrownBy;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.stream.IntStream;
import org.bouncycastle.util.Pack; import org.bouncycastle.util.Pack;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -29,6 +36,16 @@ import org.junit.jupiter.params.provider.CsvFileSource;
*/ */
public class Blake2bfMessageDigestTest { public class Blake2bfMessageDigestTest {
private static final SecureRandom SECURE_RANDOM;
static {
try {
SECURE_RANDOM = SecureRandom.getInstanceStrong();
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
private Blake2bfMessageDigest messageDigest; private Blake2bfMessageDigest messageDigest;
// output when input is all 0 // output when input is all 0
@ -124,6 +141,39 @@ public class Blake2bfMessageDigestTest {
.isInstanceOf(IllegalArgumentException.class); .isInstanceOf(IllegalArgumentException.class);
} }
@SuppressWarnings("unchecked")
@Test
public void testDigestThreadSafety() throws ExecutionException, InterruptedException {
final byte[] input = new byte[213];
;
SECURE_RANDOM.nextBytes(input);
int numberOfHashes = 10;
CompletableFuture<byte[]>[] futures =
IntStream.range(0, numberOfHashes)
.mapToObj(
i ->
CompletableFuture.supplyAsync(
() -> {
try {
MessageDigest clonedDigest = messageDigest.clone();
clonedDigest.update(input);
byte[] digest = clonedDigest.digest();
return digest;
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
}))
.toArray(CompletableFuture[]::new);
CompletableFuture.allOf(futures).get();
byte[] expectedHash = futures[0].get();
for (CompletableFuture<byte[]> future : futures) {
assertThat(expectedHash).isEqualTo(future.get());
}
}
@ParameterizedTest @ParameterizedTest
@CsvFileSource(resources = "eip152TestCases.csv", numLinesToSkip = 1) @CsvFileSource(resources = "eip152TestCases.csv", numLinesToSkip = 1)
public void eip152TestCases(final String hexIn, final String hexExpected) { public void eip152TestCases(final String hexIn, final String hexExpected) {

@ -94,7 +94,7 @@ public class StorageSlotKey implements Comparable<StorageSlotKey> {
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(slotHash.hashCode()); return slotHash.hashCode();
} }
@Override @Override

@ -24,6 +24,7 @@ import org.hyperledger.besu.ethereum.mainnet.MainnetProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ScheduleBasedBlockHeaderFunctions; import org.hyperledger.besu.ethereum.mainnet.ScheduleBasedBlockHeaderFunctions;
import org.hyperledger.besu.ethereum.util.RawBlockIterator; import org.hyperledger.besu.ethereum.util.RawBlockIterator;
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
import java.net.URL; import java.net.URL;
import java.nio.file.Paths; import java.nio.file.Paths;
@ -46,7 +47,9 @@ public class BlockchainImporter {
MainnetProtocolSchedule.fromConfig( MainnetProtocolSchedule.fromConfig(
GenesisConfigFile.fromConfig(genesisJson).getConfigOptions(), GenesisConfigFile.fromConfig(genesisJson).getConfigOptions(),
MiningParameters.newDefault(), MiningParameters.newDefault(),
new BadBlockManager()); new BadBlockManager(),
false,
new NoOpMetricsSystem());
final BlockHeaderFunctions blockHeaderFunctions = final BlockHeaderFunctions blockHeaderFunctions =
ScheduleBasedBlockHeaderFunctions.create(protocolSchedule); ScheduleBasedBlockHeaderFunctions.create(protocolSchedule);
blocks = new ArrayList<>(); blocks = new ArrayList<>();

@ -109,7 +109,9 @@ public class JsonRpcHttpServiceHostAllowlistTest {
MainnetProtocolSchedule.fromConfig( MainnetProtocolSchedule.fromConfig(
new StubGenesisConfigOptions().constantinopleBlock(0).chainId(CHAIN_ID), new StubGenesisConfigOptions().constantinopleBlock(0).chainId(CHAIN_ID),
MiningParameters.MINING_DISABLED, MiningParameters.MINING_DISABLED,
new BadBlockManager()), new BadBlockManager(),
false,
new NoOpMetricsSystem()),
mock(ProtocolContext.class), mock(ProtocolContext.class),
mock(FilterManager.class), mock(FilterManager.class),
mock(TransactionPool.class), mock(TransactionPool.class),

@ -138,7 +138,11 @@ public class JsonRpcHttpServiceLoginTest {
blockchainQueries, blockchainQueries,
synchronizer, synchronizer,
MainnetProtocolSchedule.fromConfig( MainnetProtocolSchedule.fromConfig(
genesisConfigOptions, MiningParameters.MINING_DISABLED, new BadBlockManager()), genesisConfigOptions,
MiningParameters.MINING_DISABLED,
new BadBlockManager(),
false,
new NoOpMetricsSystem()),
mock(ProtocolContext.class), mock(ProtocolContext.class),
mock(FilterManager.class), mock(FilterManager.class),
mock(TransactionPool.class), mock(TransactionPool.class),

@ -118,7 +118,9 @@ public class JsonRpcHttpServiceTestBase {
new StubGenesisConfigOptions().constantinopleBlock(0).chainId(CHAIN_ID), new StubGenesisConfigOptions().constantinopleBlock(0).chainId(CHAIN_ID),
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED, MiningParameters.MINING_DISABLED,
new BadBlockManager()), new BadBlockManager(),
false,
new NoOpMetricsSystem()),
mock(ProtocolContext.class), mock(ProtocolContext.class),
mock(FilterManager.class), mock(FilterManager.class),
mock(TransactionPool.class), mock(TransactionPool.class),

@ -123,7 +123,9 @@ public class JsonRpcHttpServiceTlsClientAuthTest {
MainnetProtocolSchedule.fromConfig( MainnetProtocolSchedule.fromConfig(
new StubGenesisConfigOptions().constantinopleBlock(0).chainId(CHAIN_ID), new StubGenesisConfigOptions().constantinopleBlock(0).chainId(CHAIN_ID),
MiningParameters.MINING_DISABLED, MiningParameters.MINING_DISABLED,
new BadBlockManager()), new BadBlockManager(),
false,
new NoOpMetricsSystem()),
mock(ProtocolContext.class), mock(ProtocolContext.class),
mock(FilterManager.class), mock(FilterManager.class),
mock(TransactionPool.class), mock(TransactionPool.class),

@ -111,7 +111,9 @@ class JsonRpcHttpServiceTlsMisconfigurationTest {
MainnetProtocolSchedule.fromConfig( MainnetProtocolSchedule.fromConfig(
new StubGenesisConfigOptions().constantinopleBlock(0).chainId(CHAIN_ID), new StubGenesisConfigOptions().constantinopleBlock(0).chainId(CHAIN_ID),
MiningParameters.MINING_DISABLED, MiningParameters.MINING_DISABLED,
new BadBlockManager()), new BadBlockManager(),
false,
new NoOpMetricsSystem()),
mock(ProtocolContext.class), mock(ProtocolContext.class),
mock(FilterManager.class), mock(FilterManager.class),
mock(TransactionPool.class), mock(TransactionPool.class),

@ -112,7 +112,9 @@ public class JsonRpcHttpServiceTlsTest {
MainnetProtocolSchedule.fromConfig( MainnetProtocolSchedule.fromConfig(
new StubGenesisConfigOptions().constantinopleBlock(0).chainId(CHAIN_ID), new StubGenesisConfigOptions().constantinopleBlock(0).chainId(CHAIN_ID),
MiningParameters.MINING_DISABLED, MiningParameters.MINING_DISABLED,
new BadBlockManager()), new BadBlockManager(),
false,
new NoOpMetricsSystem()),
mock(ProtocolContext.class), mock(ProtocolContext.class),
mock(FilterManager.class), mock(FilterManager.class),
mock(TransactionPool.class), mock(TransactionPool.class),

@ -176,7 +176,9 @@ public class WebSocketServiceLoginTest {
MainnetProtocolSchedule.fromConfig( MainnetProtocolSchedule.fromConfig(
genesisConfigOptions, genesisConfigOptions,
MiningParameters.MINING_DISABLED, MiningParameters.MINING_DISABLED,
new BadBlockManager()), new BadBlockManager(),
false,
new NoOpMetricsSystem()),
mock(ProtocolContext.class), mock(ProtocolContext.class),
mock(FilterManager.class), mock(FilterManager.class),
mock(TransactionPool.class), mock(TransactionPool.class),

@ -395,7 +395,9 @@ abstract class AbstractBlockCreatorTest {
false, false,
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED, MiningParameters.MINING_DISABLED,
new BadBlockManager()) new BadBlockManager(),
false,
new NoOpMetricsSystem())
.createProtocolSchedule()) .createProtocolSchedule())
.build(); .build();

@ -223,7 +223,9 @@ public abstract class AbstractBlockTransactionSelectorTest {
GenesisConfigFile.fromResource("/dev.json").getConfigOptions(), GenesisConfigFile.fromResource("/dev.json").getConfigOptions(),
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED, MiningParameters.MINING_DISABLED,
new BadBlockManager()); new BadBlockManager(),
false,
new NoOpMetricsSystem());
final MainnetTransactionProcessor mainnetTransactionProcessor = final MainnetTransactionProcessor mainnetTransactionProcessor =
protocolSchedule.getByBlockHeader(blockHeader(0)).getTransactionProcessor(); protocolSchedule.getByBlockHeader(blockHeader(0)).getTransactionProcessor();

@ -36,6 +36,7 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ProtocolScheduleBuilder; import org.hyperledger.besu.ethereum.mainnet.ProtocolScheduleBuilder;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecAdapters; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecAdapters;
import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.evm.internal.EvmConfiguration;
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
import org.hyperledger.besu.testutil.TestClock; import org.hyperledger.besu.testutil.TestClock;
import org.hyperledger.besu.util.number.Fraction; import org.hyperledger.besu.util.number.Fraction;
@ -60,7 +61,9 @@ public class LegacyFeeMarketBlockTransactionSelectorTest
false, false,
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED, MiningParameters.MINING_DISABLED,
new BadBlockManager()) new BadBlockManager(),
false,
new NoOpMetricsSystem())
.createProtocolSchedule(); .createProtocolSchedule();
} }

@ -43,6 +43,7 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolScheduleBuilder;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecAdapters; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecAdapters;
import org.hyperledger.besu.ethereum.mainnet.ValidationResult; import org.hyperledger.besu.ethereum.mainnet.ValidationResult;
import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.evm.internal.EvmConfiguration;
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
import org.hyperledger.besu.plugin.data.TransactionSelectionResult; import org.hyperledger.besu.plugin.data.TransactionSelectionResult;
import org.hyperledger.besu.testutil.TestClock; import org.hyperledger.besu.testutil.TestClock;
import org.hyperledger.besu.util.number.Fraction; import org.hyperledger.besu.util.number.Fraction;
@ -71,7 +72,9 @@ public class LondonFeeMarketBlockTransactionSelectorTest
false, false,
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED, MiningParameters.MINING_DISABLED,
new BadBlockManager()) new BadBlockManager(),
false,
new NoOpMetricsSystem())
.createProtocolSchedule(); .createProtocolSchedule();
} }

@ -97,8 +97,10 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest {
PrivacyParameters.DEFAULT, PrivacyParameters.DEFAULT,
false, false,
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
miningParameters, MiningParameters.MINING_DISABLED,
new BadBlockManager()) new BadBlockManager(),
false,
new NoOpMetricsSystem())
.createProtocolSchedule()) .createProtocolSchedule())
.build(); .build();
@ -158,8 +160,10 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest {
PrivacyParameters.DEFAULT, PrivacyParameters.DEFAULT,
false, false,
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
miningParameters, MiningParameters.MINING_DISABLED,
new BadBlockManager()) new BadBlockManager(),
false,
new NoOpMetricsSystem())
.createProtocolSchedule()) .createProtocolSchedule())
.build(); .build();
@ -209,8 +213,10 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest {
PrivacyParameters.DEFAULT, PrivacyParameters.DEFAULT,
false, false,
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
miningParameters, MiningParameters.MINING_DISABLED,
new BadBlockManager()) new BadBlockManager(),
false,
new NoOpMetricsSystem())
.createProtocolSchedule(); .createProtocolSchedule();
final ExecutionContextTestFixture executionContextTestFixture = final ExecutionContextTestFixture executionContextTestFixture =
ExecutionContextTestFixture.builder(genesisConfigFile) ExecutionContextTestFixture.builder(genesisConfigFile)
@ -285,8 +291,10 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest {
PrivacyParameters.DEFAULT, PrivacyParameters.DEFAULT,
false, false,
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
miningParameters, MiningParameters.MINING_DISABLED,
new BadBlockManager()) new BadBlockManager(),
false,
new NoOpMetricsSystem())
.createProtocolSchedule(); .createProtocolSchedule();
final ExecutionContextTestFixture executionContextTestFixture = final ExecutionContextTestFixture executionContextTestFixture =
ExecutionContextTestFixture.builder(genesisConfigFile) ExecutionContextTestFixture.builder(genesisConfigFile)

@ -22,6 +22,7 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ProtocolScheduleBuilder; import org.hyperledger.besu.ethereum.mainnet.ProtocolScheduleBuilder;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecAdapters; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecAdapters;
import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.evm.internal.EvmConfiguration;
import org.hyperledger.besu.plugin.services.MetricsSystem;
/** A ProtocolSchedule which behaves similarly to MainNet, but with a much reduced difficulty. */ /** A ProtocolSchedule which behaves similarly to MainNet, but with a much reduced difficulty. */
public class FixedDifficultyProtocolSchedule { public class FixedDifficultyProtocolSchedule {
@ -32,7 +33,9 @@ public class FixedDifficultyProtocolSchedule {
final boolean isRevertReasonEnabled, final boolean isRevertReasonEnabled,
final EvmConfiguration evmConfiguration, final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters, final MiningParameters miningParameters,
final BadBlockManager badBlockManager) { final BadBlockManager badBlockManager,
final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
return new ProtocolScheduleBuilder( return new ProtocolScheduleBuilder(
config, config,
ProtocolSpecAdapters.create( ProtocolSpecAdapters.create(
@ -43,7 +46,9 @@ public class FixedDifficultyProtocolSchedule {
isRevertReasonEnabled, isRevertReasonEnabled,
evmConfiguration, evmConfiguration,
miningParameters, miningParameters,
badBlockManager) badBlockManager,
isParallelTxProcessingEnabled,
metricsSystem)
.createProtocolSchedule(); .createProtocolSchedule();
} }
@ -52,27 +57,35 @@ public class FixedDifficultyProtocolSchedule {
final boolean isRevertReasonEnabled, final boolean isRevertReasonEnabled,
final EvmConfiguration evmConfiguration, final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters, final MiningParameters miningParameters,
final BadBlockManager badBlockManager) { final BadBlockManager badBlockManager,
final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
return create( return create(
config, config,
PrivacyParameters.DEFAULT, PrivacyParameters.DEFAULT,
isRevertReasonEnabled, isRevertReasonEnabled,
evmConfiguration, evmConfiguration,
miningParameters, miningParameters,
badBlockManager); badBlockManager,
isParallelTxProcessingEnabled,
metricsSystem);
} }
public static ProtocolSchedule create( public static ProtocolSchedule create(
final GenesisConfigOptions config, final GenesisConfigOptions config,
final EvmConfiguration evmConfiguration, final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters, final MiningParameters miningParameters,
final BadBlockManager badBlockManager) { final BadBlockManager badBlockManager,
final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
return create( return create(
config, config,
PrivacyParameters.DEFAULT, PrivacyParameters.DEFAULT,
false, false,
evmConfiguration, evmConfiguration,
miningParameters, miningParameters,
badBlockManager); badBlockManager,
isParallelTxProcessingEnabled,
metricsSystem);
} }
} }

@ -38,6 +38,7 @@ import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.worldview.BonsaiWorld
import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.worldview.BonsaiWorldStateUpdateAccumulator; import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.worldview.BonsaiWorldStateUpdateAccumulator;
import org.hyperledger.besu.ethereum.vm.CachingBlockHashLookup; import org.hyperledger.besu.ethereum.vm.CachingBlockHashLookup;
import org.hyperledger.besu.evm.gascalculator.CancunGasCalculator; import org.hyperledger.besu.evm.gascalculator.CancunGasCalculator;
import org.hyperledger.besu.evm.operation.BlockHashOperation;
import org.hyperledger.besu.evm.tracing.OperationTracer; import org.hyperledger.besu.evm.tracing.OperationTracer;
import org.hyperledger.besu.evm.worldstate.WorldState; import org.hyperledger.besu.evm.worldstate.WorldState;
import org.hyperledger.besu.evm.worldstate.WorldUpdater; import org.hyperledger.besu.evm.worldstate.WorldUpdater;
@ -110,57 +111,67 @@ public abstract class AbstractBlockProcessor implements BlockProcessor {
protocolSpec.getBlockHashProcessor().processBlockHashes(blockchain, worldState, blockHeader); protocolSpec.getBlockHashProcessor().processBlockHashes(blockchain, worldState, blockHeader);
final BlockHashLookup blockHashLookup = new CachingBlockHashLookup(blockHeader, blockchain); final BlockHashLookup blockHashLookup = new CachingBlockHashLookup(blockHeader, blockchain);
for (final Transaction transaction : transactions) { final Address miningBeneficiary = miningBeneficiaryCalculator.calculateBeneficiary(blockHeader);
Optional<BlockHeader> maybeParentHeader =
blockchain.getBlockHeader(blockHeader.getParentHash());
Wei blobGasPrice =
maybeParentHeader
.map(
parentHeader ->
protocolSpec
.getFeeMarket()
.blobGasPricePerGas(
calculateExcessBlobGasForParent(protocolSpec, parentHeader)))
.orElse(Wei.ZERO);
final Optional<PreprocessingContext> preProcessingContext =
runBlockPreProcessing(
worldState,
privateMetadataUpdater,
blockHeader,
transactions,
miningBeneficiary,
blockHashLookup,
blobGasPrice);
for (int i = 0; i < transactions.size(); i++) {
final Transaction transaction = transactions.get(i);
if (!hasAvailableBlockBudget(blockHeader, transaction, currentGasUsed)) { if (!hasAvailableBlockBudget(blockHeader, transaction, currentGasUsed)) {
return new BlockProcessingResult(Optional.empty(), "provided gas insufficient"); return new BlockProcessingResult(Optional.empty(), "provided gas insufficient");
} }
final WorldUpdater blockUpdater = worldState.updater();
final WorldUpdater worldStateUpdater = worldState.updater(); TransactionProcessingResult transactionProcessingResult =
getTransactionProcessingResult(
final Address miningBeneficiary = preProcessingContext,
miningBeneficiaryCalculator.calculateBeneficiary(blockHeader); worldState,
blockUpdater,
Optional<BlockHeader> maybeParentHeader = privateMetadataUpdater,
blockchain.getBlockHeader(blockHeader.getParentHash());
Wei blobGasPrice =
maybeParentHeader
.map(
parentHeader ->
protocolSpec
.getFeeMarket()
.blobGasPricePerGas(
calculateExcessBlobGasForParent(protocolSpec, parentHeader)))
.orElse(Wei.ZERO);
final TransactionProcessingResult result =
transactionProcessor.processTransaction(
worldStateUpdater,
blockHeader, blockHeader,
transaction, blobGasPrice,
miningBeneficiary, miningBeneficiary,
OperationTracer.NO_TRACING, transaction,
blockHashLookup, i,
true, blockHashLookup);
TransactionValidationParams.processingBlock(), if (transactionProcessingResult.isInvalid()) {
privateMetadataUpdater,
blobGasPrice);
if (result.isInvalid()) {
String errorMessage = String errorMessage =
MessageFormat.format( MessageFormat.format(
"Block processing error: transaction invalid {0}. Block {1} Transaction {2}", "Block processing error: transaction invalid {0}. Block {1} Transaction {2}",
result.getValidationResult().getErrorMessage(), transactionProcessingResult.getValidationResult().getErrorMessage(),
blockHeader.getHash().toHexString(), blockHeader.getHash().toHexString(),
transaction.getHash().toHexString()); transaction.getHash().toHexString());
LOG.info(errorMessage); LOG.info(errorMessage);
if (worldState instanceof BonsaiWorldState) { if (worldState instanceof BonsaiWorldState) {
((BonsaiWorldStateUpdateAccumulator) worldStateUpdater).reset(); ((BonsaiWorldStateUpdateAccumulator) blockUpdater).reset();
} }
return new BlockProcessingResult(Optional.empty(), errorMessage); return new BlockProcessingResult(Optional.empty(), errorMessage);
} }
worldStateUpdater.commit();
currentGasUsed += transaction.getGasLimit() - result.getGasRemaining(); blockUpdater.commit();
currentGasUsed += transaction.getGasLimit() - transactionProcessingResult.getGasRemaining();
if (transaction.getVersionedHashes().isPresent()) { if (transaction.getVersionedHashes().isPresent()) {
currentBlobGasUsed += currentBlobGasUsed +=
(transaction.getVersionedHashes().get().size() * CancunGasCalculator.BLOB_GAS_PER_BLOB); (transaction.getVersionedHashes().get().size() * CancunGasCalculator.BLOB_GAS_PER_BLOB);
@ -168,7 +179,7 @@ public abstract class AbstractBlockProcessor implements BlockProcessor {
final TransactionReceipt transactionReceipt = final TransactionReceipt transactionReceipt =
transactionReceiptFactory.create( transactionReceiptFactory.create(
transaction.getType(), result, worldState, currentGasUsed); transaction.getType(), transactionProcessingResult, worldState, currentGasUsed);
receipts.add(transactionReceipt); receipts.add(transactionReceipt);
} }
if (blockHeader.getBlobGasUsed().isPresent() if (blockHeader.getBlobGasUsed().isPresent()
@ -235,6 +246,41 @@ public abstract class AbstractBlockProcessor implements BlockProcessor {
Optional.of(new BlockProcessingOutputs(worldState, receipts, maybeRequests))); Optional.of(new BlockProcessingOutputs(worldState, receipts, maybeRequests)));
} }
protected Optional<PreprocessingContext> runBlockPreProcessing(
final MutableWorldState worldState,
final PrivateMetadataUpdater privateMetadataUpdater,
final BlockHeader blockHeader,
final List<Transaction> transactions,
final Address miningBeneficiary,
final BlockHashOperation.BlockHashLookup blockHashLookup,
final Wei blobGasPrice) {
return Optional.empty();
}
protected TransactionProcessingResult getTransactionProcessingResult(
final Optional<PreprocessingContext> preProcessingContext,
final MutableWorldState worldState,
final WorldUpdater blockUpdater,
final PrivateMetadataUpdater privateMetadataUpdater,
final BlockHeader blockHeader,
final Wei blobGasPrice,
final Address miningBeneficiary,
final Transaction transaction,
final int location,
final BlockHashLookup blockHashLookup) {
return transactionProcessor.processTransaction(
blockUpdater,
blockHeader,
transaction,
miningBeneficiary,
OperationTracer.NO_TRACING,
blockHashLookup,
true,
TransactionValidationParams.processingBlock(),
privateMetadataUpdater,
blobGasPrice);
}
protected boolean hasAvailableBlockBudget( protected boolean hasAvailableBlockBudget(
final BlockHeader blockHeader, final Transaction transaction, final long currentGasUsed) { final BlockHeader blockHeader, final Transaction transaction, final long currentGasUsed) {
final long remainingGasBudget = blockHeader.getGasLimit() - currentGasUsed; final long remainingGasBudget = blockHeader.getGasLimit() - currentGasUsed;
@ -261,4 +307,7 @@ public abstract class AbstractBlockProcessor implements BlockProcessor {
final BlockHeader header, final BlockHeader header,
final List<BlockHeader> ommers, final List<BlockHeader> ommers,
final boolean skipZeroBlockRewards); final boolean skipZeroBlockRewards);
public interface PreprocessingContext {}
;
} }

@ -38,6 +38,7 @@ import org.hyperledger.besu.evm.internal.EvmConfiguration;
import org.hyperledger.besu.evm.processor.ContractCreationProcessor; import org.hyperledger.besu.evm.processor.ContractCreationProcessor;
import org.hyperledger.besu.evm.processor.MessageCallProcessor; import org.hyperledger.besu.evm.processor.MessageCallProcessor;
import org.hyperledger.besu.evm.worldstate.WorldState; import org.hyperledger.besu.evm.worldstate.WorldState;
import org.hyperledger.besu.plugin.services.MetricsSystem;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.Collections; import java.util.Collections;
@ -54,16 +55,23 @@ public class ClassicProtocolSpecs {
} }
public static ProtocolSpecBuilder classicRecoveryInitDefinition( public static ProtocolSpecBuilder classicRecoveryInitDefinition(
final EvmConfiguration evmConfiguration) { final EvmConfiguration evmConfiguration,
return MainnetProtocolSpecs.homesteadDefinition(evmConfiguration) final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
return MainnetProtocolSpecs.homesteadDefinition(
evmConfiguration, isParallelTxProcessingEnabled, metricsSystem)
.blockHeaderValidatorBuilder( .blockHeaderValidatorBuilder(
feeMarket -> MainnetBlockHeaderValidator.createClassicValidator()) feeMarket -> MainnetBlockHeaderValidator.createClassicValidator())
.name("ClassicRecoveryInit"); .name("ClassicRecoveryInit");
} }
public static ProtocolSpecBuilder tangerineWhistleDefinition( public static ProtocolSpecBuilder tangerineWhistleDefinition(
final Optional<BigInteger> chainId, final EvmConfiguration evmConfiguration) { final Optional<BigInteger> chainId,
return MainnetProtocolSpecs.homesteadDefinition(evmConfiguration) final EvmConfiguration evmConfiguration,
final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
return MainnetProtocolSpecs.homesteadDefinition(
evmConfiguration, isParallelTxProcessingEnabled, metricsSystem)
.isReplayProtectionSupported(true) .isReplayProtectionSupported(true)
.gasCalculator(TangerineWhistleGasCalculator::new) .gasCalculator(TangerineWhistleGasCalculator::new)
.transactionValidatorFactoryBuilder( .transactionValidatorFactoryBuilder(
@ -74,8 +82,12 @@ public class ClassicProtocolSpecs {
} }
public static ProtocolSpecBuilder dieHardDefinition( public static ProtocolSpecBuilder dieHardDefinition(
final Optional<BigInteger> chainId, final EvmConfiguration evmConfiguration) { final Optional<BigInteger> chainId,
return tangerineWhistleDefinition(chainId, evmConfiguration) final EvmConfiguration evmConfiguration,
final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
return tangerineWhistleDefinition(
chainId, evmConfiguration, isParallelTxProcessingEnabled, metricsSystem)
.gasCalculator(DieHardGasCalculator::new) .gasCalculator(DieHardGasCalculator::new)
.difficultyCalculator(ClassicDifficultyCalculators.DIFFICULTY_BOMB_PAUSED) .difficultyCalculator(ClassicDifficultyCalculators.DIFFICULTY_BOMB_PAUSED)
.name("DieHard"); .name("DieHard");
@ -84,8 +96,11 @@ public class ClassicProtocolSpecs {
public static ProtocolSpecBuilder gothamDefinition( public static ProtocolSpecBuilder gothamDefinition(
final Optional<BigInteger> chainId, final Optional<BigInteger> chainId,
final OptionalLong ecip1017EraRounds, final OptionalLong ecip1017EraRounds,
final EvmConfiguration evmConfiguration) { final EvmConfiguration evmConfiguration,
return dieHardDefinition(chainId, evmConfiguration) final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
return dieHardDefinition(
chainId, evmConfiguration, isParallelTxProcessingEnabled, metricsSystem)
.blockReward(MAX_BLOCK_REWARD) .blockReward(MAX_BLOCK_REWARD)
.difficultyCalculator(ClassicDifficultyCalculators.DIFFICULTY_BOMB_DELAYED) .difficultyCalculator(ClassicDifficultyCalculators.DIFFICULTY_BOMB_DELAYED)
.blockProcessorBuilder( .blockProcessorBuilder(
@ -109,8 +124,15 @@ public class ClassicProtocolSpecs {
public static ProtocolSpecBuilder defuseDifficultyBombDefinition( public static ProtocolSpecBuilder defuseDifficultyBombDefinition(
final Optional<BigInteger> chainId, final Optional<BigInteger> chainId,
final OptionalLong ecip1017EraRounds, final OptionalLong ecip1017EraRounds,
final EvmConfiguration evmConfiguration) { final EvmConfiguration evmConfiguration,
return gothamDefinition(chainId, ecip1017EraRounds, evmConfiguration) final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
return gothamDefinition(
chainId,
ecip1017EraRounds,
evmConfiguration,
isParallelTxProcessingEnabled,
metricsSystem)
.difficultyCalculator(ClassicDifficultyCalculators.DIFFICULTY_BOMB_REMOVED) .difficultyCalculator(ClassicDifficultyCalculators.DIFFICULTY_BOMB_REMOVED)
.transactionValidatorFactoryBuilder( .transactionValidatorFactoryBuilder(
(evm, gasLimitCalculator, feeMarket) -> (evm, gasLimitCalculator, feeMarket) ->
@ -123,8 +145,15 @@ public class ClassicProtocolSpecs {
final Optional<BigInteger> chainId, final Optional<BigInteger> chainId,
final boolean enableRevertReason, final boolean enableRevertReason,
final OptionalLong ecip1017EraRounds, final OptionalLong ecip1017EraRounds,
final EvmConfiguration evmConfiguration) { final EvmConfiguration evmConfiguration,
return gothamDefinition(chainId, ecip1017EraRounds, evmConfiguration) final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
return gothamDefinition(
chainId,
ecip1017EraRounds,
evmConfiguration,
isParallelTxProcessingEnabled,
metricsSystem)
.evmBuilder(MainnetEVMs::byzantium) .evmBuilder(MainnetEVMs::byzantium)
.evmConfiguration(evmConfiguration) .evmConfiguration(evmConfiguration)
.gasCalculator(SpuriousDragonGasCalculator::new) .gasCalculator(SpuriousDragonGasCalculator::new)
@ -163,8 +192,16 @@ public class ClassicProtocolSpecs {
final Optional<BigInteger> chainId, final Optional<BigInteger> chainId,
final boolean enableRevertReason, final boolean enableRevertReason,
final OptionalLong ecip1017EraRounds, final OptionalLong ecip1017EraRounds,
final EvmConfiguration evmConfiguration) { final EvmConfiguration evmConfiguration,
return atlantisDefinition(chainId, enableRevertReason, ecip1017EraRounds, evmConfiguration) final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
return atlantisDefinition(
chainId,
enableRevertReason,
ecip1017EraRounds,
evmConfiguration,
isParallelTxProcessingEnabled,
metricsSystem)
.evmBuilder(MainnetEVMs::constantinople) .evmBuilder(MainnetEVMs::constantinople)
.gasCalculator(PetersburgGasCalculator::new) .gasCalculator(PetersburgGasCalculator::new)
.evmBuilder(MainnetEVMs::constantinople) .evmBuilder(MainnetEVMs::constantinople)
@ -176,8 +213,16 @@ public class ClassicProtocolSpecs {
final Optional<BigInteger> chainId, final Optional<BigInteger> chainId,
final boolean enableRevertReason, final boolean enableRevertReason,
final OptionalLong ecip1017EraRounds, final OptionalLong ecip1017EraRounds,
final EvmConfiguration evmConfiguration) { final EvmConfiguration evmConfiguration,
return aghartaDefinition(chainId, enableRevertReason, ecip1017EraRounds, evmConfiguration) final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
return aghartaDefinition(
chainId,
enableRevertReason,
ecip1017EraRounds,
evmConfiguration,
isParallelTxProcessingEnabled,
metricsSystem)
.gasCalculator(IstanbulGasCalculator::new) .gasCalculator(IstanbulGasCalculator::new)
.evmBuilder( .evmBuilder(
(gasCalculator, evmConfig) -> (gasCalculator, evmConfig) ->
@ -191,8 +236,16 @@ public class ClassicProtocolSpecs {
final Optional<BigInteger> chainId, final Optional<BigInteger> chainId,
final boolean enableRevertReason, final boolean enableRevertReason,
final OptionalLong ecip1017EraRounds, final OptionalLong ecip1017EraRounds,
final EvmConfiguration evmConfiguration) { final EvmConfiguration evmConfiguration,
return phoenixDefinition(chainId, enableRevertReason, ecip1017EraRounds, evmConfiguration) final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
return phoenixDefinition(
chainId,
enableRevertReason,
ecip1017EraRounds,
evmConfiguration,
isParallelTxProcessingEnabled,
metricsSystem)
.blockHeaderValidatorBuilder( .blockHeaderValidatorBuilder(
feeMarket -> feeMarket ->
MainnetBlockHeaderValidator.createPgaBlockHeaderValidator( MainnetBlockHeaderValidator.createPgaBlockHeaderValidator(
@ -228,8 +281,16 @@ public class ClassicProtocolSpecs {
final Optional<BigInteger> chainId, final Optional<BigInteger> chainId,
final boolean enableRevertReason, final boolean enableRevertReason,
final OptionalLong ecip1017EraRounds, final OptionalLong ecip1017EraRounds,
final EvmConfiguration evmConfiguration) { final EvmConfiguration evmConfiguration,
return thanosDefinition(chainId, enableRevertReason, ecip1017EraRounds, evmConfiguration) final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
return thanosDefinition(
chainId,
enableRevertReason,
ecip1017EraRounds,
evmConfiguration,
isParallelTxProcessingEnabled,
metricsSystem)
.gasCalculator(BerlinGasCalculator::new) .gasCalculator(BerlinGasCalculator::new)
.transactionValidatorFactoryBuilder( .transactionValidatorFactoryBuilder(
(evm, gasLimitCalculator, feeMarket) -> (evm, gasLimitCalculator, feeMarket) ->
@ -250,8 +311,16 @@ public class ClassicProtocolSpecs {
final Optional<BigInteger> chainId, final Optional<BigInteger> chainId,
final boolean enableRevertReason, final boolean enableRevertReason,
final OptionalLong ecip1017EraRounds, final OptionalLong ecip1017EraRounds,
final EvmConfiguration evmConfiguration) { final EvmConfiguration evmConfiguration,
return magnetoDefinition(chainId, enableRevertReason, ecip1017EraRounds, evmConfiguration) final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
return magnetoDefinition(
chainId,
enableRevertReason,
ecip1017EraRounds,
evmConfiguration,
isParallelTxProcessingEnabled,
metricsSystem)
.gasCalculator(LondonGasCalculator::new) .gasCalculator(LondonGasCalculator::new)
.contractCreationProcessorBuilder( .contractCreationProcessorBuilder(
evm -> evm ->
@ -264,8 +333,16 @@ public class ClassicProtocolSpecs {
final Optional<BigInteger> chainId, final Optional<BigInteger> chainId,
final boolean enableRevertReason, final boolean enableRevertReason,
final OptionalLong ecip1017EraRounds, final OptionalLong ecip1017EraRounds,
final EvmConfiguration evmConfiguration) { final EvmConfiguration evmConfiguration,
return mystiqueDefinition(chainId, enableRevertReason, ecip1017EraRounds, evmConfiguration) final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
return mystiqueDefinition(
chainId,
enableRevertReason,
ecip1017EraRounds,
evmConfiguration,
isParallelTxProcessingEnabled,
metricsSystem)
// EIP-3860 // EIP-3860
.gasCalculator(ShanghaiGasCalculator::new) .gasCalculator(ShanghaiGasCalculator::new)
// EIP-3855 // EIP-3855

@ -21,6 +21,7 @@ import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.ethereum.difficulty.fixed.FixedDifficultyCalculators; import org.hyperledger.besu.ethereum.difficulty.fixed.FixedDifficultyCalculators;
import org.hyperledger.besu.ethereum.difficulty.fixed.FixedDifficultyProtocolSchedule; import org.hyperledger.besu.ethereum.difficulty.fixed.FixedDifficultyProtocolSchedule;
import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.evm.internal.EvmConfiguration;
import org.hyperledger.besu.plugin.services.MetricsSystem;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.function.Function; import java.util.function.Function;
@ -40,6 +41,8 @@ public class MainnetProtocolSchedule {
* @param evmConfiguration how to configure the EVMs jumpdest cache * @param evmConfiguration how to configure the EVMs jumpdest cache
* @param miningParameters the mining parameters * @param miningParameters the mining parameters
* @param badBlockManager the cache to use to keep invalid blocks * @param badBlockManager the cache to use to keep invalid blocks
* @param isParallelTxProcessingEnabled indicates whether parallel transaction is enabled
* @param metricsSystem A metricSystem instance to expose metrics in the underlying calls
* @return A configured mainnet protocol schedule * @return A configured mainnet protocol schedule
*/ */
public static ProtocolSchedule fromConfig( public static ProtocolSchedule fromConfig(
@ -48,7 +51,9 @@ public class MainnetProtocolSchedule {
final boolean isRevertReasonEnabled, final boolean isRevertReasonEnabled,
final EvmConfiguration evmConfiguration, final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters, final MiningParameters miningParameters,
final BadBlockManager badBlockManager) { final BadBlockManager badBlockManager,
final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
if (FixedDifficultyCalculators.isFixedDifficultyInConfig(config)) { if (FixedDifficultyCalculators.isFixedDifficultyInConfig(config)) {
return FixedDifficultyProtocolSchedule.create( return FixedDifficultyProtocolSchedule.create(
config, config,
@ -56,7 +61,9 @@ public class MainnetProtocolSchedule {
isRevertReasonEnabled, isRevertReasonEnabled,
evmConfiguration, evmConfiguration,
miningParameters, miningParameters,
badBlockManager); badBlockManager,
isParallelTxProcessingEnabled,
metricsSystem);
} }
return new ProtocolScheduleBuilder( return new ProtocolScheduleBuilder(
config, config,
@ -66,7 +73,9 @@ public class MainnetProtocolSchedule {
isRevertReasonEnabled, isRevertReasonEnabled,
evmConfiguration, evmConfiguration,
miningParameters, miningParameters,
badBlockManager) badBlockManager,
isParallelTxProcessingEnabled,
metricsSystem)
.createProtocolSchedule(); .createProtocolSchedule();
} }
@ -79,6 +88,7 @@ public class MainnetProtocolSchedule {
* @param evmConfiguration how to configure the EVMs jumpdest cache * @param evmConfiguration how to configure the EVMs jumpdest cache
* @param miningParameters the mining parameters * @param miningParameters the mining parameters
* @param badBlockManager the cache to use to keep invalid blocks * @param badBlockManager the cache to use to keep invalid blocks
* @param isParallelTxProcessingEnabled indicates whether parallel transaction is enabled.
* @return A configured mainnet protocol schedule * @return A configured mainnet protocol schedule
*/ */
public static ProtocolSchedule fromConfig( public static ProtocolSchedule fromConfig(
@ -86,14 +96,18 @@ public class MainnetProtocolSchedule {
final boolean isRevertReasonEnabled, final boolean isRevertReasonEnabled,
final EvmConfiguration evmConfiguration, final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters, final MiningParameters miningParameters,
final BadBlockManager badBlockManager) { final BadBlockManager badBlockManager,
final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
return fromConfig( return fromConfig(
config, config,
PrivacyParameters.DEFAULT, PrivacyParameters.DEFAULT,
isRevertReasonEnabled, isRevertReasonEnabled,
evmConfiguration, evmConfiguration,
miningParameters, miningParameters,
badBlockManager); badBlockManager,
isParallelTxProcessingEnabled,
metricsSystem);
} }
/** /**
@ -104,20 +118,25 @@ public class MainnetProtocolSchedule {
* @param evmConfiguration size of * @param evmConfiguration size of
* @param miningParameters the mining parameters * @param miningParameters the mining parameters
* @param badBlockManager the cache to use to keep invalid blocks * @param badBlockManager the cache to use to keep invalid blocks
* @param isParallelTxProcessingEnabled indicates whether parallel transaction is enabled.
* @return A configured mainnet protocol schedule * @return A configured mainnet protocol schedule
*/ */
public static ProtocolSchedule fromConfig( public static ProtocolSchedule fromConfig(
final GenesisConfigOptions config, final GenesisConfigOptions config,
final EvmConfiguration evmConfiguration, final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters, final MiningParameters miningParameters,
final BadBlockManager badBlockManager) { final BadBlockManager badBlockManager,
final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
return fromConfig( return fromConfig(
config, config,
PrivacyParameters.DEFAULT, PrivacyParameters.DEFAULT,
false, false,
evmConfiguration, evmConfiguration,
miningParameters, miningParameters,
badBlockManager); badBlockManager,
isParallelTxProcessingEnabled,
metricsSystem);
} }
/** /**
@ -127,18 +146,23 @@ public class MainnetProtocolSchedule {
* starting points * starting points
* @param miningParameters the mining parameters * @param miningParameters the mining parameters
* @param badBlockManager the cache to use to keep invalid blocks * @param badBlockManager the cache to use to keep invalid blocks
* @param isParallelTxProcessingEnabled indicates whether parallel transaction is enabled.
* @return A configured mainnet protocol schedule * @return A configured mainnet protocol schedule
*/ */
public static ProtocolSchedule fromConfig( public static ProtocolSchedule fromConfig(
final GenesisConfigOptions config, final GenesisConfigOptions config,
final MiningParameters miningParameters, final MiningParameters miningParameters,
final BadBlockManager badBlockManager) { final BadBlockManager badBlockManager,
final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
return fromConfig( return fromConfig(
config, config,
PrivacyParameters.DEFAULT, PrivacyParameters.DEFAULT,
false, false,
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
miningParameters, miningParameters,
badBlockManager); badBlockManager,
isParallelTxProcessingEnabled,
metricsSystem);
} }
} }

@ -17,6 +17,7 @@ package org.hyperledger.besu.ethereum.mainnet;
import org.hyperledger.besu.config.GenesisConfigOptions; import org.hyperledger.besu.config.GenesisConfigOptions;
import org.hyperledger.besu.ethereum.core.MiningParameters; import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.evm.internal.EvmConfiguration;
import org.hyperledger.besu.plugin.services.MetricsSystem;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.Optional; import java.util.Optional;
@ -29,118 +30,209 @@ public class MainnetProtocolSpecFactory {
private final OptionalLong ecip1017EraRounds; private final OptionalLong ecip1017EraRounds;
private final EvmConfiguration evmConfiguration; private final EvmConfiguration evmConfiguration;
private final MiningParameters miningParameters; private final MiningParameters miningParameters;
private final boolean isParallelTxProcessingEnabled;
private final MetricsSystem metricsSystem;
public MainnetProtocolSpecFactory( public MainnetProtocolSpecFactory(
final Optional<BigInteger> chainId, final Optional<BigInteger> chainId,
final boolean isRevertReasonEnabled, final boolean isRevertReasonEnabled,
final OptionalLong ecip1017EraRounds, final OptionalLong ecip1017EraRounds,
final EvmConfiguration evmConfiguration, final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters) { final MiningParameters miningParameters,
final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
this.chainId = chainId; this.chainId = chainId;
this.isRevertReasonEnabled = isRevertReasonEnabled; this.isRevertReasonEnabled = isRevertReasonEnabled;
this.ecip1017EraRounds = ecip1017EraRounds; this.ecip1017EraRounds = ecip1017EraRounds;
this.evmConfiguration = evmConfiguration; this.evmConfiguration = evmConfiguration;
this.miningParameters = miningParameters; this.miningParameters = miningParameters;
this.isParallelTxProcessingEnabled = isParallelTxProcessingEnabled;
this.metricsSystem = metricsSystem;
} }
public ProtocolSpecBuilder frontierDefinition() { public ProtocolSpecBuilder frontierDefinition() {
return MainnetProtocolSpecs.frontierDefinition(evmConfiguration); return MainnetProtocolSpecs.frontierDefinition(
evmConfiguration, isParallelTxProcessingEnabled, metricsSystem);
} }
public ProtocolSpecBuilder homesteadDefinition() { public ProtocolSpecBuilder homesteadDefinition() {
return MainnetProtocolSpecs.homesteadDefinition(evmConfiguration); return MainnetProtocolSpecs.homesteadDefinition(
evmConfiguration, isParallelTxProcessingEnabled, metricsSystem);
} }
public ProtocolSpecBuilder daoRecoveryInitDefinition() { public ProtocolSpecBuilder daoRecoveryInitDefinition() {
return MainnetProtocolSpecs.daoRecoveryInitDefinition(evmConfiguration); return MainnetProtocolSpecs.daoRecoveryInitDefinition(
evmConfiguration, isParallelTxProcessingEnabled, metricsSystem);
} }
public ProtocolSpecBuilder daoRecoveryTransitionDefinition() { public ProtocolSpecBuilder daoRecoveryTransitionDefinition() {
return MainnetProtocolSpecs.daoRecoveryTransitionDefinition(evmConfiguration); return MainnetProtocolSpecs.daoRecoveryTransitionDefinition(
evmConfiguration, isParallelTxProcessingEnabled, metricsSystem);
} }
public ProtocolSpecBuilder tangerineWhistleDefinition() { public ProtocolSpecBuilder tangerineWhistleDefinition() {
return MainnetProtocolSpecs.tangerineWhistleDefinition(evmConfiguration); return MainnetProtocolSpecs.tangerineWhistleDefinition(
evmConfiguration, isParallelTxProcessingEnabled, metricsSystem);
} }
public ProtocolSpecBuilder spuriousDragonDefinition() { public ProtocolSpecBuilder spuriousDragonDefinition() {
return MainnetProtocolSpecs.spuriousDragonDefinition(chainId, evmConfiguration); return MainnetProtocolSpecs.spuriousDragonDefinition(
chainId, evmConfiguration, isParallelTxProcessingEnabled, metricsSystem);
} }
public ProtocolSpecBuilder byzantiumDefinition() { public ProtocolSpecBuilder byzantiumDefinition() {
return MainnetProtocolSpecs.byzantiumDefinition( return MainnetProtocolSpecs.byzantiumDefinition(
chainId, isRevertReasonEnabled, evmConfiguration); chainId,
isRevertReasonEnabled,
evmConfiguration,
isParallelTxProcessingEnabled,
metricsSystem);
} }
public ProtocolSpecBuilder constantinopleDefinition() { public ProtocolSpecBuilder constantinopleDefinition() {
return MainnetProtocolSpecs.constantinopleDefinition( return MainnetProtocolSpecs.constantinopleDefinition(
chainId, isRevertReasonEnabled, evmConfiguration); chainId,
isRevertReasonEnabled,
evmConfiguration,
isParallelTxProcessingEnabled,
metricsSystem);
} }
public ProtocolSpecBuilder petersburgDefinition() { public ProtocolSpecBuilder petersburgDefinition() {
return MainnetProtocolSpecs.petersburgDefinition( return MainnetProtocolSpecs.petersburgDefinition(
chainId, isRevertReasonEnabled, evmConfiguration); chainId,
isRevertReasonEnabled,
evmConfiguration,
isParallelTxProcessingEnabled,
metricsSystem);
} }
public ProtocolSpecBuilder istanbulDefinition() { public ProtocolSpecBuilder istanbulDefinition() {
return MainnetProtocolSpecs.istanbulDefinition( return MainnetProtocolSpecs.istanbulDefinition(
chainId, isRevertReasonEnabled, evmConfiguration); chainId,
isRevertReasonEnabled,
evmConfiguration,
isParallelTxProcessingEnabled,
metricsSystem);
} }
public ProtocolSpecBuilder muirGlacierDefinition() { public ProtocolSpecBuilder muirGlacierDefinition() {
return MainnetProtocolSpecs.muirGlacierDefinition( return MainnetProtocolSpecs.muirGlacierDefinition(
chainId, isRevertReasonEnabled, evmConfiguration); chainId,
isRevertReasonEnabled,
evmConfiguration,
isParallelTxProcessingEnabled,
metricsSystem);
} }
public ProtocolSpecBuilder berlinDefinition() { public ProtocolSpecBuilder berlinDefinition() {
return MainnetProtocolSpecs.berlinDefinition(chainId, isRevertReasonEnabled, evmConfiguration); return MainnetProtocolSpecs.berlinDefinition(
chainId,
isRevertReasonEnabled,
evmConfiguration,
isParallelTxProcessingEnabled,
metricsSystem);
} }
public ProtocolSpecBuilder londonDefinition(final GenesisConfigOptions genesisConfigOptions) { public ProtocolSpecBuilder londonDefinition(final GenesisConfigOptions genesisConfigOptions) {
return MainnetProtocolSpecs.londonDefinition( return MainnetProtocolSpecs.londonDefinition(
chainId, isRevertReasonEnabled, genesisConfigOptions, evmConfiguration, miningParameters); chainId,
isRevertReasonEnabled,
genesisConfigOptions,
evmConfiguration,
miningParameters,
isParallelTxProcessingEnabled,
metricsSystem);
} }
public ProtocolSpecBuilder arrowGlacierDefinition( public ProtocolSpecBuilder arrowGlacierDefinition(
final GenesisConfigOptions genesisConfigOptions) { final GenesisConfigOptions genesisConfigOptions) {
return MainnetProtocolSpecs.arrowGlacierDefinition( return MainnetProtocolSpecs.arrowGlacierDefinition(
chainId, isRevertReasonEnabled, genesisConfigOptions, evmConfiguration, miningParameters); chainId,
isRevertReasonEnabled,
genesisConfigOptions,
evmConfiguration,
miningParameters,
isParallelTxProcessingEnabled,
metricsSystem);
} }
public ProtocolSpecBuilder grayGlacierDefinition( public ProtocolSpecBuilder grayGlacierDefinition(
final GenesisConfigOptions genesisConfigOptions) { final GenesisConfigOptions genesisConfigOptions) {
return MainnetProtocolSpecs.grayGlacierDefinition( return MainnetProtocolSpecs.grayGlacierDefinition(
chainId, isRevertReasonEnabled, genesisConfigOptions, evmConfiguration, miningParameters); chainId,
isRevertReasonEnabled,
genesisConfigOptions,
evmConfiguration,
miningParameters,
isParallelTxProcessingEnabled,
metricsSystem);
} }
public ProtocolSpecBuilder parisDefinition(final GenesisConfigOptions genesisConfigOptions) { public ProtocolSpecBuilder parisDefinition(final GenesisConfigOptions genesisConfigOptions) {
return MainnetProtocolSpecs.parisDefinition( return MainnetProtocolSpecs.parisDefinition(
chainId, isRevertReasonEnabled, genesisConfigOptions, evmConfiguration, miningParameters); chainId,
isRevertReasonEnabled,
genesisConfigOptions,
evmConfiguration,
miningParameters,
isParallelTxProcessingEnabled,
metricsSystem);
} }
public ProtocolSpecBuilder shanghaiDefinition(final GenesisConfigOptions genesisConfigOptions) { public ProtocolSpecBuilder shanghaiDefinition(final GenesisConfigOptions genesisConfigOptions) {
return MainnetProtocolSpecs.shanghaiDefinition( return MainnetProtocolSpecs.shanghaiDefinition(
chainId, isRevertReasonEnabled, genesisConfigOptions, evmConfiguration, miningParameters); chainId,
isRevertReasonEnabled,
genesisConfigOptions,
evmConfiguration,
miningParameters,
isParallelTxProcessingEnabled,
metricsSystem);
} }
public ProtocolSpecBuilder cancunDefinition(final GenesisConfigOptions genesisConfigOptions) { public ProtocolSpecBuilder cancunDefinition(final GenesisConfigOptions genesisConfigOptions) {
return MainnetProtocolSpecs.cancunDefinition( return MainnetProtocolSpecs.cancunDefinition(
chainId, isRevertReasonEnabled, genesisConfigOptions, evmConfiguration, miningParameters); chainId,
isRevertReasonEnabled,
genesisConfigOptions,
evmConfiguration,
miningParameters,
isParallelTxProcessingEnabled,
metricsSystem);
} }
public ProtocolSpecBuilder cancunEOFDefinition(final GenesisConfigOptions genesisConfigOptions) { public ProtocolSpecBuilder cancunEOFDefinition(final GenesisConfigOptions genesisConfigOptions) {
return MainnetProtocolSpecs.cancunEOFDefinition( return MainnetProtocolSpecs.cancunEOFDefinition(
chainId, isRevertReasonEnabled, genesisConfigOptions, evmConfiguration, miningParameters); chainId,
isRevertReasonEnabled,
genesisConfigOptions,
evmConfiguration,
miningParameters,
isParallelTxProcessingEnabled,
metricsSystem);
} }
public ProtocolSpecBuilder pragueDefinition(final GenesisConfigOptions genesisConfigOptions) { public ProtocolSpecBuilder pragueDefinition(final GenesisConfigOptions genesisConfigOptions) {
return MainnetProtocolSpecs.pragueDefinition( return MainnetProtocolSpecs.pragueDefinition(
chainId, isRevertReasonEnabled, genesisConfigOptions, evmConfiguration, miningParameters); chainId,
isRevertReasonEnabled,
genesisConfigOptions,
evmConfiguration,
miningParameters,
isParallelTxProcessingEnabled,
metricsSystem);
} }
public ProtocolSpecBuilder pragueEOFDefinition(final GenesisConfigOptions genesisConfigOptions) { public ProtocolSpecBuilder pragueEOFDefinition(final GenesisConfigOptions genesisConfigOptions) {
return MainnetProtocolSpecs.pragueEOFDefinition( return MainnetProtocolSpecs.pragueEOFDefinition(
chainId, isRevertReasonEnabled, genesisConfigOptions, evmConfiguration, miningParameters); chainId,
isRevertReasonEnabled,
genesisConfigOptions,
evmConfiguration,
miningParameters,
isParallelTxProcessingEnabled,
metricsSystem);
} }
/** /**
@ -156,7 +248,13 @@ public class MainnetProtocolSpecFactory {
*/ */
public ProtocolSpecBuilder futureEipsDefinition(final GenesisConfigOptions genesisConfigOptions) { public ProtocolSpecBuilder futureEipsDefinition(final GenesisConfigOptions genesisConfigOptions) {
return MainnetProtocolSpecs.futureEipsDefinition( return MainnetProtocolSpecs.futureEipsDefinition(
chainId, isRevertReasonEnabled, genesisConfigOptions, evmConfiguration, miningParameters); chainId,
isRevertReasonEnabled,
genesisConfigOptions,
evmConfiguration,
miningParameters,
isParallelTxProcessingEnabled,
metricsSystem);
} }
/** /**
@ -172,57 +270,100 @@ public class MainnetProtocolSpecFactory {
public ProtocolSpecBuilder experimentalEipsDefinition( public ProtocolSpecBuilder experimentalEipsDefinition(
final GenesisConfigOptions genesisConfigOptions) { final GenesisConfigOptions genesisConfigOptions) {
return MainnetProtocolSpecs.experimentalEipsDefinition( return MainnetProtocolSpecs.experimentalEipsDefinition(
chainId, isRevertReasonEnabled, genesisConfigOptions, evmConfiguration, miningParameters); chainId,
isRevertReasonEnabled,
genesisConfigOptions,
evmConfiguration,
miningParameters,
isParallelTxProcessingEnabled,
metricsSystem);
} }
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
// Classic Protocol Specs // Classic Protocol Specs
public ProtocolSpecBuilder dieHardDefinition() { public ProtocolSpecBuilder dieHardDefinition() {
return ClassicProtocolSpecs.dieHardDefinition(chainId, evmConfiguration); return ClassicProtocolSpecs.dieHardDefinition(
chainId, evmConfiguration, isParallelTxProcessingEnabled, metricsSystem);
} }
public ProtocolSpecBuilder gothamDefinition() { public ProtocolSpecBuilder gothamDefinition() {
return ClassicProtocolSpecs.gothamDefinition(chainId, ecip1017EraRounds, evmConfiguration); return ClassicProtocolSpecs.gothamDefinition(
chainId, ecip1017EraRounds, evmConfiguration, isParallelTxProcessingEnabled, metricsSystem);
} }
public ProtocolSpecBuilder defuseDifficultyBombDefinition() { public ProtocolSpecBuilder defuseDifficultyBombDefinition() {
return ClassicProtocolSpecs.defuseDifficultyBombDefinition( return ClassicProtocolSpecs.defuseDifficultyBombDefinition(
chainId, ecip1017EraRounds, evmConfiguration); chainId, ecip1017EraRounds, evmConfiguration, isParallelTxProcessingEnabled, metricsSystem);
} }
public ProtocolSpecBuilder atlantisDefinition() { public ProtocolSpecBuilder atlantisDefinition() {
return ClassicProtocolSpecs.atlantisDefinition( return ClassicProtocolSpecs.atlantisDefinition(
chainId, isRevertReasonEnabled, ecip1017EraRounds, evmConfiguration); chainId,
isRevertReasonEnabled,
ecip1017EraRounds,
evmConfiguration,
isParallelTxProcessingEnabled,
metricsSystem);
} }
public ProtocolSpecBuilder aghartaDefinition() { public ProtocolSpecBuilder aghartaDefinition() {
return ClassicProtocolSpecs.aghartaDefinition( return ClassicProtocolSpecs.aghartaDefinition(
chainId, isRevertReasonEnabled, ecip1017EraRounds, evmConfiguration); chainId,
isRevertReasonEnabled,
ecip1017EraRounds,
evmConfiguration,
isParallelTxProcessingEnabled,
metricsSystem);
} }
public ProtocolSpecBuilder phoenixDefinition() { public ProtocolSpecBuilder phoenixDefinition() {
return ClassicProtocolSpecs.phoenixDefinition( return ClassicProtocolSpecs.phoenixDefinition(
chainId, isRevertReasonEnabled, ecip1017EraRounds, evmConfiguration); chainId,
isRevertReasonEnabled,
ecip1017EraRounds,
evmConfiguration,
isParallelTxProcessingEnabled,
metricsSystem);
} }
public ProtocolSpecBuilder thanosDefinition() { public ProtocolSpecBuilder thanosDefinition() {
return ClassicProtocolSpecs.thanosDefinition( return ClassicProtocolSpecs.thanosDefinition(
chainId, isRevertReasonEnabled, ecip1017EraRounds, evmConfiguration); chainId,
isRevertReasonEnabled,
ecip1017EraRounds,
evmConfiguration,
isParallelTxProcessingEnabled,
metricsSystem);
} }
public ProtocolSpecBuilder magnetoDefinition() { public ProtocolSpecBuilder magnetoDefinition() {
return ClassicProtocolSpecs.magnetoDefinition( return ClassicProtocolSpecs.magnetoDefinition(
chainId, isRevertReasonEnabled, ecip1017EraRounds, evmConfiguration); chainId,
isRevertReasonEnabled,
ecip1017EraRounds,
evmConfiguration,
isParallelTxProcessingEnabled,
metricsSystem);
} }
public ProtocolSpecBuilder mystiqueDefinition() { public ProtocolSpecBuilder mystiqueDefinition() {
return ClassicProtocolSpecs.mystiqueDefinition( return ClassicProtocolSpecs.mystiqueDefinition(
chainId, isRevertReasonEnabled, ecip1017EraRounds, evmConfiguration); chainId,
isRevertReasonEnabled,
ecip1017EraRounds,
evmConfiguration,
isParallelTxProcessingEnabled,
metricsSystem);
} }
public ProtocolSpecBuilder spiralDefinition() { public ProtocolSpecBuilder spiralDefinition() {
return ClassicProtocolSpecs.spiralDefinition( return ClassicProtocolSpecs.spiralDefinition(
chainId, isRevertReasonEnabled, ecip1017EraRounds, evmConfiguration); chainId,
isRevertReasonEnabled,
ecip1017EraRounds,
evmConfiguration,
isParallelTxProcessingEnabled,
metricsSystem);
} }
} }

@ -39,6 +39,7 @@ import org.hyperledger.besu.ethereum.mainnet.blockhash.FrontierBlockHashProcesso
import org.hyperledger.besu.ethereum.mainnet.blockhash.PragueBlockHashProcessor; import org.hyperledger.besu.ethereum.mainnet.blockhash.PragueBlockHashProcessor;
import org.hyperledger.besu.ethereum.mainnet.feemarket.BaseFeeMarket; import org.hyperledger.besu.ethereum.mainnet.feemarket.BaseFeeMarket;
import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket;
import org.hyperledger.besu.ethereum.mainnet.parallelization.MainnetParallelBlockProcessor;
import org.hyperledger.besu.ethereum.privacy.PrivateTransactionProcessor; import org.hyperledger.besu.ethereum.privacy.PrivateTransactionProcessor;
import org.hyperledger.besu.ethereum.privacy.PrivateTransactionValidator; import org.hyperledger.besu.ethereum.privacy.PrivateTransactionValidator;
import org.hyperledger.besu.ethereum.privacy.storage.PrivateMetadataUpdater; import org.hyperledger.besu.ethereum.privacy.storage.PrivateMetadataUpdater;
@ -67,6 +68,7 @@ import org.hyperledger.besu.evm.processor.ContractCreationProcessor;
import org.hyperledger.besu.evm.processor.MessageCallProcessor; import org.hyperledger.besu.evm.processor.MessageCallProcessor;
import org.hyperledger.besu.evm.worldstate.WorldState; import org.hyperledger.besu.evm.worldstate.WorldState;
import org.hyperledger.besu.evm.worldstate.WorldUpdater; import org.hyperledger.besu.evm.worldstate.WorldUpdater;
import org.hyperledger.besu.plugin.services.MetricsSystem;
import java.io.IOException; import java.io.IOException;
import java.math.BigInteger; import java.math.BigInteger;
@ -101,7 +103,10 @@ public abstract class MainnetProtocolSpecs {
private MainnetProtocolSpecs() {} private MainnetProtocolSpecs() {}
public static ProtocolSpecBuilder frontierDefinition(final EvmConfiguration evmConfiguration) { public static ProtocolSpecBuilder frontierDefinition(
final EvmConfiguration evmConfiguration,
final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
return new ProtocolSpecBuilder() return new ProtocolSpecBuilder()
.gasCalculator(FrontierGasCalculator::new) .gasCalculator(FrontierGasCalculator::new)
.gasLimitCalculatorBuilder(feeMarket -> new FrontierTargetingGasLimitCalculator()) .gasLimitCalculatorBuilder(feeMarket -> new FrontierTargetingGasLimitCalculator())
@ -152,7 +157,10 @@ public abstract class MainnetProtocolSpecs {
.transactionReceiptFactory(MainnetProtocolSpecs::frontierTransactionReceiptFactory) .transactionReceiptFactory(MainnetProtocolSpecs::frontierTransactionReceiptFactory)
.blockReward(FRONTIER_BLOCK_REWARD) .blockReward(FRONTIER_BLOCK_REWARD)
.skipZeroBlockRewards(false) .skipZeroBlockRewards(false)
.blockProcessorBuilder(MainnetBlockProcessor::new) .blockProcessorBuilder(
isParallelTxProcessingEnabled
? new MainnetParallelBlockProcessor.ParallelBlockProcessorBuilder(metricsSystem)
: MainnetBlockProcessor::new)
.blockValidatorBuilder(MainnetProtocolSpecs.blockValidatorBuilder()) .blockValidatorBuilder(MainnetProtocolSpecs.blockValidatorBuilder())
.blockImporterBuilder(MainnetBlockImporter::new) .blockImporterBuilder(MainnetBlockImporter::new)
.blockHeaderFunctions(new MainnetBlockHeaderFunctions()) .blockHeaderFunctions(new MainnetBlockHeaderFunctions())
@ -173,8 +181,11 @@ public abstract class MainnetProtocolSpecs {
return MainnetBlockValidator::new; return MainnetBlockValidator::new;
} }
public static ProtocolSpecBuilder homesteadDefinition(final EvmConfiguration evmConfiguration) { public static ProtocolSpecBuilder homesteadDefinition(
return frontierDefinition(evmConfiguration) final EvmConfiguration evmConfiguration,
final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
return frontierDefinition(evmConfiguration, isParallelTxProcessingEnabled, metricsSystem)
.gasCalculator(HomesteadGasCalculator::new) .gasCalculator(HomesteadGasCalculator::new)
.evmBuilder(MainnetEVMs::homestead) .evmBuilder(MainnetEVMs::homestead)
.contractCreationProcessorBuilder( .contractCreationProcessorBuilder(
@ -190,8 +201,10 @@ public abstract class MainnetProtocolSpecs {
} }
public static ProtocolSpecBuilder daoRecoveryInitDefinition( public static ProtocolSpecBuilder daoRecoveryInitDefinition(
final EvmConfiguration evmConfiguration) { final EvmConfiguration evmConfiguration,
return homesteadDefinition(evmConfiguration) final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
return homesteadDefinition(evmConfiguration, isParallelTxProcessingEnabled, metricsSystem)
.blockHeaderValidatorBuilder(feeMarket -> MainnetBlockHeaderValidator.createDaoValidator()) .blockHeaderValidatorBuilder(feeMarket -> MainnetBlockHeaderValidator.createDaoValidator())
.blockProcessorBuilder( .blockProcessorBuilder(
(transactionProcessor, (transactionProcessor,
@ -201,33 +214,53 @@ public abstract class MainnetProtocolSpecs {
skipZeroBlockRewards, skipZeroBlockRewards,
protocolSchedule) -> protocolSchedule) ->
new DaoBlockProcessor( new DaoBlockProcessor(
new MainnetBlockProcessor( isParallelTxProcessingEnabled
transactionProcessor, ? new MainnetParallelBlockProcessor(
transactionReceiptFactory, transactionProcessor,
blockReward, transactionReceiptFactory,
miningBeneficiaryCalculator, blockReward,
skipZeroBlockRewards, miningBeneficiaryCalculator,
protocolSchedule))) skipZeroBlockRewards,
protocolSchedule,
metricsSystem)
: new MainnetBlockProcessor(
transactionProcessor,
transactionReceiptFactory,
blockReward,
miningBeneficiaryCalculator,
skipZeroBlockRewards,
protocolSchedule)))
.name("DaoRecoveryInit"); .name("DaoRecoveryInit");
} }
public static ProtocolSpecBuilder daoRecoveryTransitionDefinition( public static ProtocolSpecBuilder daoRecoveryTransitionDefinition(
final EvmConfiguration evmConfiguration) { final EvmConfiguration evmConfiguration,
return daoRecoveryInitDefinition(evmConfiguration) final boolean isParallelTxProcessingEnabled,
.blockProcessorBuilder(MainnetBlockProcessor::new) final MetricsSystem metricsSystem) {
return daoRecoveryInitDefinition(evmConfiguration, isParallelTxProcessingEnabled, metricsSystem)
.blockProcessorBuilder(
isParallelTxProcessingEnabled
? new MainnetParallelBlockProcessor.ParallelBlockProcessorBuilder(metricsSystem)
: MainnetBlockProcessor::new)
.name("DaoRecoveryTransition"); .name("DaoRecoveryTransition");
} }
public static ProtocolSpecBuilder tangerineWhistleDefinition( public static ProtocolSpecBuilder tangerineWhistleDefinition(
final EvmConfiguration evmConfiguration) { final EvmConfiguration evmConfiguration,
return homesteadDefinition(evmConfiguration) final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
return homesteadDefinition(evmConfiguration, isParallelTxProcessingEnabled, metricsSystem)
.gasCalculator(TangerineWhistleGasCalculator::new) .gasCalculator(TangerineWhistleGasCalculator::new)
.name("TangerineWhistle"); .name("TangerineWhistle");
} }
public static ProtocolSpecBuilder spuriousDragonDefinition( public static ProtocolSpecBuilder spuriousDragonDefinition(
final Optional<BigInteger> chainId, final EvmConfiguration evmConfiguration) { final Optional<BigInteger> chainId,
return tangerineWhistleDefinition(evmConfiguration) final EvmConfiguration evmConfiguration,
final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
return tangerineWhistleDefinition(
evmConfiguration, isParallelTxProcessingEnabled, metricsSystem)
.isReplayProtectionSupported(true) .isReplayProtectionSupported(true)
.gasCalculator(SpuriousDragonGasCalculator::new) .gasCalculator(SpuriousDragonGasCalculator::new)
.skipZeroBlockRewards(true) .skipZeroBlockRewards(true)
@ -271,8 +304,11 @@ public abstract class MainnetProtocolSpecs {
public static ProtocolSpecBuilder byzantiumDefinition( public static ProtocolSpecBuilder byzantiumDefinition(
final Optional<BigInteger> chainId, final Optional<BigInteger> chainId,
final boolean enableRevertReason, final boolean enableRevertReason,
final EvmConfiguration evmConfiguration) { final EvmConfiguration evmConfiguration,
return spuriousDragonDefinition(chainId, evmConfiguration) final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
return spuriousDragonDefinition(
chainId, evmConfiguration, isParallelTxProcessingEnabled, metricsSystem)
.gasCalculator(ByzantiumGasCalculator::new) .gasCalculator(ByzantiumGasCalculator::new)
.evmBuilder(MainnetEVMs::byzantium) .evmBuilder(MainnetEVMs::byzantium)
.precompileContractRegistryBuilder(MainnetPrecompiledContractRegistries::byzantium) .precompileContractRegistryBuilder(MainnetPrecompiledContractRegistries::byzantium)
@ -301,8 +337,15 @@ public abstract class MainnetProtocolSpecs {
public static ProtocolSpecBuilder constantinopleDefinition( public static ProtocolSpecBuilder constantinopleDefinition(
final Optional<BigInteger> chainId, final Optional<BigInteger> chainId,
final boolean enableRevertReason, final boolean enableRevertReason,
final EvmConfiguration evmConfiguration) { final EvmConfiguration evmConfiguration,
return byzantiumDefinition(chainId, enableRevertReason, evmConfiguration) final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
return byzantiumDefinition(
chainId,
enableRevertReason,
evmConfiguration,
isParallelTxProcessingEnabled,
metricsSystem)
.difficultyCalculator(MainnetDifficultyCalculators.CONSTANTINOPLE) .difficultyCalculator(MainnetDifficultyCalculators.CONSTANTINOPLE)
.gasCalculator(ConstantinopleGasCalculator::new) .gasCalculator(ConstantinopleGasCalculator::new)
.evmBuilder(MainnetEVMs::constantinople) .evmBuilder(MainnetEVMs::constantinople)
@ -313,8 +356,15 @@ public abstract class MainnetProtocolSpecs {
public static ProtocolSpecBuilder petersburgDefinition( public static ProtocolSpecBuilder petersburgDefinition(
final Optional<BigInteger> chainId, final Optional<BigInteger> chainId,
final boolean enableRevertReason, final boolean enableRevertReason,
final EvmConfiguration evmConfiguration) { final EvmConfiguration evmConfiguration,
return constantinopleDefinition(chainId, enableRevertReason, evmConfiguration) final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
return constantinopleDefinition(
chainId,
enableRevertReason,
evmConfiguration,
isParallelTxProcessingEnabled,
metricsSystem)
.gasCalculator(PetersburgGasCalculator::new) .gasCalculator(PetersburgGasCalculator::new)
.name("Petersburg"); .name("Petersburg");
} }
@ -322,8 +372,15 @@ public abstract class MainnetProtocolSpecs {
public static ProtocolSpecBuilder istanbulDefinition( public static ProtocolSpecBuilder istanbulDefinition(
final Optional<BigInteger> chainId, final Optional<BigInteger> chainId,
final boolean enableRevertReason, final boolean enableRevertReason,
final EvmConfiguration evmConfiguration) { final EvmConfiguration evmConfiguration,
return petersburgDefinition(chainId, enableRevertReason, evmConfiguration) final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
return petersburgDefinition(
chainId,
enableRevertReason,
evmConfiguration,
isParallelTxProcessingEnabled,
metricsSystem)
.gasCalculator(IstanbulGasCalculator::new) .gasCalculator(IstanbulGasCalculator::new)
.evmBuilder( .evmBuilder(
(gasCalculator, jdCacheConfig) -> (gasCalculator, jdCacheConfig) ->
@ -344,8 +401,15 @@ public abstract class MainnetProtocolSpecs {
static ProtocolSpecBuilder muirGlacierDefinition( static ProtocolSpecBuilder muirGlacierDefinition(
final Optional<BigInteger> chainId, final Optional<BigInteger> chainId,
final boolean enableRevertReason, final boolean enableRevertReason,
final EvmConfiguration evmConfiguration) { final EvmConfiguration evmConfiguration,
return istanbulDefinition(chainId, enableRevertReason, evmConfiguration) final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
return istanbulDefinition(
chainId,
enableRevertReason,
evmConfiguration,
isParallelTxProcessingEnabled,
metricsSystem)
.difficultyCalculator(MainnetDifficultyCalculators.MUIR_GLACIER) .difficultyCalculator(MainnetDifficultyCalculators.MUIR_GLACIER)
.name("MuirGlacier"); .name("MuirGlacier");
} }
@ -353,8 +417,15 @@ public abstract class MainnetProtocolSpecs {
static ProtocolSpecBuilder berlinDefinition( static ProtocolSpecBuilder berlinDefinition(
final Optional<BigInteger> chainId, final Optional<BigInteger> chainId,
final boolean enableRevertReason, final boolean enableRevertReason,
final EvmConfiguration evmConfiguration) { final EvmConfiguration evmConfiguration,
return muirGlacierDefinition(chainId, enableRevertReason, evmConfiguration) final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
return muirGlacierDefinition(
chainId,
enableRevertReason,
evmConfiguration,
isParallelTxProcessingEnabled,
metricsSystem)
.gasCalculator(BerlinGasCalculator::new) .gasCalculator(BerlinGasCalculator::new)
.transactionValidatorFactoryBuilder( .transactionValidatorFactoryBuilder(
(evm, gasLimitCalculator, feeMarket) -> (evm, gasLimitCalculator, feeMarket) ->
@ -376,7 +447,9 @@ public abstract class MainnetProtocolSpecs {
final boolean enableRevertReason, final boolean enableRevertReason,
final GenesisConfigOptions genesisConfigOptions, final GenesisConfigOptions genesisConfigOptions,
final EvmConfiguration evmConfiguration, final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters) { final MiningParameters miningParameters,
final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
final long londonForkBlockNumber = final long londonForkBlockNumber =
genesisConfigOptions.getLondonBlockNumber().orElse(Long.MAX_VALUE); genesisConfigOptions.getLondonBlockNumber().orElse(Long.MAX_VALUE);
final BaseFeeMarket londonFeeMarket; final BaseFeeMarket londonFeeMarket;
@ -390,7 +463,12 @@ public abstract class MainnetProtocolSpecs {
londonFeeMarket = londonFeeMarket =
FeeMarket.london(londonForkBlockNumber, genesisConfigOptions.getBaseFeePerGas()); FeeMarket.london(londonForkBlockNumber, genesisConfigOptions.getBaseFeePerGas());
} }
return berlinDefinition(chainId, enableRevertReason, evmConfiguration) return berlinDefinition(
chainId,
enableRevertReason,
evmConfiguration,
isParallelTxProcessingEnabled,
metricsSystem)
.feeMarket(londonFeeMarket) .feeMarket(londonFeeMarket)
.gasCalculator(LondonGasCalculator::new) .gasCalculator(LondonGasCalculator::new)
.gasLimitCalculatorBuilder( .gasLimitCalculatorBuilder(
@ -455,9 +533,17 @@ public abstract class MainnetProtocolSpecs {
final boolean enableRevertReason, final boolean enableRevertReason,
final GenesisConfigOptions genesisConfigOptions, final GenesisConfigOptions genesisConfigOptions,
final EvmConfiguration evmConfiguration, final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters) { final MiningParameters miningParameters,
final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
return londonDefinition( return londonDefinition(
chainId, enableRevertReason, genesisConfigOptions, evmConfiguration, miningParameters) chainId,
enableRevertReason,
genesisConfigOptions,
evmConfiguration,
miningParameters,
isParallelTxProcessingEnabled,
metricsSystem)
.difficultyCalculator(MainnetDifficultyCalculators.ARROW_GLACIER) .difficultyCalculator(MainnetDifficultyCalculators.ARROW_GLACIER)
.name("ArrowGlacier"); .name("ArrowGlacier");
} }
@ -467,9 +553,17 @@ public abstract class MainnetProtocolSpecs {
final boolean enableRevertReason, final boolean enableRevertReason,
final GenesisConfigOptions genesisConfigOptions, final GenesisConfigOptions genesisConfigOptions,
final EvmConfiguration evmConfiguration, final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters) { final MiningParameters miningParameters,
final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
return arrowGlacierDefinition( return arrowGlacierDefinition(
chainId, enableRevertReason, genesisConfigOptions, evmConfiguration, miningParameters) chainId,
enableRevertReason,
genesisConfigOptions,
evmConfiguration,
miningParameters,
isParallelTxProcessingEnabled,
metricsSystem)
.difficultyCalculator(MainnetDifficultyCalculators.GRAY_GLACIER) .difficultyCalculator(MainnetDifficultyCalculators.GRAY_GLACIER)
.name("GrayGlacier"); .name("GrayGlacier");
} }
@ -479,10 +573,18 @@ public abstract class MainnetProtocolSpecs {
final boolean enableRevertReason, final boolean enableRevertReason,
final GenesisConfigOptions genesisConfigOptions, final GenesisConfigOptions genesisConfigOptions,
final EvmConfiguration evmConfiguration, final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters) { final MiningParameters miningParameters,
final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
return grayGlacierDefinition( return grayGlacierDefinition(
chainId, enableRevertReason, genesisConfigOptions, evmConfiguration, miningParameters) chainId,
enableRevertReason,
genesisConfigOptions,
evmConfiguration,
miningParameters,
isParallelTxProcessingEnabled,
metricsSystem)
.evmBuilder( .evmBuilder(
(gasCalculator, jdCacheConfig) -> (gasCalculator, jdCacheConfig) ->
MainnetEVMs.paris(gasCalculator, chainId.orElse(BigInteger.ZERO), evmConfiguration)) MainnetEVMs.paris(gasCalculator, chainId.orElse(BigInteger.ZERO), evmConfiguration))
@ -499,9 +601,17 @@ public abstract class MainnetProtocolSpecs {
final boolean enableRevertReason, final boolean enableRevertReason,
final GenesisConfigOptions genesisConfigOptions, final GenesisConfigOptions genesisConfigOptions,
final EvmConfiguration evmConfiguration, final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters) { final MiningParameters miningParameters,
final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
return parisDefinition( return parisDefinition(
chainId, enableRevertReason, genesisConfigOptions, evmConfiguration, miningParameters) chainId,
enableRevertReason,
genesisConfigOptions,
evmConfiguration,
miningParameters,
isParallelTxProcessingEnabled,
metricsSystem)
// gas calculator has new code to support EIP-3860 limit and meter initcode // gas calculator has new code to support EIP-3860 limit and meter initcode
.gasCalculator(ShanghaiGasCalculator::new) .gasCalculator(ShanghaiGasCalculator::new)
// EVM has a new operation for EIP-3855 PUSH0 instruction // EVM has a new operation for EIP-3855 PUSH0 instruction
@ -550,7 +660,9 @@ public abstract class MainnetProtocolSpecs {
final boolean enableRevertReason, final boolean enableRevertReason,
final GenesisConfigOptions genesisConfigOptions, final GenesisConfigOptions genesisConfigOptions,
final EvmConfiguration evmConfiguration, final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters) { final MiningParameters miningParameters,
final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
final long londonForkBlockNumber = genesisConfigOptions.getLondonBlockNumber().orElse(0L); final long londonForkBlockNumber = genesisConfigOptions.getLondonBlockNumber().orElse(0L);
final BaseFeeMarket cancunFeeMarket; final BaseFeeMarket cancunFeeMarket;
if (genesisConfigOptions.isZeroBaseFee()) { if (genesisConfigOptions.isZeroBaseFee()) {
@ -565,7 +677,13 @@ public abstract class MainnetProtocolSpecs {
} }
return shanghaiDefinition( return shanghaiDefinition(
chainId, enableRevertReason, genesisConfigOptions, evmConfiguration, miningParameters) chainId,
enableRevertReason,
genesisConfigOptions,
evmConfiguration,
miningParameters,
isParallelTxProcessingEnabled,
metricsSystem)
.feeMarket(cancunFeeMarket) .feeMarket(cancunFeeMarket)
// gas calculator for EIP-4844 blob gas // gas calculator for EIP-4844 blob gas
.gasCalculator(CancunGasCalculator::new) .gasCalculator(CancunGasCalculator::new)
@ -623,11 +741,19 @@ public abstract class MainnetProtocolSpecs {
final boolean enableRevertReason, final boolean enableRevertReason,
final GenesisConfigOptions genesisConfigOptions, final GenesisConfigOptions genesisConfigOptions,
final EvmConfiguration evmConfiguration, final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters) { final MiningParameters miningParameters,
final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
ProtocolSpecBuilder protocolSpecBuilder = ProtocolSpecBuilder protocolSpecBuilder =
cancunDefinition( cancunDefinition(
chainId, enableRevertReason, genesisConfigOptions, evmConfiguration, miningParameters); chainId,
enableRevertReason,
genesisConfigOptions,
evmConfiguration,
miningParameters,
isParallelTxProcessingEnabled,
metricsSystem);
return addEOF(chainId, evmConfiguration, protocolSpecBuilder).name("CancunEOF"); return addEOF(chainId, evmConfiguration, protocolSpecBuilder).name("CancunEOF");
} }
@ -636,14 +762,22 @@ public abstract class MainnetProtocolSpecs {
final boolean enableRevertReason, final boolean enableRevertReason,
final GenesisConfigOptions genesisConfigOptions, final GenesisConfigOptions genesisConfigOptions,
final EvmConfiguration evmConfiguration, final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters) { final MiningParameters miningParameters,
final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
final Address depositContractAddress = final Address depositContractAddress =
genesisConfigOptions.getDepositContractAddress().orElse(DEFAULT_DEPOSIT_CONTRACT_ADDRESS); genesisConfigOptions.getDepositContractAddress().orElse(DEFAULT_DEPOSIT_CONTRACT_ADDRESS);
return cancunDefinition( return cancunDefinition(
chainId, enableRevertReason, genesisConfigOptions, evmConfiguration, miningParameters) chainId,
// EIP-3074 AUTH and AUTHCALL gas enableRevertReason,
genesisConfigOptions,
evmConfiguration,
miningParameters,
isParallelTxProcessingEnabled,
metricsSystem)
// EIP-3074 AUTH and AUTCALL gas
.gasCalculator(PragueGasCalculator::new) .gasCalculator(PragueGasCalculator::new)
// EIP-3074 AUTH and AUTHCALL // EIP-3074 AUTH and AUTHCALL
.evmBuilder( .evmBuilder(
@ -686,11 +820,19 @@ public abstract class MainnetProtocolSpecs {
final boolean enableRevertReason, final boolean enableRevertReason,
final GenesisConfigOptions genesisConfigOptions, final GenesisConfigOptions genesisConfigOptions,
final EvmConfiguration evmConfiguration, final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters) { final MiningParameters miningParameters,
final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
ProtocolSpecBuilder protocolSpecBuilder = ProtocolSpecBuilder protocolSpecBuilder =
pragueDefinition( pragueDefinition(
chainId, enableRevertReason, genesisConfigOptions, evmConfiguration, miningParameters); chainId,
enableRevertReason,
genesisConfigOptions,
evmConfiguration,
miningParameters,
isParallelTxProcessingEnabled,
metricsSystem);
return addEOF(chainId, evmConfiguration, protocolSpecBuilder).name("PragueEOF"); return addEOF(chainId, evmConfiguration, protocolSpecBuilder).name("PragueEOF");
} }
@ -722,9 +864,17 @@ public abstract class MainnetProtocolSpecs {
final boolean enableRevertReason, final boolean enableRevertReason,
final GenesisConfigOptions genesisConfigOptions, final GenesisConfigOptions genesisConfigOptions,
final EvmConfiguration evmConfiguration, final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters) { final MiningParameters miningParameters,
final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
return pragueEOFDefinition( return pragueEOFDefinition(
chainId, enableRevertReason, genesisConfigOptions, evmConfiguration, miningParameters) chainId,
enableRevertReason,
genesisConfigOptions,
evmConfiguration,
miningParameters,
isParallelTxProcessingEnabled,
metricsSystem)
// Use Future EIP configured EVM // Use Future EIP configured EVM
.evmBuilder( .evmBuilder(
(gasCalculator, jdCacheConfig) -> (gasCalculator, jdCacheConfig) ->
@ -749,10 +899,18 @@ public abstract class MainnetProtocolSpecs {
final boolean enableRevertReason, final boolean enableRevertReason,
final GenesisConfigOptions genesisConfigOptions, final GenesisConfigOptions genesisConfigOptions,
final EvmConfiguration evmConfiguration, final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters) { final MiningParameters miningParameters,
final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
return futureEipsDefinition( return futureEipsDefinition(
chainId, enableRevertReason, genesisConfigOptions, evmConfiguration, miningParameters) chainId,
enableRevertReason,
genesisConfigOptions,
evmConfiguration,
miningParameters,
isParallelTxProcessingEnabled,
metricsSystem)
.evmBuilder( .evmBuilder(
(gasCalculator, jdCacheConfig) -> (gasCalculator, jdCacheConfig) ->
MainnetEVMs.experimentalEips( MainnetEVMs.experimentalEips(

@ -507,7 +507,6 @@ public class MainnetTransactionProcessor {
final long gasUsedByTransaction = transaction.getGasLimit() - initialFrame.getRemainingGas(); final long gasUsedByTransaction = transaction.getGasLimit() - initialFrame.getRemainingGas();
// update the coinbase // update the coinbase
final var coinbase = worldState.getOrCreate(miningBeneficiary);
final long usedGas = transaction.getGasLimit() - refundedGas; final long usedGas = transaction.getGasLimit() - refundedGas;
final CoinbaseFeePriceCalculator coinbaseCalculator; final CoinbaseFeePriceCalculator coinbaseCalculator;
if (blockHeader.getBaseFee().isPresent()) { if (blockHeader.getBaseFee().isPresent()) {
@ -529,6 +528,9 @@ public class MainnetTransactionProcessor {
final Wei coinbaseWeiDelta = final Wei coinbaseWeiDelta =
coinbaseCalculator.price(usedGas, transactionGasPrice, blockHeader.getBaseFee()); coinbaseCalculator.price(usedGas, transactionGasPrice, blockHeader.getBaseFee());
operationTracer.traceBeforeRewardTransaction(worldUpdater, transaction, coinbaseWeiDelta);
final var coinbase = worldState.getOrCreate(miningBeneficiary);
coinbase.incrementBalance(coinbaseWeiDelta); coinbase.incrementBalance(coinbaseWeiDelta);
authorizedCodeService.resetAuthorities(); authorizedCodeService.resetAuthorities();

@ -20,6 +20,7 @@ import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.core.PrivacyParameters; import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.ethereum.privacy.PrivateTransactionValidator; import org.hyperledger.besu.ethereum.privacy.PrivateTransactionValidator;
import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.evm.internal.EvmConfiguration;
import org.hyperledger.besu.plugin.services.MetricsSystem;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.NavigableMap; import java.util.NavigableMap;
@ -45,6 +46,8 @@ public class ProtocolScheduleBuilder {
private final EvmConfiguration evmConfiguration; private final EvmConfiguration evmConfiguration;
private final MiningParameters miningParameters; private final MiningParameters miningParameters;
private final BadBlockManager badBlockManager; private final BadBlockManager badBlockManager;
private final boolean isParallelTxProcessingEnabled;
private final MetricsSystem metricsSystem;
public ProtocolScheduleBuilder( public ProtocolScheduleBuilder(
final GenesisConfigOptions config, final GenesisConfigOptions config,
@ -54,7 +57,9 @@ public class ProtocolScheduleBuilder {
final boolean isRevertReasonEnabled, final boolean isRevertReasonEnabled,
final EvmConfiguration evmConfiguration, final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters, final MiningParameters miningParameters,
final BadBlockManager badBlockManager) { final BadBlockManager badBlockManager,
final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
this( this(
config, config,
Optional.of(defaultChainId), Optional.of(defaultChainId),
@ -63,7 +68,9 @@ public class ProtocolScheduleBuilder {
isRevertReasonEnabled, isRevertReasonEnabled,
evmConfiguration, evmConfiguration,
miningParameters, miningParameters,
badBlockManager); badBlockManager,
isParallelTxProcessingEnabled,
metricsSystem);
} }
public ProtocolScheduleBuilder( public ProtocolScheduleBuilder(
@ -73,7 +80,9 @@ public class ProtocolScheduleBuilder {
final boolean isRevertReasonEnabled, final boolean isRevertReasonEnabled,
final EvmConfiguration evmConfiguration, final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters, final MiningParameters miningParameters,
final BadBlockManager badBlockManager) { final BadBlockManager badBlockManager,
final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
this( this(
config, config,
Optional.empty(), Optional.empty(),
@ -82,7 +91,9 @@ public class ProtocolScheduleBuilder {
isRevertReasonEnabled, isRevertReasonEnabled,
evmConfiguration, evmConfiguration,
miningParameters, miningParameters,
badBlockManager); badBlockManager,
isParallelTxProcessingEnabled,
metricsSystem);
} }
private ProtocolScheduleBuilder( private ProtocolScheduleBuilder(
@ -93,7 +104,9 @@ public class ProtocolScheduleBuilder {
final boolean isRevertReasonEnabled, final boolean isRevertReasonEnabled,
final EvmConfiguration evmConfiguration, final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters, final MiningParameters miningParameters,
final BadBlockManager badBlockManager) { final BadBlockManager badBlockManager,
final boolean isParallelTxProcessingEnabled,
final MetricsSystem metricsSystem) {
this.config = config; this.config = config;
this.protocolSpecAdapters = protocolSpecAdapters; this.protocolSpecAdapters = protocolSpecAdapters;
this.privacyParameters = privacyParameters; this.privacyParameters = privacyParameters;
@ -102,6 +115,8 @@ public class ProtocolScheduleBuilder {
this.defaultChainId = defaultChainId; this.defaultChainId = defaultChainId;
this.miningParameters = miningParameters; this.miningParameters = miningParameters;
this.badBlockManager = badBlockManager; this.badBlockManager = badBlockManager;
this.isParallelTxProcessingEnabled = isParallelTxProcessingEnabled;
this.metricsSystem = metricsSystem;
} }
public ProtocolSchedule createProtocolSchedule() { public ProtocolSchedule createProtocolSchedule() {
@ -121,7 +136,9 @@ public class ProtocolScheduleBuilder {
config.getEcip1017EraRounds(), config.getEcip1017EraRounds(),
evmConfiguration.overrides( evmConfiguration.overrides(
config.getContractSizeLimit(), OptionalInt.empty(), config.getEvmStackSize()), config.getContractSizeLimit(), OptionalInt.empty(), config.getEvmStackSize()),
miningParameters); miningParameters,
isParallelTxProcessingEnabled,
metricsSystem);
validateForkOrdering(); validateForkOrdering();
@ -203,7 +220,8 @@ public class ProtocolScheduleBuilder {
protocolSchedule, protocolSchedule,
BuilderMapEntry.MilestoneType.BLOCK_NUMBER, BuilderMapEntry.MilestoneType.BLOCK_NUMBER,
classicBlockNumber, classicBlockNumber,
ClassicProtocolSpecs.classicRecoveryInitDefinition(evmConfiguration), ClassicProtocolSpecs.classicRecoveryInitDefinition(
evmConfiguration, isParallelTxProcessingEnabled, metricsSystem),
Function.identity()); Function.identity());
protocolSchedule.putBlockNumberMilestone( protocolSchedule.putBlockNumberMilestone(
classicBlockNumber + 1, originalProtocolSpec); classicBlockNumber + 1, originalProtocolSpec);

@ -51,6 +51,7 @@ public class ProtocolSpecBuilder {
private Function<FeeMarket, GasLimitCalculator> gasLimitCalculatorBuilder; private Function<FeeMarket, GasLimitCalculator> gasLimitCalculatorBuilder;
private Wei blockReward; private Wei blockReward;
private boolean skipZeroBlockRewards; private boolean skipZeroBlockRewards;
private BlockHeaderFunctions blockHeaderFunctions; private BlockHeaderFunctions blockHeaderFunctions;
private AbstractBlockProcessor.TransactionReceiptFactory transactionReceiptFactory; private AbstractBlockProcessor.TransactionReceiptFactory transactionReceiptFactory;
private DifficultyCalculator difficultyCalculator; private DifficultyCalculator difficultyCalculator;
@ -66,9 +67,11 @@ public class ProtocolSpecBuilder {
private BiFunction<EVM, PrecompileContractRegistry, AbstractMessageProcessor> private BiFunction<EVM, PrecompileContractRegistry, AbstractMessageProcessor>
messageCallProcessorBuilder; messageCallProcessorBuilder;
private TransactionProcessorBuilder transactionProcessorBuilder; private TransactionProcessorBuilder transactionProcessorBuilder;
private BlockProcessorBuilder blockProcessorBuilder; private BlockProcessorBuilder blockProcessorBuilder;
private BlockValidatorBuilder blockValidatorBuilder; private BlockValidatorBuilder blockValidatorBuilder;
private BlockImporterBuilder blockImporterBuilder; private BlockImporterBuilder blockImporterBuilder;
private String name; private String name;
private MiningBeneficiaryCalculator miningBeneficiaryCalculator; private MiningBeneficiaryCalculator miningBeneficiaryCalculator;
private PrivacyParameters privacyParameters; private PrivacyParameters privacyParameters;

@ -0,0 +1,199 @@
/*
* 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.ethereum.mainnet.parallelization;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.MutableWorldState;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.mainnet.BlockProcessor;
import org.hyperledger.besu.ethereum.mainnet.MainnetBlockProcessor;
import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor;
import org.hyperledger.besu.ethereum.mainnet.MiningBeneficiaryCalculator;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecBuilder;
import org.hyperledger.besu.ethereum.privacy.storage.PrivateMetadataUpdater;
import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult;
import org.hyperledger.besu.ethereum.trie.diffbased.common.worldview.DiffBasedWorldState;
import org.hyperledger.besu.evm.operation.BlockHashOperation;
import org.hyperledger.besu.evm.worldstate.WorldUpdater;
import org.hyperledger.besu.metrics.BesuMetricCategory;
import org.hyperledger.besu.plugin.services.MetricsSystem;
import org.hyperledger.besu.plugin.services.metrics.Counter;
import java.util.List;
import java.util.Optional;
public class MainnetParallelBlockProcessor extends MainnetBlockProcessor {
private final Optional<MetricsSystem> metricsSystem;
private final Optional<Counter> confirmedParallelizedTransactionCounter;
private final Optional<Counter> conflictingButCachedTransactionCounter;
public MainnetParallelBlockProcessor(
final MainnetTransactionProcessor transactionProcessor,
final TransactionReceiptFactory transactionReceiptFactory,
final Wei blockReward,
final MiningBeneficiaryCalculator miningBeneficiaryCalculator,
final boolean skipZeroBlockRewards,
final ProtocolSchedule protocolSchedule,
final MetricsSystem metricsSystem) {
super(
transactionProcessor,
transactionReceiptFactory,
blockReward,
miningBeneficiaryCalculator,
skipZeroBlockRewards,
protocolSchedule);
this.metricsSystem = Optional.of(metricsSystem);
this.confirmedParallelizedTransactionCounter =
Optional.of(
this.metricsSystem
.get()
.createCounter(
BesuMetricCategory.BLOCK_PROCESSING,
"parallelized_transactions_counter",
"Counter for the number of parallelized transactions during block processing"));
this.conflictingButCachedTransactionCounter =
Optional.of(
this.metricsSystem
.get()
.createCounter(
BesuMetricCategory.BLOCK_PROCESSING,
"conflicted_transactions_counter",
"Counter for the number of conflicted transactions during block processing"));
}
@Override
protected Optional<PreprocessingContext> runBlockPreProcessing(
final MutableWorldState worldState,
final PrivateMetadataUpdater privateMetadataUpdater,
final BlockHeader blockHeader,
final List<Transaction> transactions,
final Address miningBeneficiary,
final BlockHashOperation.BlockHashLookup blockHashLookup,
final Wei blobGasPrice) {
if ((worldState instanceof DiffBasedWorldState)) {
ParallelizedConcurrentTransactionProcessor parallelizedConcurrentTransactionProcessor =
new ParallelizedConcurrentTransactionProcessor(transactionProcessor);
// runAsyncBlock, if activated, facilitates the non-blocking parallel execution of
// transactions in the background through an optimistic strategy.
parallelizedConcurrentTransactionProcessor.runAsyncBlock(
worldState,
blockHeader,
transactions,
miningBeneficiary,
blockHashLookup,
blobGasPrice,
privateMetadataUpdater);
return Optional.of(
new ParallelizedPreProcessingContext(parallelizedConcurrentTransactionProcessor));
}
return Optional.empty();
}
@Override
protected TransactionProcessingResult getTransactionProcessingResult(
final Optional<PreprocessingContext> preProcessingContext,
final MutableWorldState worldState,
final WorldUpdater blockUpdater,
final PrivateMetadataUpdater privateMetadataUpdater,
final BlockHeader blockHeader,
final Wei blobGasPrice,
final Address miningBeneficiary,
final Transaction transaction,
final int location,
final BlockHashOperation.BlockHashLookup blockHashLookup) {
TransactionProcessingResult transactionProcessingResult = null;
if (preProcessingContext.isPresent()) {
final ParallelizedPreProcessingContext parallelizedPreProcessingContext =
(ParallelizedPreProcessingContext) preProcessingContext.get();
transactionProcessingResult =
parallelizedPreProcessingContext
.getParallelizedConcurrentTransactionProcessor()
.applyParallelizedTransactionResult(
worldState,
miningBeneficiary,
transaction,
location,
confirmedParallelizedTransactionCounter,
conflictingButCachedTransactionCounter)
.orElse(null);
}
if (transactionProcessingResult == null) {
return super.getTransactionProcessingResult(
preProcessingContext,
worldState,
blockUpdater,
privateMetadataUpdater,
blockHeader,
blobGasPrice,
miningBeneficiary,
transaction,
location,
blockHashLookup);
} else {
return transactionProcessingResult;
}
}
static class ParallelizedPreProcessingContext implements PreprocessingContext {
final ParallelizedConcurrentTransactionProcessor parallelizedConcurrentTransactionProcessor;
public ParallelizedPreProcessingContext(
final ParallelizedConcurrentTransactionProcessor
parallelizedConcurrentTransactionProcessor) {
this.parallelizedConcurrentTransactionProcessor = parallelizedConcurrentTransactionProcessor;
}
public ParallelizedConcurrentTransactionProcessor
getParallelizedConcurrentTransactionProcessor() {
return parallelizedConcurrentTransactionProcessor;
}
}
public static class ParallelBlockProcessorBuilder
implements ProtocolSpecBuilder.BlockProcessorBuilder {
final MetricsSystem metricsSystem;
public ParallelBlockProcessorBuilder(final MetricsSystem metricsSystem) {
this.metricsSystem = metricsSystem;
}
@Override
public BlockProcessor apply(
final MainnetTransactionProcessor transactionProcessor,
final TransactionReceiptFactory transactionReceiptFactory,
final Wei blockReward,
final MiningBeneficiaryCalculator miningBeneficiaryCalculator,
final boolean skipZeroBlockRewards,
final ProtocolSchedule protocolSchedule) {
return new MainnetParallelBlockProcessor(
transactionProcessor,
transactionReceiptFactory,
blockReward,
miningBeneficiaryCalculator,
skipZeroBlockRewards,
protocolSchedule,
metricsSystem);
}
}
}

@ -0,0 +1,268 @@
/*
* 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.ethereum.mainnet.parallelization;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.MutableWorldState;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor;
import org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams;
import org.hyperledger.besu.ethereum.privacy.storage.PrivateMetadataUpdater;
import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult;
import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.cache.NoopBonsaiCachedMerkleTrieLoader;
import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.worldview.BonsaiWorldState;
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.evm.operation.BlockHashOperation;
import org.hyperledger.besu.evm.tracing.OperationTracer;
import org.hyperledger.besu.evm.worldstate.WorldView;
import org.hyperledger.besu.plugin.services.metrics.Counter;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import com.google.common.annotations.VisibleForTesting;
/**
* Optimizes transaction processing by executing transactions in parallel within a given block.
* Transactions are executed optimistically in a non-blocking manner. After execution, the class
* checks for potential conflicts among transactions to ensure data integrity before applying the
* results to the world state.
*/
@SuppressWarnings({"unchecked", "rawtypes"})
public class ParallelizedConcurrentTransactionProcessor {
private static final int NCPU = Runtime.getRuntime().availableProcessors();
private static final Executor executor = Executors.newFixedThreadPool(NCPU);
private final MainnetTransactionProcessor transactionProcessor;
private final TransactionCollisionDetector transactionCollisionDetector;
private final Map<Integer, ParallelizedTransactionContext>
parallelizedTransactionContextByLocation = new ConcurrentHashMap<>();
/**
* Constructs a PreloadConcurrentTransactionProcessor with a specified transaction processor. This
* processor is responsible for the individual processing of transactions.
*
* @param transactionProcessor The transaction processor for processing individual transactions.
*/
public ParallelizedConcurrentTransactionProcessor(
final MainnetTransactionProcessor transactionProcessor) {
this.transactionProcessor = transactionProcessor;
this.transactionCollisionDetector = new TransactionCollisionDetector();
}
@VisibleForTesting
public ParallelizedConcurrentTransactionProcessor(
final MainnetTransactionProcessor transactionProcessor,
final TransactionCollisionDetector transactionCollisionDetector) {
this.transactionProcessor = transactionProcessor;
this.transactionCollisionDetector = transactionCollisionDetector;
}
/**
* Initiates the parallel and optimistic execution of transactions within a block by creating a
* copy of the world state for each transaction. This method processes transactions in a
* non-blocking manner. Transactions are executed against their respective copies of the world
* state, ensuring that the original world state passed as a parameter remains unmodified during
* this process.
*
* @param worldState Mutable world state intended for applying transaction results. This world
* state is not modified directly; instead, copies are made for transaction execution.
* @param blockHeader Header of the current block containing the transactions.
* @param transactions List of transactions to be processed.
* @param miningBeneficiary Address of the beneficiary to receive mining rewards.
* @param blockHashLookup Function for block hash lookup.
* @param blobGasPrice Gas price for blob transactions.
* @param privateMetadataUpdater Updater for private transaction metadata.
*/
public void runAsyncBlock(
final MutableWorldState worldState,
final BlockHeader blockHeader,
final List<Transaction> transactions,
final Address miningBeneficiary,
final BlockHashOperation.BlockHashLookup blockHashLookup,
final Wei blobGasPrice,
final PrivateMetadataUpdater privateMetadataUpdater) {
for (int i = 0; i < transactions.size(); i++) {
final Transaction transaction = transactions.get(i);
final int transactionLocation = i;
/*
* All transactions are executed in the background by copying the world state of the block on which the transactions need to be executed, ensuring that each one has its own accumulator.
*/
CompletableFuture.runAsync(
() ->
runTransaction(
worldState,
blockHeader,
transactionLocation,
transaction,
miningBeneficiary,
blockHashLookup,
blobGasPrice,
privateMetadataUpdater),
executor);
}
}
@VisibleForTesting
public void runTransaction(
final MutableWorldState worldState,
final BlockHeader blockHeader,
final int transactionLocation,
final Transaction transaction,
final Address miningBeneficiary,
final BlockHashOperation.BlockHashLookup blockHashLookup,
final Wei blobGasPrice,
final PrivateMetadataUpdater privateMetadataUpdater) {
try (final DiffBasedWorldState roundWorldState =
new BonsaiWorldState(
(BonsaiWorldState) worldState, new NoopBonsaiCachedMerkleTrieLoader())) {
roundWorldState.freeze(); // make the clone frozen
final ParallelizedTransactionContext.Builder contextBuilder =
new ParallelizedTransactionContext.Builder();
final DiffBasedWorldStateUpdateAccumulator<?> roundWorldStateUpdater =
(DiffBasedWorldStateUpdateAccumulator<?>) roundWorldState.updater();
final TransactionProcessingResult result =
transactionProcessor.processTransaction(
roundWorldStateUpdater,
blockHeader,
transaction,
miningBeneficiary,
new OperationTracer() {
@Override
public void traceBeforeRewardTransaction(
final WorldView worldView,
final org.hyperledger.besu.datatypes.Transaction tx,
final Wei miningReward) {
/*
* This part checks if the mining beneficiary's account was accessed before increasing its balance for rewards.
* Indeed, if the transaction has interacted with the address to read or modify it,
* it means that the value is necessary for the proper execution of the transaction and will therefore be considered in collision detection.
* If this is not the case, we can ignore this address during conflict detection.
*/
if (transactionCollisionDetector
.getAddressesTouchedByTransaction(
transaction, Optional.of(roundWorldStateUpdater))
.contains(miningBeneficiary)) {
contextBuilder.isMiningBeneficiaryTouchedPreRewardByTransaction(true);
}
contextBuilder.miningBeneficiaryReward(miningReward);
}
},
blockHashLookup,
true,
TransactionValidationParams.processingBlock(),
privateMetadataUpdater,
blobGasPrice);
// commit the accumulator in order to apply all the modifications
roundWorldState.getAccumulator().commit();
contextBuilder
.transactionAccumulator(roundWorldState.getAccumulator())
.transactionProcessingResult(result);
final ParallelizedTransactionContext parallelizedTransactionContext = contextBuilder.build();
if (!parallelizedTransactionContext.isMiningBeneficiaryTouchedPreRewardByTransaction()) {
/*
* If the address of the mining beneficiary has been touched only for adding rewards,
* we remove it from the accumulator to avoid a false positive collision.
* The balance will be increased during the sequential processing.
*/
roundWorldStateUpdater.getAccountsToUpdate().remove(miningBeneficiary);
}
parallelizedTransactionContextByLocation.put(
transactionLocation, parallelizedTransactionContext);
}
}
/**
* Applies the results of parallelized transactions to the world state after checking for
* conflicts.
*
* <p>If a transaction was executed optimistically without any detected conflicts, its result is
* directly applied to the world state. If there is a conflict, this method does not apply the
* transaction's modifications directly to the world state. Instead, it caches the data read from
* the database during the transaction's execution. This cached data is then used to optimize the
* replay of the transaction by reducing the need for additional reads from the disk, thereby
* making the replay process faster. This approach ensures that the integrity of the world state
* is maintained while optimizing the performance of transaction processing.
*
* @param worldState Mutable world state intended for applying transaction results.
* @param miningBeneficiary Address of the beneficiary for mining rewards.
* @param transaction Transaction for which the result is to be applied.
* @param transactionLocation Index of the transaction within the block.
* @param confirmedParallelizedTransactionCounter Metric counter for confirmed parallelized
* transactions
* @param conflictingButCachedTransactionCounter Metric counter for conflicting but cached
* transactions
* @return Optional containing the transaction processing result if applied, or empty if the
* transaction needs to be replayed due to a conflict.
*/
public Optional<TransactionProcessingResult> applyParallelizedTransactionResult(
final MutableWorldState worldState,
final Address miningBeneficiary,
final Transaction transaction,
final int transactionLocation,
final Optional<Counter> confirmedParallelizedTransactionCounter,
final Optional<Counter> conflictingButCachedTransactionCounter) {
final DiffBasedWorldState diffBasedWorldState = (DiffBasedWorldState) worldState;
final DiffBasedWorldStateUpdateAccumulator blockAccumulator =
(DiffBasedWorldStateUpdateAccumulator) diffBasedWorldState.updater();
final ParallelizedTransactionContext parallelizedTransactionContext =
parallelizedTransactionContextByLocation.remove(transactionLocation);
/*
* If `parallelizedTransactionContext` is not null, it means that the transaction had time to complete in the background.
*/
if (parallelizedTransactionContext != null) {
final DiffBasedWorldStateUpdateAccumulator<?> transactionAccumulator =
parallelizedTransactionContext.transactionAccumulator();
final TransactionProcessingResult transactionProcessingResult =
parallelizedTransactionContext.transactionProcessingResult();
final boolean hasCollision =
transactionCollisionDetector.hasCollision(
transaction, miningBeneficiary, parallelizedTransactionContext, blockAccumulator);
if (transactionProcessingResult.isSuccessful() && !hasCollision) {
blockAccumulator
.getOrCreate(miningBeneficiary)
.incrementBalance(parallelizedTransactionContext.miningBeneficiaryReward());
blockAccumulator.importStateChangesFromSource(transactionAccumulator);
if (confirmedParallelizedTransactionCounter.isPresent())
confirmedParallelizedTransactionCounter.get().inc();
return Optional.of(transactionProcessingResult);
} else {
blockAccumulator.importPriorStateFromSource(transactionAccumulator);
if (conflictingButCachedTransactionCounter.isPresent())
conflictingButCachedTransactionCounter.get().inc();
// If there is a conflict, we return an empty result to signal the block processor to
// re-execute the transaction.
return Optional.empty();
}
}
return Optional.empty();
}
}

@ -0,0 +1,133 @@
/*
* 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.ethereum.mainnet.parallelization;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult;
import org.hyperledger.besu.ethereum.trie.diffbased.common.worldview.accumulator.DiffBasedWorldStateUpdateAccumulator;
import java.util.Objects;
public final class ParallelizedTransactionContext {
private final DiffBasedWorldStateUpdateAccumulator<?> transactionAccumulator;
private final TransactionProcessingResult transactionProcessingResult;
private final boolean isMiningBeneficiaryTouchedPreRewardByTransaction;
private final Wei miningBeneficiaryReward;
public ParallelizedTransactionContext(
final DiffBasedWorldStateUpdateAccumulator<?> transactionAccumulator,
final TransactionProcessingResult transactionProcessingResult,
final boolean isMiningBeneficiaryTouchedPreRewardByTransaction,
final Wei miningBeneficiaryReward) {
this.transactionAccumulator = transactionAccumulator;
this.transactionProcessingResult = transactionProcessingResult;
this.isMiningBeneficiaryTouchedPreRewardByTransaction =
isMiningBeneficiaryTouchedPreRewardByTransaction;
this.miningBeneficiaryReward = miningBeneficiaryReward;
}
public DiffBasedWorldStateUpdateAccumulator<?> transactionAccumulator() {
return transactionAccumulator;
}
public TransactionProcessingResult transactionProcessingResult() {
return transactionProcessingResult;
}
public boolean isMiningBeneficiaryTouchedPreRewardByTransaction() {
return isMiningBeneficiaryTouchedPreRewardByTransaction;
}
public Wei miningBeneficiaryReward() {
return miningBeneficiaryReward;
}
@Override
public boolean equals(final Object obj) {
if (obj == this) return true;
if (obj == null || obj.getClass() != this.getClass()) return false;
var that = (ParallelizedTransactionContext) obj;
return Objects.equals(this.transactionAccumulator, that.transactionAccumulator)
&& Objects.equals(this.transactionProcessingResult, that.transactionProcessingResult)
&& this.isMiningBeneficiaryTouchedPreRewardByTransaction
== that.isMiningBeneficiaryTouchedPreRewardByTransaction
&& Objects.equals(this.miningBeneficiaryReward, that.miningBeneficiaryReward);
}
@Override
public int hashCode() {
return Objects.hash(
transactionAccumulator,
transactionProcessingResult,
isMiningBeneficiaryTouchedPreRewardByTransaction,
miningBeneficiaryReward);
}
@Override
public String toString() {
return "ParallelizedTransactionContext["
+ "transactionAccumulator="
+ transactionAccumulator
+ ", "
+ "transactionProcessingResult="
+ transactionProcessingResult
+ ", "
+ "isMiningBeneficiaryTouchedPreRewardByTransaction="
+ isMiningBeneficiaryTouchedPreRewardByTransaction
+ ", "
+ "miningBeneficiaryReward="
+ miningBeneficiaryReward
+ ']';
}
public static class Builder {
private DiffBasedWorldStateUpdateAccumulator<?> transactionAccumulator;
private TransactionProcessingResult transactionProcessingResult;
private boolean isMiningBeneficiaryTouchedPreRewardByTransaction;
private Wei miningBeneficiaryReward = Wei.ZERO;
public Builder transactionAccumulator(
final DiffBasedWorldStateUpdateAccumulator<?> transactionAccumulator) {
this.transactionAccumulator = transactionAccumulator;
return this;
}
public Builder transactionProcessingResult(
final TransactionProcessingResult transactionProcessingResult) {
this.transactionProcessingResult = transactionProcessingResult;
return this;
}
public Builder isMiningBeneficiaryTouchedPreRewardByTransaction(
final boolean isMiningBeneficiaryTouchedPreRewardByTransaction) {
this.isMiningBeneficiaryTouchedPreRewardByTransaction =
isMiningBeneficiaryTouchedPreRewardByTransaction;
return this;
}
public Builder miningBeneficiaryReward(final Wei miningBeneficiaryReward) {
this.miningBeneficiaryReward = miningBeneficiaryReward;
return this;
}
public ParallelizedTransactionContext build() {
return new ParallelizedTransactionContext(
transactionAccumulator,
transactionProcessingResult,
isMiningBeneficiaryTouchedPreRewardByTransaction,
miningBeneficiaryReward);
}
}
}

@ -0,0 +1,114 @@
/*
* 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.ethereum.mainnet.parallelization;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.trie.diffbased.common.worldview.accumulator.DiffBasedWorldStateUpdateAccumulator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Optional;
import java.util.Set;
public class TransactionCollisionDetector {
/**
* Determines if a transaction has a collision based on the addresses it touches. A collision
* occurs if the transaction touches the mining beneficiary address or if there are common
* addresses touched by both the transaction and other transactions within the same block.
*
* @param transaction The transaction to check for collisions.
* @param miningBeneficiary The address of the mining beneficiary.
* @param parallelizedTransactionContext The context containing the accumulator for the
* transaction.
* @param blockAccumulator The accumulator for the block.
* @return true if there is a collision; false otherwise.
*/
public boolean hasCollision(
final Transaction transaction,
final Address miningBeneficiary,
final ParallelizedTransactionContext parallelizedTransactionContext,
final DiffBasedWorldStateUpdateAccumulator<?> blockAccumulator) {
final Set<Address> addressesTouchedByTransaction =
getAddressesTouchedByTransaction(
transaction, Optional.of(parallelizedTransactionContext.transactionAccumulator()));
if (addressesTouchedByTransaction.contains(miningBeneficiary)) {
return true;
}
final Set<Address> addressesTouchedByBlock =
getAddressesTouchedByBlock(Optional.of(blockAccumulator));
final Iterator<Address> it = addressesTouchedByTransaction.iterator();
boolean commonAddressFound = false;
while (it.hasNext() && !commonAddressFound) {
if (addressesTouchedByBlock.contains(it.next())) {
commonAddressFound = true;
}
}
return commonAddressFound;
}
/**
* Retrieves the set of addresses that were touched by a transaction. This includes the sender and
* recipient of the transaction, as well as any addresses that were read from or written to by the
* transaction's execution.
*
* @param transaction The transaction to analyze.
* @param accumulator An optional accumulator containing state changes made by the transaction.
* @return A set of addresses touched by the transaction.
*/
public Set<Address> getAddressesTouchedByTransaction(
final Transaction transaction,
final Optional<DiffBasedWorldStateUpdateAccumulator<?>> accumulator) {
HashSet<Address> addresses = new HashSet<>();
addresses.add(transaction.getSender());
if (transaction.getTo().isPresent()) {
addresses.add(transaction.getTo().get());
}
accumulator.ifPresent(
diffBasedWorldStateUpdateAccumulator -> {
diffBasedWorldStateUpdateAccumulator
.getAccountsToUpdate()
.forEach((address, diffBasedValue) -> addresses.add(address));
addresses.addAll(diffBasedWorldStateUpdateAccumulator.getDeletedAccountAddresses());
});
return addresses;
}
/**
* Retrieves the set of addresses that were touched by all transactions within a block. This
* method filters out addresses that were only read and not modified.
*
* @param accumulator An optional accumulator containing state changes made by the block.
* @return A set of addresses that were modified by the block's transactions.
*/
private Set<Address> getAddressesTouchedByBlock(
final Optional<DiffBasedWorldStateUpdateAccumulator<?>> accumulator) {
HashSet<Address> addresses = new HashSet<>();
accumulator.ifPresent(
diffBasedWorldStateUpdateAccumulator -> {
diffBasedWorldStateUpdateAccumulator
.getAccountsToUpdate()
.forEach(
(address, diffBasedValue) -> {
if (!diffBasedValue.isUnchanged()) {
addresses.add(address);
}
});
addresses.addAll(diffBasedWorldStateUpdateAccumulator.getDeletedAccountAddresses());
});
return addresses;
}
}

@ -0,0 +1,44 @@
/*
* 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.ethereum.trie.diffbased.bonsai.cache;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.datatypes.StorageSlotKey;
import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.BonsaiWorldStateKeyValueStorage;
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
public class NoopBonsaiCachedMerkleTrieLoader extends BonsaiCachedMerkleTrieLoader {
public NoopBonsaiCachedMerkleTrieLoader() {
super(new NoOpMetricsSystem());
}
@Override
public void preLoadAccount(
final BonsaiWorldStateKeyValueStorage worldStateKeyValueStorage,
final Hash worldStateRootHash,
final Address account) {
// noop
}
@Override
public void preLoadStorageSlot(
final BonsaiWorldStateKeyValueStorage worldStateKeyValueStorage,
final Address account,
final StorageSlotKey slotKey) {
// noop
}
}

@ -76,6 +76,18 @@ public class BonsaiWorldState extends DiffBasedWorldState {
diffBasedWorldStateConfig); diffBasedWorldStateConfig);
} }
public BonsaiWorldState(
final BonsaiWorldState worldState,
final BonsaiCachedMerkleTrieLoader cachedMerkleTrieLoader) {
this(
new BonsaiWorldStateLayerStorage(worldState.getWorldStateStorage()),
cachedMerkleTrieLoader,
worldState.cachedWorldStorageManager,
worldState.trieLogManager,
worldState.accumulator.getEvmConfiguration(),
new DiffBasedWorldStateConfig(worldState.worldStateConfig));
}
public BonsaiWorldState( public BonsaiWorldState(
final BonsaiWorldStateKeyValueStorage worldStateKeyValueStorage, final BonsaiWorldStateKeyValueStorage worldStateKeyValueStorage,
final BonsaiCachedMerkleTrieLoader bonsaiCachedMerkleTrieLoader, final BonsaiCachedMerkleTrieLoader bonsaiCachedMerkleTrieLoader,

@ -90,7 +90,7 @@ public abstract class DiffBasedWorldStateUpdateAccumulator<ACCOUNT extends DiffB
this.evmConfiguration = evmConfiguration; this.evmConfiguration = evmConfiguration;
} }
protected void cloneFromUpdater(final DiffBasedWorldStateUpdateAccumulator<ACCOUNT> source) { public void cloneFromUpdater(final DiffBasedWorldStateUpdateAccumulator<ACCOUNT> source) {
accountsToUpdate.putAll(source.getAccountsToUpdate()); accountsToUpdate.putAll(source.getAccountsToUpdate());
codeToUpdate.putAll(source.codeToUpdate); codeToUpdate.putAll(source.codeToUpdate);
storageToClear.addAll(source.storageToClear); storageToClear.addAll(source.storageToClear);
@ -100,6 +100,120 @@ public abstract class DiffBasedWorldStateUpdateAccumulator<ACCOUNT extends DiffB
this.isAccumulatorStateChanged = true; this.isAccumulatorStateChanged = true;
} }
/**
* Integrates prior state changes from an external source into the current state. This method
* retrieves state modifications from the specified source and adds them to the current state's
* list of modifications. It does not remove any existing elements in the current state's
* modification list. If a modification has been made in both the current state and the source,
* the modification from the source will be taken. This approach ensures that the source's state
* changes are prioritized and overrides any conflicting changes in the current state.
*
* @param source The source accumulator
*/
public void importStateChangesFromSource(
final DiffBasedWorldStateUpdateAccumulator<ACCOUNT> source) {
source
.getAccountsToUpdate()
.forEach(
(address, diffBasedValue) -> {
ACCOUNT copyPrior =
diffBasedValue.getPrior() != null
? copyAccount(diffBasedValue.getPrior(), this, false)
: null;
ACCOUNT copyUpdated =
diffBasedValue.getUpdated() != null
? copyAccount(diffBasedValue.getUpdated(), this, true)
: null;
accountsToUpdate.put(address, new DiffBasedValue<>(copyPrior, copyUpdated));
});
source
.getCodeToUpdate()
.forEach(
(address, diffBasedValue) -> {
codeToUpdate.put(
address,
new DiffBasedValue<>(diffBasedValue.getPrior(), diffBasedValue.getUpdated()));
});
source
.getStorageToUpdate()
.forEach(
(address, slots) -> {
StorageConsumingMap<StorageSlotKey, DiffBasedValue<UInt256>> storageConsumingMap =
storageToUpdate.computeIfAbsent(
address,
k ->
new StorageConsumingMap<>(
address, new ConcurrentHashMap<>(), storagePreloader));
slots.forEach(
(storageSlotKey, uInt256DiffBasedValue) -> {
storageConsumingMap.put(
storageSlotKey,
new DiffBasedValue<>(
uInt256DiffBasedValue.getPrior(), uInt256DiffBasedValue.getUpdated()));
});
});
storageToClear.addAll(source.storageToClear);
this.isAccumulatorStateChanged = true;
}
/**
* Imports unchanged state data from an external source into the current state. This method
* focuses on integrating state data from the specified source that has been read but not
* modified.
*
* <p>The method ensures that only new, unmodified data from the source is added to the current
* state. If a state data has already been read or modified in the current state, it will not be
* added again to avoid overwriting any existing modifications.
*
* @param source The source accumulator
*/
public void importPriorStateFromSource(
final DiffBasedWorldStateUpdateAccumulator<ACCOUNT> source) {
source
.getAccountsToUpdate()
.forEach(
(address, diffBasedValue) -> {
ACCOUNT copyPrior =
diffBasedValue.getPrior() != null
? copyAccount(diffBasedValue.getPrior(), this, false)
: null;
ACCOUNT copyUpdated =
diffBasedValue.getPrior() != null
? copyAccount(diffBasedValue.getPrior(), this, true)
: null;
accountsToUpdate.putIfAbsent(address, new DiffBasedValue<>(copyPrior, copyUpdated));
});
source
.getCodeToUpdate()
.forEach(
(address, diffBasedValue) -> {
codeToUpdate.putIfAbsent(
address,
new DiffBasedValue<>(diffBasedValue.getPrior(), diffBasedValue.getPrior()));
});
source
.getStorageToUpdate()
.forEach(
(address, slots) -> {
StorageConsumingMap<StorageSlotKey, DiffBasedValue<UInt256>> storageConsumingMap =
storageToUpdate.computeIfAbsent(
address,
k ->
new StorageConsumingMap<>(
address, new ConcurrentHashMap<>(), storagePreloader));
slots.forEach(
(storageSlotKey, uInt256DiffBasedValue) -> {
storageConsumingMap.putIfAbsent(
storageSlotKey,
new DiffBasedValue<>(
uInt256DiffBasedValue.getPrior(), uInt256DiffBasedValue.getPrior()));
});
});
this.isAccumulatorStateChanged = true;
}
protected Consumer<DiffBasedValue<ACCOUNT>> getAccountPreloader() { protected Consumer<DiffBasedValue<ACCOUNT>> getAccountPreloader() {
return accountPreloader; return accountPreloader;
} }
@ -108,7 +222,7 @@ public abstract class DiffBasedWorldStateUpdateAccumulator<ACCOUNT extends DiffB
return storagePreloader; return storagePreloader;
} }
protected EvmConfiguration getEvmConfiguration() { public EvmConfiguration getEvmConfiguration() {
return evmConfiguration; return evmConfiguration;
} }
@ -234,6 +348,7 @@ public abstract class DiffBasedWorldStateUpdateAccumulator<ACCOUNT extends DiffB
@Override @Override
public void commit() { public void commit() {
this.isAccumulatorStateChanged = true; this.isAccumulatorStateChanged = true;
for (final Address deletedAddress : getDeletedAccounts()) { for (final Address deletedAddress : getDeletedAccounts()) {
final DiffBasedValue<ACCOUNT> accountValue = final DiffBasedValue<ACCOUNT> accountValue =
accountsToUpdate.computeIfAbsent( accountsToUpdate.computeIfAbsent(
@ -305,7 +420,6 @@ public abstract class DiffBasedWorldStateUpdateAccumulator<ACCOUNT extends DiffB
final ACCOUNT updatedAccount; final ACCOUNT updatedAccount;
final DiffBasedValue<ACCOUNT> updatedAccountValue = final DiffBasedValue<ACCOUNT> updatedAccountValue =
accountsToUpdate.get(updatedAddress); accountsToUpdate.get(updatedAddress);
final Map<StorageSlotKey, DiffBasedValue<UInt256>> pendingStorageUpdates = final Map<StorageSlotKey, DiffBasedValue<UInt256>> pendingStorageUpdates =
storageToUpdate.computeIfAbsent( storageToUpdate.computeIfAbsent(
updatedAddress, updatedAddress,
@ -359,12 +473,6 @@ public abstract class DiffBasedWorldStateUpdateAccumulator<ACCOUNT extends DiffB
pendingStorageUpdates.clear(); pendingStorageUpdates.clear();
} }
// This is especially to avoid unnecessary computation for withdrawals and
// self-destruct beneficiaries
if (updatedAccount.getUpdatedStorage().isEmpty()) {
return;
}
// parallel stream here may cause database corruption // parallel stream here may cause database corruption
updatedAccount updatedAccount
.getUpdatedStorage() .getUpdatedStorage()

@ -85,6 +85,8 @@ public interface DataStorageConfiguration {
boolean DEFAULT_BONSAI_FULL_FLAT_DB_ENABLED = true; boolean DEFAULT_BONSAI_FULL_FLAT_DB_ENABLED = true;
boolean DEFAULT_BONSAI_CODE_USING_CODE_HASH_ENABLED = true; boolean DEFAULT_BONSAI_CODE_USING_CODE_HASH_ENABLED = true;
boolean DEFAULT_PARALLEL_TRX_ENABLED = false;
DataStorageConfiguration.Unstable DEFAULT = DataStorageConfiguration.Unstable DEFAULT =
ImmutableDataStorageConfiguration.Unstable.builder().build(); ImmutableDataStorageConfiguration.Unstable.builder().build();
@ -100,5 +102,10 @@ public interface DataStorageConfiguration {
default boolean getBonsaiCodeStoredByCodeHashEnabled() { default boolean getBonsaiCodeStoredByCodeHashEnabled() {
return DEFAULT_BONSAI_CODE_USING_CODE_HASH_ENABLED; return DEFAULT_BONSAI_CODE_USING_CODE_HASH_ENABLED;
} }
@Value.Default
default boolean isParallelTxProcessingEnabled() {
return DEFAULT_PARALLEL_TRX_ENABLED;
}
} }
} }

@ -142,7 +142,9 @@ public class BlockchainSetupUtil {
genesisConfigFile.getConfigOptions(), genesisConfigFile.getConfigOptions(),
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
MiningParameters.newDefault(), MiningParameters.newDefault(),
new BadBlockManager()); new BadBlockManager(),
false,
new NoOpMetricsSystem());
} }
private static ProtocolContext mainnetProtocolContextProvider( private static ProtocolContext mainnetProtocolContextProvider(

@ -146,7 +146,9 @@ public class ExecutionContextTestFixture {
false, false,
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED, MiningParameters.MINING_DISABLED,
new BadBlockManager()) new BadBlockManager(),
false,
new NoOpMetricsSystem())
.createProtocolSchedule(); .createProtocolSchedule();
} }
if (blockchainKeyValueStorage == null) { if (blockchainKeyValueStorage == null) {

@ -23,6 +23,7 @@ import org.hyperledger.besu.ethereum.chain.BadBlockManager;
import org.hyperledger.besu.ethereum.mainnet.MainnetProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.MainnetProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.evm.internal.EvmConfiguration;
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
import java.io.IOException; import java.io.IOException;
@ -39,7 +40,9 @@ public class ProtocolScheduleFixture {
false, false,
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
MiningParameters.newDefault(), MiningParameters.newDefault(),
new BadBlockManager()); new BadBlockManager(),
false,
new NoOpMetricsSystem());
private static GenesisConfigOptions getMainnetConfigOptions() { private static GenesisConfigOptions getMainnetConfigOptions() {
// this method avoids reading all the alloc accounts when all we want is the "config" section // this method avoids reading all the alloc accounts when all we want is the "config" section

@ -41,6 +41,7 @@ import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
import org.hyperledger.besu.ethereum.mainnet.blockhash.FrontierBlockHashProcessor; import org.hyperledger.besu.ethereum.mainnet.blockhash.FrontierBlockHashProcessor;
import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket;
import org.hyperledger.besu.ethereum.mainnet.requests.RequestsValidatorCoordinator; import org.hyperledger.besu.ethereum.mainnet.requests.RequestsValidatorCoordinator;
import org.hyperledger.besu.ethereum.storage.StorageProvider; import org.hyperledger.besu.ethereum.storage.StorageProvider;
import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.BonsaiWorldStateProvider; import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.BonsaiWorldStateProvider;
@ -50,6 +51,7 @@ import org.hyperledger.besu.ethereum.trie.diffbased.common.worldview.DiffBasedWo
import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration;
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator;
import org.hyperledger.besu.evm.gascalculator.GasCalculator;
import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.evm.internal.EvmConfiguration;
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
import org.hyperledger.besu.plugin.services.exception.StorageException; import org.hyperledger.besu.plugin.services.exception.StorageException;
@ -80,6 +82,8 @@ class BlockImportExceptionHandlingTest {
private final BlockBodyValidator blockBodyValidator = mock(BlockBodyValidator.class); private final BlockBodyValidator blockBodyValidator = mock(BlockBodyValidator.class);
private final ProtocolContext protocolContext = mock(ProtocolContext.class); private final ProtocolContext protocolContext = mock(ProtocolContext.class);
private final ProtocolSpec protocolSpec = mock(ProtocolSpec.class); private final ProtocolSpec protocolSpec = mock(ProtocolSpec.class);
private final GasCalculator gasCalculator = mock(GasCalculator.class);
private final FeeMarket feeMarket = mock(FeeMarket.class);
protected final MutableBlockchain blockchain = mock(MutableBlockchain.class); protected final MutableBlockchain blockchain = mock(MutableBlockchain.class);
private final StorageProvider storageProvider = new InMemoryKeyValueStorageProvider(); private final StorageProvider storageProvider = new InMemoryKeyValueStorageProvider();
@ -116,6 +120,8 @@ class BlockImportExceptionHandlingTest {
when(protocolSpec.getRequestsValidatorCoordinator()) when(protocolSpec.getRequestsValidatorCoordinator())
.thenReturn(RequestsValidatorCoordinator.empty()); .thenReturn(RequestsValidatorCoordinator.empty());
when(protocolSpec.getBlockHashProcessor()).thenReturn(new FrontierBlockHashProcessor()); when(protocolSpec.getBlockHashProcessor()).thenReturn(new FrontierBlockHashProcessor());
when(protocolSpec.getGasCalculator()).thenReturn(gasCalculator);
when(protocolSpec.getFeeMarket()).thenReturn(feeMarket);
mainnetBlockValidator = mainnetBlockValidator =
new MainnetBlockValidator( new MainnetBlockValidator(
blockHeaderValidator, blockBodyValidator, blockProcessor, badBlockManager); blockHeaderValidator, blockBodyValidator, blockProcessor, badBlockManager);

@ -23,6 +23,7 @@ import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
import org.hyperledger.besu.ethereum.core.MiningParameters; import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.evm.internal.EvmConfiguration;
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -36,7 +37,9 @@ public class FixedProtocolScheduleTest {
GenesisConfigFile.fromResource("/dev.json").getConfigOptions(), GenesisConfigFile.fromResource("/dev.json").getConfigOptions(),
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED, MiningParameters.MINING_DISABLED,
new BadBlockManager()); new BadBlockManager(),
false,
new NoOpMetricsSystem());
final BlockHeaderTestFixture headerBuilder = new BlockHeaderTestFixture(); final BlockHeaderTestFixture headerBuilder = new BlockHeaderTestFixture();

@ -25,6 +25,7 @@ import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
import org.hyperledger.besu.ethereum.core.MiningParameters; import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.core.PrivacyParameters; import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.evm.internal.EvmConfiguration;
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.Optional; import java.util.Optional;
@ -61,7 +62,9 @@ public class DefaultProtocolScheduleTest {
isRevertReasonEnabled, isRevertReasonEnabled,
evmConfiguration, evmConfiguration,
MiningParameters.MINING_DISABLED, MiningParameters.MINING_DISABLED,
new BadBlockManager()); new BadBlockManager(),
false,
new NoOpMetricsSystem());
} }
@Test @Test

@ -21,6 +21,7 @@ import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
import org.hyperledger.besu.ethereum.core.MiningParameters; import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.core.ProtocolScheduleFixture; import org.hyperledger.besu.ethereum.core.ProtocolScheduleFixture;
import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.evm.internal.EvmConfiguration;
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
import org.assertj.core.api.Assertions; import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -73,7 +74,9 @@ public class MainnetProtocolScheduleTest {
GenesisConfigFile.fromConfig("{}").getConfigOptions(), GenesisConfigFile.fromConfig("{}").getConfigOptions(),
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED, MiningParameters.MINING_DISABLED,
new BadBlockManager()); new BadBlockManager(),
false,
new NoOpMetricsSystem());
Assertions.assertThat(sched.getByBlockHeader(blockHeader(1L)).getName()).isEqualTo("Frontier"); Assertions.assertThat(sched.getByBlockHeader(blockHeader(1L)).getName()).isEqualTo("Frontier");
Assertions.assertThat(sched.getByBlockHeader(blockHeader(Long.MAX_VALUE)).getName()) Assertions.assertThat(sched.getByBlockHeader(blockHeader(Long.MAX_VALUE)).getName())
.isEqualTo("Frontier"); .isEqualTo("Frontier");
@ -88,7 +91,9 @@ public class MainnetProtocolScheduleTest {
GenesisConfigFile.fromConfig(json).getConfigOptions(), GenesisConfigFile.fromConfig(json).getConfigOptions(),
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED, MiningParameters.MINING_DISABLED,
new BadBlockManager()); new BadBlockManager(),
false,
new NoOpMetricsSystem());
Assertions.assertThat(sched.getByBlockHeader(blockHeader(1)).getName()).isEqualTo("Frontier"); Assertions.assertThat(sched.getByBlockHeader(blockHeader(1)).getName()).isEqualTo("Frontier");
Assertions.assertThat(sched.getByBlockHeader(blockHeader(2)).getName()).isEqualTo("Homestead"); Assertions.assertThat(sched.getByBlockHeader(blockHeader(2)).getName()).isEqualTo("Homestead");
Assertions.assertThat(sched.getByBlockHeader(blockHeader(3)).getName()) Assertions.assertThat(sched.getByBlockHeader(blockHeader(3)).getName())
@ -120,7 +125,9 @@ public class MainnetProtocolScheduleTest {
GenesisConfigFile.fromConfig(json).getConfigOptions(), GenesisConfigFile.fromConfig(json).getConfigOptions(),
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED, MiningParameters.MINING_DISABLED,
new BadBlockManager())); new BadBlockManager(),
false,
new NoOpMetricsSystem()));
} }
private BlockHeader blockHeader(final long number) { private BlockHeader blockHeader(final long number) {

@ -29,6 +29,7 @@ import org.hyperledger.besu.ethereum.core.MilestoneStreamingProtocolSchedule;
import org.hyperledger.besu.ethereum.core.MiningParameters; import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.core.PrivacyParameters; import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.evm.internal.EvmConfiguration;
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.OptionalLong; import java.util.OptionalLong;
@ -61,7 +62,9 @@ class ProtocolScheduleBuilderTest {
false, false,
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED, MiningParameters.MINING_DISABLED,
new BadBlockManager()); new BadBlockManager(),
false,
new NoOpMetricsSystem());
} }
@Test @Test
@ -216,7 +219,9 @@ class ProtocolScheduleBuilderTest {
false, false,
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED, MiningParameters.MINING_DISABLED,
new BadBlockManager()); new BadBlockManager(),
false,
new NoOpMetricsSystem());
return new MilestoneStreamingProtocolSchedule( return new MilestoneStreamingProtocolSchedule(
(DefaultProtocolSchedule) builder.createProtocolSchedule()); (DefaultProtocolSchedule) builder.createProtocolSchedule());

@ -0,0 +1,213 @@
/*
* 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.ethereum.mainnet.parallelization;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor;
import org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams;
import org.hyperledger.besu.ethereum.mainnet.ValidationResult;
import org.hyperledger.besu.ethereum.privacy.storage.PrivateMetadataUpdater;
import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult;
import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason;
import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.cache.NoOpBonsaiCachedWorldStorageManager;
import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.cache.NoopBonsaiCachedMerkleTrieLoader;
import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.BonsaiWorldStateKeyValueStorage;
import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.worldview.BonsaiWorldState;
import org.hyperledger.besu.ethereum.trie.diffbased.common.trielog.NoOpTrieLogManager;
import org.hyperledger.besu.ethereum.trie.diffbased.common.worldview.DiffBasedWorldStateConfig;
import org.hyperledger.besu.ethereum.trie.diffbased.common.worldview.accumulator.DiffBasedWorldStateUpdateAccumulator;
import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration;
import org.hyperledger.besu.evm.internal.EvmConfiguration;
import org.hyperledger.besu.evm.operation.BlockHashOperation;
import org.hyperledger.besu.evm.tracing.OperationTracer;
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
import java.util.Collections;
import java.util.Optional;
import org.apache.tuweni.bytes.Bytes;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
@ExtendWith(MockitoExtension.class)
class ParallelizedConcurrentTransactionProcessorTest {
@Mock private MainnetTransactionProcessor transactionProcessor;
@Mock private BlockHeader blockHeader;
@Mock private Transaction transaction;
@Mock private PrivateMetadataUpdater privateMetadataUpdater;
@Mock private TransactionCollisionDetector transactionCollisionDetector;
private BonsaiWorldState worldState;
private ParallelizedConcurrentTransactionProcessor processor;
@BeforeEach
void setUp() {
processor =
new ParallelizedConcurrentTransactionProcessor(
transactionProcessor, transactionCollisionDetector);
final BonsaiWorldStateKeyValueStorage bonsaiWorldStateKeyValueStorage =
new BonsaiWorldStateKeyValueStorage(
new InMemoryKeyValueStorageProvider(),
new NoOpMetricsSystem(),
DataStorageConfiguration.DEFAULT_BONSAI_CONFIG);
worldState =
new BonsaiWorldState(
bonsaiWorldStateKeyValueStorage,
new NoopBonsaiCachedMerkleTrieLoader(),
new NoOpBonsaiCachedWorldStorageManager(bonsaiWorldStateKeyValueStorage),
new NoOpTrieLogManager(),
EvmConfiguration.DEFAULT,
new DiffBasedWorldStateConfig());
when(transactionCollisionDetector.hasCollision(any(), any(), any(), any())).thenReturn(false);
}
@Test
void testRunTransaction() {
Address miningBeneficiary = Address.fromHexString("0x1");
Wei blobGasPrice = Wei.ZERO;
Mockito.when(
transactionProcessor.processTransaction(
any(), any(), any(), any(), any(), any(), anyBoolean(), any(), any(), any()))
.thenReturn(
TransactionProcessingResult.successful(
Collections.emptyList(), 0, 0, Bytes.EMPTY, ValidationResult.valid()));
processor.runTransaction(
worldState,
blockHeader,
0,
transaction,
miningBeneficiary,
(blockNumber) -> Hash.EMPTY,
blobGasPrice,
privateMetadataUpdater);
verify(transactionProcessor, times(1))
.processTransaction(
any(DiffBasedWorldStateUpdateAccumulator.class),
eq(blockHeader),
eq(transaction),
eq(miningBeneficiary),
any(OperationTracer.class),
any(BlockHashOperation.BlockHashLookup.class),
eq(true),
eq(TransactionValidationParams.processingBlock()),
eq(privateMetadataUpdater),
eq(blobGasPrice));
assertTrue(
processor
.applyParallelizedTransactionResult(
worldState, miningBeneficiary, transaction, 0, Optional.empty(), Optional.empty())
.isPresent(),
"Expected the transaction context to be stored");
}
@Test
void testRunTransactionWithFailure() {
Address miningBeneficiary = Address.fromHexString("0x1");
Wei blobGasPrice = Wei.ZERO;
when(transactionProcessor.processTransaction(
any(), any(), any(), any(), any(), any(), anyBoolean(), any(), any(), any()))
.thenReturn(
TransactionProcessingResult.failed(
0,
0,
ValidationResult.invalid(
TransactionInvalidReason.BLOB_GAS_PRICE_BELOW_CURRENT_BLOB_BASE_FEE),
Optional.of(Bytes.EMPTY)));
processor.runTransaction(
worldState,
blockHeader,
0,
transaction,
miningBeneficiary,
(blockNumber) -> Hash.EMPTY,
blobGasPrice,
privateMetadataUpdater);
Optional<TransactionProcessingResult> result =
processor.applyParallelizedTransactionResult(
worldState, miningBeneficiary, transaction, 0, Optional.empty(), Optional.empty());
assertTrue(result.isEmpty(), "Expected the transaction result to indicate a failure");
}
@Test
void testRunTransactionWithConflict() {
Address miningBeneficiary = Address.fromHexString("0x1");
Wei blobGasPrice = Wei.ZERO;
Mockito.when(
transactionProcessor.processTransaction(
any(), any(), any(), any(), any(), any(), anyBoolean(), any(), any(), any()))
.thenReturn(
TransactionProcessingResult.successful(
Collections.emptyList(), 0, 0, Bytes.EMPTY, ValidationResult.valid()));
processor.runTransaction(
worldState,
blockHeader,
0,
transaction,
miningBeneficiary,
(blockNumber) -> Hash.EMPTY,
blobGasPrice,
privateMetadataUpdater);
verify(transactionProcessor, times(1))
.processTransaction(
any(DiffBasedWorldStateUpdateAccumulator.class),
eq(blockHeader),
eq(transaction),
eq(miningBeneficiary),
any(OperationTracer.class),
any(BlockHashOperation.BlockHashLookup.class),
eq(true),
eq(TransactionValidationParams.processingBlock()),
eq(privateMetadataUpdater),
eq(blobGasPrice));
// simulate a conflict
when(transactionCollisionDetector.hasCollision(any(), any(), any(), any())).thenReturn(true);
Optional<TransactionProcessingResult> result =
processor.applyParallelizedTransactionResult(
worldState, miningBeneficiary, transaction, 0, Optional.empty(), Optional.empty());
assertTrue(result.isEmpty(), "Expected no transaction result to be applied due to conflict");
}
}

@ -0,0 +1,290 @@
/*
* 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.ethereum.mainnet.parallelization;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.BonsaiAccount;
import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.worldview.BonsaiWorldState;
import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.worldview.BonsaiWorldStateUpdateAccumulator;
import org.hyperledger.besu.ethereum.trie.diffbased.common.DiffBasedValue;
import org.hyperledger.besu.evm.internal.EvmConfiguration;
import java.math.BigInteger;
import org.apache.tuweni.bytes.Bytes;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
@ExtendWith(MockitoExtension.class)
class TransactionCollisionDetectorTest {
private TransactionCollisionDetector collisionDetector;
@Mock BonsaiWorldState worldState;
BonsaiWorldStateUpdateAccumulator bonsaiUpdater;
BonsaiWorldStateUpdateAccumulator trxUpdater;
@BeforeEach
public void setUp() {
collisionDetector = new TransactionCollisionDetector();
bonsaiUpdater =
new BonsaiWorldStateUpdateAccumulator(
worldState, (__, ___) -> {}, (__, ___) -> {}, EvmConfiguration.DEFAULT);
trxUpdater =
new BonsaiWorldStateUpdateAccumulator(
worldState, (__, ___) -> {}, (__, ___) -> {}, EvmConfiguration.DEFAULT);
}
private Transaction createTransaction(final Address sender, final Address to) {
return new Transaction.Builder()
.nonce(1)
.gasPrice(Wei.of(1))
.gasLimit(21000)
.to(to)
.value(Wei.ZERO)
.payload(Bytes.EMPTY)
.chainId(BigInteger.ONE)
.sender(sender)
.build();
}
private BonsaiAccount createAccount(final Address address) {
return new BonsaiAccount(
worldState,
address,
Hash.hash(Address.ZERO),
0,
Wei.ONE,
Hash.EMPTY_TRIE_HASH,
Hash.EMPTY,
false);
}
@Test
void testCollisionWithModifiedBalance() {
final Address address = Address.fromHexString("0x1");
final BonsaiAccount priorAccountValue = createAccount(address);
final BonsaiAccount nextAccountValue = new BonsaiAccount(priorAccountValue, worldState, true);
nextAccountValue.setBalance(Wei.MAX_WEI);
// Simulate that the address was already modified in the block
bonsaiUpdater
.getAccountsToUpdate()
.put(address, new DiffBasedValue<>(priorAccountValue, nextAccountValue));
final Transaction transaction = createTransaction(address, address);
// Simulate that the address is read in the next transaction
trxUpdater
.getAccountsToUpdate()
.put(address, new DiffBasedValue<>(priorAccountValue, priorAccountValue));
boolean hasCollision =
collisionDetector.hasCollision(
transaction,
Address.ZERO,
new ParallelizedTransactionContext(trxUpdater, null, false, Wei.ZERO),
bonsaiUpdater);
assertTrue(hasCollision, "Expected a collision with the modified address");
}
@Test
void testCollisionWithModifiedNonce() {
final Address address = Address.fromHexString("0x1");
final BonsaiAccount priorAccountValue = createAccount(address);
final BonsaiAccount nextAccountValue = new BonsaiAccount(priorAccountValue, worldState, true);
nextAccountValue.setNonce(1);
// Simulate that the address was already modified in the block
bonsaiUpdater
.getAccountsToUpdate()
.put(address, new DiffBasedValue<>(priorAccountValue, nextAccountValue));
final Transaction transaction = createTransaction(address, address);
// Simulate that the address is read in the next transaction
trxUpdater
.getAccountsToUpdate()
.put(address, new DiffBasedValue<>(priorAccountValue, priorAccountValue));
boolean hasCollision =
collisionDetector.hasCollision(
transaction,
Address.ZERO,
new ParallelizedTransactionContext(trxUpdater, null, false, Wei.ZERO),
bonsaiUpdater);
assertTrue(hasCollision, "Expected a collision with the modified address");
}
@Test
void testCollisionWithModifiedCode() {
final Address address = Address.fromHexString("0x1");
final BonsaiAccount priorAccountValue = createAccount(address);
final BonsaiAccount nextAccountValue = new BonsaiAccount(priorAccountValue, worldState, true);
nextAccountValue.setCode(Bytes.repeat((byte) 0x01, 10));
// Simulate that the address was already modified in the block
bonsaiUpdater
.getAccountsToUpdate()
.put(address, new DiffBasedValue<>(priorAccountValue, nextAccountValue));
final Transaction transaction = createTransaction(address, address);
// Simulate that the address is read in the next transaction
trxUpdater
.getAccountsToUpdate()
.put(address, new DiffBasedValue<>(priorAccountValue, priorAccountValue));
boolean hasCollision =
collisionDetector.hasCollision(
transaction,
Address.ZERO,
new ParallelizedTransactionContext(trxUpdater, null, false, Wei.ZERO),
bonsaiUpdater);
assertTrue(hasCollision, "Expected a collision with the modified address");
}
@Test
void testCollisionWithModifiedStorageRoot() {
final Address address = Address.fromHexString("0x1");
final BonsaiAccount priorAccountValue = createAccount(address);
final BonsaiAccount nextAccountValue = new BonsaiAccount(priorAccountValue, worldState, true);
nextAccountValue.setStorageRoot(Hash.EMPTY);
// Simulate that the address was already modified in the block
bonsaiUpdater
.getAccountsToUpdate()
.put(address, new DiffBasedValue<>(priorAccountValue, nextAccountValue));
final Transaction transaction = createTransaction(address, address);
// Simulate that the address is read in the next transaction
trxUpdater
.getAccountsToUpdate()
.put(address, new DiffBasedValue<>(priorAccountValue, priorAccountValue));
boolean hasCollision =
collisionDetector.hasCollision(
transaction,
Address.ZERO,
new ParallelizedTransactionContext(trxUpdater, null, false, Wei.ZERO),
bonsaiUpdater);
assertTrue(hasCollision, "Expected a collision with the modified address");
}
@Test
void testCollisionWithMiningBeneficiaryAddress() {
final Address miningBeneficiary = Address.ZERO;
final Address address = Address.fromHexString("0x1");
final Transaction transaction = createTransaction(miningBeneficiary, address);
boolean hasCollision =
collisionDetector.hasCollision(
transaction,
miningBeneficiary,
new ParallelizedTransactionContext(trxUpdater, null, false, Wei.ZERO),
bonsaiUpdater);
assertTrue(hasCollision, "Expected collision with the mining beneficiary address as sender");
}
@Test
void testCollisionWithAnotherMiningBeneficiaryAddress() {
final Address miningBeneficiary = Address.ZERO;
final Address address = Address.fromHexString("0x1");
final BonsaiAccount miningBeneficiaryValue = createAccount(address);
final Transaction transaction = createTransaction(address, address);
// Simulate that the mining beneficiary is read in the next transaction
trxUpdater
.getAccountsToUpdate()
.put(
miningBeneficiary,
new DiffBasedValue<>(miningBeneficiaryValue, miningBeneficiaryValue));
boolean hasCollision =
collisionDetector.hasCollision(
transaction,
miningBeneficiary,
new ParallelizedTransactionContext(trxUpdater, null, true, Wei.ZERO),
bonsaiUpdater);
assertTrue(hasCollision, "Expected collision with the read mining beneficiary address");
}
@Test
void testCollisionWithDeletedAddress() {
final Address address = Address.fromHexString("0x1");
final BonsaiAccount accountValue = createAccount(address);
// Simulate that the address was deleted in the block
bonsaiUpdater.getDeletedAccountAddresses().add(address);
final Transaction transaction = createTransaction(address, address);
// Simulate that the deleted address is read in the next transaction
trxUpdater.getAccountsToUpdate().put(address, new DiffBasedValue<>(accountValue, accountValue));
boolean hasCollision =
collisionDetector.hasCollision(
transaction,
Address.ZERO,
new ParallelizedTransactionContext(trxUpdater, null, false, Wei.ZERO),
bonsaiUpdater);
assertTrue(hasCollision, "Expected a collision with the deleted address");
}
@Test
void testCollisionWithNoModifiedAddress() {
final Address address = Address.fromHexString("0x1");
final BonsaiAccount priorAccountValue = createAccount(address);
// Simulate that the address was already read in the block
bonsaiUpdater
.getAccountsToUpdate()
.put(address, new DiffBasedValue<>(priorAccountValue, priorAccountValue));
final Transaction transaction = createTransaction(address, address);
// Simulate that the address is read in the next transaction
trxUpdater
.getAccountsToUpdate()
.put(address, new DiffBasedValue<>(priorAccountValue, priorAccountValue));
boolean hasCollision =
collisionDetector.hasCollision(
transaction,
Address.ZERO,
new ParallelizedTransactionContext(trxUpdater, null, false, Wei.ZERO),
bonsaiUpdater);
assertFalse(hasCollision, "Expected no collision with the read address");
}
}

@ -105,7 +105,9 @@ public abstract class AbstractIsolationTests {
MainnetProtocolSchedule.fromConfig( MainnetProtocolSchedule.fromConfig(
GenesisConfigFile.fromResource("/dev.json").getConfigOptions(), GenesisConfigFile.fromResource("/dev.json").getConfigOptions(),
MiningParameters.MINING_DISABLED, MiningParameters.MINING_DISABLED,
new BadBlockManager()); new BadBlockManager(),
false,
new NoOpMetricsSystem());
protected final GenesisState genesisState = protected final GenesisState genesisState =
GenesisState.fromConfig(GenesisConfigFile.fromResource("/dev.json"), protocolSchedule); GenesisState.fromConfig(GenesisConfigFile.fromResource("/dev.json"), protocolSchedule);
protected final MutableBlockchain blockchain = createInMemoryBlockchain(genesisState.getBlock()); protected final MutableBlockchain blockchain = createInMemoryBlockchain(genesisState.getBlock());

@ -34,6 +34,7 @@ import org.hyperledger.besu.ethereum.rlp.RLP;
import org.hyperledger.besu.ethereum.rlp.RLPException; import org.hyperledger.besu.ethereum.rlp.RLPException;
import org.hyperledger.besu.ethereum.rlp.RLPInput; import org.hyperledger.besu.ethereum.rlp.RLPInput;
import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.evm.internal.EvmConfiguration;
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
@ -60,7 +61,9 @@ public final class BlockBodiesMessageTest {
false, false,
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED, MiningParameters.MINING_DISABLED,
new BadBlockManager()); new BadBlockManager(),
false,
new NoOpMetricsSystem());
} }
@Test @Test

@ -26,6 +26,7 @@ import org.hyperledger.besu.ethereum.rlp.BytesValueRLPInput;
import org.hyperledger.besu.ethereum.rlp.RLP; import org.hyperledger.besu.ethereum.rlp.RLP;
import org.hyperledger.besu.ethereum.rlp.RLPInput; import org.hyperledger.besu.ethereum.rlp.RLPInput;
import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.evm.internal.EvmConfiguration;
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
@ -67,7 +68,9 @@ public final class BlockHeadersMessageTest {
false, false,
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED, MiningParameters.MINING_DISABLED,
new BadBlockManager())); new BadBlockManager(),
false,
new NoOpMetricsSystem()));
for (int i = 0; i < 50; ++i) { for (int i = 0; i < 50; ++i) {
Assertions.assertThat(readHeaders.get(i)).isEqualTo(headers.get(i)); Assertions.assertThat(readHeaders.get(i)).isEqualTo(headers.get(i));

@ -59,7 +59,9 @@ public class ChainHeadTrackerTest {
false, false,
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED, MiningParameters.MINING_DISABLED,
new BadBlockManager()); new BadBlockManager(),
false,
new NoOpMetricsSystem());
private final TrailingPeerLimiter trailingPeerLimiter = mock(TrailingPeerLimiter.class); private final TrailingPeerLimiter trailingPeerLimiter = mock(TrailingPeerLimiter.class);

@ -48,6 +48,7 @@ import org.hyperledger.besu.ethereum.mainnet.MainnetProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
import org.hyperledger.besu.ethereum.referencetests.ForestReferenceTestWorldState; import org.hyperledger.besu.ethereum.referencetests.ForestReferenceTestWorldState;
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
import org.hyperledger.besu.plugin.services.MetricsSystem; import org.hyperledger.besu.plugin.services.MetricsSystem;
import org.hyperledger.besu.services.kvstore.InMemoryKeyValueStorage; import org.hyperledger.besu.services.kvstore.InMemoryKeyValueStorage;
@ -93,7 +94,11 @@ public class BackwardSyncContextTest {
@Spy @Spy
private ProtocolSchedule protocolSchedule = private ProtocolSchedule protocolSchedule =
MainnetProtocolSchedule.fromConfig( MainnetProtocolSchedule.fromConfig(
new StubGenesisConfigOptions(), MiningParameters.MINING_DISABLED, new BadBlockManager()); new StubGenesisConfigOptions(),
MiningParameters.MINING_DISABLED,
new BadBlockManager(),
false,
new NoOpMetricsSystem());
@Spy @Spy
private ProtocolSpec protocolSpec = private ProtocolSpec protocolSpec =

@ -39,6 +39,7 @@ import org.hyperledger.besu.ethereum.eth.manager.exceptions.MaxRetriesReachedExc
import org.hyperledger.besu.ethereum.mainnet.MainnetBlockHeaderFunctions; import org.hyperledger.besu.ethereum.mainnet.MainnetBlockHeaderFunctions;
import org.hyperledger.besu.ethereum.mainnet.MainnetProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.MainnetProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
import org.hyperledger.besu.services.kvstore.InMemoryKeyValueStorage; import org.hyperledger.besu.services.kvstore.InMemoryKeyValueStorage;
import org.hyperledger.besu.testutil.DeterministicEthScheduler; import org.hyperledger.besu.testutil.DeterministicEthScheduler;
@ -70,7 +71,11 @@ public class BackwardSyncStepTest {
private final ProtocolSchedule protocolSchedule = private final ProtocolSchedule protocolSchedule =
MainnetProtocolSchedule.fromConfig( MainnetProtocolSchedule.fromConfig(
new StubGenesisConfigOptions(), MiningParameters.MINING_DISABLED, new BadBlockManager()); new StubGenesisConfigOptions(),
MiningParameters.MINING_DISABLED,
new BadBlockManager(),
false,
new NoOpMetricsSystem());
private final DeterministicEthScheduler ethScheduler = new DeterministicEthScheduler(); private final DeterministicEthScheduler ethScheduler = new DeterministicEthScheduler();

@ -38,6 +38,7 @@ import org.hyperledger.besu.ethereum.mainnet.MainnetBlockHeaderFunctions;
import org.hyperledger.besu.ethereum.mainnet.MainnetProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.MainnetProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.referencetests.ForestReferenceTestWorldState; import org.hyperledger.besu.ethereum.referencetests.ForestReferenceTestWorldState;
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
import org.hyperledger.besu.services.kvstore.InMemoryKeyValueStorage; import org.hyperledger.besu.services.kvstore.InMemoryKeyValueStorage;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
@ -73,7 +74,11 @@ public class ForwardSyncStepTest {
private final ProtocolSchedule protocolSchedule = private final ProtocolSchedule protocolSchedule =
MainnetProtocolSchedule.fromConfig( MainnetProtocolSchedule.fromConfig(
new StubGenesisConfigOptions(), MiningParameters.MINING_DISABLED, new BadBlockManager()); new StubGenesisConfigOptions(),
MiningParameters.MINING_DISABLED,
new BadBlockManager(),
false,
new NoOpMetricsSystem());
private MutableBlockchain localBlockchain; private MutableBlockchain localBlockchain;
GenericKeyValueStorageFacade<Hash, BlockHeader> headersStorage; GenericKeyValueStorageFacade<Hash, BlockHeader> headersStorage;
GenericKeyValueStorageFacade<Hash, Block> blocksStorage; GenericKeyValueStorageFacade<Hash, Block> blocksStorage;

@ -201,7 +201,9 @@ public abstract class AbstractTransactionPoolTest {
false, false,
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED, MiningParameters.MINING_DISABLED,
new BadBlockManager()) new BadBlockManager(),
false,
new NoOpMetricsSystem())
.createProtocolSchedule(); .createProtocolSchedule();
final ExecutionContextTestFixture executionContextTestFixture = final ExecutionContextTestFixture executionContextTestFixture =
ExecutionContextTestFixture.builder(genesisConfigFile) ExecutionContextTestFixture.builder(genesisConfigFile)

@ -123,7 +123,9 @@ public class TestNode implements Closeable {
false, false,
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED, MiningParameters.MINING_DISABLED,
new BadBlockManager()); new BadBlockManager(),
false,
new NoOpMetricsSystem());
final GenesisState genesisState = GenesisState.fromConfig(genesisConfigFile, protocolSchedule); final GenesisState genesisState = GenesisState.fromConfig(genesisConfigFile, protocolSchedule);
final BlockHeaderFunctions blockHeaderFunctions = final BlockHeaderFunctions blockHeaderFunctions =

@ -379,7 +379,9 @@ public class TransactionPoolFactoryTest {
false, false,
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED, MiningParameters.MINING_DISABLED,
new BadBlockManager()) new BadBlockManager(),
false,
new NoOpMetricsSystem())
.createProtocolSchedule(); .createProtocolSchedule();
protocolContext = mock(ProtocolContext.class); protocolContext = mock(ProtocolContext.class);

@ -29,6 +29,7 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolScheduleBuilder;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecAdapters; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecAdapters;
import org.hyperledger.besu.evm.EvmSpecVersion; import org.hyperledger.besu.evm.EvmSpecVersion;
import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.evm.internal.EvmConfiguration;
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.Locale; import java.util.Locale;
@ -80,7 +81,12 @@ class MainnetGenesisFileModule extends GenesisFileModule {
} }
return MainnetProtocolSchedule.fromConfig( return MainnetProtocolSchedule.fromConfig(
configOptions, evmConfiguration, MiningParameters.newDefault(), new BadBlockManager()); configOptions,
evmConfiguration,
MiningParameters.newDefault(),
new BadBlockManager(),
false,
new NoOpMetricsSystem());
} }
public static Map<String, Supplier<ProtocolSchedule>> createSchedules() { public static Map<String, Supplier<ProtocolSchedule>> createSchedules() {
@ -145,7 +151,9 @@ class MainnetGenesisFileModule extends GenesisFileModule {
false, false,
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED, MiningParameters.MINING_DISABLED,
new BadBlockManager()) new BadBlockManager(),
false,
new NoOpMetricsSystem())
.createProtocolSchedule(); .createProtocolSchedule();
} }
} }

@ -194,6 +194,7 @@ dependencies {
referenceTestImplementation project(path: ':config') referenceTestImplementation project(path: ':config')
referenceTestImplementation project(path: ':datatypes') referenceTestImplementation project(path: ':datatypes')
referenceTestImplementation project(path: ':ethereum:core') referenceTestImplementation project(path: ':ethereum:core')
referenceTestImplementation project(path: ':metrics:core')
referenceTestImplementation project(path: ':ethereum:core', configuration: 'testSupportArtifacts') referenceTestImplementation project(path: ':ethereum:core', configuration: 'testSupportArtifacts')
referenceTestImplementation project(path: ':ethereum:rlp') referenceTestImplementation project(path: ':ethereum:rlp')
referenceTestImplementation project(path: ':ethereum:rlp', configuration: 'testSupportArtifacts') referenceTestImplementation project(path: ':ethereum:rlp', configuration: 'testSupportArtifacts')

@ -27,6 +27,7 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecAdapters; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecAdapters;
import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.evm.internal.EvmConfiguration;
import org.hyperledger.besu.evm.precompile.KZGPointEvalPrecompiledContract; import org.hyperledger.besu.evm.precompile.KZGPointEvalPrecompiledContract;
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.Arrays; import java.util.Arrays;
@ -130,7 +131,9 @@ public class ReferenceTestProtocolSchedules {
false, false,
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
MiningParameters.MINING_DISABLED, MiningParameters.MINING_DISABLED,
new BadBlockManager()) new BadBlockManager(),
false,
new NoOpMetricsSystem())
.createProtocolSchedule(); .createProtocolSchedule();
} }

@ -18,6 +18,7 @@ package org.hyperledger.besu.ethereum.mainnet;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import org.checkerframework.checker.units.qual.N;
import org.hyperledger.besu.config.GenesisConfigFile; import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.JsonUtil; import org.hyperledger.besu.config.JsonUtil;
import org.hyperledger.besu.config.StubGenesisConfigOptions; import org.hyperledger.besu.config.StubGenesisConfigOptions;
@ -43,6 +44,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.io.Resources; import com.google.common.io.Resources;
import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.units.bigints.UInt256; import org.apache.tuweni.units.bigints.UInt256;
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource; import org.junit.jupiter.params.provider.MethodSource;
@ -59,64 +61,64 @@ public class DifficultyCalculatorTests {
MainnetProtocolSchedule.fromConfig( MainnetProtocolSchedule.fromConfig(
GenesisConfigFile.mainnet() GenesisConfigFile.mainnet()
.getConfigOptions(postMergeOverrides), .getConfigOptions(postMergeOverrides),
EvmConfiguration.DEFAULT, MiningParameters.newDefault(), new BadBlockManager())), EvmConfiguration.DEFAULT, MiningParameters.newDefault(), new BadBlockManager(), false, new NoOpMetricsSystem())),
Arguments.of( Arguments.of(
"/DifficultyTests/dfGrayGlacier/difficultyGrayGlacierForkBlock.json", "/DifficultyTests/dfGrayGlacier/difficultyGrayGlacierForkBlock.json",
MainnetProtocolSchedule.fromConfig( MainnetProtocolSchedule.fromConfig(
new StubGenesisConfigOptions().grayGlacierBlock(15050000), MiningParameters.newDefault(), new BadBlockManager()) new StubGenesisConfigOptions().grayGlacierBlock(15050000), MiningParameters.newDefault(), new BadBlockManager(), false, new NoOpMetricsSystem())
), ),
Arguments.of( Arguments.of(
"/DifficultyTests/dfGrayGlacier/difficultyGrayGlacierTimeDiff1.json", "/DifficultyTests/dfGrayGlacier/difficultyGrayGlacierTimeDiff1.json",
MainnetProtocolSchedule.fromConfig( MainnetProtocolSchedule.fromConfig(
new StubGenesisConfigOptions().grayGlacierBlock(15050000), MiningParameters.newDefault(), new BadBlockManager()) new StubGenesisConfigOptions().grayGlacierBlock(15050000), MiningParameters.newDefault(), new BadBlockManager(), false, new NoOpMetricsSystem())
), ),
Arguments.of( Arguments.of(
"/DifficultyTests/dfGrayGlacier/difficultyGrayGlacierTimeDiff2.json", "/DifficultyTests/dfGrayGlacier/difficultyGrayGlacierTimeDiff2.json",
MainnetProtocolSchedule.fromConfig( MainnetProtocolSchedule.fromConfig(
new StubGenesisConfigOptions().grayGlacierBlock(15050000), MiningParameters.newDefault(), new BadBlockManager()) new StubGenesisConfigOptions().grayGlacierBlock(15050000), MiningParameters.newDefault(), new BadBlockManager(), false, new NoOpMetricsSystem())
), ),
Arguments.of( Arguments.of(
"/DifficultyTests/dfArrowGlacier/difficultyArrowGlacierForkBlock.json", "/DifficultyTests/dfArrowGlacier/difficultyArrowGlacierForkBlock.json",
MainnetProtocolSchedule.fromConfig( MainnetProtocolSchedule.fromConfig(
new StubGenesisConfigOptions().arrowGlacierBlock(13773000), MiningParameters.newDefault(), new BadBlockManager()) new StubGenesisConfigOptions().arrowGlacierBlock(13773000), MiningParameters.newDefault(), new BadBlockManager(), false, new NoOpMetricsSystem())
), ),
Arguments.of( Arguments.of(
"/DifficultyTests/dfArrowGlacier/difficultyArrowGlacierTimeDiff1.json", "/DifficultyTests/dfArrowGlacier/difficultyArrowGlacierTimeDiff1.json",
MainnetProtocolSchedule.fromConfig( MainnetProtocolSchedule.fromConfig(
new StubGenesisConfigOptions().arrowGlacierBlock(13773000), MiningParameters.newDefault(), new BadBlockManager()) new StubGenesisConfigOptions().arrowGlacierBlock(13773000), MiningParameters.newDefault(), new BadBlockManager(), false, new NoOpMetricsSystem())
), ),
Arguments.of( Arguments.of(
"/DifficultyTests/dfArrowGlacier/difficultyArrowGlacierTimeDiff2.json", "/DifficultyTests/dfArrowGlacier/difficultyArrowGlacierTimeDiff2.json",
MainnetProtocolSchedule.fromConfig( MainnetProtocolSchedule.fromConfig(
new StubGenesisConfigOptions().arrowGlacierBlock(13773000), MiningParameters.newDefault(), new BadBlockManager()) new StubGenesisConfigOptions().arrowGlacierBlock(13773000), MiningParameters.newDefault(), new BadBlockManager(), false, new NoOpMetricsSystem())
), ),
Arguments.of( Arguments.of(
"/DifficultyTests/dfByzantium/difficultyByzantium.json", "/DifficultyTests/dfByzantium/difficultyByzantium.json",
MainnetProtocolSchedule.fromConfig(new StubGenesisConfigOptions().byzantiumBlock(0), MiningParameters.newDefault(), new BadBlockManager()) MainnetProtocolSchedule.fromConfig(new StubGenesisConfigOptions().byzantiumBlock(0), MiningParameters.newDefault(), new BadBlockManager(), false, new NoOpMetricsSystem())
), ),
Arguments.of( Arguments.of(
"/DifficultyTests/dfConstantinople/difficultyConstantinople.json", "/DifficultyTests/dfConstantinople/difficultyConstantinople.json",
MainnetProtocolSchedule.fromConfig(new StubGenesisConfigOptions().constantinopleBlock(0), MiningParameters.newDefault(), new BadBlockManager()) MainnetProtocolSchedule.fromConfig(new StubGenesisConfigOptions().constantinopleBlock(0), MiningParameters.newDefault(), new BadBlockManager(), false, new NoOpMetricsSystem())
), ),
Arguments.of( Arguments.of(
"/DifficultyTests/dfEIP2384/difficultyEIP2384.json", "/DifficultyTests/dfEIP2384/difficultyEIP2384.json",
MainnetProtocolSchedule.fromConfig(new StubGenesisConfigOptions().muirGlacierBlock(0), MiningParameters.newDefault(), new BadBlockManager()) MainnetProtocolSchedule.fromConfig(new StubGenesisConfigOptions().muirGlacierBlock(0), MiningParameters.newDefault(), new BadBlockManager(), false, new NoOpMetricsSystem())
), ),
Arguments.of( Arguments.of(
"/DifficultyTests/dfEIP2384/difficultyEIP2384_random.json", "/DifficultyTests/dfEIP2384/difficultyEIP2384_random.json",
MainnetProtocolSchedule.fromConfig(new StubGenesisConfigOptions().muirGlacierBlock(0), MiningParameters.newDefault(), new BadBlockManager()) MainnetProtocolSchedule.fromConfig(new StubGenesisConfigOptions().muirGlacierBlock(0), MiningParameters.newDefault(), new BadBlockManager(), false, new NoOpMetricsSystem())
), ),
Arguments.of( Arguments.of(
"/DifficultyTests/dfEIP2384/difficultyEIP2384_random_to20M.json", "/DifficultyTests/dfEIP2384/difficultyEIP2384_random_to20M.json",
MainnetProtocolSchedule.fromConfig(new StubGenesisConfigOptions().muirGlacierBlock(0), MiningParameters.newDefault(), new BadBlockManager()) MainnetProtocolSchedule.fromConfig(new StubGenesisConfigOptions().muirGlacierBlock(0), MiningParameters.newDefault(), new BadBlockManager(), false, new NoOpMetricsSystem())
), ),
Arguments.of( Arguments.of(
"/DifficultyTests/dfFrontier/difficultyFrontier.json", "/DifficultyTests/dfFrontier/difficultyFrontier.json",
MainnetProtocolSchedule.fromConfig(new StubGenesisConfigOptions(), MiningParameters.newDefault(), new BadBlockManager()) MainnetProtocolSchedule.fromConfig(new StubGenesisConfigOptions(), MiningParameters.newDefault(), new BadBlockManager(), false, new NoOpMetricsSystem())
), ),
Arguments.of( Arguments.of(
"/DifficultyTests/dfHomestead/difficultyHomestead.json", "/DifficultyTests/dfHomestead/difficultyHomestead.json",
MainnetProtocolSchedule.fromConfig(new StubGenesisConfigOptions().homesteadBlock(0), MiningParameters.newDefault(), new BadBlockManager()) MainnetProtocolSchedule.fromConfig(new StubGenesisConfigOptions().homesteadBlock(0), MiningParameters.newDefault(), new BadBlockManager(), false, new NoOpMetricsSystem())
)); ));
} }

@ -161,7 +161,12 @@ public class RetestethContext {
JsonUtil.getObjectNode(genesisConfig, "config").get()); JsonUtil.getObjectNode(genesisConfig, "config").get());
protocolSchedule = protocolSchedule =
MainnetProtocolSchedule.fromConfig( MainnetProtocolSchedule.fromConfig(
jsonGenesisConfigOptions, EvmConfiguration.DEFAULT, miningParameters, badBlockManager); jsonGenesisConfigOptions,
EvmConfiguration.DEFAULT,
miningParameters,
badBlockManager,
false,
new NoOpMetricsSystem());
if ("NoReward".equalsIgnoreCase(sealEngine)) { if ("NoReward".equalsIgnoreCase(sealEngine)) {
protocolSchedule = new NoRewardProtocolScheduleWrapper(protocolSchedule, badBlockManager); protocolSchedule = new NoRewardProtocolScheduleWrapper(protocolSchedule, badBlockManager);
} }

@ -16,6 +16,7 @@ package org.hyperledger.besu.evm.tracing;
import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Transaction; import org.hyperledger.besu.datatypes.Transaction;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; import org.hyperledger.besu.evm.frame.ExceptionalHaltReason;
import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.frame.MessageFrame;
import org.hyperledger.besu.evm.log.Log; import org.hyperledger.besu.evm.log.Log;
@ -85,6 +86,17 @@ public interface OperationTracer {
*/ */
default void traceStartTransaction(final WorldView worldView, final Transaction transaction) {} default void traceStartTransaction(final WorldView worldView, final Transaction transaction) {}
/**
* Trace the end of a transaction just before mining reward.
*
* @param worldView an immutable view of the execution context
* @param tx the transaction that just concluded
* @param miningReward the reward that the mining beneficiary will receive.
*/
default void traceBeforeRewardTransaction(
final WorldView worldView, final Transaction tx, final Wei miningReward) {}
;
/** /**
* Trace the end of a transaction. * Trace the end of a transaction.
* *

@ -53,7 +53,9 @@ public enum BesuMetricCategory implements MetricCategory {
/** Transaction pool besu metric category. */ /** Transaction pool besu metric category. */
TRANSACTION_POOL("transaction_pool"), TRANSACTION_POOL("transaction_pool"),
/** Stratum besu metric category. */ /** Stratum besu metric category. */
STRATUM("stratum"); STRATUM("stratum"),
/** Block processing besu metric category. */
BLOCK_PROCESSING("block_processing");
private static final Optional<String> BESU_PREFIX = Optional.of("besu_"); private static final Optional<String> BESU_PREFIX = Optional.of("besu_");

Loading…
Cancel
Save