From dbf63330843b7e09aedac8de722890ca9f0176d2 Mon Sep 17 00:00:00 2001 From: Karim Taam Date: Wed, 30 Oct 2024 09:25:49 +0100 Subject: [PATCH] merge main into verkle (#7824) Signed-off-by: Karim Taam --- .github/ISSUE_TEMPLATE/release-checklist.md | 31 +- .github/workflows/BesuContainerVerify.sh | 4 +- .github/workflows/docker-promote.yml | 64 +- .github/workflows/draft-release.yml | 160 +- .github/workflows/sonarcloud.yml | 2 +- .github/workflows/splitList.sh | 2 +- .github/workflows/splitTestsByTime.sh | 2 +- CHANGELOG.md | 26 +- MAINTAINERS.md | 3 +- README.md | 21 +- acceptance-tests/dsl/build.gradle | 2 - .../acceptance/dsl/AcceptanceTestBase.java | 20 +- .../dsl/AcceptanceTestBaseJunit5.java | 200 - .../blockchain/ExpectBlockNotCreated.java | 2 +- .../tests/acceptance/dsl/node/BesuNode.java | 4 +- .../dsl/node/ProcessBesuNodeRunner.java | 2 +- .../dsl/node/ThreadBesuNodeRunner.java | 12 + .../account/TransferTransactionBuilder.java | 2 +- acceptance-tests/test-plugins/build.gradle | 2 - acceptance-tests/tests/build.gradle | 19 +- .../bft/ParameterizedBftTestBase.java | 4 +- .../bft/qbft/QbftContractAcceptanceTest.java | 4 +- .../acceptance/bftsoak/BftMiningSoakTest.java | 2 +- .../CliqueDiscardRpcAcceptanceTest.java | 4 +- .../CliqueGetSignersRpcAcceptanceTest.java | 4 +- .../clique/CliqueMiningAcceptanceTest.java | 4 +- .../CliqueProposalRpcAcceptanceTest.java | 4 +- .../CliqueProposeRpcAcceptanceTest.java | 4 +- .../CliqueZeroValidatorsAcceptanceTest.java | 4 +- .../crypto/SECP256R1AcceptanceTest.java | 4 +- .../ethereum/PragueAcceptanceTestHelper.java | 21 +- .../ExecutionEnginePragueAcceptanceTest.java | 3 + .../mining/MiningAcceptanceTest.java | 10 +- .../plugins/BadCLIOptionsPluginTest.java | 4 +- .../plugins/BesuEventsPluginTest.java | 4 +- .../plugins/PermissioningPluginTest.java | 4 +- .../src/test/resources/dev/dev_prague.json | 12 +- .../jsonrpc/engine/prague/genesis.json | 23 +- .../test-cases/00_get_genesis_block_info.json | 4 +- .../test-cases/01_cancun_prepare_payload.json | 8 +- .../test-cases/02_cancun_getPayloadV3.json | 8 +- .../test-cases/03_cancun_newPayloadV3.json | 14 +- .../04_cancun_forkchoiceUpdatedV3.json | 8 +- .../05_prague_forkchoiceUpdatedV3.json | 10 +- .../test-cases/06_prague_getPayloadV4.json | 26 +- ...send_raw_transaction_deposit_request.json} | 0 ...null_deposit_request_execute_payload.json} | 16 +- .../test-cases/09_prague_newPayloadV4.json | 34 +- .../10_prague_forkchoiceUpdatedV3.json | 10 +- .../test-cases/11_prague_getPayloadV4.json | 20 +- .../test-cases/12_cancun_newPayloadV3.json | 21 +- .../15_prague_forkchoiceUpdatedV3.json | 10 +- .../test-cases/16_prague_getPayloadV4.json | 40 +- besu/build.gradle | 10 +- .../org/hyperledger/besu/cli/BesuCommand.java | 549 +- .../cli/ConfigurationOverviewBuilder.java | 22 +- .../besu/cli/config/EthNetworkConfig.java | 1 + .../besu/cli/config/NetworkName.java | 6 + .../stable/ApiConfigurationOptions.java | 1 + .../options/stable/DataStorageOptions.java | 249 - .../stable/EngineRPCConfiguration.java | 36 + .../cli/options/stable/EngineRPCOptions.java | 81 + .../cli/options/stable/GraphQlOptions.java | 1 + .../options/stable/JsonRpcHttpOptions.java | 37 +- ...csOptionGroup.java => MetricsOptions.java} | 113 +- .../options/stable/P2PDiscoveryOptions.java | 225 + .../options/stable/PermissionsOptions.java | 1 + .../options/storage/DataStorageOptions.java | 121 + .../storage/DiffBasedSubStorageOptions.java | 217 + .../options/unstable/MetricsCLIOptions.java | 79 - .../P2PTLSConfigOptions.java | 2 +- .../cli/subcommands/PasswordSubCommand.java | 2 + .../subcommands/blocks/BlocksSubCommand.java | 2 + .../cli/subcommands/operator/BackupState.java | 2 + .../operator/GenerateBlockchainConfig.java | 3 + .../subcommands/operator/RestoreState.java | 2 + .../subcommands/storage/TrieLogHelper.java | 75 +- .../storage/TrieLogSubCommand.java | 7 +- .../besu/components/BesuCommandModule.java | 16 +- .../controller/BesuControllerBuilder.java | 42 +- .../controller/IbftBesuControllerBuilder.java | 15 +- .../controller/QbftBesuControllerBuilder.java | 15 +- .../besu/services/BesuEventsImpl.java | 2 +- .../services/TransactionPoolServiceImpl.java | 8 + .../besu/util/EphemeryGenesisUpdater.java | 81 + besu/src/main/scripts/besu-entry.sh | 2 +- .../besu/ForkIdsNetworkConfigTest.java | 17 +- .../hyperledger/besu/RunnerBuilderTest.java | 10 +- .../java/org/hyperledger/besu/RunnerTest.java | 6 +- .../chainimport/RlpBlockImporterTest.java | 4 +- .../hyperledger/besu/cli/BesuCommandTest.java | 100 +- .../besu/cli/CommandTestAbstract.java | 9 +- .../cli/ConfigurationOverviewBuilderTest.java | 12 +- .../cli/NetworkDeprecationMessageTest.java | 4 +- .../besu/cli/PrivacyOptionsTest.java | 10 +- .../cli/options/AbstractCLIOptionsTest.java | 1 - ...tionsTest.java => MetricsOptionsTest.java} | 14 +- .../stable/DataStorageOptionsTest.java | 63 +- .../storage/TrieLogHelperTest.java | 79 +- .../storage/TrieLogSubCommandTest.java | 13 +- .../services/RlpConverterServiceImplTest.java | 2 +- .../besu/util/EphemeryGenesisUpdaterTest.java | 139 + build.gradle | 62 +- .../besu/config/GenesisConfigFile.java | 14 + .../besu/config/GenesisConfigOptions.java | 6 +- .../besu/config/JsonGenesisConfigOptions.java | 8 +- ...igOptions.java => MergeConfiguration.java} | 8 +- .../besu/config/StubGenesisConfigOptions.java | 13 +- config/src/main/resources/ephemery.json | 916 +++ .../besu/config/GenesisConfigOptionsTest.java | 9 +- .../BlockHeaderValidationRulesetFactory.java | 4 +- .../consensus/common/bft/BftEventQueue.java | 5 + .../consensus/common/bft/BftExecutors.java | 2 +- .../consensus/common/bft/BftProcessor.java | 9 +- .../blockcreation/BftMiningCoordinator.java | 13 +- .../common/bft/BftEventQueueTest.java | 34 + .../BftMiningCoordinatorTest.java | 23 + .../besu/consensus/merge/PayloadWrapper.java | 19 +- .../merge/blockcreation/MergeCoordinator.java | 8 +- .../blockcreation/MergeCoordinatorTest.java | 6 +- .../merge/blockcreation/MergeReorgTest.java | 4 +- .../qbft/messagewrappers/ProposalTest.java | 3 +- .../besu/datatypes/HardforkId.java | 2 - .../org/hyperledger/besu/datatypes/Hash.java | 12 + .../hyperledger/besu/datatypes/HashTest.java | 8 + docker/test.sh | 2 +- enclave/build.gradle | 1 - ethereum/api/build.gradle | 62 +- .../api/jsonrpc/JsonRpcResponseKey.java | 3 +- .../api/jsonrpc/JsonRpcResponseUtils.java | 14 +- .../jsonrpc/JsonRpcTestMethodsFactory.java | 12 +- .../fork/london/EthCallIntegrationTest.java | 22 + .../london/EthEstimateGasIntegrationTest.java | 30 + .../api/jsonrpc/JsonRpcConfiguration.java | 2 +- .../execution/TracedJsonRpcProcessor.java | 1 + .../internal/methods/AbstractEstimateGas.java | 5 +- .../internal/methods/EthFeeHistory.java | 45 +- .../internal/methods/EthGetBlockReceipts.java | 3 +- .../engine/AbstractEngineNewPayload.java | 98 +- .../engine/EngineGetClientVersionV1.java | 12 +- .../methods/engine/EngineNewPayloadV2.java | 3 +- .../methods/engine/EngineNewPayloadV3.java | 3 +- .../methods/engine/EngineNewPayloadV4.java | 8 +- .../methods/engine/EngineNewPayloadV6800.java | 7 +- .../engine/RequestValidatorProvider.java | 49 +- .../ConsolidationRequestParameter.java | 102 - .../parameters/DepositRequestParameter.java | 144 - .../parameters/EnginePayloadParameter.java | 27 +- .../parameters/JsonCallParameter.java | 19 + .../WithdrawalRequestParameter.java | 103 - .../internal/response/RpcErrorType.java | 1 + .../jsonrpc/internal/results/BlockResult.java | 7 + .../internal/results/BlockResultFactory.java | 19 +- .../results/EngineGetPayloadResultV4.java | 81 +- .../jsonrpc/methods/EthJsonRpcMethods.java | 6 +- .../ExecutionEngineJsonRpcMethods.java | 2 +- ...TransactionDroppedSubscriptionService.java | 3 +- .../jsonrpc/internal/methods/EthCallTest.java | 19 +- .../internal/methods/EthFeeHistoryTest.java | 67 +- .../methods/EthMaxPriorityFeePerGasTest.java | 1 + .../engine/AbstractEngineGetPayloadTest.java | 15 +- .../engine/AbstractEngineNewPayloadTest.java | 95 +- .../engine/EngineGetClientVersionV1Test.java | 15 +- .../EngineGetPayloadBodiesByHashV1Test.java | 7 +- .../EngineGetPayloadBodiesByRangeV1Test.java | 19 +- .../engine/EngineGetPayloadV2Test.java | 3 +- .../engine/EngineGetPayloadV3Test.java | 4 +- .../engine/EngineGetPayloadV4Test.java | 29 +- .../engine/EngineNewPayloadV2Test.java | 48 +- .../engine/EngineNewPayloadV3Test.java | 29 +- .../engine/EngineNewPayloadV4Test.java | 235 +- .../DepositParameterTestFixture.java | 42 - .../DepositRequestRequestParameterTest.java | 61 - .../WithdrawalRequestParameterTest.java | 52 - .../WithdrawalRequestTestFixture.java | 31 - ...sactionDroppedSubscriptionServiceTest.java | 15 +- .../blockcreation/AbstractBlockCreator.java | 7 +- .../AbstractBlockCreatorTest.java | 115 +- ethereum/core/build.gradle | 1 - .../besu/ethereum/BlockProcessingResult.java | 10 + .../besu/ethereum/BlockValidator.java | 4 - .../besu/ethereum/MainnetBlockValidator.java | 16 +- .../besu/ethereum/ProtocolContext.java | 8 +- .../besu/ethereum/chain/GenesisState.java | 26 +- .../hyperledger/besu/ethereum/core/Block.java | 5 +- .../besu/ethereum/core/BlockBody.java | 34 +- .../besu/ethereum/core/BlockHeader.java | 43 +- .../ethereum/core/BlockHeaderBuilder.java | 32 +- .../ethereum/core/ConsolidationRequest.java | 90 - .../besu/ethereum/core/DepositRequest.java | 112 - .../ethereum/core/ProcessableBlockHeader.java | 17 +- .../besu/ethereum/core/Request.java | 23 +- .../ethereum/core/SealableBlockHeader.java | 19 +- .../besu/ethereum/core/Synchronizer.java | 17 + .../besu/ethereum/core/WithdrawalRequest.java | 89 - .../encoding/ConsolidationRequestDecoder.java | 40 - .../encoding/ConsolidationRequestEncoder.java | 60 - .../core/encoding/DepositLogDecoder.java | 40 + .../core/encoding/DepositRequestDecoder.java | 70 - .../core/encoding/DepositRequestEncoder.java | 42 - .../core/encoding/RequestDecoder.java | 106 - .../core/encoding/RequestEncoder.java | 83 - .../encoding/WithdrawalRequestDecoder.java | 41 - .../encoding/WithdrawalRequestEncoder.java | 59 - .../core/json/ChainIdDeserializer.java | 46 + .../mainnet/AbstractBlockProcessor.java | 2 +- .../mainnet/BaseFeeBlockBodyValidator.java | 4 +- .../ethereum/mainnet/BlockBodyValidator.java | 4 - .../besu/ethereum/mainnet/BodyValidation.java | 23 +- .../mainnet/MainnetBlockBodyValidator.java | 19 +- .../mainnet/MainnetBlockHeaderValidator.java | 4 +- .../mainnet/MainnetBlockImporter.java | 8 +- .../mainnet/MainnetProtocolSpecFactory.java | 4 +- .../mainnet/MainnetProtocolSpecs.java | 19 +- .../mainnet/ProtocolScheduleBuilder.java | 9 +- .../besu/ethereum/mainnet/ProtocolSpec.java | 14 +- .../ethereum/mainnet/ProtocolSpecBuilder.java | 13 +- .../ethereum/mainnet/SystemCallProcessor.java | 5 +- .../AbstractSystemCallRequestProcessor.java | 102 - .../ConsolidationRequestProcessor.java | 73 - .../ConsolidationRequestValidator.java | 92 - .../requests/DepositRequestProcessor.java | 37 +- .../requests/DepositRequestValidator.java | 86 - .../requests/MainnetRequestsProcessor.java | 39 + .../requests/MainnetRequestsValidator.java | 67 +- .../requests/ProhibitedRequestValidator.java | 38 + .../requests/ProhibitedRequestsValidator.java | 53 - .../requests/RequestContractAddresses.java | 13 +- .../mainnet/requests/RequestProcessor.java | 5 +- .../requests/RequestProcessorCoordinator.java | 25 +- .../mainnet/requests/RequestUtil.java | 85 - ...tValidator.java => RequestsValidator.java} | 12 +- .../RequestsValidatorCoordinator.java | 202 - .../requests/SystemCallRequestProcessor.java | 57 + .../requests/WithdrawalRequestProcessor.java | 79 - .../requests/WithdrawalRequestValidator.java | 93 - .../ethereum/transaction/CallParameter.java | 18 +- .../transaction/TransactionSimulator.java | 11 +- .../BonsaiWorldStateKeyValueStorage.java | 26 +- .../storage/flat/BonsaiFlatDbStrategy.java | 173 + .../flat/BonsaiFlatDbStrategyProvider.java | 88 + ...egy.java => BonsaiFullFlatDbStrategy.java} | 5 +- ....java => BonsaiPartialFlatDbStrategy.java} | 5 +- .../common/storage/flat/FlatDbStrategy.java | 144 +- .../storage/flat/FlatDbStrategyProvider.java | 119 +- .../VerkleWorldStateKeyValueStorage.java | 11 +- .../worldstate/DataStorageConfiguration.java | 69 +- .../DiffBasedSubStorageConfiguration.java | 95 + .../besu/ethereum/core/BlobTestFixture.java | 14 +- .../ethereum/core/BlockDataGenerator.java | 17 +- .../ethereum/core/BlockHeaderTestFixture.java | 16 +- .../ethereum/core/BlockchainSetupUtil.java | 1 + .../ethereum/core}/DummySynchronizer.java | 13 +- .../core/InMemoryKeyValueStorageProvider.java | 6 +- .../ethereum/core/NonBesuBlockHeader.java | 2 +- .../BlockImportExceptionHandlingTest.java | 6 - .../ethereum/MainnetBlockValidatorTest.java | 15 +- .../besu/ethereum/chain/GenesisStateTest.java | 20 +- .../ConsolidationRequestDecoderTest.java | 46 - .../ConsolidationRequestEncoderTest.java | 55 - ...erTest.java => DepositLogDecoderTest.java} | 45 +- .../encoding/DepositRequestEncoderTest.java | 61 - .../WithdrawalRequestDecoderTest.java | 46 - .../WithdrawalRequestEncoderTest.java | 55 - .../mainnet/AbstractBlockProcessorTest.java | 4 - .../ethereum/mainnet/BodyValidationTest.java | 28 + ...olidationRequestValidatorTestFixtures.java | 136 - .../mainnet/DepositRequestValidatorTest.java | 234 - .../MainnetBlockBodyValidatorTest.java | 49 +- .../mainnet/MainnetBlockProcessorTest.java | 3 - ...agueConsolidationRequestValidatorTest.java | 76 - .../mainnet/PragueRequestsValidatorTest.java | 120 - .../PragueWithdrawalRequestValidatorTest.java | 83 - .../mainnet/SystemCallProcessorTest.java | 4 +- .../ethereum/mainnet/ValidationTestUtils.java | 7 +- .../WithdrawalRequestValidatorTest.java | 87 - ...ithdrawalRequestValidatorTestFixtures.java | 186 - .../MainnetRequestsValidatorTest.java | 58 + .../ProhibitedRequestValidatorTest.java | 47 + .../transaction/TransactionSimulatorTest.java | 1 + .../BonsaiWorldStateKeyValueStorageTest.java | 14 +- ... => BonsaiFlatDbStrategyProviderTest.java} | 64 +- .../besu/ethereum/chain/genesis_prague.json | 3 +- .../besu/ethereum/eth/manager/EthPeers.java | 20 +- .../InvalidPeerTaskResponseException.java | 26 + .../peertask/NoAvailablePeerException.java | 17 + .../eth/manager/peertask/PeerSelector.java | 42 + .../eth/manager/peertask/PeerTask.java | 83 + .../manager/peertask/PeerTaskExecutor.java | 196 + .../PeerTaskExecutorResponseCode.java | 24 + .../peertask/PeerTaskExecutorResult.java | 20 + .../peertask/PeerTaskRequestSender.java | 56 + .../ethereum/eth/manager/snap/SnapServer.java | 14 +- .../manager/task/GetBodiesFromPeerTask.java | 25 +- .../task/GetHeadersFromPeerByNumberTask.java | 14 +- .../AbstractPeerBlockValidator.java | 7 - .../eth/sync/DefaultSynchronizer.java | 2 + .../eth/sync/fastsync/SyncTargetManager.java | 12 +- .../sync/fullsync/FullSyncTargetManager.java | 5 +- .../request/StorageRangeDataRequest.java | 4 + .../request/heal/TrieNodeHealingRequest.java | 9 +- .../eth/sync/tasks/CompleteBlocksTask.java | 15 +- .../sync/tasks/GetReceiptsForHeadersTask.java | 10 +- ...PooledTransactionHashesMessageHandler.java | 8 +- .../transactions/PeerTransactionTracker.java | 25 +- .../PendingTransactionDroppedListener.java | 2 +- .../eth/transactions/RemovalReason.java | 32 + .../eth/transactions/TransactionPool.java | 34 +- .../TransactionsMessageHandler.java | 5 +- .../AbstractPrioritizedTransactions.java | 2 +- .../AbstractSequentialTransactionsLayer.java | 6 +- .../layered/AbstractTransactionsLayer.java | 31 +- .../BaseFeePrioritizedTransactions.java | 2 +- .../eth/transactions/layered/EndLayer.java | 11 +- .../layered/LayeredPendingTransactions.java | 4 +- ...lReason.java => LayeredRemovalReason.java} | 76 +- .../layered/ReadyTransactions.java | 4 +- .../layered/SparseTransactions.java | 8 +- .../layered/TransactionsLayer.java | 2 +- .../AbstractPendingTransactionsSorter.java | 24 +- .../sorter/SequencedRemovalReason.java | 45 + .../peertask/PeerTaskExecutorTest.java | 290 + .../peertask/PeerTaskRequestSenderTest.java | 75 + .../eth/manager/snap/SnapServerTest.java | 5 +- .../task/GetBodiesFromPeerTaskTest.java | 55 +- .../GetHeadersFromPeerByNumberTaskTest.java | 12 +- .../eth/messages/MessageWrapperTest.java | 6 +- .../backwardsync/ChainForTestCreator.java | 5 +- .../sync/snapsync/CompleteTaskStepTest.java | 4 +- .../sync/snapsync/PersistDataStepTest.java | 71 +- .../eth/sync/snapsync/TaskGenerator.java | 14 +- .../sync/tasks/CompleteBlocksTaskTest.java | 17 +- .../tasks/GetReceiptsForHeadersTaskTest.java | 20 +- .../AbstractTransactionPoolTest.java | 508 +- .../AbstractTransactionPoolTestBase.java | 585 ++ .../BlobV1TransactionPoolTest.java | 141 + .../PeerTransactionTrackerTest.java | 37 + .../LayeredPendingTransactionsTest.java | 6 +- .../eth/transactions/layered/LayersTest.java | 5 +- .../eth/transactions/layered/ReplayTest.java | 2 +- .../AbstractPendingTransactionsTestBase.java | 26 +- ethereum/evmtool/build.gradle | 2 - .../besu/evmtool/BenchmarkSubCommand.java | 5 +- .../besu/evmtool/CodeValidateSubCommand.java | 2 +- .../besu/evmtool/EOFTestSubCommand.java | 6 +- .../besu/evmtool/EvmToolCommand.java | 4 +- .../evmtool/MainnetGenesisFileModule.java | 11 +- .../besu/evmtool/PrettyPrintSubCommand.java | 2 +- .../hyperledger/besu/evmtool/T8nExecutor.java | 47 +- .../evmtool/benchmarks/BLS12Benchmark.java | 390 + .../evmtool/benchmarks/BenchmarkExecutor.java | 16 +- .../src/test/benchmarks/bench-caliper.sh | 2 +- .../evmtool/src/test/benchmarks/bench-loop.sh | 2 +- .../src/test/benchmarks/bench-mainnet.sh | 2 +- .../src/test/benchmarks/bench-static.sh | 2 +- ...ue-eof-rjump.json => osaka-eof-rjump.json} | 47 +- .../besu/evmtool/state-test/create-eof.json | 4 +- .../state-test/create-invalid-eof.json | 4 +- .../besu/evmtool/t8n/prague-deposit.json | 115 +- .../besu/evmtool/t8n/prague-withdrawal.json | 213 +- .../besu/evmtool/trace/create-eof-error.json | 2 +- .../besu/evmtool/trace/create-eof.json | 4 +- .../besu/evmtool/trace/eof-section.json | 8 +- .../hyperledger/besu/evmtool/trace/eof.json | 4 +- .../besu/evmtool/trace/initcode-error.json | 2 +- .../besu/evmtool/trace/revert.json | 2 +- .../discovery/P2PDiscoveryConfiguration.java | 39 + .../p2p/discovery/internal/PeerTable.java | 48 +- .../p2p/discovery/internal/PeerTableTest.java | 15 +- ethereum/referencetests/build.gradle | 3 + .../BlockchainReferenceTestCase.java | 2 + .../BlockchainReferenceTestCaseSpec.java | 51 +- .../referencetests/ReferenceTestEnv.java | 3 +- .../ReferenceTestProtocolSchedules.java | 11 +- .../referencetests/TransactionSequence.java | 22 + .../VerkleReferenceTestCaseSpec.java | 24 +- .../ethereum/eof/EOFReferenceTestTools.java | 49 +- .../BlockchainReferenceTestCaseSpecTest.java | 312 + .../vm/BlockchainReferenceTestTools.java | 17 +- ethereum/retesteth/build.gradle | 1 + .../NoRewardProtocolScheduleWrapper.java | 2 +- .../ethereum/retesteth/RetestethService.java | 1 + .../hyperledger/besu/evm/EvmSpecVersion.java | 8 +- .../org/hyperledger/besu/evm/MainnetEVMs.java | 102 +- .../besu/evm/fluent/EVMExecutor.java | 16 - ...alculator.java => OsakaGasCalculator.java} | 6 +- .../operation/AbstractExtCallOperation.java | 27 +- .../besu/evm/operation/CallFOperation.java | 8 + .../besu/evm/operation/JumpFOperation.java | 8 + .../operation/ReturnDataLoadOperation.java | 6 + .../AbstractBLS12PrecompiledContract.java | 14 + .../besu/evm/tracing/StandardJsonTracer.java | 39 +- .../besu/evm/code/CodeFactoryTest.java | 8 +- .../hyperledger/besu/evm/code/CodeV0Test.java | 2 +- .../besu/evm/fluent/EVMExecutorTest.java | 6 +- ...rTest.java => OsakaGasCalculatorTest.java} | 6 +- .../besu/evm/internal/CodeCacheTest.java | 2 +- .../evm/operation/Create2OperationTest.java | 2 +- .../evm/operation/CreateOperationTest.java | 4 +- .../evm/operation/DataCopyOperationTest.java | 8 +- .../evm/operation/EofCreateOperationTest.java | 4 +- .../evm/operation/ExtCallOperationTest.java | 12 +- .../ExtDelegateCallOperationTest.java | 12 +- .../operation/ExtStaticCallOperationTest.java | 13 +- .../besu/evm/operation/JumpOperationTest.java | 2 +- .../operation/SelfDestructOperationTest.java | 2 +- .../ContractCreationProcessorTest.java | 2 +- .../besu/evm/toy/EvmToyCommand.java | 5 +- .../tracing/ExtendedOperationTracerTest.java | 4 +- gradle.properties | 6 +- gradle/spotless/java.current.license | 2 +- gradle/spotless/sh.license | 2 +- gradle/verification-metadata.xml | 6332 ----------------- gradle/versions.gradle | 253 - .../besu/metrics/noop/NoOpMetricsSystem.java | 9 + .../besu/metrics/noop/NoOpValueCollector.java | 6 + .../opentelemetry/OpenTelemetryGauge.java | 8 + .../prometheus/MetricsConfiguration.java | 8 +- .../metrics/prometheus/PrometheusGauge.java | 18 +- .../nat/kubernetes/KubernetesNatManager.java | 2 +- platform/build.gradle | 216 + plugin-api/build.gradle | 2 +- .../besu/plugin/data/BlockBody.java | 9 - .../besu/plugin/data/BlockHeader.java | 2 +- .../plugin/data/ConsolidationRequest.java | 45 - .../besu/plugin/data/DepositRequest.java | 68 - .../plugin/data/ProcessableBlockHeader.java | 12 + .../hyperledger/besu/plugin/data/Request.java | 9 + .../besu/plugin/data/WithdrawalRequest.java | 49 - .../services/metrics/LabelledGauge.java | 11 + .../TransactionPoolService.java | 10 + plugins/rocksdb/build.gradle | 2 - .../src/main/solidity/generateWrappers.sh | 2 +- scripts/dco_check.sh | 2 +- settings.gradle | 1 + .../besu/testfuzz/EofContainerSubCommand.java | 2 +- .../besu/testfuzz/InternalClient.java | 2 +- testutil/build.gradle | 6 +- .../besu/testutil/JsonTestParameters.java | 9 +- .../enclave/testutil/TesseraTestHarness.java | 290 - .../testutil/TesseraTestHarnessFactory.java | 126 - 441 files changed, 8460 insertions(+), 14927 deletions(-) delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/AcceptanceTestBaseJunit5.java rename acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/{07_prague_send_raw_transaction.json => 07_prague_send_raw_transaction_deposit_request.json} (100%) rename acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/{08_prague_invalid_null_deposits_execute_payload.json => 08_prague_invalid_null_deposit_request_execute_payload.json} (88%) delete mode 100644 besu/src/main/java/org/hyperledger/besu/cli/options/stable/DataStorageOptions.java create mode 100644 besu/src/main/java/org/hyperledger/besu/cli/options/stable/EngineRPCConfiguration.java create mode 100644 besu/src/main/java/org/hyperledger/besu/cli/options/stable/EngineRPCOptions.java rename besu/src/main/java/org/hyperledger/besu/cli/options/stable/{MetricsOptionGroup.java => MetricsOptions.java} (57%) create mode 100644 besu/src/main/java/org/hyperledger/besu/cli/options/stable/P2PDiscoveryOptions.java create mode 100644 besu/src/main/java/org/hyperledger/besu/cli/options/storage/DataStorageOptions.java create mode 100644 besu/src/main/java/org/hyperledger/besu/cli/options/storage/DiffBasedSubStorageOptions.java delete mode 100644 besu/src/main/java/org/hyperledger/besu/cli/options/unstable/MetricsCLIOptions.java rename besu/src/main/java/org/hyperledger/besu/cli/options/{stable => unstable}/P2PTLSConfigOptions.java (99%) create mode 100644 besu/src/main/java/org/hyperledger/besu/util/EphemeryGenesisUpdater.java rename besu/src/test/java/org/hyperledger/besu/cli/options/{MetricsCLIOptionsTest.java => MetricsOptionsTest.java} (78%) create mode 100644 besu/src/test/java/org/hyperledger/besu/util/EphemeryGenesisUpdaterTest.java rename config/src/main/java/org/hyperledger/besu/config/{MergeConfigOptions.java => MergeConfiguration.java} (91%) create mode 100644 config/src/main/resources/ephemery.json delete mode 100644 ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/ConsolidationRequestParameter.java delete mode 100644 ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/DepositRequestParameter.java delete mode 100644 ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/WithdrawalRequestParameter.java delete mode 100644 ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/DepositParameterTestFixture.java delete mode 100644 ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/DepositRequestRequestParameterTest.java delete mode 100644 ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/WithdrawalRequestParameterTest.java delete mode 100644 ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/WithdrawalRequestTestFixture.java delete mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/ConsolidationRequest.java delete mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/DepositRequest.java delete mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/WithdrawalRequest.java delete mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/ConsolidationRequestDecoder.java delete mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/ConsolidationRequestEncoder.java create mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/DepositLogDecoder.java delete mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/DepositRequestDecoder.java delete mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/DepositRequestEncoder.java delete mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/RequestDecoder.java delete mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/RequestEncoder.java delete mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalRequestDecoder.java delete mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalRequestEncoder.java create mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/json/ChainIdDeserializer.java delete mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/AbstractSystemCallRequestProcessor.java delete mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/ConsolidationRequestProcessor.java delete mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/ConsolidationRequestValidator.java delete mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/DepositRequestValidator.java create mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/MainnetRequestsProcessor.java create mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/ProhibitedRequestValidator.java delete mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/ProhibitedRequestsValidator.java delete mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/RequestUtil.java rename ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/{RequestValidator.java => RequestsValidator.java} (63%) delete mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/RequestsValidatorCoordinator.java create mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/SystemCallRequestProcessor.java delete mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/WithdrawalRequestProcessor.java delete mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/WithdrawalRequestValidator.java create mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/flat/BonsaiFlatDbStrategy.java create mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/flat/BonsaiFlatDbStrategyProvider.java rename ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/flat/{FullFlatDbStrategy.java => BonsaiFullFlatDbStrategy.java} (95%) rename ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/flat/{PartialFlatDbStrategy.java => BonsaiPartialFlatDbStrategy.java} (97%) create mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/worldstate/DiffBasedSubStorageConfiguration.java rename ethereum/{retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth => core/src/test-support/java/org/hyperledger/besu/ethereum/core}/DummySynchronizer.java (89%) delete mode 100644 ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/ConsolidationRequestDecoderTest.java delete mode 100644 ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/ConsolidationRequestEncoderTest.java rename ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/{DepositRequestDecoderTest.java => DepositLogDecoderTest.java} (51%) delete mode 100644 ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/DepositRequestEncoderTest.java delete mode 100644 ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalRequestDecoderTest.java delete mode 100644 ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalRequestEncoderTest.java delete mode 100644 ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/ConsolidationRequestValidatorTestFixtures.java delete mode 100644 ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/DepositRequestValidatorTest.java delete mode 100644 ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/PragueConsolidationRequestValidatorTest.java delete mode 100644 ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/PragueRequestsValidatorTest.java delete mode 100644 ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/PragueWithdrawalRequestValidatorTest.java delete mode 100644 ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/WithdrawalRequestValidatorTest.java delete mode 100644 ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/WithdrawalRequestValidatorTestFixtures.java create mode 100644 ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/requests/MainnetRequestsValidatorTest.java create mode 100644 ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/requests/ProhibitedRequestValidatorTest.java rename ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/common/storage/flat/{FlatDbStrategyProviderTest.java => BonsaiFlatDbStrategyProviderTest.java} (74%) create mode 100644 ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/peertask/InvalidPeerTaskResponseException.java create mode 100644 ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/peertask/NoAvailablePeerException.java create mode 100644 ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/peertask/PeerSelector.java create mode 100644 ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/peertask/PeerTask.java create mode 100644 ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/peertask/PeerTaskExecutor.java create mode 100644 ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/peertask/PeerTaskExecutorResponseCode.java create mode 100644 ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/peertask/PeerTaskExecutorResult.java create mode 100644 ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/peertask/PeerTaskRequestSender.java create mode 100644 ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/RemovalReason.java rename ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/{RemovalReason.java => LayeredRemovalReason.java} (67%) create mode 100644 ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/sorter/SequencedRemovalReason.java create mode 100644 ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/peertask/PeerTaskExecutorTest.java create mode 100644 ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/peertask/PeerTaskRequestSenderTest.java create mode 100644 ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/AbstractTransactionPoolTestBase.java create mode 100644 ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/BlobV1TransactionPoolTest.java create mode 100644 ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/benchmarks/BLS12Benchmark.java rename ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/block-test/{prague-eof-rjump.json => osaka-eof-rjump.json} (92%) create mode 100644 ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/P2PDiscoveryConfiguration.java create mode 100644 ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/TransactionSequence.java create mode 100644 ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/referencetests/BlockchainReferenceTestCaseSpecTest.java rename evm/src/main/java/org/hyperledger/besu/evm/gascalculator/{PragueEOFGasCalculator.java => OsakaGasCalculator.java} (89%) rename evm/src/test/java/org/hyperledger/besu/evm/gascalculator/{PragueEOFGasCalculatorTest.java => OsakaGasCalculatorTest.java} (88%) delete mode 100644 gradle/verification-metadata.xml create mode 100644 platform/build.gradle delete mode 100644 plugin-api/src/main/java/org/hyperledger/besu/plugin/data/ConsolidationRequest.java delete mode 100644 plugin-api/src/main/java/org/hyperledger/besu/plugin/data/DepositRequest.java delete mode 100644 plugin-api/src/main/java/org/hyperledger/besu/plugin/data/WithdrawalRequest.java delete mode 100644 testutil/src/main/java/org/hyperledger/enclave/testutil/TesseraTestHarness.java delete mode 100644 testutil/src/main/java/org/hyperledger/enclave/testutil/TesseraTestHarnessFactory.java diff --git a/.github/ISSUE_TEMPLATE/release-checklist.md b/.github/ISSUE_TEMPLATE/release-checklist.md index 413d68933f..dcf10977f0 100644 --- a/.github/ISSUE_TEMPLATE/release-checklist.md +++ b/.github/ISSUE_TEMPLATE/release-checklist.md @@ -12,25 +12,34 @@ assignees: '' - [ ] Notify maintainers about updating changelog for in-flight PRs - [ ] Optional: for hotfixes, create a release branch and cherry-pick, e.g. `release--hotfix` - [ ] Optional: for hotfixes, create a PR into main from the hotfix branch to see the CI checks pass -- [ ] On the appropriate branch/commit, create a calver tag for the release candidate, format example: `24.4.0-RC2` - - [ ] git tag 24.4.0-RC2 - - [ ] git push upstream 24.4.0-RC2 +- [ ] On the appropriate branch/commit, create a calver tag for the release candidate, format example: `24.4.0-RC1` + - [ ] git tag 24.4.0-RC1 + - [ ] git push upstream 24.4.0-RC1 - [ ] Sign-off with team; announce the tag in #besu-release in Discord - - [ ] Targeting this tag for the burn-in: https://github.com/hyperledger/besu/releases/tag/24.4.0-RC2 + - [ ] Targeting this tag for the burn-in: https://github.com/hyperledger/besu/releases/tag/24.4.0-RC1 - [ ] Consensys staff start burn-in using this tag - [ ] Seek sign off for burn-in - [ ] Pass? Go ahead and complete the release process - [ ] Fail? Put a message in #besu-release in Discord indicating the release will be aborted because it failed burn-in -- [ ] Using the same git sha, create a calver tag for the FULL RELEASE, example format `24.4.0` -- [ ] Using the FULL RELEASE tag, create a release in github to trigger the workflows. Once published: +- [ ] Optional: Perform a dry run with https://github.com/consensys/protocols-release-sandbox to test the workflows + - [ ] Sync fork + - [ ] git checkout + - [ ] git tag 24.4.0 + - [ ] git push origin 24.4.0 + - [ ] Manually run https://github.com/Consensys/protocols-release-sandbox/actions/workflows/draft-release.yml using `main` branch and `24.4.0` tag +- [ ] Back on besu, using the same git sha as 24.4.0-RC1, create a calver tag for the FULL RELEASE, example format `24.4.0` + - [ ] git checkout 24.4.0-RC1 + - [ ] git tag 24.4.0 + - [ ] git push upstream 24.4.0 +- [ ] Manually run https://github.com/hyperledger/besu/actions/workflows/draft-release.yml using `main` branch` and the FULL RELEASE tag name, i.e. `24.4.0`. Note, this workflow should always be run from `main` branch (hotfix tags will still be released even if they were created based on another branch) + - publishes artefacts and version-specific docker tags but does not fully publish the GitHub release so subscribers are not yet notified +- [ ] Check all draft-release workflow jobs went green +- [ ] Check binary SHAs are correct on the release page +- [ ] Update release notes in the GitHub draft release, save draft and sign-off with team +- [ ] Publish draft release ensuring it is marked as latest release (if appropriate) - this is now public and notifies subscribed users - makes the release "latest" in github - - publishes artefacts and version-specific docker tags - publishes the docker `latest` tag variants -- [ ] Check binary SHAs are correct on the release page -- [ ] Check "Container Verify" GitHub workflow has run successfully -- [ ] Update the besu-docs version [update-version workflow](https://github.com/hyperledger/besu-docs/actions/workflows/update-version.yml) - - If the PR has not been automatically created, create the PR manually using the created branch `besu-version-` - [ ] Create homebrew release using [update-version workflow](https://github.com/hyperledger/homebrew-besu/actions/workflows/update-version.yml) - If the PR has not been automatically created, create the PR manually using the created branch `update-` - Run commands `brew tap hyperledger/besu && brew install besu` on MacOSX and verify latest version has been installed diff --git a/.github/workflows/BesuContainerVerify.sh b/.github/workflows/BesuContainerVerify.sh index 81537f3264..4c73b2d092 100644 --- a/.github/workflows/BesuContainerVerify.sh +++ b/.github/workflows/BesuContainerVerify.sh @@ -1,6 +1,6 @@ #!/bin/bash ## -## Copyright contributors to Hyperledger Besu. +## Copyright contributors to 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 @@ -57,7 +57,7 @@ else fi # For the latest tag check the version match -if [[ ${TAG} == "latest" && ${CHECK_LATEST} == "true" ]] +if [[ ${TAG} =~ ^latest && ${CHECK_LATEST} == "true" ]] then _VERSION_IN_LOG=$(docker logs ${CONTAINER_NAME} | grep "#" | grep "Besu version" | cut -d " " -f 4 | sed 's/\s//g') echo "Extracted version from logs [$_VERSION_IN_LOG]" diff --git a/.github/workflows/docker-promote.yml b/.github/workflows/docker-promote.yml index 858ea7d20e..18a3cc3170 100644 --- a/.github/workflows/docker-promote.yml +++ b/.github/workflows/docker-promote.yml @@ -14,25 +14,25 @@ jobs: validate: runs-on: ubuntu-22.04 env: - RELEASE_NAME: "${{ github.event.release.name }}" + RELEASE_VERSION: "${{ github.event.release.name }}" steps: - name: Pre-process Release Name - id: pre_process_release_name + id: pre_process_release_version run: | # strip all whitespace - RELEASE_NAME="${RELEASE_NAME//[[:space:]]/}" - if [[ ! "$RELEASE_NAME" =~ ^[0-9]+\.[0-9]+(\.[0-9]+)?(-.*)?$ ]]; then + RELEASE_VERSION="${RELEASE_VERSION//[[:space:]]/}" + if [[ ! "$RELEASE_VERSION" =~ ^[0-9]+\.[0-9]+(\.[0-9]+)?(-.*)?$ ]]; then echo "Release name does not conform to a valid besu release format YY.M.v[-suffix], e.g. 24.8.0-RC1." exit 1 fi - echo "release_name=$RELEASE_NAME" >> $GITHUB_OUTPUT # Set as output using the new syntax + echo "release_version=$RELEASE_VERSION" >> $GITHUB_OUTPUT # Set as output using the new syntax outputs: - release_name: ${{ steps.pre_process_release_name.outputs.release_name }} + release_version: ${{ steps.pre_process_release_version.outputs.release_version }} docker-promote: needs: [validate] env: - RELEASE_NAME: ${{ needs.validate.outputs.release_name }} # Use the output from the pre_process_release job + RELEASE_VERSION: ${{ needs.validate.outputs.release_version }} runs-on: ubuntu-22.04 steps: - name: Checkout @@ -58,24 +58,52 @@ jobs: cache-disabled: true - name: Docker upload - run: ./gradlew "-Prelease.releaseVersion=${{ env.RELEASE_NAME }}" "-PdockerOrgName=${{ env.registry }}/${{ secrets.DOCKER_ORG }}" dockerUploadRelease + run: ./gradlew "-Prelease.releaseVersion=${{ env.RELEASE_VERSION }}" "-PdockerOrgName=${{ env.registry }}/${{ secrets.DOCKER_ORG }}" dockerUploadRelease - name: Docker manifest - run: ./gradlew "-Prelease.releaseVersion=${{ env.RELEASE_NAME }}" "-PdockerOrgName=${{ env.registry }}/${{ secrets.DOCKER_ORG }}" manifestDockerRelease + run: ./gradlew "-Prelease.releaseVersion=${{ env.RELEASE_VERSION }}" "-PdockerOrgName=${{ env.registry }}/${{ secrets.DOCKER_ORG }}" manifestDockerRelease docker-verify: - needs: [validate, docker-promote] + needs: [validate,docker-promote] env: - RELEASE_NAME: ${{ needs.validate.outputs.release_name }} # Use the output from the pre_process_release job - runs-on: ubuntu-22.04 - permissions: - contents: read - actions: write + CONTAINER_NAME: besu-check + RELEASE_VERSION: ${{ needs.validate.outputs.release_version }} + runs-on: ${{ matrix.combination.runner }} + timeout-minutes: 4 + strategy: + matrix: + combination: + - tag: latest-amd64 + platform: 'linux/amd64' + runner: ubuntu-22.04 + - tag: latest + platform: '' + runner: ubuntu-22.04 + - tag: latest-arm64 + platform: '' + runner: besu-arm64 + - tag: latest + platform: '' + runner: besu-arm64 + steps: - name: Checkout uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 + with: + sparse-checkout: '.github/workflows/BesuContainerVerify.sh' - - name: Trigger container verify - run: echo '{"version":"${{ env.RELEASE_NAME }}","verify-latest-version":"true"}' | gh workflow run container-verify.yml --json + - name: Start container + run: | + PLATFORM_OPT="" + [[ x${{ matrix.combination.platform }} != 'x' ]] && PLATFORM_OPT="--platform ${{ matrix.combination.platform }}" + docker run -d $PLATFORM_OPT --name ${{ env.CONTAINER_NAME }} ${{ secrets.DOCKER_ORG }}/besu:${{ matrix.combination.tag }} + + - name: Verify besu container + run: bash .github/workflows/BesuContainerVerify.sh env: - GH_TOKEN: ${{ github.token }} + TAG: ${{ matrix.combination.tag }} + VERSION: ${{ env.RELEASE_VERSION }} + CHECK_LATEST: true + + - name: Stop container + run: docker stop ${{ env.CONTAINER_NAME }} diff --git a/.github/workflows/draft-release.yml b/.github/workflows/draft-release.yml index f6e01e1890..8dc61bec46 100644 --- a/.github/workflows/draft-release.yml +++ b/.github/workflows/draft-release.yml @@ -16,7 +16,7 @@ jobs: validate: runs-on: ubuntu-22.04 env: - RELEASE_NAME: "${{ inputs.tag }}" + RELEASE_VERSION: "${{ inputs.tag }}" steps: - name: Check default branch run: | @@ -24,36 +24,36 @@ jobs: echo "Default Branch: ${{ github.event.repository.default_branch }}" if [[ ${{ github.ref_name }} != ${{ github.event.repository.default_branch }} ]] then - echo "This workflow can only be run on default branch" + echo "This workflow can only be run on default branch. This is not an issue for hot fixes as code is checked out from the tag" exit 1 fi - + - name: Pre-process Release Name - id: pre_process_release_name + id: validate_release_version run: | # strip all whitespace - RELEASE_NAME="${RELEASE_NAME//[[:space:]]/}" - if [[ ! "$RELEASE_NAME" =~ ^[0-9]+\.[0-9]+(\.[0-9]+)?(-.*)?$ ]]; then + RELEASE_VERSION="${RELEASE_VERSION//[[:space:]]/}" + if [[ ! "$RELEASE_VERSION" =~ ^[0-9]+\.[0-9]+(\.[0-9]+)?(-.*)?$ ]]; then echo "Release name does not conform to a valid besu release format YY.M.v[-suffix], e.g. 24.8.0-RC1." exit 1 fi - echo "release_name=$RELEASE_NAME" >> $GITHUB_OUTPUT # Set as output using the new syntax - + echo "release_version=$RELEASE_VERSION" >> $GITHUB_OUTPUT # Set as output using the new syntax + # Perform a tag checkout to ensure tag is available - name: Verify tag Exist uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 - with: - ref: ${{ steps.pre_process_release_name.outputs.release_name }} + with: + ref: ${{ steps.validate_release_version.outputs.release_version }} fetch-depth: 1 outputs: - release_name: ${{ steps.pre_process_release_name.outputs.release_name }} + release_version: ${{ steps.validate_release_version.outputs.release_version }} build: runs-on: ubuntu-22.04 needs: validate env: - RELEASE_NAME: ${{ needs.validate.outputs.release_name }} # Use the output from the pre_process_release job + RELEASE_VERSION: ${{ needs.validate.outputs.release_version }} # Use the output from the pre_process_release job outputs: tarSha: ${{steps.hashes.outputs.tarSha}} zipSha: ${{steps.hashes.outputs.zipSha}} @@ -61,22 +61,22 @@ jobs: - name: Checkout tag uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 with: - ref: ${{ env.RELEASE_NAME }} - + ref: ${{ env.RELEASE_VERSION }} + - name: Set up Java uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 with: distribution: temurin java-version: 21 - + - name: Setup gradle uses: gradle/actions/setup-gradle@9e899d11ad247ec76be7a60bc1cf9d3abbb9e7f1 with: cache-disabled: true - + - name: Assemble release run: - ./gradlew -Prelease.releaseVersion=${{env.RELEASE_NAME}} -Pversion=${{env.RELEASE_NAME}} assemble + ./gradlew -Prelease.releaseVersion=${{env.RELEASE_VERSION}} -Pversion=${{env.RELEASE_VERSION}} assemble - name: Hashes id: hashes @@ -86,35 +86,35 @@ jobs: echo "tarSha=$(shasum -a 256 besu*.tar.gz)" echo "zipSha=$(shasum -a 256 besu*.zip)" >> $GITHUB_OUTPUT echo "tarSha=$(shasum -a 256 besu*.tar.gz)" >> $GITHUB_OUTPUT - shasum -a 256 besu-${{env.RELEASE_NAME}}.tar.gz > besu-${{env.RELEASE_NAME}}.tar.gz.sha256 - shasum -a 256 besu-${{env.RELEASE_NAME}}.zip > besu-${{env.RELEASE_NAME}}.zip.sha256 - + shasum -a 256 besu-${{env.RELEASE_VERSION}}.tar.gz > besu-${{env.RELEASE_VERSION}}.tar.gz.sha256 + shasum -a 256 besu-${{env.RELEASE_VERSION}}.zip > besu-${{env.RELEASE_VERSION}}.zip.sha256 + - name: Upload tarball uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 with: - path: 'build/distributions/besu-${{ env.RELEASE_NAME }}.tar.gz' - name: besu-${{ env.RELEASE_NAME }}.tar.gz + path: 'build/distributions/besu-${{ env.RELEASE_VERSION }}.tar.gz' + name: besu-${{ env.RELEASE_VERSION }}.tar.gz compression-level: 0 - + - name: upload zipfile uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 with: - path: 'build/distributions/besu-${{ env.RELEASE_NAME }}.zip' - name: besu-${{ env.RELEASE_NAME }}.zip + path: 'build/distributions/besu-${{ env.RELEASE_VERSION }}.zip' + name: besu-${{ env.RELEASE_VERSION }}.zip compression-level: 0 - name: upload checksum zip uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 with: - path: 'build/distributions/besu-${{ env.RELEASE_NAME }}.zip.sha256' - name: besu-${{ env.RELEASE_NAME }}.zip.sha256 + path: 'build/distributions/besu-${{ env.RELEASE_VERSION }}.zip.sha256' + name: besu-${{ env.RELEASE_VERSION }}.zip.sha256 compression-level: 0 - name: upload checksum tar.gz uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 with: - path: 'build/distributions/besu-${{ env.RELEASE_NAME }}.tar.gz.sha256' - name: besu-${{ env.RELEASE_NAME }}.tar.gz.sha256 + path: 'build/distributions/besu-${{ env.RELEASE_VERSION }}.tar.gz.sha256' + name: besu-${{ env.RELEASE_VERSION }}.tar.gz.sha256 compression-level: 0 test-windows: @@ -127,7 +127,7 @@ jobs: with: distribution: temurin java-version: 21 - + - name: Download zip uses: actions/download-artifact@eaceaf801fd36c7dee90939fad912460b18a1ffe with: @@ -153,7 +153,7 @@ jobs: with: distribution: temurin java-version: 21 - + - name: Download tar.gz uses: actions/download-artifact@eaceaf801fd36c7dee90939fad912460b18a1ffe with: @@ -172,20 +172,20 @@ jobs: runs-on: ubuntu-22.04 needs: [test-linux, test-windows] env: - RELEASE_NAME: ${{ needs.validate.outputs.release_name }} # Use the output from the pre_process_release job + RELEASE_VERSION: ${{ needs.validate.outputs.release_version }} # Use the output from the pre_process_release job steps: - name: Checkout Repo uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 with: - ref: ${{ env.RELEASE_NAME }} + ref: ${{ env.RELEASE_VERSION }} - name: hadoLint run: docker run --rm -i hadolint/hadolint < docker/Dockerfile - + docker-publish: needs: [validate, docker-lint] env: - RELEASE_NAME: ${{ needs.validate.outputs.release_name }} # Use the output from the pre_process_release job + RELEASE_VERSION: ${{ needs.validate.outputs.release_version }} # Use the output from the pre_process_release job strategy: fail-fast: false matrix: @@ -198,7 +198,7 @@ jobs: id: prep run: | platform=${{ matrix.platform }} - if [ "$platform" = 'ubuntu-22.04' ]; then + if [ "$platform" = 'ubuntu-22.04' ]; then echo "PLATFORM_PAIR=linux-amd64" >> $GITHUB_OUTPUT echo "ARCH=amd64" >> $GITHUB_OUTPUT else @@ -209,7 +209,7 @@ jobs: - name: Checkout Repo uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 with: - ref: ${{ env.RELEASE_NAME }} + ref: ${{ env.RELEASE_VERSION }} - name: short sha id: shortSha @@ -225,7 +225,7 @@ jobs: uses: gradle/actions/setup-gradle@9e899d11ad247ec76be7a60bc1cf9d3abbb9e7f1 with: cache-disabled: true - + - name: install goss run: | mkdir -p docker/reports @@ -244,23 +244,23 @@ jobs: architecture: ${{ steps.prep.outputs.ARCH }} with: cache-disabled: true - arguments: testDocker -PdockerOrgName=${{ env.registry }}/${{ secrets.DOCKER_ORG }} -Pversion=${{env.RELEASE_NAME}} -Prelease.releaseVersion=${{ env.RELEASE_NAME }} + arguments: testDocker -PdockerOrgName=${{ env.registry }}/${{ secrets.DOCKER_ORG }} -Pversion=${{env.RELEASE_VERSION}} -Prelease.releaseVersion=${{ env.RELEASE_VERSION }} - name: publish env: architecture: ${{ steps.prep.outputs.ARCH }} - run: ./gradlew --no-daemon dockerUpload -PdockerOrgName=${{ env.registry }}/${{ secrets.DOCKER_ORG }} -Pversion=${{env.RELEASE_NAME}} -Prelease.releaseVersion=${{ env.RELEASE_NAME }} + run: ./gradlew --no-daemon dockerUpload -PdockerOrgName=${{ env.registry }}/${{ secrets.DOCKER_ORG }} -Pversion=${{env.RELEASE_VERSION}} -Prelease.releaseVersion=${{ env.RELEASE_VERSION }} docker-manifest: needs: [validate, docker-publish] runs-on: ubuntu-22.04 env: - RELEASE_NAME: ${{ needs.validate.outputs.release_name }} # Use the output from the pre_process_release job + RELEASE_VERSION: ${{ needs.validate.outputs.release_version }} steps: - name: Checkout Repo uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 with: - ref: ${{ env.RELEASE_NAME }} + ref: ${{ env.RELEASE_VERSION }} - name: Set up Java uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 @@ -281,24 +281,48 @@ jobs: password: ${{ secrets.DOCKER_PASSWORD_RW }} - name: multi-arch docker - run: ./gradlew manifestDocker -PdockerOrgName=${{ env.registry }}/${{ secrets.DOCKER_ORG }} -Pversion=${{env.RELEASE_NAME}} -Prelease.releaseVersion=${{ env.RELEASE_NAME }} + run: ./gradlew manifestDocker -PdockerOrgName=${{ env.registry }}/${{ secrets.DOCKER_ORG }} -Pversion=${{env.RELEASE_VERSION}} -Prelease.releaseVersion=${{ env.RELEASE_VERSION }} docker-verify: needs: [validate,docker-manifest] env: - RELEASE_NAME: ${{ needs.validate.outputs.release_name }} # Use the output from the pre_process_release job - runs-on: ubuntu-22.04 - permissions: - contents: read - actions: write + CONTAINER_NAME: besu-check + RELEASE_VERSION: ${{ needs.validate.outputs.release_version }} + runs-on: ${{ matrix.combination.runner }} + timeout-minutes: 4 + strategy: + matrix: + combination: + - tag: ${{ needs.validate.outputs.release_version }} + platform: '' + runner: ubuntu-22.04 + - tag: ${{ needs.validate.outputs.release_version }}-amd64 + platform: 'linux/amd64' + runner: ubuntu-22.04 + - tag: ${{ needs.validate.outputs.release_version }}-arm64 + platform: '' + runner: besu-arm64 steps: - name: Checkout uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 + with: + sparse-checkout: '.github/workflows/BesuContainerVerify.sh' + + - name: Start container + run: | + PLATFORM_OPT="" + [[ x${{ matrix.combination.platform }} != 'x' ]] && PLATFORM_OPT="--platform ${{ matrix.combination.platform }}" + docker run -d $PLATFORM_OPT --name ${{ env.CONTAINER_NAME }} ${{ secrets.DOCKER_ORG }}/besu:${{ matrix.combination.tag }} - - name: Trigger container verify - run: echo '{"version":"${{ env.RELEASE_NAME }}","verify-latest-version":"false"}' | gh workflow run container-verify.yml --json + - name: Verify besu container + run: bash .github/workflows/BesuContainerVerify.sh env: - GH_TOKEN: ${{ github.token }} + TAG: ${{ matrix.combination.tag }} + VERSION: ${{ env.RELEASE_VERSION }} + CHECK_LATEST: false + + - name: Stop container + run: docker stop ${{ env.CONTAINER_NAME }} release-draft: runs-on: ubuntu-22.04 @@ -306,42 +330,42 @@ jobs: permissions: contents: write env: - RELEASE_NAME: ${{ needs.validate.outputs.release_name }} + RELEASE_VERSION: ${{ needs.validate.outputs.release_version }} steps: - name: Checkout Repo uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 with: - ref: ${{ env.RELEASE_NAME }} + ref: ${{ env.RELEASE_VERSION }} - name: Download Besu artifacts uses: actions/download-artifact@eaceaf801fd36c7dee90939fad912460b18a1ffe with: - pattern: besu-${{env.RELEASE_NAME}}* + pattern: besu-${{env.RELEASE_VERSION}}* merge-multiple: true - name: Draft release notes run: | - echo "## ${{env.RELEASE_NAME}}" > draft-release-notes.md + echo "## ${{env.RELEASE_VERSION}}" > draft-release-notes.md echo "## Upcoming Breaking Changes" >> draft-release-notes.md echo "## Breaking Changes" >> draft-release-notes.md echo "## Additions and Improvements" >> draft-release-notes.md echo "## Bug fixes" >> draft-release-notes.md - echo "`$(cat besu-${{env.RELEASE_NAME}}.zip.sha256)`" >> draft-release-notes.md - echo "`$(cat besu-${{env.RELEASE_NAME}}.tar.gz.sha256)`" >> draft-release-notes.md - cat besu-${{env.RELEASE_NAME}}.zip.sha256 >> draft-release-notes.md - cat besu-${{env.RELEASE_NAME}}.tar.gz.sha256 >> draft-release-notes.md + echo "`$(cat besu-${{env.RELEASE_VERSION}}.zip.sha256)`" >> draft-release-notes.md + echo "`$(cat besu-${{env.RELEASE_VERSION}}.tar.gz.sha256)`" >> draft-release-notes.md + cat besu-${{env.RELEASE_VERSION}}.zip.sha256 >> draft-release-notes.md + cat besu-${{env.RELEASE_VERSION}}.tar.gz.sha256 >> draft-release-notes.md - name: Draft release run: | gh release create \ --draft \ - --title=${{env.RELEASE_NAME}} \ + --title=${{env.RELEASE_VERSION}} \ --notes-file draft-release-notes.md \ - --verify-tag ${{env.RELEASE_NAME}} \ - besu-${{env.RELEASE_NAME}}.tar.gz \ - besu-${{env.RELEASE_NAME}}.zip \ - besu-${{env.RELEASE_NAME}}.zip.sha256 \ - besu-${{env.RELEASE_NAME}}.tar.gz.sha256 + --verify-tag ${{env.RELEASE_VERSION}} \ + besu-${{env.RELEASE_VERSION}}.tar.gz \ + besu-${{env.RELEASE_VERSION}}.zip \ + besu-${{env.RELEASE_VERSION}}.zip.sha256 \ + besu-${{env.RELEASE_VERSION}}.tar.gz.sha256 env: GH_TOKEN: ${{ github.token }} @@ -349,12 +373,12 @@ jobs: runs-on: ubuntu-22.04 needs: [validate, test-linux, test-windows] env: - RELEASE_NAME: ${{ needs.validate.outputs.release_name }} + RELEASE_VERSION: ${{ needs.validate.outputs.release_version }} steps: - name: checkout uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 with: - ref: ${{ env.RELEASE_NAME }} + ref: ${{ env.RELEASE_VERSION }} - name: Set up Java uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 @@ -371,4 +395,4 @@ jobs: env: ARTIFACTORY_USER: ${{ secrets.BESU_ARTIFACTORY_USER }} ARTIFACTORY_KEY: ${{ secrets.BESU_ARTIFACTORY_TOKEN }} - run: ./gradlew -Prelease.releaseVersion=${{ env.RELEASE_NAME }} -Pversion=${{env.RELEASE_NAME}} artifactoryPublish + run: ./gradlew -Prelease.releaseVersion=${{ env.RELEASE_VERSION }} -Pversion=${{env.RELEASE_VERSION}} artifactoryPublish diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml index 7549656d22..1ad9e067f2 100644 --- a/.github/workflows/sonarcloud.yml +++ b/.github/workflows/sonarcloud.yml @@ -38,4 +38,4 @@ jobs: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} SONAR_ORGANIZATION: ${{ vars.SONAR_ORGANIZATION }} SONAR_PROJECT_KEY: ${{ vars.SONAR_PROJECT_KEY }} - run: ./gradlew build sonarqube --continue --info -Dorg.gradle.parallel=true -Dorg.gradle.caching=true + run: ./gradlew build sonar --continue -Dorg.gradle.parallel=true -Dorg.gradle.caching=true diff --git a/.github/workflows/splitList.sh b/.github/workflows/splitList.sh index 4f302dc0cc..25f8e9dcf5 100755 --- a/.github/workflows/splitList.sh +++ b/.github/workflows/splitList.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash ## -## Copyright contributors to Hyperledger Besu. +## Copyright contributors to 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 diff --git a/.github/workflows/splitTestsByTime.sh b/.github/workflows/splitTestsByTime.sh index 219d2d74e7..c77c70d4bb 100755 --- a/.github/workflows/splitTestsByTime.sh +++ b/.github/workflows/splitTestsByTime.sh @@ -1,6 +1,6 @@ #!/bin/bash ## -## Copyright contributors to Hyperledger Besu. +## Copyright contributors to 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 diff --git a/CHANGELOG.md b/CHANGELOG.md index cb965bfb10..8bfb4ebd3e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,13 +1,29 @@ # Changelog ## [Unreleased] +- Added isLabelsObserved to LabelledGauge in plugin-api. Default implementation returns false. + +### Breaking Changes ### Upcoming Breaking Changes -- k8s (KUBERNETES) Nat method is now deprecated and will be removed in a future release + +### Additions and Improvements +- Fine tune already seen txs tracker when a tx is removed from the pool [#7755](https://github.com/hyperledger/besu/pull/7755) +- Create and publish Besu BOM (Bill of Materials) [#7615](https://github.com/hyperledger/besu/pull/7615) +- Update Java dependencies [#7786](https://github.com/hyperledger/besu/pull/7786) +- Add a method to get all the transaction in the pool, to the `TransactionPoolService`, to easily access the transaction pool content from plugins [#7813](https://github.com/hyperledger/besu/pull/7813) + +### Bug fixes + +## 24.10.0 ### Breaking Changes - Besu will now fail to start if any plugins encounter errors during initialization. To allow Besu to continue running despite plugin errors, use the `--plugin-continue-on-error` option. [#7662](https://github.com/hyperledger/besu/pull/7662) +### Upcoming Breaking Changes +- k8s (KUBERNETES) Nat method is now deprecated and will be removed in a future release +- `--host-whitelist` has been deprecated in favor of `--host-allowlist` since 2020 and will be removed in a future release + ### Additions and Improvements - Remove privacy test classes support [#7569](https://github.com/hyperledger/besu/pull/7569) - Add Blob Transaction Metrics [#7622](https://github.com/hyperledger/besu/pull/7622) @@ -17,6 +33,9 @@ - Interrupt pending transaction processing on block creation timeout [#7673](https://github.com/hyperledger/besu/pull/7673) - Align gas cap calculation for transaction simulation to Geth approach [#7703](https://github.com/hyperledger/besu/pull/7703) - Expose chainId in the `BlockchainService` [7702](https://github.com/hyperledger/besu/pull/7702) +- Add support for `chainId` in `CallParameters` [#7720](https://github.com/hyperledger/besu/pull/7720) +- Add `--ephemery` network support for Ephemery Testnet [#7563](https://github.com/hyperledger/besu/pull/7563) thanks to [@gconnect](https://github.com/gconnect) +- Add configuration of Consolidation Request Contract Address via genesis configuration [#7647](https://github.com/hyperledger/besu/pull/7647) ### Bug fixes - Fix mounted data path directory permissions for besu user [#7575](https://github.com/hyperledger/besu/pull/7575) @@ -24,6 +43,10 @@ - Corrects a regression where custom plugin services are not initialized correctly. [#7625](https://github.com/hyperledger/besu/pull/7625) - Fix for IBFT2 chains using the BONSAI DB format [#7631](https://github.com/hyperledger/besu/pull/7631) - Fix reading `tx-pool-min-score` option from configuration file [#7623](https://github.com/hyperledger/besu/pull/7623) +- Fix an unhandled PeerTable exception [#7733](https://github.com/hyperledger/besu/issues/7733) +- Fix RocksDBException: Busy leading to MerkleTrieException: Unable to load trie node value [#7745](https://github.com/hyperledger/besu/pull/7745) +- If a BFT validator node is syncing, pause block production until sync has completed [#7657](https://github.com/hyperledger/besu/pull/7657) +- Fix eth_feeHistory rewards when bounded by configuration [#7750](https://github.com/hyperledger/besu/pull/7750) ## 24.9.1 @@ -4461,7 +4484,6 @@ Specify `*` or `all` for `--host-whitelist` to effectively disable host protecti - Send client quitting disconnect message to peers on shutdown (PR [#253](https://github.com/PegaSysEng/pantheon/pull/253)) - Improved error message for port conflict error (PR [#232](https://github.com/PegaSysEng/pantheon/pull/232)) - ### Technical Improvements - Upgraded Ethereum reference tests to 6.0 beta 2. (thanks to [@jvirtanen](https://github.com/jvirtanen) for the initial upgrade to beta 1) - Set Java compiler default encoding to UTF-8 (PR [#238](https://github.com/PegaSysEng/pantheon/pull/238) thanks to [@matt9ucci](https://github.com/matt9ucci)) diff --git a/MAINTAINERS.md b/MAINTAINERS.md index cf040c25bc..ae6720632a 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -9,6 +9,7 @@ | Name | Github | LFID | | ---------------- | ---------------- | ---------------- | | Ameziane Hamlat | ahamlat | ahamlat | +| Chaminda Divitotawela | cdivitotawela | cdivitotawela | | Daniel Lehrner | daniellehrner | daniellehrner | | Diego López León | diega | diega | | Fabio Di Fabio | fab-10 | fab-10 | @@ -18,7 +19,7 @@ | Justin Florentine| jflo | RoboCopsGoneMad | | Jason Frame | jframe | jframe | | Joshua Fernandes | joshuafernandes | joshuafernandes | -| Luis Pinto | lu-pinto | lu-pinto +| Luis Pinto | lu-pinto | lu-pinto | | Lucas Saldanha | lucassaldanha | lucassaldanha | | Sally MacFarlane | macfarla | macfarla | | Karim Taam | matkt | matkt | diff --git a/README.md b/README.md index 00aad005ac..7139df8580 100644 --- a/README.md +++ b/README.md @@ -14,15 +14,15 @@ Besu is an Apache 2.0 licensed, MainNet compatible, Ethereum client written in J * [Besu User Documentation] * [Besu Issues] -* [Besu Wiki](https://wiki.hyperledger.org/display/BESU/Besu) -* [How to Contribute to Besu](https://wiki.hyperledger.org/display/BESU/How+to+Contribute) -* [Besu Roadmap & Planning](https://wiki.hyperledger.org/pages/viewpage.action?pageId=24781786) +* [Besu Wiki](https://lf-hyperledger.atlassian.net/wiki/spaces/BESU/) +* [How to Contribute to Besu](https://lf-hyperledger.atlassian.net/wiki/spaces/BESU/pages/22156850/How+to+Contribute) +* [Besu Roadmap & Planning](https://lf-hyperledger.atlassian.net/wiki/spaces/BESU/pages/22154278/Besu+Roadmap+Planning) ## Issues Besu issues are tracked [in the github issues tab][Besu Issues]. -See our [guidelines](https://wiki.hyperledger.org/display/BESU/Issues) for more details on searching and creating issues. +See our [guidelines](https://lf-hyperledger.atlassian.net/wiki/spaces/BESU/pages/22154243/Issues) for more details on searching and creating issues. If you have any questions, queries or comments, [Besu channel on Discord] is the place to find us. @@ -34,20 +34,19 @@ To install the Besu binary, follow [these instructions](https://besu.hyperledger ## Besu Developers * [Contributing Guidelines] -* [Coding Conventions](https://wiki.hyperledger.org/display/BESU/Coding+Conventions) -* [Command Line Interface (CLI) Style Guide](https://wiki.hyperledger.org/display/BESU/Besu+CLI+Style+Guide) +* [Coding Conventions](https://lf-hyperledger.atlassian.net/wiki/spaces/BESU/pages/22154259/Coding+Conventions) +* [Command Line Interface (CLI) Style Guide](https://lf-hyperledger.atlassian.net/wiki/spaces/BESU/pages/22154260/Besu+CLI+Style+Guide) * [Besu User Documentation] for running and using Besu ### Development Instructions for how to get started with developing on the Besu codebase. Please also read the -[wiki](https://wiki.hyperledger.org/display/BESU/Pull+Requests) for more details on how to submit a pull request (PR). +[wiki](https://lf-hyperledger.atlassian.net/wiki/spaces/BESU/pages/22154251/Pull+Requests) for more details on how to submit a pull request (PR). -* [Checking Out and Building](https://wiki.hyperledger.org/display/BESU/Building+from+source) -* [Running Developer Builds](https://wiki.hyperledger.org/display/BESU/Building+from+source#running-developer-builds) -* [Code Coverage](https://wiki.hyperledger.org/display/BESU/Code+coverage) -* [Logging](https://wiki.hyperledger.org/display/BESU/Logging) or the [Documentation's Logging section](https://besu.hyperledger.org/public-networks/how-to/monitor/logging) +* [Checking Out and Building](https://lf-hyperledger.atlassian.net/wiki/spaces/BESU/pages/22154264/Building+from+source) +* [Code Coverage](https://lf-hyperledger.atlassian.net/wiki/spaces/BESU/pages/22154288/Code+coverage) +* [Logging](https://lf-hyperledger.atlassian.net/wiki/spaces/BESU/pages/22154291/Logging) or the [Documentation's Logging section](https://besu.hyperledger.org/public-networks/how-to/monitor/logging) ## Release Notes diff --git a/acceptance-tests/dsl/build.gradle b/acceptance-tests/dsl/build.gradle index 6c9090fe9b..0b664c5255 100644 --- a/acceptance-tests/dsl/build.gradle +++ b/acceptance-tests/dsl/build.gradle @@ -33,7 +33,6 @@ dependencies { implementation 'info.picocli:picocli' implementation 'io.reactivex.rxjava2:rxjava' implementation 'io.vertx:vertx-core' - implementation 'junit:junit' implementation 'io.opentelemetry:opentelemetry-api' implementation 'io.tmio:tuweni-bytes' implementation 'io.tmio:tuweni-io' @@ -46,6 +45,5 @@ dependencies { implementation 'org.web3j:crypto' implementation 'org.wiremock:wiremock' - implementation 'org.testcontainers:testcontainers' implementation 'org.junit.jupiter:junit-jupiter' } diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/AcceptanceTestBase.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/AcceptanceTestBase.java index 5256e71ee3..72233adbb8 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/AcceptanceTestBase.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/AcceptanceTestBase.java @@ -49,13 +49,15 @@ import org.hyperledger.besu.tests.acceptance.dsl.transaction.web3.Web3Transactio import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; -import java.lang.ProcessBuilder.Redirect; import java.math.BigInteger; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import org.junit.After; +import org.apache.logging.log4j.ThreadContext; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; import org.junit.jupiter.api.extension.ExtendWith; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -125,7 +127,15 @@ public class AcceptanceTestBase { exitedSuccessfully = new ExitedWithCode(0); } - @After + @BeforeEach + public void setUp(final TestInfo testInfo) { + // log4j is configured to create a file per test + // build/acceptanceTestLogs/${ctx:class}.${ctx:test}.log + ThreadContext.put("class", this.getClass().getSimpleName()); + ThreadContext.put("test", testInfo.getTestMethod().get().getName()); + } + + @AfterEach public void tearDownAcceptanceTestBase() { reportMemory(); cluster.close(); @@ -143,7 +153,9 @@ public class AcceptanceTestBase { if (command != null) { LOG.info("Memory usage at end of test:"); final ProcessBuilder processBuilder = - new ProcessBuilder(command).redirectErrorStream(true).redirectInput(Redirect.INHERIT); + new ProcessBuilder(command) + .redirectErrorStream(true) + .redirectInput(ProcessBuilder.Redirect.INHERIT); try { final Process memInfoProcess = processBuilder.start(); outputProcessorExecutor.execute(() -> printOutput(memInfoProcess)); diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/AcceptanceTestBaseJunit5.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/AcceptanceTestBaseJunit5.java deleted file mode 100644 index 4f3046c1ab..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/AcceptanceTestBaseJunit5.java +++ /dev/null @@ -1,200 +0,0 @@ -/* - * 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.tests.acceptance.dsl; - -import static java.nio.charset.StandardCharsets.UTF_8; -import static org.assertj.core.api.Assertions.assertThat; - -import org.hyperledger.besu.tests.acceptance.dsl.account.Accounts; -import org.hyperledger.besu.tests.acceptance.dsl.blockchain.Blockchain; -import org.hyperledger.besu.tests.acceptance.dsl.condition.admin.AdminConditions; -import org.hyperledger.besu.tests.acceptance.dsl.condition.bft.BftConditions; -import org.hyperledger.besu.tests.acceptance.dsl.condition.clique.CliqueConditions; -import org.hyperledger.besu.tests.acceptance.dsl.condition.eth.EthConditions; -import org.hyperledger.besu.tests.acceptance.dsl.condition.login.LoginConditions; -import org.hyperledger.besu.tests.acceptance.dsl.condition.net.NetConditions; -import org.hyperledger.besu.tests.acceptance.dsl.condition.perm.PermissioningConditions; -import org.hyperledger.besu.tests.acceptance.dsl.condition.process.ExitedWithCode; -import org.hyperledger.besu.tests.acceptance.dsl.condition.txpool.TxPoolConditions; -import org.hyperledger.besu.tests.acceptance.dsl.condition.web3.Web3Conditions; -import org.hyperledger.besu.tests.acceptance.dsl.contract.ContractVerifier; -import org.hyperledger.besu.tests.acceptance.dsl.node.Node; -import org.hyperledger.besu.tests.acceptance.dsl.node.cluster.Cluster; -import org.hyperledger.besu.tests.acceptance.dsl.node.configuration.BesuNodeFactory; -import org.hyperledger.besu.tests.acceptance.dsl.node.configuration.permissioning.PermissionedNodeBuilder; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.account.AccountTransactions; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.admin.AdminTransactions; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.bft.BftTransactions; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.clique.CliqueTransactions; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.contract.ContractTransactions; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.eth.EthTransactions; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.miner.MinerTransactions; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.net.NetTransactions; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.perm.PermissioningTransactions; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.txpool.TxPoolTransactions; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.web3.Web3Transactions; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.math.BigInteger; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -import org.apache.logging.log4j.ThreadContext; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestInfo; -import org.junit.jupiter.api.extension.ExtendWith; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Superclass for acceptance tests. For now (transition to junit5 is ongoing) this class supports - * junit5 format. Once the transition is complete, this class can be removed and recombined with - * AcceptanceTestBase (original). - */ -@ExtendWith(AcceptanceTestBaseTestWatcher.class) -public class AcceptanceTestBaseJunit5 { - - private static final Logger LOG = LoggerFactory.getLogger(AcceptanceTestBaseJunit5.class); - - protected final Accounts accounts; - protected final AccountTransactions accountTransactions; - protected final AdminConditions admin; - protected final AdminTransactions adminTransactions; - protected final Blockchain blockchain; - protected final CliqueConditions clique; - protected final CliqueTransactions cliqueTransactions; - protected final Cluster cluster; - protected final ContractVerifier contractVerifier; - protected final ContractTransactions contractTransactions; - protected final EthConditions eth; - protected final EthTransactions ethTransactions; - protected final BftTransactions bftTransactions; - protected final BftConditions bft; - protected final LoginConditions login; - protected final NetConditions net; - protected final BesuNodeFactory besu; - protected final PermissioningConditions perm; - protected final PermissionedNodeBuilder permissionedNodeBuilder; - protected final PermissioningTransactions permissioningTransactions; - protected final MinerTransactions minerTransactions; - protected final Web3Conditions web3; - protected final TxPoolConditions txPoolConditions; - protected final TxPoolTransactions txPoolTransactions; - protected final ExitedWithCode exitedSuccessfully; - - private final ExecutorService outputProcessorExecutor = Executors.newCachedThreadPool(); - - protected AcceptanceTestBaseJunit5() { - ethTransactions = new EthTransactions(); - accounts = new Accounts(ethTransactions); - adminTransactions = new AdminTransactions(); - cliqueTransactions = new CliqueTransactions(); - bftTransactions = new BftTransactions(); - accountTransactions = new AccountTransactions(accounts); - permissioningTransactions = new PermissioningTransactions(); - contractTransactions = new ContractTransactions(); - minerTransactions = new MinerTransactions(); - blockchain = new Blockchain(ethTransactions); - clique = new CliqueConditions(ethTransactions, cliqueTransactions); - eth = new EthConditions(ethTransactions); - bft = new BftConditions(bftTransactions); - login = new LoginConditions(); - net = new NetConditions(new NetTransactions()); - cluster = new Cluster(net); - perm = new PermissioningConditions(permissioningTransactions); - admin = new AdminConditions(adminTransactions); - web3 = new Web3Conditions(new Web3Transactions()); - besu = new BesuNodeFactory(); - txPoolTransactions = new TxPoolTransactions(); - txPoolConditions = new TxPoolConditions(txPoolTransactions); - contractVerifier = new ContractVerifier(accounts.getPrimaryBenefactor()); - permissionedNodeBuilder = new PermissionedNodeBuilder(); - exitedSuccessfully = new ExitedWithCode(0); - } - - @BeforeEach - public void setUp(final TestInfo testInfo) { - // log4j is configured to create a file per test - // build/acceptanceTestLogs/${ctx:class}.${ctx:test}.log - ThreadContext.put("class", this.getClass().getSimpleName()); - ThreadContext.put("test", testInfo.getTestMethod().get().getName()); - } - - @AfterEach - public void tearDownAcceptanceTestBase() { - reportMemory(); - cluster.close(); - } - - public void reportMemory() { - String os = System.getProperty("os.name"); - String[] command = null; - if (os.contains("Linux")) { - command = new String[] {"/usr/bin/top", "-n", "1", "-o", "%MEM", "-b", "-c", "-w", "180"}; - } - if (os.contains("Mac")) { - command = new String[] {"/usr/bin/top", "-l", "1", "-o", "mem", "-n", "20"}; - } - if (command != null) { - LOG.info("Memory usage at end of test:"); - final ProcessBuilder processBuilder = - new ProcessBuilder(command) - .redirectErrorStream(true) - .redirectInput(ProcessBuilder.Redirect.INHERIT); - try { - final Process memInfoProcess = processBuilder.start(); - outputProcessorExecutor.execute(() -> printOutput(memInfoProcess)); - memInfoProcess.waitFor(); - LOG.debug("Memory info process exited with code {}", memInfoProcess.exitValue()); - } catch (final Exception e) { - LOG.warn("Error running memory information process", e); - } - } else { - LOG.info("Don't know how to report memory for OS {}", os); - } - } - - private void printOutput(final Process process) { - try (final BufferedReader in = - new BufferedReader(new InputStreamReader(process.getInputStream(), UTF_8))) { - String line = in.readLine(); - while (line != null) { - LOG.info(line); - line = in.readLine(); - } - } catch (final IOException e) { - LOG.warn("Failed to read output from memory information process: ", e); - } - } - - protected void waitForBlockHeight(final Node node, final long blockchainHeight) { - WaitUtils.waitFor( - 120, - () -> - assertThat(node.execute(ethTransactions.blockNumber())) - .isGreaterThanOrEqualTo(BigInteger.valueOf(blockchainHeight))); - } - - @Test - void dryRunDetector() { - assertThat(true) - .withFailMessage("This test is here so gradle --dry-run executes this class") - .isTrue(); - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/blockchain/ExpectBlockNotCreated.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/blockchain/ExpectBlockNotCreated.java index 4deb1c1ee3..42cab06539 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/blockchain/ExpectBlockNotCreated.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/blockchain/ExpectBlockNotCreated.java @@ -14,7 +14,7 @@ */ package org.hyperledger.besu.tests.acceptance.dsl.condition.blockchain; -import static junit.framework.TestCase.fail; +import static org.junit.jupiter.api.Assertions.fail; import org.hyperledger.besu.tests.acceptance.dsl.condition.Condition; import org.hyperledger.besu.tests.acceptance.dsl.node.Node; diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/BesuNode.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/BesuNode.java index 4e48be0401..21ca45070b 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/BesuNode.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/BesuNode.java @@ -18,7 +18,7 @@ import static java.util.Collections.unmodifiableList; import static org.apache.tuweni.io.file.Files.copyResource; import org.hyperledger.besu.cli.config.NetworkName; -import org.hyperledger.besu.config.MergeConfigOptions; +import org.hyperledger.besu.config.MergeConfiguration; import org.hyperledger.besu.crypto.KeyPair; import org.hyperledger.besu.crypto.KeyPairUtil; import org.hyperledger.besu.datatypes.Address; @@ -228,7 +228,7 @@ public class BesuNode implements NodeConfiguration, RunnableNode, AutoCloseable }); this.requestedPlugins = requestedPlugins; engineRpcConfiguration.ifPresent( - config -> MergeConfigOptions.setMergeEnabled(config.isEnabled())); + config -> MergeConfiguration.setMergeEnabled(config.isEnabled())); this.extraCLIOptions = extraCLIOptions; this.staticNodes = staticNodes; this.isDnsEnabled = isDnsEnabled; diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/ProcessBesuNodeRunner.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/ProcessBesuNodeRunner.java index 62951a442d..75307d9520 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/ProcessBesuNodeRunner.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/ProcessBesuNodeRunner.java @@ -18,7 +18,7 @@ import static com.google.common.base.Preconditions.checkState; import static java.nio.charset.StandardCharsets.UTF_8; import org.hyperledger.besu.cli.options.TransactionPoolOptions; -import org.hyperledger.besu.cli.options.stable.DataStorageOptions; +import org.hyperledger.besu.cli.options.storage.DataStorageOptions; import org.hyperledger.besu.cli.options.unstable.NetworkingOptions; import org.hyperledger.besu.ethereum.api.jsonrpc.ipc.JsonRpcIpcConfiguration; import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration; diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/ThreadBesuNodeRunner.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/ThreadBesuNodeRunner.java index d4334fd93c..42c0df73c7 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/ThreadBesuNodeRunner.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/ThreadBesuNodeRunner.java @@ -54,6 +54,7 @@ import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.cache.BonsaiCachedMer import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; import org.hyperledger.besu.evm.internal.EvmConfiguration; +import org.hyperledger.besu.metrics.MetricCategoryRegistryImpl; import org.hyperledger.besu.metrics.MetricsSystemModule; import org.hyperledger.besu.metrics.ObservableMetricsSystem; import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration; @@ -71,6 +72,7 @@ import org.hyperledger.besu.plugin.services.StorageService; import org.hyperledger.besu.plugin.services.TransactionPoolValidatorService; import org.hyperledger.besu.plugin.services.TransactionSelectionService; import org.hyperledger.besu.plugin.services.TransactionSimulationService; +import org.hyperledger.besu.plugin.services.metrics.MetricCategoryRegistry; import org.hyperledger.besu.plugin.services.storage.rocksdb.RocksDBPlugin; import org.hyperledger.besu.services.BesuConfigurationImpl; import org.hyperledger.besu.services.BesuEventsImpl; @@ -396,6 +398,12 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner { retval.init(blockchain, transactionSimulator); return retval; } + + @Provides + @Singleton + MetricCategoryRegistryImpl provideMetricCategoryRegistry() { + return new MetricCategoryRegistryImpl(); + } } @Module @@ -476,6 +484,8 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner { final RpcEndpointServiceImpl rpcEndpointServiceImpl, final BesuConfiguration commonPluginConfiguration, final PermissioningServiceImpl permissioningService, + final MetricCategoryRegistryImpl metricCategoryRegistry, + final MetricsSystem metricsSystem, final @Named("ExtraCLIOptions") List extraCLIOptions, final @Named("RequestedPlugins") List requestedPlugins) { final CommandLine commandLine = new CommandLine(CommandSpec.create()); @@ -492,6 +502,8 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner { TransactionSimulationService.class, transactionSimulationServiceImpl); besuPluginContext.addService(BlockchainService.class, blockchainServiceImpl); besuPluginContext.addService(BesuConfiguration.class, commonPluginConfiguration); + besuPluginContext.addService(MetricCategoryRegistry.class, metricCategoryRegistry); + besuPluginContext.addService(MetricsSystem.class, metricsSystem); final Path pluginsPath; final String pluginDir = System.getProperty("besu.plugins.dir"); diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/account/TransferTransactionBuilder.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/account/TransferTransactionBuilder.java index 1d85969444..bb5fd5c4ed 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/account/TransferTransactionBuilder.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/account/TransferTransactionBuilder.java @@ -14,7 +14,7 @@ */ package org.hyperledger.besu.tests.acceptance.dsl.transaction.account; -import static org.testcontainers.shaded.com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkNotNull; import org.hyperledger.besu.crypto.SECP256K1; import org.hyperledger.besu.crypto.SignatureAlgorithm; diff --git a/acceptance-tests/test-plugins/build.gradle b/acceptance-tests/test-plugins/build.gradle index 65a3dc64dc..7c70c52c81 100644 --- a/acceptance-tests/test-plugins/build.gradle +++ b/acceptance-tests/test-plugins/build.gradle @@ -14,8 +14,6 @@ dependencies { testImplementation 'org.assertj:assertj-core' testImplementation 'org.junit.jupiter:junit-jupiter' - - testRuntimeOnly 'org.junit.vintage:junit-vintage-engine' } task testPluginsJar(type: Jar) { diff --git a/acceptance-tests/tests/build.gradle b/acceptance-tests/tests/build.gradle index 8bb8fb2f2f..fdc7735452 100644 --- a/acceptance-tests/tests/build.gradle +++ b/acceptance-tests/tests/build.gradle @@ -68,21 +68,17 @@ dependencies { testImplementation 'io.opentracing:opentracing-api' testImplementation 'io.opentracing:opentracing-util' testImplementation 'io.vertx:vertx-core' - testImplementation 'junit:junit' testImplementation 'org.apache.commons:commons-compress' testImplementation 'org.apache.logging.log4j:log4j-core' testImplementation 'io.tmio:tuweni-crypto' testImplementation 'org.assertj:assertj-core' testImplementation 'org.awaitility:awaitility' testImplementation 'org.junit.jupiter:junit-jupiter' - testImplementation 'org.testcontainers:testcontainers' testImplementation 'org.web3j:abi' testImplementation 'org.web3j:besu' testImplementation 'org.web3j:core' testImplementation 'org.wiremock:wiremock' testImplementation project(path: ':acceptance-tests:tests:shanghai') - - testRuntimeOnly 'org.junit.vintage:junit-vintage-engine' } test.enabled = false @@ -106,7 +102,8 @@ task acceptanceTest(type: Test) { setSystemProperties(test.getSystemProperties()) systemProperty 'acctests.runBesuAsProcess', 'true' systemProperty 'java.security.properties', "${buildDir}/resources/test/acceptanceTesting.security" - mustRunAfter rootProject.subprojects*.test + def javaProjects = rootProject.subprojects - project(':platform') + mustRunAfter javaProjects.test description = 'Runs ALL Besu acceptance tests (mainnet and non-mainnet).' group = 'verification' @@ -135,7 +132,8 @@ task acceptanceTestNotPrivacy(type: Test) { setSystemProperties(test.getSystemProperties()) systemProperty 'acctests.runBesuAsProcess', 'true' systemProperty 'java.security.properties', "${buildDir}/resources/test/acceptanceTesting.security" - mustRunAfter rootProject.subprojects*.test + def javaProjects = rootProject.subprojects - project(':platform') + mustRunAfter javaProjects.test description = 'Runs MAINNET Besu acceptance tests (excluding specific non-mainnet suites).' group = 'verification' @@ -163,7 +161,8 @@ task acceptanceTestCliqueBft(type: Test) { setSystemProperties(test.getSystemProperties()) systemProperty 'acctests.runBesuAsProcess', 'true' systemProperty 'java.security.properties', "${buildDir}/resources/test/acceptanceTesting.security" - mustRunAfter rootProject.subprojects*.test + def javaProjects = rootProject.subprojects - project(':platform') + mustRunAfter javaProjects.test description = 'Runs Clique and BFT Besu acceptance tests.' group = 'verification' @@ -192,7 +191,8 @@ task acceptanceTestBftSoak(type: Test) { // Set to any time > 60 minutes to run the soak test for longer // systemProperty 'acctests.soakTimeMins', '120' systemProperty 'java.security.properties', "${buildDir}/resources/test/acceptanceTesting.security" - mustRunAfter rootProject.subprojects*.test + def javaProjects = rootProject.subprojects - project(':platform') + mustRunAfter javaProjects.test description = 'Runs BFT soak test.' group = 'verification' @@ -219,7 +219,8 @@ task acceptanceTestPermissioning(type: Test) { setSystemProperties(test.getSystemProperties()) systemProperty 'acctests.runBesuAsProcess', 'true' systemProperty 'java.security.properties', "${buildDir}/resources/test/acceptanceTesting.security" - mustRunAfter rootProject.subprojects*.test + def javaProjects = rootProject.subprojects - project(':platform') + mustRunAfter javaProjects.test description = 'Runs Permissioning Besu acceptance tests.' group = 'verification' diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bft/ParameterizedBftTestBase.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bft/ParameterizedBftTestBase.java index b3d1e321ae..76a1a4a6bc 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bft/ParameterizedBftTestBase.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bft/ParameterizedBftTestBase.java @@ -14,7 +14,7 @@ */ package org.hyperledger.besu.tests.acceptance.bft; -import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBaseJunit5; +import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBase; import java.util.stream.Stream; @@ -22,7 +22,7 @@ import org.junit.jupiter.api.Disabled; import org.junit.jupiter.params.provider.Arguments; @Disabled("This is not a test class, it offers BFT parameterization only.") -public abstract class ParameterizedBftTestBase extends AcceptanceTestBaseJunit5 { +public abstract class ParameterizedBftTestBase extends AcceptanceTestBase { protected String bftType; protected BftAcceptanceTestParameterization nodeFactory; diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bft/qbft/QbftContractAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bft/qbft/QbftContractAcceptanceTest.java index b62eb96e19..038f2be16c 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bft/qbft/QbftContractAcceptanceTest.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bft/qbft/QbftContractAcceptanceTest.java @@ -14,13 +14,13 @@ */ package org.hyperledger.besu.tests.acceptance.bft.qbft; -import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBaseJunit5; +import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBase; import org.hyperledger.besu.tests.acceptance.dsl.account.Account; import org.hyperledger.besu.tests.acceptance.dsl.node.BesuNode; import org.junit.jupiter.api.Test; -public class QbftContractAcceptanceTest extends AcceptanceTestBaseJunit5 { +public class QbftContractAcceptanceTest extends AcceptanceTestBase { @Test public void shouldMineOnMultipleNodesEvenWhenClusterContainsNonValidator() throws Exception { diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bftsoak/BftMiningSoakTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bftsoak/BftMiningSoakTest.java index 878e503ba3..9098fcbb7d 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bftsoak/BftMiningSoakTest.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bftsoak/BftMiningSoakTest.java @@ -41,7 +41,7 @@ public class BftMiningSoakTest extends ParameterizedBftTestBase { private static final long ONE_MINUTE = Duration.of(1, ChronoUnit.MINUTES).toMillis(); - private static final long THREE_MINUTES = Duration.of(1, ChronoUnit.MINUTES).toMillis(); + private static final long THREE_MINUTES = Duration.of(3, ChronoUnit.MINUTES).toMillis(); private static final long TEN_SECONDS = Duration.of(10, ChronoUnit.SECONDS).toMillis(); diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/clique/CliqueDiscardRpcAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/clique/CliqueDiscardRpcAcceptanceTest.java index 6ea274b699..3ac42cb056 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/clique/CliqueDiscardRpcAcceptanceTest.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/clique/CliqueDiscardRpcAcceptanceTest.java @@ -14,14 +14,14 @@ */ package org.hyperledger.besu.tests.acceptance.clique; -import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBaseJunit5; +import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBase; import org.hyperledger.besu.tests.acceptance.dsl.node.BesuNode; import java.io.IOException; import org.junit.jupiter.api.Test; -public class CliqueDiscardRpcAcceptanceTest extends AcceptanceTestBaseJunit5 { +public class CliqueDiscardRpcAcceptanceTest extends AcceptanceTestBase { @Test public void shouldDiscardVotes() throws IOException { diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/clique/CliqueGetSignersRpcAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/clique/CliqueGetSignersRpcAcceptanceTest.java index ba848b0052..25a1d33510 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/clique/CliqueGetSignersRpcAcceptanceTest.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/clique/CliqueGetSignersRpcAcceptanceTest.java @@ -16,7 +16,7 @@ package org.hyperledger.besu.tests.acceptance.clique; import static org.hyperledger.besu.tests.acceptance.dsl.transaction.clique.CliqueTransactions.LATEST; -import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBaseJunit5; +import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBase; import org.hyperledger.besu.tests.acceptance.dsl.node.BesuNode; import org.junit.jupiter.api.BeforeEach; @@ -24,7 +24,7 @@ import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; @Disabled("flaky test due to hardcoded block numbers") -public class CliqueGetSignersRpcAcceptanceTest extends AcceptanceTestBaseJunit5 { +public class CliqueGetSignersRpcAcceptanceTest extends AcceptanceTestBase { private BesuNode minerNode1; private BesuNode minerNode2; diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/clique/CliqueMiningAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/clique/CliqueMiningAcceptanceTest.java index f6718b4ded..f2bae44580 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/clique/CliqueMiningAcceptanceTest.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/clique/CliqueMiningAcceptanceTest.java @@ -18,7 +18,7 @@ import static java.util.stream.Collectors.joining; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import static org.assertj.core.data.Percentage.withPercentage; -import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBaseJunit5; +import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBase; import org.hyperledger.besu.tests.acceptance.dsl.account.Account; import org.hyperledger.besu.tests.acceptance.dsl.node.BesuNode; import org.hyperledger.besu.tests.acceptance.dsl.node.configuration.genesis.GenesisConfigurationFactory.CliqueOptions; @@ -32,7 +32,7 @@ import java.util.Optional; import org.junit.jupiter.api.Test; import org.web3j.protocol.core.DefaultBlockParameter; -public class CliqueMiningAcceptanceTest extends AcceptanceTestBaseJunit5 { +public class CliqueMiningAcceptanceTest extends AcceptanceTestBase { @Test public void shouldMineTransactionsOnSingleNode() throws IOException { diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/clique/CliqueProposalRpcAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/clique/CliqueProposalRpcAcceptanceTest.java index a7e8ebb9c9..6cbfbbda0f 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/clique/CliqueProposalRpcAcceptanceTest.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/clique/CliqueProposalRpcAcceptanceTest.java @@ -14,14 +14,14 @@ */ package org.hyperledger.besu.tests.acceptance.clique; -import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBaseJunit5; +import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBase; import org.hyperledger.besu.tests.acceptance.dsl.node.BesuNode; import java.io.IOException; import org.junit.jupiter.api.Test; -public class CliqueProposalRpcAcceptanceTest extends AcceptanceTestBaseJunit5 { +public class CliqueProposalRpcAcceptanceTest extends AcceptanceTestBase { @Test public void shouldReturnProposals() throws IOException { diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java index d4fb71c36b..1674c551a4 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java @@ -14,7 +14,7 @@ */ package org.hyperledger.besu.tests.acceptance.clique; -import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBaseJunit5; +import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBase; import org.hyperledger.besu.tests.acceptance.dsl.condition.Condition; import org.hyperledger.besu.tests.acceptance.dsl.condition.clique.ExpectNonceVote.CLIQUE_NONCE_VOTE; import org.hyperledger.besu.tests.acceptance.dsl.node.BesuNode; @@ -23,7 +23,7 @@ import java.io.IOException; import org.junit.jupiter.api.Test; -public class CliqueProposeRpcAcceptanceTest extends AcceptanceTestBaseJunit5 { +public class CliqueProposeRpcAcceptanceTest extends AcceptanceTestBase { @Test public void shouldAddValidators() throws IOException { diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/clique/CliqueZeroValidatorsAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/clique/CliqueZeroValidatorsAcceptanceTest.java index b0c6afd93f..e124e669d9 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/clique/CliqueZeroValidatorsAcceptanceTest.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/clique/CliqueZeroValidatorsAcceptanceTest.java @@ -14,14 +14,14 @@ */ package org.hyperledger.besu.tests.acceptance.clique; -import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBaseJunit5; +import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBase; import org.hyperledger.besu.tests.acceptance.dsl.node.BesuNode; import java.io.IOException; import org.junit.jupiter.api.Test; -public class CliqueZeroValidatorsAcceptanceTest extends AcceptanceTestBaseJunit5 { +public class CliqueZeroValidatorsAcceptanceTest extends AcceptanceTestBase { @Test public void zeroValidatorsFormValidCluster() throws IOException { diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/crypto/SECP256R1AcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/crypto/SECP256R1AcceptanceTest.java index 27679463bf..cc2d1a36bc 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/crypto/SECP256R1AcceptanceTest.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/crypto/SECP256R1AcceptanceTest.java @@ -15,7 +15,7 @@ package org.hyperledger.besu.tests.acceptance.crypto; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assumptions.assumeThat; +import static org.junit.jupiter.api.Assumptions.assumeTrue; import org.hyperledger.besu.crypto.KeyPair; import org.hyperledger.besu.crypto.SECP256R1; @@ -80,7 +80,7 @@ public class SECP256R1AcceptanceTest extends AcceptanceTestBase { // the signature algorithm instance to SECP256R1 as it could influence other tests running at // the same time. So we only execute the test when ProcessBesuNodeRunner is used, as there is // not conflict because we use separate processes. - assumeThat(BesuNodeRunner.isProcessBesuNodeRunner()).isTrue(); + assumeTrue(BesuNodeRunner.isProcessBesuNodeRunner()); minerNode.verify(net.awaitPeerCount(1)); otherNode.verify(net.awaitPeerCount(1)); diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/ethereum/PragueAcceptanceTestHelper.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/ethereum/PragueAcceptanceTestHelper.java index fa190f3de1..754e28165c 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/ethereum/PragueAcceptanceTestHelper.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/ethereum/PragueAcceptanceTestHelper.java @@ -22,7 +22,9 @@ import org.hyperledger.besu.tests.acceptance.dsl.transaction.eth.EthTransactions import java.io.IOException; import java.util.Optional; +import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import okhttp3.Call; import okhttp3.MediaType; @@ -74,17 +76,15 @@ public class PragueAcceptanceTestHelper { final Call getPayloadRequest = createEngineCall(createGetPayloadRequest(payloadId)); final ObjectNode executionPayload; + final ArrayNode executionRequests; final String newBlockHash; final String parentBeaconBlockRoot; try (final Response getPayloadResponse = getPayloadRequest.execute()) { assertThat(getPayloadResponse.code()).isEqualTo(200); - executionPayload = - (ObjectNode) - mapper - .readTree(getPayloadResponse.body().string()) - .get("result") - .get("executionPayload"); + JsonNode result = mapper.readTree(getPayloadResponse.body().string()).get("result"); + executionPayload = (ObjectNode) result.get("executionPayload"); + executionRequests = (ArrayNode) result.get("executionRequests"); newBlockHash = executionPayload.get("blockHash").asText(); parentBeaconBlockRoot = executionPayload.remove("parentBeaconBlockRoot").asText(); @@ -94,7 +94,8 @@ public class PragueAcceptanceTestHelper { final Call newPayloadRequest = createEngineCall( - createNewPayloadRequest(executionPayload.toString(), parentBeaconBlockRoot)); + createNewPayloadRequest( + executionPayload.toString(), parentBeaconBlockRoot, executionRequests.toString())); try (final Response newPayloadResponse = newPayloadRequest.execute()) { assertThat(newPayloadResponse.code()).isEqualTo(200); } @@ -168,7 +169,9 @@ public class PragueAcceptanceTestHelper { } private String createNewPayloadRequest( - final String executionPayload, final String parentBeaconBlockRoot) { + final String executionPayload, + final String parentBeaconBlockRoot, + final String executionRequests) { return "{" + " \"jsonrpc\": \"2.0\"," + " \"method\": \"engine_newPayloadV4\"," @@ -178,6 +181,8 @@ public class PragueAcceptanceTestHelper { + "\"" + parentBeaconBlockRoot + "\"" + + "," + + executionRequests + "]," + " \"id\": 67" + "}"; diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/jsonrpc/ExecutionEnginePragueAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/jsonrpc/ExecutionEnginePragueAcceptanceTest.java index 966c02bebd..f38a192d4d 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/jsonrpc/ExecutionEnginePragueAcceptanceTest.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/jsonrpc/ExecutionEnginePragueAcceptanceTest.java @@ -20,8 +20,11 @@ import java.util.stream.Stream; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.params.provider.Arguments; +// TODO SLD +@Disabled("TODO SLD - Enable when Prague spec is finalized") public class ExecutionEnginePragueAcceptanceTest extends AbstractJsonRpcTest { private static final String GENESIS_FILE = "/jsonrpc/engine/prague/genesis.json"; private static final String TEST_CASE_PATH = "/jsonrpc/engine/prague/test-cases/"; diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/mining/MiningAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/mining/MiningAcceptanceTest.java index 69d6d19d18..a0de84fb3b 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/mining/MiningAcceptanceTest.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/mining/MiningAcceptanceTest.java @@ -18,21 +18,21 @@ import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBase; import org.hyperledger.besu.tests.acceptance.dsl.account.Account; import org.hyperledger.besu.tests.acceptance.dsl.node.Node; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; -public class MiningAcceptanceTest extends AcceptanceTestBase { +class MiningAcceptanceTest extends AcceptanceTestBase { private Node minerNode; - @Before + @BeforeEach public void setUp() throws Exception { minerNode = besu.createMinerNode("miner1"); cluster.start(minerNode); } @Test - public void shouldMineTransactions() { + void shouldMineTransactions() { final Account sender = accounts.createAccount("account1"); final Account receiver = accounts.createAccount("account2"); minerNode.execute(accountTransactions.createTransfer(sender, 50)); diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/plugins/BadCLIOptionsPluginTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/plugins/BadCLIOptionsPluginTest.java index fb35aaacf5..91c70439da 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/plugins/BadCLIOptionsPluginTest.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/plugins/BadCLIOptionsPluginTest.java @@ -16,7 +16,7 @@ package org.hyperledger.besu.tests.acceptance.plugins; import static org.assertj.core.api.Assertions.assertThat; -import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBaseJunit5; +import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBase; import org.hyperledger.besu.tests.acceptance.dsl.node.BesuNode; import java.io.File; @@ -34,7 +34,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.DisabledOnOs; import org.junit.jupiter.api.condition.OS; -public class BadCLIOptionsPluginTest extends AcceptanceTestBaseJunit5 { +public class BadCLIOptionsPluginTest extends AcceptanceTestBase { private BesuNode node; @BeforeEach diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/plugins/BesuEventsPluginTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/plugins/BesuEventsPluginTest.java index a35309ef6f..4906193362 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/plugins/BesuEventsPluginTest.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/plugins/BesuEventsPluginTest.java @@ -14,7 +14,7 @@ */ package org.hyperledger.besu.tests.acceptance.plugins; -import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBaseJunit5; +import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBase; import org.hyperledger.besu.tests.acceptance.dsl.node.BesuNode; import java.io.File; @@ -28,7 +28,7 @@ import org.awaitility.Awaitility; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -public class BesuEventsPluginTest extends AcceptanceTestBaseJunit5 { +public class BesuEventsPluginTest extends AcceptanceTestBase { private BesuNode pluginNode; private BesuNode minerNode; diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/plugins/PermissioningPluginTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/plugins/PermissioningPluginTest.java index 86756a4208..c469802fc1 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/plugins/PermissioningPluginTest.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/plugins/PermissioningPluginTest.java @@ -15,7 +15,7 @@ package org.hyperledger.besu.tests.acceptance.plugins; import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBaseJunit5; +import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBase; import org.hyperledger.besu.tests.acceptance.dsl.account.Account; import org.hyperledger.besu.tests.acceptance.dsl.blockchain.Amount; import org.hyperledger.besu.tests.acceptance.dsl.node.BesuNode; @@ -27,7 +27,7 @@ import java.util.List; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -public class PermissioningPluginTest extends AcceptanceTestBaseJunit5 { +public class PermissioningPluginTest extends AcceptanceTestBase { private BesuNode minerNode; private BesuNode aliceNode; diff --git a/acceptance-tests/tests/src/test/resources/dev/dev_prague.json b/acceptance-tests/tests/src/test/resources/dev/dev_prague.json index 26e59992d1..942edc4e70 100644 --- a/acceptance-tests/tests/src/test/resources/dev/dev_prague.json +++ b/acceptance-tests/tests/src/test/resources/dev/dev_prague.json @@ -19,7 +19,9 @@ "period": 5, "epoch": 30000 }, - "depositContractAddress": "0x4242424242424242424242424242424242424242" + "depositContractAddress": "0x4242424242424242424242424242424242424242", + "withdrawalRequestContractAddress": "0x00A3ca265EBcb825B45F985A16CEFB49958cE017", + "consolidationRequestContractAddress": "0x00b42dbF2194e931E80326D950320f7d9Dbeac02" }, "nonce":"0x42", "timestamp":"0x0", @@ -53,9 +55,9 @@ "balance": "1000000000000000000000000000" }, "0x00A3ca265EBcb825B45F985A16CEFB49958cE017": { - "comment": "This is the runtime bytecode for the Withdrawal Request Smart Contract. It was created from the deployment transaction in EIP-7002 (https://eips.ethereum.org/EIPS/eip-7002#deployment)", + "comment": "This is the runtime bytecode for the Withdrawal Request Smart Contract. It was created from the generated alloc section of fork_Prague_blockchain_test_engine_single_block_single_withdrawal_request_from_contract spec test", "balance": "0", - "code": "0x3373fffffffffffffffffffffffffffffffffffffffe146090573615156028575f545f5260205ff35b36603814156101215760115f54600182026001905f5b5f82111560595781019083028483029004916001019190603e565b90939004341061012157600154600101600155600354806003026004013381556001015f3581556001016020359055600101600355005b6003546002548082038060101160a4575060105b5f5b81811460dd5780604c02838201600302600401805490600101805490600101549160601b83528260140152906034015260010160a6565b910180921460ed579060025560f8565b90505f6002555f6003555b5f5460015460028282011161010f5750505f610115565b01600290035b5f555f600155604c025ff35b5f5ffd", + "code": "0x3373fffffffffffffffffffffffffffffffffffffffe1460c7573615156028575f545f5260205ff35b36603814156101f05760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff146101f057600182026001905f5b5f821115608057810190830284830290049160010191906065565b9093900434106101f057600154600101600155600354806003026004013381556001015f35815560010160203590553360601b5f5260385f601437604c5fa0600101600355005b6003546002548082038060101160db575060105b5f5b81811461017f5780604c02838201600302600401805490600101805490600101549160601b83528260140152807fffffffffffffffffffffffffffffffff0000000000000000000000000000000016826034015260401c906044018160381c81600701538160301c81600601538160281c81600501538160201c81600401538160181c81600301538160101c81600201538160081c81600101535360010160dd565b9101809214610191579060025561019c565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14156101c957505f5b6001546002828201116101de5750505f6101e4565b01600290035b5f555f600155604c025ff35b5f5ffd", "storage": { "0x0000000000000000000000000000000000000000000000000000000000000000": "0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001": "0000000000000000000000000000000000000000000000000000000000000001", @@ -67,9 +69,9 @@ } }, "0x4242424242424242424242424242424242424242": { - "comment": "The deposit contract", + "comment": "This is the runtime bytecode for the Deposit Request Smart Contract. It was created from the generated alloc section of fork_Prague_blockchain_test_engine_single_deposit_from_contract spec test", "balance": "0", - "code": "0x60806040526004361061003f5760003560e01c806301ffc9a71461004457806322895118146100a4578063621fd130146101ba578063c5f2892f14610244575b600080fd5b34801561005057600080fd5b506100906004803603602081101561006757600080fd5b50357fffffffff000000000000000000000000000000000000000000000000000000001661026b565b604080519115158252519081900360200190f35b6101b8600480360360808110156100ba57600080fd5b8101906020810181356401000000008111156100d557600080fd5b8201836020820111156100e757600080fd5b8035906020019184600183028401116401000000008311171561010957600080fd5b91939092909160208101903564010000000081111561012757600080fd5b82018360208201111561013957600080fd5b8035906020019184600183028401116401000000008311171561015b57600080fd5b91939092909160208101903564010000000081111561017957600080fd5b82018360208201111561018b57600080fd5b803590602001918460018302840111640100000000831117156101ad57600080fd5b919350915035610304565b005b3480156101c657600080fd5b506101cf6110b5565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102095781810151838201526020016101f1565b50505050905090810190601f1680156102365780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561025057600080fd5b506102596110c7565b60408051918252519081900360200190f35b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a70000000000000000000000000000000000000000000000000000000014806102fe57507fffffffff0000000000000000000000000000000000000000000000000000000082167f8564090700000000000000000000000000000000000000000000000000000000145b92915050565b6030861461035d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118056026913960400191505060405180910390fd5b602084146103b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603681526020018061179c6036913960400191505060405180910390fd5b6060821461040f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260298152602001806118786029913960400191505060405180910390fd5b670de0b6b3a7640000341015610470576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118526026913960400191505060405180910390fd5b633b9aca003406156104cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260338152602001806117d26033913960400191505060405180910390fd5b633b9aca00340467ffffffffffffffff811115610535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602781526020018061182b6027913960400191505060405180910390fd5b6060610540826114ba565b90507f649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c589898989858a8a6105756020546114ba565b6040805160a0808252810189905290819060208201908201606083016080840160c085018e8e80828437600083820152601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690910187810386528c815260200190508c8c808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690920188810386528c5181528c51602091820193918e019250908190849084905b83811015610648578181015183820152602001610630565b50505050905090810190601f1680156106755780820380516001836020036101000a031916815260200191505b5086810383528881526020018989808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169092018881038452895181528951602091820193918b019250908190849084905b838110156106ef5781810151838201526020016106d7565b50505050905090810190601f16801561071c5780820380516001836020036101000a031916815260200191505b509d505050505050505050505050505060405180910390a1600060028a8a600060801b604051602001808484808284377fffffffffffffffffffffffffffffffff0000000000000000000000000000000090941691909301908152604080517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0818403018152601090920190819052815191955093508392506020850191508083835b602083106107fc57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016107bf565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610859573d6000803e3d6000fd5b5050506040513d602081101561086e57600080fd5b5051905060006002806108846040848a8c6116fe565b6040516020018083838082843780830192505050925050506040516020818303038152906040526040518082805190602001908083835b602083106108f857805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016108bb565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610955573d6000803e3d6000fd5b5050506040513d602081101561096a57600080fd5b5051600261097b896040818d6116fe565b60405160009060200180848480828437919091019283525050604080518083038152602092830191829052805190945090925082918401908083835b602083106109f457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016109b7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610a51573d6000803e3d6000fd5b5050506040513d6020811015610a6657600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610ada57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610a9d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610b37573d6000803e3d6000fd5b5050506040513d6020811015610b4c57600080fd5b50516040805160208101858152929350600092600292839287928f928f92018383808284378083019250505093505050506040516020818303038152906040526040518082805190602001908083835b60208310610bd957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610b9c565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610c36573d6000803e3d6000fd5b5050506040513d6020811015610c4b57600080fd5b50516040518651600291889160009188916020918201918291908601908083835b60208310610ca957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610c6c565b6001836020036101000a0380198251168184511680821785525050505050509050018367ffffffffffffffff191667ffffffffffffffff1916815260180182815260200193505050506040516020818303038152906040526040518082805190602001908083835b60208310610d4e57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610d11565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610dab573d6000803e3d6000fd5b5050506040513d6020811015610dc057600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610e3457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610df7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610e91573d6000803e3d6000fd5b5050506040513d6020811015610ea657600080fd5b50519050858114610f02576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260548152602001806117486054913960600191505060405180910390fd5b60205463ffffffff11610f60576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806117276021913960400191505060405180910390fd5b602080546001019081905560005b60208110156110a9578160011660011415610fa0578260008260208110610f9157fe5b0155506110ac95505050505050565b600260008260208110610faf57fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061102557805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610fe8565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015611082573d6000803e3d6000fd5b5050506040513d602081101561109757600080fd5b50519250600282049150600101610f6e565b50fe5b50505050505050565b60606110c26020546114ba565b905090565b6020546000908190815b60208110156112f05781600116600114156111e6576002600082602081106110f557fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061116b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161112e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156111c8573d6000803e3d6000fd5b5050506040513d60208110156111dd57600080fd5b505192506112e2565b600283602183602081106111f657fe5b015460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061126b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161122e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156112c8573d6000803e3d6000fd5b5050506040513d60208110156112dd57600080fd5b505192505b6002820491506001016110d1565b506002826112ff6020546114ba565b600060401b6040516020018084815260200183805190602001908083835b6020831061135a57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161131d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790527fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000095909516920191825250604080518083037ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8018152601890920190819052815191955093508392850191508083835b6020831061143f57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611402565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa15801561149c573d6000803e3d6000fd5b5050506040513d60208110156114b157600080fd5b50519250505090565b60408051600880825281830190925260609160208201818036833701905050905060c082901b8060071a60f81b826000815181106114f457fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060061a60f81b8260018151811061153757fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060051a60f81b8260028151811061157a57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060041a60f81b826003815181106115bd57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060031a60f81b8260048151811061160057fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060021a60f81b8260058151811061164357fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060011a60f81b8260068151811061168657fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060001a60f81b826007815181106116c957fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535050919050565b6000808585111561170d578182fd5b83861115611719578182fd5b505082019391909203915056fe4465706f736974436f6e74726163743a206d65726b6c6520747265652066756c6c4465706f736974436f6e74726163743a207265636f6e7374727563746564204465706f7369744461746120646f6573206e6f74206d6174636820737570706c696564206465706f7369745f646174615f726f6f744465706f736974436f6e74726163743a20696e76616c6964207769746864726177616c5f63726564656e7469616c73206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c7565206e6f74206d756c7469706c65206f6620677765694465706f736974436f6e74726163743a20696e76616c6964207075626b6579206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f20686967684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f206c6f774465706f736974436f6e74726163743a20696e76616c6964207369676e6174757265206c656e677468a26469706673582212201dd26f37a621703009abf16e77e69c93dc50c79db7f6cc37543e3e0e3decdc9764736f6c634300060b0033", + "code": "0x60806040526004361061003f5760003560e01c806301ffc9a71461004457806322895118146100a4578063621fd130146101ba578063c5f2892f14610244575b600080fd5b34801561005057600080fd5b506100906004803603602081101561006757600080fd5b50357fffffffff000000000000000000000000000000000000000000000000000000001661026b565b604080519115158252519081900360200190f35b6101b8600480360360808110156100ba57600080fd5b8101906020810181356401000000008111156100d557600080fd5b8201836020820111156100e757600080fd5b8035906020019184600183028401116401000000008311171561010957600080fd5b91939092909160208101903564010000000081111561012757600080fd5b82018360208201111561013957600080fd5b8035906020019184600183028401116401000000008311171561015b57600080fd5b91939092909160208101903564010000000081111561017957600080fd5b82018360208201111561018b57600080fd5b803590602001918460018302840111640100000000831117156101ad57600080fd5b919350915035610304565b005b3480156101c657600080fd5b506101cf6110b5565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102095781810151838201526020016101f1565b50505050905090810190601f1680156102365780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561025057600080fd5b506102596110c7565b60408051918252519081900360200190f35b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a70000000000000000000000000000000000000000000000000000000014806102fe57507fffffffff0000000000000000000000000000000000000000000000000000000082167f8564090700000000000000000000000000000000000000000000000000000000145b92915050565b6030861461035d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118056026913960400191505060405180910390fd5b602084146103b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603681526020018061179c6036913960400191505060405180910390fd5b6060821461040f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260298152602001806118786029913960400191505060405180910390fd5b670de0b6b3a7640000341015610470576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118526026913960400191505060405180910390fd5b633b9aca003406156104cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260338152602001806117d26033913960400191505060405180910390fd5b633b9aca00340467ffffffffffffffff811115610535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602781526020018061182b6027913960400191505060405180910390fd5b6060610540826114ba565b90507f649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c589898989858a8a6105756020546114ba565b6040805160a0808252810189905290819060208201908201606083016080840160c085018e8e80828437600083820152601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690910187810386528c815260200190508c8c808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690920188810386528c5181528c51602091820193918e019250908190849084905b83811015610648578181015183820152602001610630565b50505050905090810190601f1680156106755780820380516001836020036101000a031916815260200191505b5086810383528881526020018989808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169092018881038452895181528951602091820193918b019250908190849084905b838110156106ef5781810151838201526020016106d7565b50505050905090810190601f16801561071c5780820380516001836020036101000a031916815260200191505b509d505050505050505050505050505060405180910390a1600060028a8a600060801b604051602001808484808284377fffffffffffffffffffffffffffffffff0000000000000000000000000000000090941691909301908152604080517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0818403018152601090920190819052815191955093508392506020850191508083835b602083106107fc57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016107bf565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610859573d6000803e3d6000fd5b5050506040513d602081101561086e57600080fd5b5051905060006002806108846040848a8c6116fe565b6040516020018083838082843780830192505050925050506040516020818303038152906040526040518082805190602001908083835b602083106108f857805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016108bb565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610955573d6000803e3d6000fd5b5050506040513d602081101561096a57600080fd5b5051600261097b896040818d6116fe565b60405160009060200180848480828437919091019283525050604080518083038152602092830191829052805190945090925082918401908083835b602083106109f457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016109b7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610a51573d6000803e3d6000fd5b5050506040513d6020811015610a6657600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610ada57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610a9d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610b37573d6000803e3d6000fd5b5050506040513d6020811015610b4c57600080fd5b50516040805160208101858152929350600092600292839287928f928f92018383808284378083019250505093505050506040516020818303038152906040526040518082805190602001908083835b60208310610bd957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610b9c565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610c36573d6000803e3d6000fd5b5050506040513d6020811015610c4b57600080fd5b50516040518651600291889160009188916020918201918291908601908083835b60208310610ca957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610c6c565b6001836020036101000a0380198251168184511680821785525050505050509050018367ffffffffffffffff191667ffffffffffffffff1916815260180182815260200193505050506040516020818303038152906040526040518082805190602001908083835b60208310610d4e57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610d11565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610dab573d6000803e3d6000fd5b5050506040513d6020811015610dc057600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610e3457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610df7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610e91573d6000803e3d6000fd5b5050506040513d6020811015610ea657600080fd5b50519050858114610f02576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260548152602001806117486054913960600191505060405180910390fd5b60205463ffffffff11610f60576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806117276021913960400191505060405180910390fd5b602080546001019081905560005b60208110156110a9578160011660011415610fa0578260008260208110610f9157fe5b0155506110ac95505050505050565b600260008260208110610faf57fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061102557805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610fe8565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015611082573d6000803e3d6000fd5b5050506040513d602081101561109757600080fd5b50519250600282049150600101610f6e565b50fe5b50505050505050565b60606110c26020546114ba565b905090565b6020546000908190815b60208110156112f05781600116600114156111e6576002600082602081106110f557fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061116b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161112e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156111c8573d6000803e3d6000fd5b5050506040513d60208110156111dd57600080fd5b505192506112e2565b600283602183602081106111f657fe5b015460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061126b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161122e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156112c8573d6000803e3d6000fd5b5050506040513d60208110156112dd57600080fd5b505192505b6002820491506001016110d1565b506002826112ff6020546114ba565b600060401b6040516020018084815260200183805190602001908083835b6020831061135a57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161131d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790527fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000095909516920191825250604080518083037ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8018152601890920190819052815191955093508392850191508083835b6020831061143f57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611402565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa15801561149c573d6000803e3d6000fd5b5050506040513d60208110156114b157600080fd5b50519250505090565b60408051600880825281830190925260609160208201818036833701905050905060c082901b8060071a60f81b826000815181106114f457fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060061a60f81b8260018151811061153757fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060051a60f81b8260028151811061157a57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060041a60f81b826003815181106115bd57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060031a60f81b8260048151811061160057fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060021a60f81b8260058151811061164357fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060011a60f81b8260068151811061168657fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060001a60f81b826007815181106116c957fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535050919050565b6000808585111561170d578182fd5b83861115611719578182fd5b505082019391909203915056fe4465706f736974436f6e74726163743a206d65726b6c6520747265652066756c6c4465706f736974436f6e74726163743a207265636f6e7374727563746564204465706f7369744461746120646f6573206e6f74206d6174636820737570706c696564206465706f7369745f646174615f726f6f744465706f736974436f6e74726163743a20696e76616c6964207769746864726177616c5f63726564656e7469616c73206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c7565206e6f74206d756c7469706c65206f6620677765694465706f736974436f6e74726163743a20696e76616c6964207075626b6579206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f20686967684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f206c6f774465706f736974436f6e74726163743a20696e76616c6964207369676e6174757265206c656e677468a2646970667358221220dceca8706b29e917dacf25fceef95acac8d90d765ac926663ce4096195952b6164736f6c634300060b0033", "storage": { "0x0000000000000000000000000000000000000000000000000000000000000022": "0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b", "0x0000000000000000000000000000000000000000000000000000000000000023": "0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71", diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/genesis.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/genesis.json index ac474c0245..ef3d2c1be4 100644 --- a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/genesis.json +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/genesis.json @@ -19,7 +19,9 @@ "period": 5, "epoch": 30000 }, - "depositContractAddress": "0x4242424242424242424242424242424242424242" + "depositContractAddress": "0x4242424242424242424242424242424242424242", + "withdrawalRequestContractAddress": "0x00A3ca265EBcb825B45F985A16CEFB49958cE017", + "consolidationRequestContractAddress": "0x00b42dbF2194e931E80326D950320f7d9Dbeac02" }, "nonce":"0x42", "timestamp":"0x0", @@ -37,9 +39,10 @@ "balance": "1000000000000000000000000000" }, "0x00A3ca265EBcb825B45F985A16CEFB49958cE017": { - "comment": "This is the runtime bytecode for the Withdrawal Request Smart Contract. It was created from the deployment transaction in EIP-7002 (https://eips.ethereum.org/EIPS/eip-7002#deployment)", - "balance": "0", - "code": "0x3373fffffffffffffffffffffffffffffffffffffffe146090573615156028575f545f5260205ff35b36603814156101215760115f54600182026001905f5b5f82111560595781019083028483029004916001019190603e565b90939004341061012157600154600101600155600354806003026004013381556001015f3581556001016020359055600101600355005b6003546002548082038060101160a4575060105b5f5b81811460dd5780604c02838201600302600401805490600101805490600101549160601b83528260140152906034015260010160a6565b910180921460ed579060025560f8565b90505f6002555f6003555b5f5460015460028282011161010f5750505f610115565b01600290035b5f555f600155604c025ff35b5f5ffd", + "comment": "This is the runtime bytecode for the Withdrawal Request Smart Contract. It was created from the generated alloc section of fork_Prague_blockchain_test_engine_single_block_single_withdrawal_request_from_contract spec test", + "nonce": "0x01", + "balance": "0x00", + "code": "0x3373fffffffffffffffffffffffffffffffffffffffe1460c7573615156028575f545f5260205ff35b36603814156101f05760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff146101f057600182026001905f5b5f821115608057810190830284830290049160010191906065565b9093900434106101f057600154600101600155600354806003026004013381556001015f35815560010160203590553360601b5f5260385f601437604c5fa0600101600355005b6003546002548082038060101160db575060105b5f5b81811461017f5780604c02838201600302600401805490600101805490600101549160601b83528260140152807fffffffffffffffffffffffffffffffff0000000000000000000000000000000016826034015260401c906044018160381c81600701538160301c81600601538160281c81600501538160201c81600401538160181c81600301538160101c81600201538160081c81600101535360010160dd565b9101809214610191579060025561019c565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14156101c957505f5b6001546002828201116101de5750505f6101e4565b01600290035b5f555f600155604c025ff35b5f5ffd", "storage": { "0x0000000000000000000000000000000000000000000000000000000000000000": "0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001": "0000000000000000000000000000000000000000000000000000000000000001", @@ -51,9 +54,10 @@ } }, "0x00b42dbF2194e931E80326D950320f7d9Dbeac02": { - "comment": "This is the runtime bytecode for the Consolidation Request Smart Contract. It was created from the deployment transaction in EIP-7251 (https://eips.ethereum.org/EIPS/eip-7251#deployment)", - "balance": "0", - "code": "0x3373fffffffffffffffffffffffffffffffffffffffe146098573615156028575f545f5260205ff35b36606014156101445760115f54600182026001905f5b5f82111560595781019083028483029004916001019190603e565b90939004341061014457600154600101600155600354806004026004013381556001015f35815560010160203581556001016040359055600101600355005b6003546002548082038060011160ac575060015b5f5b81811460f15780607402838201600402600401805490600101805490600101805490600101549260601b84529083601401528260340152906054015260010160ae565b9101809214610103579060025561010e565b90505f6002555f6003555b5f548061049d141561011d57505f5b6001546001828201116101325750505f610138565b01600190035b5f555f6001556074025ff35b5f5ffd", + "comment": "This is the runtime bytecode for the Consolidation Request Smart Contract. It was created from the generated alloc section of fork_Prague_blockchain_test_engine_single_block_single_consolidation_request_from_contract spec test", + "nonce": "0x01", + "balance": "0x0", + "code": "0x3373fffffffffffffffffffffffffffffffffffffffe1460cf573615156028575f545f5260205ff35b366060141561019a5760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1461019a57600182026001905f5b5f821115608057810190830284830290049160010191906065565b90939004341061019a57600154600101600155600354806004026004013381556001015f358155600101602035815560010160403590553360601b5f5260605f60143760745fa0600101600355005b6003546002548082038060011160e3575060015b5f5b8181146101295780607402838201600402600401805490600101805490600101805490600101549260601b84529083601401528260340152906054015260010160e5565b910180921461013b5790600255610146565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff141561017357505f5b6001546001828201116101885750505f61018e565b01600190035b5f555f6001556074025ff35b5f5ffd", "storage": { "0x0000000000000000000000000000000000000000000000000000000000000000": "0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001": "0000000000000000000000000000000000000000000000000000000000000000", @@ -65,8 +69,9 @@ } }, "0x4242424242424242424242424242424242424242": { - "balance": "0", - "code": "0x60806040526004361061003f5760003560e01c806301ffc9a71461004457806322895118146100a4578063621fd130146101ba578063c5f2892f14610244575b600080fd5b34801561005057600080fd5b506100906004803603602081101561006757600080fd5b50357fffffffff000000000000000000000000000000000000000000000000000000001661026b565b604080519115158252519081900360200190f35b6101b8600480360360808110156100ba57600080fd5b8101906020810181356401000000008111156100d557600080fd5b8201836020820111156100e757600080fd5b8035906020019184600183028401116401000000008311171561010957600080fd5b91939092909160208101903564010000000081111561012757600080fd5b82018360208201111561013957600080fd5b8035906020019184600183028401116401000000008311171561015b57600080fd5b91939092909160208101903564010000000081111561017957600080fd5b82018360208201111561018b57600080fd5b803590602001918460018302840111640100000000831117156101ad57600080fd5b919350915035610304565b005b3480156101c657600080fd5b506101cf6110b5565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102095781810151838201526020016101f1565b50505050905090810190601f1680156102365780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561025057600080fd5b506102596110c7565b60408051918252519081900360200190f35b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a70000000000000000000000000000000000000000000000000000000014806102fe57507fffffffff0000000000000000000000000000000000000000000000000000000082167f8564090700000000000000000000000000000000000000000000000000000000145b92915050565b6030861461035d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118056026913960400191505060405180910390fd5b602084146103b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603681526020018061179c6036913960400191505060405180910390fd5b6060821461040f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260298152602001806118786029913960400191505060405180910390fd5b670de0b6b3a7640000341015610470576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118526026913960400191505060405180910390fd5b633b9aca003406156104cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260338152602001806117d26033913960400191505060405180910390fd5b633b9aca00340467ffffffffffffffff811115610535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602781526020018061182b6027913960400191505060405180910390fd5b6060610540826114ba565b90507f649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c589898989858a8a6105756020546114ba565b6040805160a0808252810189905290819060208201908201606083016080840160c085018e8e80828437600083820152601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690910187810386528c815260200190508c8c808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690920188810386528c5181528c51602091820193918e019250908190849084905b83811015610648578181015183820152602001610630565b50505050905090810190601f1680156106755780820380516001836020036101000a031916815260200191505b5086810383528881526020018989808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169092018881038452895181528951602091820193918b019250908190849084905b838110156106ef5781810151838201526020016106d7565b50505050905090810190601f16801561071c5780820380516001836020036101000a031916815260200191505b509d505050505050505050505050505060405180910390a1600060028a8a600060801b604051602001808484808284377fffffffffffffffffffffffffffffffff0000000000000000000000000000000090941691909301908152604080517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0818403018152601090920190819052815191955093508392506020850191508083835b602083106107fc57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016107bf565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610859573d6000803e3d6000fd5b5050506040513d602081101561086e57600080fd5b5051905060006002806108846040848a8c6116fe565b6040516020018083838082843780830192505050925050506040516020818303038152906040526040518082805190602001908083835b602083106108f857805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016108bb565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610955573d6000803e3d6000fd5b5050506040513d602081101561096a57600080fd5b5051600261097b896040818d6116fe565b60405160009060200180848480828437919091019283525050604080518083038152602092830191829052805190945090925082918401908083835b602083106109f457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016109b7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610a51573d6000803e3d6000fd5b5050506040513d6020811015610a6657600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610ada57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610a9d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610b37573d6000803e3d6000fd5b5050506040513d6020811015610b4c57600080fd5b50516040805160208101858152929350600092600292839287928f928f92018383808284378083019250505093505050506040516020818303038152906040526040518082805190602001908083835b60208310610bd957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610b9c565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610c36573d6000803e3d6000fd5b5050506040513d6020811015610c4b57600080fd5b50516040518651600291889160009188916020918201918291908601908083835b60208310610ca957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610c6c565b6001836020036101000a0380198251168184511680821785525050505050509050018367ffffffffffffffff191667ffffffffffffffff1916815260180182815260200193505050506040516020818303038152906040526040518082805190602001908083835b60208310610d4e57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610d11565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610dab573d6000803e3d6000fd5b5050506040513d6020811015610dc057600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610e3457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610df7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610e91573d6000803e3d6000fd5b5050506040513d6020811015610ea657600080fd5b50519050858114610f02576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260548152602001806117486054913960600191505060405180910390fd5b60205463ffffffff11610f60576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806117276021913960400191505060405180910390fd5b602080546001019081905560005b60208110156110a9578160011660011415610fa0578260008260208110610f9157fe5b0155506110ac95505050505050565b600260008260208110610faf57fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061102557805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610fe8565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015611082573d6000803e3d6000fd5b5050506040513d602081101561109757600080fd5b50519250600282049150600101610f6e565b50fe5b50505050505050565b60606110c26020546114ba565b905090565b6020546000908190815b60208110156112f05781600116600114156111e6576002600082602081106110f557fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061116b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161112e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156111c8573d6000803e3d6000fd5b5050506040513d60208110156111dd57600080fd5b505192506112e2565b600283602183602081106111f657fe5b015460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061126b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161122e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156112c8573d6000803e3d6000fd5b5050506040513d60208110156112dd57600080fd5b505192505b6002820491506001016110d1565b506002826112ff6020546114ba565b600060401b6040516020018084815260200183805190602001908083835b6020831061135a57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161131d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790527fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000095909516920191825250604080518083037ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8018152601890920190819052815191955093508392850191508083835b6020831061143f57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611402565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa15801561149c573d6000803e3d6000fd5b5050506040513d60208110156114b157600080fd5b50519250505090565b60408051600880825281830190925260609160208201818036833701905050905060c082901b8060071a60f81b826000815181106114f457fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060061a60f81b8260018151811061153757fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060051a60f81b8260028151811061157a57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060041a60f81b826003815181106115bd57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060031a60f81b8260048151811061160057fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060021a60f81b8260058151811061164357fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060011a60f81b8260068151811061168657fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060001a60f81b826007815181106116c957fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535050919050565b6000808585111561170d578182fd5b83861115611719578182fd5b505082019391909203915056fe4465706f736974436f6e74726163743a206d65726b6c6520747265652066756c6c4465706f736974436f6e74726163743a207265636f6e7374727563746564204465706f7369744461746120646f6573206e6f74206d6174636820737570706c696564206465706f7369745f646174615f726f6f744465706f736974436f6e74726163743a20696e76616c6964207769746864726177616c5f63726564656e7469616c73206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c7565206e6f74206d756c7469706c65206f6620677765694465706f736974436f6e74726163743a20696e76616c6964207075626b6579206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f20686967684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f206c6f774465706f736974436f6e74726163743a20696e76616c6964207369676e6174757265206c656e677468a26469706673582212201dd26f37a621703009abf16e77e69c93dc50c79db7f6cc37543e3e0e3decdc9764736f6c634300060b0033", + "comment": "This is the runtime bytecode for the Deposit Request Smart Contract. It was created from the generated alloc section of fork_Prague_blockchain_test_engine_single_deposit_from_contract spec test", + "balance": "0x0", + "code": "0x60806040526004361061003f5760003560e01c806301ffc9a71461004457806322895118146100a4578063621fd130146101ba578063c5f2892f14610244575b600080fd5b34801561005057600080fd5b506100906004803603602081101561006757600080fd5b50357fffffffff000000000000000000000000000000000000000000000000000000001661026b565b604080519115158252519081900360200190f35b6101b8600480360360808110156100ba57600080fd5b8101906020810181356401000000008111156100d557600080fd5b8201836020820111156100e757600080fd5b8035906020019184600183028401116401000000008311171561010957600080fd5b91939092909160208101903564010000000081111561012757600080fd5b82018360208201111561013957600080fd5b8035906020019184600183028401116401000000008311171561015b57600080fd5b91939092909160208101903564010000000081111561017957600080fd5b82018360208201111561018b57600080fd5b803590602001918460018302840111640100000000831117156101ad57600080fd5b919350915035610304565b005b3480156101c657600080fd5b506101cf6110b5565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102095781810151838201526020016101f1565b50505050905090810190601f1680156102365780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561025057600080fd5b506102596110c7565b60408051918252519081900360200190f35b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a70000000000000000000000000000000000000000000000000000000014806102fe57507fffffffff0000000000000000000000000000000000000000000000000000000082167f8564090700000000000000000000000000000000000000000000000000000000145b92915050565b6030861461035d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118056026913960400191505060405180910390fd5b602084146103b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603681526020018061179c6036913960400191505060405180910390fd5b6060821461040f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260298152602001806118786029913960400191505060405180910390fd5b670de0b6b3a7640000341015610470576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118526026913960400191505060405180910390fd5b633b9aca003406156104cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260338152602001806117d26033913960400191505060405180910390fd5b633b9aca00340467ffffffffffffffff811115610535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602781526020018061182b6027913960400191505060405180910390fd5b6060610540826114ba565b90507f649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c589898989858a8a6105756020546114ba565b6040805160a0808252810189905290819060208201908201606083016080840160c085018e8e80828437600083820152601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690910187810386528c815260200190508c8c808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690920188810386528c5181528c51602091820193918e019250908190849084905b83811015610648578181015183820152602001610630565b50505050905090810190601f1680156106755780820380516001836020036101000a031916815260200191505b5086810383528881526020018989808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169092018881038452895181528951602091820193918b019250908190849084905b838110156106ef5781810151838201526020016106d7565b50505050905090810190601f16801561071c5780820380516001836020036101000a031916815260200191505b509d505050505050505050505050505060405180910390a1600060028a8a600060801b604051602001808484808284377fffffffffffffffffffffffffffffffff0000000000000000000000000000000090941691909301908152604080517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0818403018152601090920190819052815191955093508392506020850191508083835b602083106107fc57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016107bf565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610859573d6000803e3d6000fd5b5050506040513d602081101561086e57600080fd5b5051905060006002806108846040848a8c6116fe565b6040516020018083838082843780830192505050925050506040516020818303038152906040526040518082805190602001908083835b602083106108f857805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016108bb565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610955573d6000803e3d6000fd5b5050506040513d602081101561096a57600080fd5b5051600261097b896040818d6116fe565b60405160009060200180848480828437919091019283525050604080518083038152602092830191829052805190945090925082918401908083835b602083106109f457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016109b7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610a51573d6000803e3d6000fd5b5050506040513d6020811015610a6657600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610ada57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610a9d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610b37573d6000803e3d6000fd5b5050506040513d6020811015610b4c57600080fd5b50516040805160208101858152929350600092600292839287928f928f92018383808284378083019250505093505050506040516020818303038152906040526040518082805190602001908083835b60208310610bd957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610b9c565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610c36573d6000803e3d6000fd5b5050506040513d6020811015610c4b57600080fd5b50516040518651600291889160009188916020918201918291908601908083835b60208310610ca957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610c6c565b6001836020036101000a0380198251168184511680821785525050505050509050018367ffffffffffffffff191667ffffffffffffffff1916815260180182815260200193505050506040516020818303038152906040526040518082805190602001908083835b60208310610d4e57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610d11565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610dab573d6000803e3d6000fd5b5050506040513d6020811015610dc057600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610e3457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610df7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610e91573d6000803e3d6000fd5b5050506040513d6020811015610ea657600080fd5b50519050858114610f02576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260548152602001806117486054913960600191505060405180910390fd5b60205463ffffffff11610f60576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806117276021913960400191505060405180910390fd5b602080546001019081905560005b60208110156110a9578160011660011415610fa0578260008260208110610f9157fe5b0155506110ac95505050505050565b600260008260208110610faf57fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061102557805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610fe8565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015611082573d6000803e3d6000fd5b5050506040513d602081101561109757600080fd5b50519250600282049150600101610f6e565b50fe5b50505050505050565b60606110c26020546114ba565b905090565b6020546000908190815b60208110156112f05781600116600114156111e6576002600082602081106110f557fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061116b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161112e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156111c8573d6000803e3d6000fd5b5050506040513d60208110156111dd57600080fd5b505192506112e2565b600283602183602081106111f657fe5b015460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061126b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161122e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156112c8573d6000803e3d6000fd5b5050506040513d60208110156112dd57600080fd5b505192505b6002820491506001016110d1565b506002826112ff6020546114ba565b600060401b6040516020018084815260200183805190602001908083835b6020831061135a57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161131d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790527fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000095909516920191825250604080518083037ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8018152601890920190819052815191955093508392850191508083835b6020831061143f57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611402565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa15801561149c573d6000803e3d6000fd5b5050506040513d60208110156114b157600080fd5b50519250505090565b60408051600880825281830190925260609160208201818036833701905050905060c082901b8060071a60f81b826000815181106114f457fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060061a60f81b8260018151811061153757fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060051a60f81b8260028151811061157a57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060041a60f81b826003815181106115bd57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060031a60f81b8260048151811061160057fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060021a60f81b8260058151811061164357fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060011a60f81b8260068151811061168657fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060001a60f81b826007815181106116c957fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535050919050565b6000808585111561170d578182fd5b83861115611719578182fd5b505082019391909203915056fe4465706f736974436f6e74726163743a206d65726b6c6520747265652066756c6c4465706f736974436f6e74726163743a207265636f6e7374727563746564204465706f7369744461746120646f6573206e6f74206d6174636820737570706c696564206465706f7369745f646174615f726f6f744465706f736974436f6e74726163743a20696e76616c6964207769746864726177616c5f63726564656e7469616c73206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c7565206e6f74206d756c7469706c65206f6620677765694465706f736974436f6e74726163743a20696e76616c6964207075626b6579206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f20686967684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f206c6f774465706f736974436f6e74726163743a20696e76616c6964207369676e6174757265206c656e677468a2646970667358221220dceca8706b29e917dacf25fceef95acac8d90d765ac926663ce4096195952b6164736f6c634300060b0033", "storage": { "0x0000000000000000000000000000000000000000000000000000000000000022": "0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b", "0x0000000000000000000000000000000000000000000000000000000000000023": "0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71", diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/00_get_genesis_block_info.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/00_get_genesis_block_info.json index d1a18826a9..ca9c3ef7e7 100644 --- a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/00_get_genesis_block_info.json +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/00_get_genesis_block_info.json @@ -12,14 +12,14 @@ "id": 67, "result": { "number": "0x0", - "hash" : "0x38d7daa68e8bac41a0a237b7cbfcef480cb9bd9adc7b282d7b0d23ff4eb8d6e5", + "hash" : "0x01f5cbf33268c161f1526d704268db760bf82c9772a8f8ca412e0c6ce5684896", "mixHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", "nonce" : "0x0000000000000042", "sha3Uncles" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", "logsBloom" : "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "transactionsRoot" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "stateRoot" : "0x3ed8435adb5f3526144e6babdd3fc8c661a86097cf7e743441b41fda096fc4dd", + "stateRoot" : "0x860be6ab5a8fc2003c3739bfe2cdbcd9dbb273c8ea42951b832a8e1f22fb3a60", "receiptsRoot" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "miner" : "0x0000000000000000000000000000000000000000", "difficulty" : "0x400000000", diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/01_cancun_prepare_payload.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/01_cancun_prepare_payload.json index ad4b9be2d0..e549da3f30 100644 --- a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/01_cancun_prepare_payload.json +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/01_cancun_prepare_payload.json @@ -4,8 +4,8 @@ "method": "engine_forkchoiceUpdatedV3", "params": [ { - "headBlockHash": "0x38d7daa68e8bac41a0a237b7cbfcef480cb9bd9adc7b282d7b0d23ff4eb8d6e5", - "safeBlockHash": "0x38d7daa68e8bac41a0a237b7cbfcef480cb9bd9adc7b282d7b0d23ff4eb8d6e5", + "headBlockHash": "0x01f5cbf33268c161f1526d704268db760bf82c9772a8f8ca412e0c6ce5684896", + "safeBlockHash": "0x01f5cbf33268c161f1526d704268db760bf82c9772a8f8ca412e0c6ce5684896", "finalizedBlockHash": "0x0000000000000000000000000000000000000000000000000000000000000000" }, { @@ -24,10 +24,10 @@ "result": { "payloadStatus": { "status": "VALID", - "latestValidHash": "0x38d7daa68e8bac41a0a237b7cbfcef480cb9bd9adc7b282d7b0d23ff4eb8d6e5", + "latestValidHash": "0x01f5cbf33268c161f1526d704268db760bf82c9772a8f8ca412e0c6ce5684896", "validationError": null }, - "payloadId": "0x28264396eca1deef" + "payloadId": "0x282643b677b85211" } }, "statusCode": 200 diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/02_cancun_getPayloadV3.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/02_cancun_getPayloadV3.json index 63cfeec26a..7a29443fef 100644 --- a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/02_cancun_getPayloadV3.json +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/02_cancun_getPayloadV3.json @@ -3,7 +3,7 @@ "jsonrpc": "2.0", "method": "engine_getPayloadV3", "params": [ - "0x28264396eca1deef" + "0x282643b677b85211" ], "id": 67 }, @@ -12,9 +12,9 @@ "id": 67, "result": { "executionPayload": { - "parentHash": "0x38d7daa68e8bac41a0a237b7cbfcef480cb9bd9adc7b282d7b0d23ff4eb8d6e5", + "parentHash": "0x01f5cbf33268c161f1526d704268db760bf82c9772a8f8ca412e0c6ce5684896", "feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", - "stateRoot": "0x3ed8435adb5f3526144e6babdd3fc8c661a86097cf7e743441b41fda096fc4dd", + "stateRoot": "0x860be6ab5a8fc2003c3739bfe2cdbcd9dbb273c8ea42951b832a8e1f22fb3a60", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "gasLimit": "0x1c9c380", @@ -29,7 +29,7 @@ "blockNumber": "0x1", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "blobGasUsed": "0x0", - "blockHash": "0x8082deff44f79489ea92415be59afb48b6f46b939553f855479828a6f87f9593" + "blockHash": "0x7cccf6d9ce3e5acaeac9058959c27ace53af3a30b15763e1703bab2d0ae9438e" }, "blockValue": "0x0", "blobsBundle": { diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/03_cancun_newPayloadV3.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/03_cancun_newPayloadV3.json index 9f984b2f35..d2191e8312 100644 --- a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/03_cancun_newPayloadV3.json +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/03_cancun_newPayloadV3.json @@ -4,9 +4,9 @@ "method": "engine_newPayloadV3", "params": [ { - "parentHash": "0x38d7daa68e8bac41a0a237b7cbfcef480cb9bd9adc7b282d7b0d23ff4eb8d6e5", + "parentHash": "0x01f5cbf33268c161f1526d704268db760bf82c9772a8f8ca412e0c6ce5684896", "feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", - "stateRoot": "0x3ed8435adb5f3526144e6babdd3fc8c661a86097cf7e743441b41fda096fc4dd", + "stateRoot": "0x860be6ab5a8fc2003c3739bfe2cdbcd9dbb273c8ea42951b832a8e1f22fb3a60", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "gasLimit": "0x1c9c380", @@ -14,13 +14,13 @@ "timestamp": "0x10", "extraData": "0x", "baseFeePerGas": "0x7", + "excessBlobGas": "0x0", "transactions": [], "withdrawals": [], "blockNumber": "0x1", - "blockHash": "0x8082deff44f79489ea92415be59afb48b6f46b939553f855479828a6f87f9593", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "excessBlobGas": "0x0", - "blobGasUsed": "0x0" + "blobGasUsed": "0x0", + "blockHash": "0x7cccf6d9ce3e5acaeac9058959c27ace53af3a30b15763e1703bab2d0ae9438e", + "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" }, [], "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -32,7 +32,7 @@ "id": 67, "result": { "status": "VALID", - "latestValidHash": "0x8082deff44f79489ea92415be59afb48b6f46b939553f855479828a6f87f9593", + "latestValidHash": "0x7cccf6d9ce3e5acaeac9058959c27ace53af3a30b15763e1703bab2d0ae9438e", "validationError": null } }, diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/04_cancun_forkchoiceUpdatedV3.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/04_cancun_forkchoiceUpdatedV3.json index b0ce0f70c1..8bbb71be33 100644 --- a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/04_cancun_forkchoiceUpdatedV3.json +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/04_cancun_forkchoiceUpdatedV3.json @@ -4,9 +4,9 @@ "method": "engine_forkchoiceUpdatedV3", "params": [ { - "headBlockHash": "0x8082deff44f79489ea92415be59afb48b6f46b939553f855479828a6f87f9593", - "safeBlockHash": "0x8082deff44f79489ea92415be59afb48b6f46b939553f855479828a6f87f9593", - "finalizedBlockHash": "0x8082deff44f79489ea92415be59afb48b6f46b939553f855479828a6f87f9593" + "headBlockHash": "0x7cccf6d9ce3e5acaeac9058959c27ace53af3a30b15763e1703bab2d0ae9438e", + "safeBlockHash": "0x7cccf6d9ce3e5acaeac9058959c27ace53af3a30b15763e1703bab2d0ae9438e", + "finalizedBlockHash": "0x7cccf6d9ce3e5acaeac9058959c27ace53af3a30b15763e1703bab2d0ae9438e" }, null ], @@ -18,7 +18,7 @@ "result": { "payloadStatus": { "status": "VALID", - "latestValidHash": "0x8082deff44f79489ea92415be59afb48b6f46b939553f855479828a6f87f9593", + "latestValidHash": "0x7cccf6d9ce3e5acaeac9058959c27ace53af3a30b15763e1703bab2d0ae9438e", "validationError": null }, "payloadId": null diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/05_prague_forkchoiceUpdatedV3.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/05_prague_forkchoiceUpdatedV3.json index 1eae1c881a..7e70a3bcac 100644 --- a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/05_prague_forkchoiceUpdatedV3.json +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/05_prague_forkchoiceUpdatedV3.json @@ -4,9 +4,9 @@ "method": "engine_forkchoiceUpdatedV3", "params": [ { - "headBlockHash": "0x8082deff44f79489ea92415be59afb48b6f46b939553f855479828a6f87f9593", - "safeBlockHash": "0x8082deff44f79489ea92415be59afb48b6f46b939553f855479828a6f87f9593", - "finalizedBlockHash": "0x8082deff44f79489ea92415be59afb48b6f46b939553f855479828a6f87f9593" + "headBlockHash": "0x7cccf6d9ce3e5acaeac9058959c27ace53af3a30b15763e1703bab2d0ae9438e", + "safeBlockHash": "0x7cccf6d9ce3e5acaeac9058959c27ace53af3a30b15763e1703bab2d0ae9438e", + "finalizedBlockHash": "0x7cccf6d9ce3e5acaeac9058959c27ace53af3a30b15763e1703bab2d0ae9438e" }, { "timestamp": "0x20", @@ -24,10 +24,10 @@ "result": { "payloadStatus": { "status": "VALID", - "latestValidHash": "0x8082deff44f79489ea92415be59afb48b6f46b939553f855479828a6f87f9593", + "latestValidHash": "0x7cccf6d9ce3e5acaeac9058959c27ace53af3a30b15763e1703bab2d0ae9438e", "validationError": null }, - "payloadId": "0x282643d3a905e721" + "payloadId": "0x282643fdcbcb1ddf" } }, "statusCode": 200 diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/06_prague_getPayloadV4.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/06_prague_getPayloadV4.json index 4cb85d5f54..92c1bbcf2e 100644 --- a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/06_prague_getPayloadV4.json +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/06_prague_getPayloadV4.json @@ -3,7 +3,7 @@ "jsonrpc": "2.0", "method": "engine_getPayloadV4", "params": [ - "0x282643d3a905e721" + "0x282643fdcbcb1ddf" ], "id": 67 }, @@ -12,9 +12,9 @@ "id": 67, "result": { "executionPayload": { - "parentHash": "0x8082deff44f79489ea92415be59afb48b6f46b939553f855479828a6f87f9593", + "parentHash": "0x7cccf6d9ce3e5acaeac9058959c27ace53af3a30b15763e1703bab2d0ae9438e", "feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", - "stateRoot": "0x2e59916a57b535875bcd80d8472aeaa0027aa685d159804e8caa2f12d060155e", + "stateRoot": "0xed4093bcd157ba955245906a1cda7695d3b3f233af709f0adf17689abb4d93b4", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "gasLimit": "0x1c9c380", @@ -23,22 +23,13 @@ "extraData": "0x", "baseFeePerGas": "0x7", "excessBlobGas": "0x0", + "blobGasUsed": "0x0", "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", "transactions": [], "withdrawals": [], - "depositRequests": [], - "withdrawalRequests": [ - { - "sourceAddress": "0xa4664c40aacebd82a2db79f0ea36c06bc6a19adb", - "validatorPubkey": "0xb10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e", - "amount": "0x0" - } - ], - "consolidationRequests" : [], "blockNumber": "0x2", - "blockHash": "0x27a2bc2ac21b3fc796f636bec1ec9cba100435f9a793176a83a5d4fa7cc13006", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "blobGasUsed": "0x0" + "blockHash": "0x303fb51567c090ed3fb7ac50a082ae3a0bcb8ff522d071011a1ca433561a4569" }, "blockValue": "0x0", "blobsBundle": { @@ -46,7 +37,12 @@ "proofs": [], "blobs": [] }, - "shouldOverrideBuilder": false + "shouldOverrideBuilder": false, + "executionRequests": [ + "0x", + "0xa4664c40aacebd82a2db79f0ea36c06bc6a19adbb10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e0000000000000000", + "0x" + ] } }, "statusCode": 200 diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/07_prague_send_raw_transaction.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/07_prague_send_raw_transaction_deposit_request.json similarity index 100% rename from acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/07_prague_send_raw_transaction.json rename to acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/07_prague_send_raw_transaction_deposit_request.json diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/08_prague_invalid_null_deposits_execute_payload.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/08_prague_invalid_null_deposit_request_execute_payload.json similarity index 88% rename from acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/08_prague_invalid_null_deposits_execute_payload.json rename to acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/08_prague_invalid_null_deposit_request_execute_payload.json index ed75e54aaf..14b6fc3d9a 100644 --- a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/08_prague_invalid_null_deposits_execute_payload.json +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/08_prague_invalid_null_deposit_request_execute_payload.json @@ -17,24 +17,24 @@ "excessBlobGas": "0x0", "transactions": [], "withdrawals": [], - "depositRequests": null, "blockNumber": "0x2", "blockHash": "0x2331b2dc9c453e9a33685099742cbbcd529d42bd5681969f45754f06866c6766", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "blobGasUsed": "0x0" }, [], - "0x0000000000000000000000000000000000000000000000000000000000000000" + "0x0000000000000000000000000000000000000000000000000000000000000000", + null ], "id": 67 }, "response": { - "jsonrpc": "2.0", - "id": 67, - "error": { - "code": -32602, - "message": "Invalid params", - "data": "Missing deposit field" + "jsonrpc" : "2.0", + "id" : 67, + "error" : { + "code" : -32602, + "message" : "Invalid execution requests params", + "data" : "Missing execution requests field" } }, "statusCode": 200 diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/09_prague_newPayloadV4.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/09_prague_newPayloadV4.json index 17496f9ed7..dcbbb3a8df 100644 --- a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/09_prague_newPayloadV4.json +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/09_prague_newPayloadV4.json @@ -4,9 +4,9 @@ "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x8082deff44f79489ea92415be59afb48b6f46b939553f855479828a6f87f9593", + "parentHash": "0x7cccf6d9ce3e5acaeac9058959c27ace53af3a30b15763e1703bab2d0ae9438e", "feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", - "stateRoot": "0x961878fdcdff52ea42db0026f59aa414a5ec2835e56ed1a8ae50c80a9fe3a04b", + "stateRoot": "0x176ea6dfa3b8efb148a025f759cccfaab02db38427b12a4ede73491eda397196", "logsBloom": "0x10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "gasLimit": "0x1c9c380", @@ -15,34 +15,22 @@ "extraData": "0x", "baseFeePerGas": "0x7", "excessBlobGas": "0x0", + "blobGasUsed": "0x0", "transactions": [ "0x02f9021c8217de808459682f008459682f0e830271009442424242424242424242424242424242424242428901bc16d674ec800000b901a422895118000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120749715de5d1226545c6b3790f515d551a5cc5bf1d49c87a696860554d2fc4f14000000000000000000000000000000000000000000000000000000000000003096a96086cff07df17668f35f7418ef8798079167e3f4f9b72ecde17b28226137cf454ab1dd20ef5d924786ab3483c2f9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020003f5102dabe0a27b1746098d1dc17a5d3fbd478759fea9287e4e419b3c3cef20000000000000000000000000000000000000000000000000000000000000060b1acdb2c4d3df3f1b8d3bfd33421660df358d84d78d16c4603551935f4b67643373e7eb63dcb16ec359be0ec41fee33b03a16e80745f2374ff1d3c352508ac5d857c6476d3c3bcf7e6ca37427c9209f17be3af5264c0e2132b3dd1156c28b4e9c080a09f597089338d7f44f5c59f8230bb38f243849228a8d4e9d2e2956e6050f5b2c7a076486996c7e62802b8f95eee114783e4b403fd11093ba96286ff42c595f24452" ], "withdrawals": [], - "depositRequests": [ - { - "amount": "0x773594000", - "index": "0x0", - "pubkey": "0x96a96086cff07df17668f35f7418ef8798079167e3f4f9b72ecde17b28226137cf454ab1dd20ef5d924786ab3483c2f9", - "signature": "0xb1acdb2c4d3df3f1b8d3bfd33421660df358d84d78d16c4603551935f4b67643373e7eb63dcb16ec359be0ec41fee33b03a16e80745f2374ff1d3c352508ac5d857c6476d3c3bcf7e6ca37427c9209f17be3af5264c0e2132b3dd1156c28b4e9", - "withdrawalCredentials": "0x003f5102dabe0a27b1746098d1dc17a5d3fbd478759fea9287e4e419b3c3cef2" - } - ], - "withdrawalRequests": [ - { - "sourceAddress": "0xa4664c40aacebd82a2db79f0ea36c06bc6a19adb", - "amount": "0x0", - "validatorPubkey": "0xb10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e" - } - ], - "consolidationRequests": [], "blockNumber": "0x2", - "blockHash": "0xc67a660f5d3c20ee603911bdff1e409e976f306883dff8ef4999dca3176f7dca", "receiptsRoot": "0x79ee3424eb720a3ad4b1c5a372bb8160580cbe4d893778660f34213c685627a9", - "blobGasUsed": "0x0" + "blockHash": "0x14ba5ec415d827d9cab33e6097b307131e8119a1cd7dc1f6a4de088ebfa4c1b6" }, [], - "0x0000000000000000000000000000000000000000000000000000000000000000" + "0x0000000000000000000000000000000000000000000000000000000000000000", + [ + "0xf84794a4664c40aacebd82a2db79f0ea36c06bc6a19adbb0b10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e80", + "0xa4664c40aacebd82a2db79f0ea36c06bc6a19adbb10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e0000000000000000", + "0x" + ] ], "id": 67 }, @@ -51,7 +39,7 @@ "id": 67, "result": { "status": "VALID", - "latestValidHash": "0xc67a660f5d3c20ee603911bdff1e409e976f306883dff8ef4999dca3176f7dca", + "latestValidHash": "0x14ba5ec415d827d9cab33e6097b307131e8119a1cd7dc1f6a4de088ebfa4c1b6", "validationError": null } }, diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/10_prague_forkchoiceUpdatedV3.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/10_prague_forkchoiceUpdatedV3.json index ba0f1e8e5b..0c817637b3 100644 --- a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/10_prague_forkchoiceUpdatedV3.json +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/10_prague_forkchoiceUpdatedV3.json @@ -4,9 +4,9 @@ "method": "engine_forkchoiceUpdatedV3", "params": [ { - "headBlockHash": "0xc67a660f5d3c20ee603911bdff1e409e976f306883dff8ef4999dca3176f7dca", - "safeBlockHash": "0xc67a660f5d3c20ee603911bdff1e409e976f306883dff8ef4999dca3176f7dca", - "finalizedBlockHash": "0xc67a660f5d3c20ee603911bdff1e409e976f306883dff8ef4999dca3176f7dca" + "headBlockHash": "0x14ba5ec415d827d9cab33e6097b307131e8119a1cd7dc1f6a4de088ebfa4c1b6", + "safeBlockHash": "0x14ba5ec415d827d9cab33e6097b307131e8119a1cd7dc1f6a4de088ebfa4c1b6", + "finalizedBlockHash": "0x14ba5ec415d827d9cab33e6097b307131e8119a1cd7dc1f6a4de088ebfa4c1b6" }, { "timestamp": "0x30", @@ -24,10 +24,10 @@ "result": { "payloadStatus": { "status": "VALID", - "latestValidHash": "0xc67a660f5d3c20ee603911bdff1e409e976f306883dff8ef4999dca3176f7dca", + "latestValidHash": "0x14ba5ec415d827d9cab33e6097b307131e8119a1cd7dc1f6a4de088ebfa4c1b6", "validationError": null }, - "payloadId": "0x282643a16a58b5cf" + "payloadId": "0x282643aeecfdbccf" } }, "statusCode": 200 diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/11_prague_getPayloadV4.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/11_prague_getPayloadV4.json index 3b76fac10a..df3080a657 100644 --- a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/11_prague_getPayloadV4.json +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/11_prague_getPayloadV4.json @@ -3,7 +3,7 @@ "jsonrpc": "2.0", "method": "engine_getPayloadV4", "params": [ - "0x282643a16a58b5cf" + "0x282643aeecfdbccf" ], "id": 67 }, @@ -12,9 +12,9 @@ "id": 67, "result": { "executionPayload": { - "parentHash": "0xc67a660f5d3c20ee603911bdff1e409e976f306883dff8ef4999dca3176f7dca", + "parentHash": "0x14ba5ec415d827d9cab33e6097b307131e8119a1cd7dc1f6a4de088ebfa4c1b6", "feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", - "stateRoot": "0x5fc31c01a451fe02f0e938de7ec7044aaba1159a81a1be64357bc70af226f304", + "stateRoot": "0xade3c29cae771ddfa994d3d2994f3bcbe084bc7bb23cdbb9bd7e35b39f007841", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "gasLimit": "0x1c9c380", @@ -23,16 +23,13 @@ "extraData": "0x", "baseFeePerGas": "0x7", "excessBlobGas": "0x0", + "blobGasUsed": "0x0", "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", "transactions": [], "withdrawals": [], - "depositRequests": [], - "withdrawalRequests": [], - "consolidationRequests" : [], "blockNumber": "0x3", - "blockHash": "0xdbb55a049f14b8152695bf3bbd754aa1fd55bbe10b306eb49caa4bd7d7fcb634", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "blobGasUsed": "0x0" + "blockHash": "0x9f157012bdc439f5fe2bb3b4236eb07043e35d16256557d73e80a95d20054929" }, "blockValue": "0x0", "blobsBundle": { @@ -40,7 +37,12 @@ "proofs": [], "blobs": [] }, - "shouldOverrideBuilder": false + "shouldOverrideBuilder": false, + "executionRequests": [ + "0x", + "0x", + "0x" + ] } }, "statusCode": 200 diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/12_cancun_newPayloadV3.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/12_cancun_newPayloadV3.json index 546872807c..e0746e9f7f 100644 --- a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/12_cancun_newPayloadV3.json +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/12_cancun_newPayloadV3.json @@ -4,9 +4,9 @@ "method": "engine_newPayloadV3", "params": [ { - "parentHash": "0xc67a660f5d3c20ee603911bdff1e409e976f306883dff8ef4999dca3176f7dca", + "parentHash": "0x14ba5ec415d827d9cab33e6097b307131e8119a1cd7dc1f6a4de088ebfa4c1b6", "feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", - "stateRoot": "0x5fc31c01a451fe02f0e938de7ec7044aaba1159a81a1be64357bc70af226f304", + "stateRoot": "0xade3c29cae771ddfa994d3d2994f3bcbe084bc7bb23cdbb9bd7e35b39f007841", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "gasLimit": "0x1c9c380", @@ -14,18 +14,21 @@ "timestamp": "0x30", "extraData": "0x", "baseFeePerGas": "0x7", + "excessBlobGas": "0x0", + "blobGasUsed": "0x0", "transactions": [], "withdrawals": [], - "depositRequests": [], - "withdrawalRequests": [], "blockNumber": "0x3", - "blockHash": "0xdbb55a049f14b8152695bf3bbd754aa1fd55bbe10b306eb49caa4bd7d7fcb634", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "excessBlobGas": "0x0", - "blobGasUsed": "0x0" + "blockHash": "0x9f157012bdc439f5fe2bb3b4236eb07043e35d16256557d73e80a95d20054929" }, [], - "0x0000000000000000000000000000000000000000000000000000000000000000" + "0x0000000000000000000000000000000000000000000000000000000000000000", + [ + "0x", + "0x", + "0x" + ] ], "id": 67 }, @@ -34,7 +37,7 @@ "id": 67, "result": { "status": "VALID", - "latestValidHash": "0xdbb55a049f14b8152695bf3bbd754aa1fd55bbe10b306eb49caa4bd7d7fcb634", + "latestValidHash": "0x9f157012bdc439f5fe2bb3b4236eb07043e35d16256557d73e80a95d20054929", "validationError": null } }, diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/15_prague_forkchoiceUpdatedV3.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/15_prague_forkchoiceUpdatedV3.json index 61750afbe7..31903a4f96 100644 --- a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/15_prague_forkchoiceUpdatedV3.json +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/15_prague_forkchoiceUpdatedV3.json @@ -4,9 +4,9 @@ "method": "engine_forkchoiceUpdatedV3", "params": [ { - "headBlockHash": "0xdbb55a049f14b8152695bf3bbd754aa1fd55bbe10b306eb49caa4bd7d7fcb634", - "safeBlockHash": "0xdbb55a049f14b8152695bf3bbd754aa1fd55bbe10b306eb49caa4bd7d7fcb634", - "finalizedBlockHash": "0xdbb55a049f14b8152695bf3bbd754aa1fd55bbe10b306eb49caa4bd7d7fcb634" + "headBlockHash": "0x9f157012bdc439f5fe2bb3b4236eb07043e35d16256557d73e80a95d20054929", + "safeBlockHash": "0x9f157012bdc439f5fe2bb3b4236eb07043e35d16256557d73e80a95d20054929", + "finalizedBlockHash": "0x9f157012bdc439f5fe2bb3b4236eb07043e35d16256557d73e80a95d20054929" }, { "timestamp": "0x40", @@ -24,10 +24,10 @@ "result": { "payloadStatus": { "status": "VALID", - "latestValidHash": "0xdbb55a049f14b8152695bf3bbd754aa1fd55bbe10b306eb49caa4bd7d7fcb634", + "latestValidHash": "0x9f157012bdc439f5fe2bb3b4236eb07043e35d16256557d73e80a95d20054929", "validationError": null }, - "payloadId": "0x28264396a9634d41" + "payloadId": "0x282643ae671b03bf" } }, "statusCode": 200 diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/16_prague_getPayloadV4.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/16_prague_getPayloadV4.json index 51843931e7..2f2d7c355c 100644 --- a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/16_prague_getPayloadV4.json +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/16_prague_getPayloadV4.json @@ -3,7 +3,7 @@ "jsonrpc": "2.0", "method": "engine_getPayloadV4", "params": [ - "0x28264396a9634d41" + "0x282643ae671b03bf" ], "id": 67 }, @@ -12,50 +12,40 @@ "id": 67, "result": { "executionPayload": { - "parentHash": "0xdbb55a049f14b8152695bf3bbd754aa1fd55bbe10b306eb49caa4bd7d7fcb634", + "parentHash": "0x9f157012bdc439f5fe2bb3b4236eb07043e35d16256557d73e80a95d20054929", "feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", - "stateRoot": "0x49df1f1a1d28a23fa752230d442077768787d392e9edb70c83d727d31e55eaac", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xc7dbe7764cb5edd271a3e7fc4ffad23736aa1b8d4a5703e05a58db88d4ecbdc3", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000100000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000008000000000000000000000000000000000000000800000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "gasLimit": "0x1c9c380", - "gasUsed": "0x3ad4d", + "gasUsed": "0x3b6c5", "timestamp": "0x40", "extraData": "0x", "baseFeePerGas": "0x7", "excessBlobGas": "0x0", + "blobGasUsed": "0x0", "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", "transactions": [ "0xf8a08085e8d4a51000832dc6c09400a3ca265ebcb825b45f985a16cefb49958ce01702b8388706d19a62f28a6a6549f96c5adaebac9124a61d44868ec94f6d2d707c6a2f82c9162071231dfeb40e24bfde4ffdf2430000000000000000822fdfa00476c1a81f80f4c130acb5f8b8075468ba0893d766b7ec51a8d9723c573ad034a03bd3eaedabbaaf745f15023185ba66584ad3ee8bb40b9bef8c0b9ed27f8b1959", "0xf8c80185e8d4a51000832dc6c09400b42dbf2194e931e80326d950320f7d9dbeac0201b860fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe822fe0a05b88b593926d340f448918ef1c6263356c37f2434774e0fdb1cb9d90cfa5a23ba003a86aac4adb774181ba51eda17efb5fbed99ad57895e6eb56ccdf508a88a7cc" ], "withdrawals": [], - "depositRequests": [], - "withdrawalRequests": [ - { - "sourceAddress": "0x23618e81e3f5cdf7f54c3d65f7fbc0abf5b21e8f", - "amount": "0x0", - "validatorPubkey": "0x8706d19a62f28a6a6549f96c5adaebac9124a61d44868ec94f6d2d707c6a2f82c9162071231dfeb40e24bfde4ffdf243" - } - ], - "consolidationRequests": [ - { - "sourceAddress": "0x23618e81e3f5cdf7f54c3d65f7fbc0abf5b21e8f", - "sourcePubkey": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - "targetPubkey": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe" - } - ], "blockNumber": "0x4", - "receiptsRoot": "0x970fc81bb3e7fb21435f9a65a184aa9e3fd2f52b89fd859302b46954354266b5", - "blobGasUsed": "0x0", - "blockHash": "0x93df6f3484202f24c692354e2ab96e9948ae45eea6ad85faea121a389e468ea8" + "receiptsRoot": "0x640f4036d53782ca4c5e9273ba6d657db4f5ff4fe526a8ed1997af9d0b8ae2d3", + "blockHash": "0x61642311e6c1e0af50abf17be1fcb6de8bd75af2ca2d188031d074f6e71bf5e6" }, - "blockValue": "0x3581baab15c12e5", + "blockValue": "0x360b8482c4b509d", "blobsBundle": { "commitments": [], "proofs": [], "blobs": [] }, - "shouldOverrideBuilder": false + "shouldOverrideBuilder": false, + "executionRequests": [ + "0x", + "0x23618e81e3f5cdf7f54c3d65f7fbc0abf5b21e8f8706d19a62f28a6a6549f96c5adaebac9124a61d44868ec94f6d2d707c6a2f82c9162071231dfeb40e24bfde4ffdf2430000000000000000", + "0x23618e81e3f5cdf7f54c3d65f7fbc0abf5b21e8ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe" + ] } }, "statusCode": 200, diff --git a/besu/build.gradle b/besu/build.gradle index fa2b0548c5..41a4b11494 100644 --- a/besu/build.gradle +++ b/besu/build.gradle @@ -68,20 +68,21 @@ dependencies { implementation 'com.google.guava:guava' implementation 'com.google.dagger:dagger' implementation 'com.graphql-java:graphql-java' + implementation 'commons-net:commons-net' implementation 'info.picocli:picocli' implementation 'io.vertx:vertx-core' implementation 'io.vertx:vertx-web' - implementation 'org.apache.commons:commons-lang3' - implementation 'org.apache.logging.log4j:log4j-core' implementation 'io.tmio:tuweni-bytes' implementation 'io.tmio:tuweni-config' implementation 'io.tmio:tuweni-toml' implementation 'io.tmio:tuweni-units' + implementation 'org.apache.commons:commons-lang3' + implementation 'org.apache.logging.log4j:log4j-core' + implementation 'org.hibernate.validator:hibernate-validator' + implementation 'org.rocksdb:rocksdbjni' implementation 'org.springframework.security:spring-security-crypto' implementation 'org.xerial.snappy:snappy-java' implementation 'tech.pegasys:jc-kzg-4844' - implementation 'org.rocksdb:rocksdbjni' - implementation 'commons-net:commons-net' runtimeOnly 'org.apache.logging.log4j:log4j-jul' runtimeOnly 'com.splunk.logging:splunk-library-javalogging' @@ -103,7 +104,6 @@ dependencies { testImplementation 'org.awaitility:awaitility' testImplementation 'org.junit.jupiter:junit-jupiter' testImplementation 'org.mockito:mockito-core' - testImplementation 'org.testcontainers:testcontainers' testImplementation 'tech.pegasys.discovery:discovery' testImplementation 'com.google.dagger:dagger' diff --git a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java index e93518cad4..886e3d6838 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java @@ -20,11 +20,11 @@ import static java.nio.charset.StandardCharsets.UTF_8; import static java.util.Arrays.asList; import static java.util.Collections.singletonList; import static org.hyperledger.besu.cli.DefaultCommandValues.getDefaultBesuDataPath; +import static org.hyperledger.besu.cli.config.NetworkName.EPHEMERY; import static org.hyperledger.besu.cli.config.NetworkName.MAINNET; import static org.hyperledger.besu.cli.util.CommandLineUtils.DEPENDENCY_WARNING_MSG; import static org.hyperledger.besu.cli.util.CommandLineUtils.isOptionSet; import static org.hyperledger.besu.controller.BesuController.DATABASE_PATH; -import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration.DEFAULT_ENGINE_JSON_RPC_PORT; import static org.hyperledger.besu.ethereum.api.jsonrpc.authentication.EngineAuthService.EPHEMERAL_JWT_FILE; import static org.hyperledger.besu.nat.kubernetes.KubernetesNatManager.DEFAULT_BESU_SERVICE_NAME_FILTER; @@ -38,35 +38,36 @@ import org.hyperledger.besu.cli.config.EthNetworkConfig; import org.hyperledger.besu.cli.config.NetworkName; import org.hyperledger.besu.cli.config.ProfilesCompletionCandidates; import org.hyperledger.besu.cli.converter.MetricCategoryConverter; -import org.hyperledger.besu.cli.converter.PercentageConverter; -import org.hyperledger.besu.cli.converter.SubnetInfoConverter; import org.hyperledger.besu.cli.custom.JsonRPCAllowlistHostsProperty; import org.hyperledger.besu.cli.error.BesuExecutionExceptionHandler; import org.hyperledger.besu.cli.error.BesuParameterExceptionHandler; import org.hyperledger.besu.cli.options.MiningOptions; import org.hyperledger.besu.cli.options.TransactionPoolOptions; import org.hyperledger.besu.cli.options.stable.ApiConfigurationOptions; -import org.hyperledger.besu.cli.options.stable.DataStorageOptions; +import org.hyperledger.besu.cli.options.stable.EngineRPCConfiguration; +import org.hyperledger.besu.cli.options.stable.EngineRPCOptions; import org.hyperledger.besu.cli.options.stable.EthstatsOptions; import org.hyperledger.besu.cli.options.stable.GraphQlOptions; import org.hyperledger.besu.cli.options.stable.JsonRpcHttpOptions; import org.hyperledger.besu.cli.options.stable.LoggingLevelOption; -import org.hyperledger.besu.cli.options.stable.MetricsOptionGroup; +import org.hyperledger.besu.cli.options.stable.MetricsOptions; import org.hyperledger.besu.cli.options.stable.NodePrivateKeyFileOption; -import org.hyperledger.besu.cli.options.stable.P2PTLSConfigOptions; +import org.hyperledger.besu.cli.options.stable.P2PDiscoveryOptions; import org.hyperledger.besu.cli.options.stable.PermissionsOptions; import org.hyperledger.besu.cli.options.stable.PluginsConfigurationOptions; import org.hyperledger.besu.cli.options.stable.RpcWebsocketOptions; +import org.hyperledger.besu.cli.options.storage.DataStorageOptions; +import org.hyperledger.besu.cli.options.storage.DiffBasedSubStorageOptions; import org.hyperledger.besu.cli.options.unstable.ChainPruningOptions; import org.hyperledger.besu.cli.options.unstable.DnsOptions; import org.hyperledger.besu.cli.options.unstable.EthProtocolOptions; import org.hyperledger.besu.cli.options.unstable.EvmOptions; import org.hyperledger.besu.cli.options.unstable.InProcessRpcOptions; import org.hyperledger.besu.cli.options.unstable.IpcOptions; -import org.hyperledger.besu.cli.options.unstable.MetricsCLIOptions; import org.hyperledger.besu.cli.options.unstable.NatOptions; import org.hyperledger.besu.cli.options.unstable.NativeLibraryOptions; import org.hyperledger.besu.cli.options.unstable.NetworkingOptions; +import org.hyperledger.besu.cli.options.unstable.P2PTLSConfigOptions; import org.hyperledger.besu.cli.options.unstable.PrivacyPluginOptions; import org.hyperledger.besu.cli.options.unstable.RPCOptions; import org.hyperledger.besu.cli.options.unstable.SynchronizerOptions; @@ -89,7 +90,7 @@ import org.hyperledger.besu.components.BesuComponent; import org.hyperledger.besu.config.CheckpointConfigOptions; import org.hyperledger.besu.config.GenesisConfigFile; import org.hyperledger.besu.config.GenesisConfigOptions; -import org.hyperledger.besu.config.MergeConfigOptions; +import org.hyperledger.besu.config.MergeConfiguration; import org.hyperledger.besu.controller.BesuController; import org.hyperledger.besu.controller.BesuControllerBuilder; import org.hyperledger.besu.crypto.Blake2bfMessageDigest; @@ -124,6 +125,7 @@ import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolCo import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration; import org.hyperledger.besu.ethereum.mainnet.FrontierTargetingGasLimitCalculator; import org.hyperledger.besu.ethereum.p2p.config.DiscoveryConfiguration; +import org.hyperledger.besu.ethereum.p2p.discovery.P2PDiscoveryConfiguration; import org.hyperledger.besu.ethereum.p2p.peers.EnodeDnsConfiguration; import org.hyperledger.besu.ethereum.p2p.peers.EnodeURLImpl; import org.hyperledger.besu.ethereum.p2p.peers.StaticNodesParser; @@ -138,7 +140,9 @@ import org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueStorageProvider; import org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueStorageProviderBuilder; import org.hyperledger.besu.ethereum.transaction.TransactionSimulator; import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; +import org.hyperledger.besu.ethereum.worldstate.DiffBasedSubStorageConfiguration; import org.hyperledger.besu.ethereum.worldstate.ImmutableDataStorageConfiguration; +import org.hyperledger.besu.ethereum.worldstate.ImmutableDiffBasedSubStorageConfiguration; import org.hyperledger.besu.evm.precompile.AbstractAltBnPrecompiledContract; import org.hyperledger.besu.evm.precompile.BigIntegerModularExponentiationPrecompiledContract; import org.hyperledger.besu.evm.precompile.KZGPointEvalPrecompiledContract; @@ -195,6 +199,7 @@ import org.hyperledger.besu.services.TransactionPoolValidatorServiceImpl; import org.hyperledger.besu.services.TransactionSelectionServiceImpl; import org.hyperledger.besu.services.TransactionSimulationServiceImpl; import org.hyperledger.besu.services.kvstore.InMemoryStoragePlugin; +import org.hyperledger.besu.util.EphemeryGenesisUpdater; import org.hyperledger.besu.util.InvalidConfigurationException; import org.hyperledger.besu.util.LogConfigurator; import org.hyperledger.besu.util.NetworkUtility; @@ -209,7 +214,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.math.BigInteger; -import java.net.InetAddress; import java.net.SocketException; import java.net.URI; import java.net.URL; @@ -246,8 +250,6 @@ import com.google.common.collect.ImmutableMap; import io.vertx.core.Vertx; import io.vertx.core.VertxOptions; import io.vertx.core.json.DecodeException; -import io.vertx.core.metrics.MetricsOptions; -import org.apache.commons.net.util.SubnetUtils.SubnetInfo; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.units.bigints.UInt256; import org.slf4j.Logger; @@ -296,7 +298,6 @@ public class BesuCommand implements DefaultCommandValues, Runnable { final NetworkingOptions unstableNetworkingOptions = NetworkingOptions.create(); final SynchronizerOptions unstableSynchronizerOptions = SynchronizerOptions.create(); final EthProtocolOptions unstableEthProtocolOptions = EthProtocolOptions.create(); - final MetricsCLIOptions unstableMetricsCLIOptions = MetricsCLIOptions.create(); private final DnsOptions unstableDnsOptions = DnsOptions.create(); private final NatOptions unstableNatOptions = NatOptions.create(); private final NativeLibraryOptions unstableNativeLibraryOptions = NativeLibraryOptions.create(); @@ -416,7 +417,9 @@ public class BesuCommand implements DefaultCommandValues, Runnable { // P2P Discovery Option Group @CommandLine.ArgGroup(validate = false, heading = "@|bold P2P Discovery Options|@%n") - P2PDiscoveryOptionGroup p2PDiscoveryOptionGroup = new P2PDiscoveryOptionGroup(); + P2PDiscoveryOptions p2PDiscoveryOptions = new P2PDiscoveryOptions(); + + P2PDiscoveryConfiguration p2PDiscoveryConfig; private final TransactionSelectionServiceImpl transactionSelectionServiceImpl; private final TransactionPoolValidatorServiceImpl transactionValidatorServiceImpl; @@ -424,163 +427,6 @@ public class BesuCommand implements DefaultCommandValues, Runnable { private final BlockchainServiceImpl blockchainServiceImpl; private BesuComponent besuComponent; - static class P2PDiscoveryOptionGroup { - - // Public IP stored to prevent having to research it each time we need it. - private InetAddress autoDiscoveredDefaultIP = null; - - // Completely disables P2P within Besu. - @Option( - names = {"--p2p-enabled"}, - description = "Enable P2P functionality (default: ${DEFAULT-VALUE})", - arity = "1") - private final Boolean p2pEnabled = true; - - // Boolean option to indicate if peers should NOT be discovered, default to - // false indicates that - // the peers should be discovered by default. - // - // This negative option is required because of the nature of the option that is - // true when - // added on the command line. You can't do --option=false, so false is set as - // default - // and you have not to set the option at all if you want it false. - // This seems to be the only way it works with Picocli. - // Also many other software use the same negative option scheme for false - // defaults - // meaning that it's probably the right way to handle disabling options. - @Option( - names = {"--discovery-enabled"}, - description = "Enable P2P discovery (default: ${DEFAULT-VALUE})", - arity = "1") - private final Boolean peerDiscoveryEnabled = true; - - // A list of bootstrap nodes can be passed - // and a hardcoded list will be used otherwise by the Runner. - // NOTE: we have no control over default value here. - @Option( - names = {"--bootnodes"}, - paramLabel = "", - description = - "Comma separated enode URLs for P2P discovery bootstrap. " - + "Default is a predefined list.", - split = ",", - arity = "0..*") - private final List bootNodes = null; - - @SuppressWarnings({"FieldCanBeFinal", "FieldMayBeFinal"}) // PicoCLI requires non-final Strings. - @Option( - names = {"--p2p-host"}, - paramLabel = MANDATORY_HOST_FORMAT_HELP, - description = "IP address this node advertises to its peers (default: ${DEFAULT-VALUE})", - arity = "1") - private String p2pHost = autoDiscoverDefaultIP().getHostAddress(); - - @SuppressWarnings({"FieldCanBeFinal", "FieldMayBeFinal"}) // PicoCLI requires non-final Strings. - @Option( - names = {"--p2p-interface"}, - paramLabel = MANDATORY_HOST_FORMAT_HELP, - description = - "The network interface address on which this node listens for P2P communication (default: ${DEFAULT-VALUE})", - arity = "1") - private String p2pInterface = NetworkUtility.INADDR_ANY; - - @Option( - names = {"--p2p-port"}, - paramLabel = MANDATORY_PORT_FORMAT_HELP, - description = "Port on which to listen for P2P communication (default: ${DEFAULT-VALUE})", - arity = "1") - private final Integer p2pPort = EnodeURLImpl.DEFAULT_LISTENING_PORT; - - @Option( - names = {"--max-peers", "--p2p-peer-upper-bound"}, - paramLabel = MANDATORY_INTEGER_FORMAT_HELP, - description = "Maximum P2P connections that can be established (default: ${DEFAULT-VALUE})") - private final Integer maxPeers = DEFAULT_MAX_PEERS; - - @Option( - names = {"--remote-connections-limit-enabled"}, - description = - "Whether to limit the number of P2P connections initiated remotely. (default: ${DEFAULT-VALUE})") - private final Boolean isLimitRemoteWireConnectionsEnabled = true; - - @Option( - names = {"--remote-connections-max-percentage"}, - paramLabel = MANDATORY_DOUBLE_FORMAT_HELP, - description = - "The maximum percentage of P2P connections that can be initiated remotely. Must be between 0 and 100 inclusive. (default: ${DEFAULT-VALUE})", - arity = "1", - converter = PercentageConverter.class) - private final Percentage maxRemoteConnectionsPercentage = - Fraction.fromFloat(DEFAULT_FRACTION_REMOTE_WIRE_CONNECTIONS_ALLOWED).toPercentage(); - - @SuppressWarnings({"FieldCanBeFinal", "FieldMayBeFinal"}) // PicoCLI requires non-final Strings. - @CommandLine.Option( - names = {"--discovery-dns-url"}, - description = "Specifies the URL to use for DNS discovery") - private String discoveryDnsUrl = null; - - @Option( - names = {"--random-peer-priority-enabled"}, - description = - "Allow for incoming connections to be prioritized randomly. This will prevent (typically small, stable) networks from forming impenetrable peer cliques. (default: ${DEFAULT-VALUE})") - private final Boolean randomPeerPriority = Boolean.FALSE; - - @Option( - names = {"--banned-node-ids", "--banned-node-id"}, - paramLabel = MANDATORY_NODE_ID_FORMAT_HELP, - description = "A list of node IDs to ban from the P2P network.", - split = ",", - arity = "1..*") - void setBannedNodeIds(final List values) { - try { - bannedNodeIds = - values.stream() - .filter(value -> !value.isEmpty()) - .map(EnodeURLImpl::parseNodeId) - .collect(Collectors.toList()); - } catch (final IllegalArgumentException e) { - throw new ParameterException( - new CommandLine(this), - "Invalid ids supplied to '--banned-node-ids'. " + e.getMessage()); - } - } - - // Boolean option to set that in a PoA network the bootnodes should always be queried during - // peer table refresh. If this flag is disabled bootnodes are only sent FINDN requests on first - // startup, meaning that an offline bootnode or network outage at the client can prevent it - // discovering any peers without a restart. - @Option( - names = {"--poa-discovery-retry-bootnodes"}, - description = - "Always use of bootnodes for discovery in PoA networks. Disabling this reverts " - + " to the same behaviour as non-PoA networks, where neighbours are only discovered from bootnodes on first startup." - + "(default: ${DEFAULT-VALUE})", - arity = "1") - private final Boolean poaDiscoveryRetryBootnodes = true; - - private Collection bannedNodeIds = new ArrayList<>(); - - // Used to discover the default IP of the client. - // Loopback IP is used by default as this is how smokeTests require it to be - // and it's probably a good security behaviour to default only on the localhost. - private InetAddress autoDiscoverDefaultIP() { - autoDiscoveredDefaultIP = - Optional.ofNullable(autoDiscoveredDefaultIP).orElseGet(InetAddress::getLoopbackAddress); - - return autoDiscoveredDefaultIP; - } - - @Option( - names = {"--net-restrict"}, - arity = "1..*", - split = ",", - converter = SubnetInfoConverter.class, - description = - "Comma-separated list of allowed IP subnets (e.g., '192.168.1.0/24,10.0.0.0/8').") - private List allowedSubnets; - } - @Option( names = {"--sync-mode"}, paramLabel = MANDATORY_MODE_FORMAT_HELP, @@ -647,42 +493,9 @@ public class BesuCommand implements DefaultCommandValues, Runnable { // Engine JSON-PRC Options @CommandLine.ArgGroup(validate = false, heading = "@|bold Engine JSON-RPC Options|@%n") - EngineRPCOptionGroup engineRPCOptionGroup = new EngineRPCOptionGroup(); + EngineRPCOptions engineRPCOptions = new EngineRPCOptions(); - static class EngineRPCOptionGroup { - @Option( - names = {"--engine-rpc-enabled"}, - description = - "enable the engine api, even in the absence of merge-specific configurations.") - private final Boolean overrideEngineRpcEnabled = false; - - @Option( - names = {"--engine-rpc-port", "--engine-rpc-http-port"}, - paramLabel = MANDATORY_PORT_FORMAT_HELP, - description = "Port to provide consensus client APIS on (default: ${DEFAULT-VALUE})", - arity = "1") - private final Integer engineRpcPort = DEFAULT_ENGINE_JSON_RPC_PORT; - - @Option( - names = {"--engine-jwt-secret"}, - paramLabel = MANDATORY_FILE_FORMAT_HELP, - description = "Path to file containing shared secret key for JWT signature verification") - private final Path engineJwtKeyFile = null; - - @Option( - names = {"--engine-jwt-disabled"}, - description = "Disable authentication for Engine APIs (default: ${DEFAULT-VALUE})") - private final Boolean isEngineAuthDisabled = false; - - @Option( - names = {"--engine-host-allowlist"}, - paramLabel = "[,...]... or * or all", - description = - "Comma separated list of hostnames to allow for ENGINE API access (applies to both HTTP and websockets), or * to accept any host (default: ${DEFAULT-VALUE})", - defaultValue = "localhost,127.0.0.1") - private final JsonRPCAllowlistHostsProperty engineHostsAllowlist = - new JsonRPCAllowlistHostsProperty(); - } + EngineRPCConfiguration engineRPCConfig = engineRPCOptions.toDomainObject(); // JSON-RPC HTTP Options @CommandLine.ArgGroup(validate = false, heading = "@|bold JSON-RPC HTTP Options|@%n") @@ -773,7 +586,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { // Metrics Option Group @CommandLine.ArgGroup(validate = false, heading = "@|bold Metrics Options|@%n") - MetricsOptionGroup metricsOptionGroup = new MetricsOptionGroup(); + MetricsOptions metricsOptions = MetricsOptions.create(); @Option( names = {"--host-allowlist"}, @@ -1342,7 +1155,6 @@ public class BesuCommand implements DefaultCommandValues, Runnable { final ImmutableMap unstableOptions = unstableOptionsBuild .put("Ethereum Wire Protocol", unstableEthProtocolOptions) - .put("Metrics", unstableMetricsCLIOptions) .put("P2P Network", unstableNetworkingOptions) .put("RPC", unstableRPCOptions) .put("DNS Configuration", unstableDnsOptions) @@ -1409,13 +1221,13 @@ public class BesuCommand implements DefaultCommandValues, Runnable { private Runner buildRunner() { return synchronize( besuController, - p2PDiscoveryOptionGroup.p2pEnabled, + p2PDiscoveryConfig.p2pEnabled(), p2pTLSConfiguration, - p2PDiscoveryOptionGroup.peerDiscoveryEnabled, + p2PDiscoveryConfig.peerDiscoveryEnabled(), ethNetworkConfig, - p2PDiscoveryOptionGroup.p2pHost, - p2PDiscoveryOptionGroup.p2pInterface, - p2PDiscoveryOptionGroup.p2pPort, + p2PDiscoveryConfig.p2pHost(), + p2PDiscoveryConfig.p2pInterface(), + p2PDiscoveryConfig.p2pPort(), graphQLConfiguration, jsonRpcConfiguration, engineJsonRpcConfiguration, @@ -1598,7 +1410,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { if (genesisConfigOptionsSupplier.get().getCancunTime().isPresent() || genesisConfigOptionsSupplier.get().getCancunEOFTime().isPresent() || genesisConfigOptionsSupplier.get().getPragueTime().isPresent() - || genesisConfigOptionsSupplier.get().getPragueEOFTime().isPresent()) { + || genesisConfigOptionsSupplier.get().getOsakaTime().isPresent()) { if (kzgTrustedSetupFile != null) { KZGPointEvalPrecompiledContract.init(kzgTrustedSetupFile); } else { @@ -1612,9 +1424,8 @@ public class BesuCommand implements DefaultCommandValues, Runnable { } private void validateOptions() { - validateRequiredOptions(); issueOptionWarnings(); - validateP2PInterface(p2PDiscoveryOptionGroup.p2pInterface); + validateP2PInterface(p2PDiscoveryOptions.p2pInterface); validateMiningParams(); validateNatParams(); validateNetStatsParams(); @@ -1666,19 +1477,6 @@ public class BesuCommand implements DefaultCommandValues, Runnable { dataStorageOptions.validate(commandLine); } - private void validateRequiredOptions() { - commandLine - .getCommandSpec() - .options() - .forEach( - option -> { - if (option.required() && option.stringValues().isEmpty()) { - throw new ParameterException( - this.commandLine, "Missing required option: " + option.longestName()); - } - }); - } - private void validateMiningParams() { miningOptions.validate( commandLine, genesisConfigOptionsSupplier.get(), isMergeEnabled(), logger); @@ -1750,13 +1548,12 @@ public class BesuCommand implements DefaultCommandValues, Runnable { } private void ensureValidPeerBoundParams() { - maxPeers = p2PDiscoveryOptionGroup.maxPeers; + maxPeers = p2PDiscoveryOptions.maxPeers; final Boolean isLimitRemoteWireConnectionsEnabled = - p2PDiscoveryOptionGroup.isLimitRemoteWireConnectionsEnabled; + p2PDiscoveryOptions.isLimitRemoteWireConnectionsEnabled; if (isLimitRemoteWireConnectionsEnabled) { final float fraction = - Fraction.fromPercentage(p2PDiscoveryOptionGroup.maxRemoteConnectionsPercentage) - .getValue(); + Fraction.fromPercentage(p2PDiscoveryOptions.maxRemoteConnectionsPercentage).getValue(); checkState( fraction >= 0.0 && fraction <= 1.0, "Fraction of remote connections allowed must be between 0.0 and 1.0 (inclusive)."); @@ -1796,11 +1593,14 @@ public class BesuCommand implements DefaultCommandValues, Runnable { } private GenesisConfigFile readGenesisConfigFile() { - final GenesisConfigFile effectiveGenesisFile = - genesisFile != null - ? GenesisConfigFile.fromSource(genesisConfigSource(genesisFile)) - : GenesisConfigFile.fromResource( - Optional.ofNullable(network).orElse(MAINNET).getGenesisFile()); + GenesisConfigFile effectiveGenesisFile; + effectiveGenesisFile = + network.equals(EPHEMERY) + ? EphemeryGenesisUpdater.updateGenesis(genesisConfigOverrides) + : genesisFile != null + ? GenesisConfigFile.fromSource(genesisConfigSource(genesisFile)) + : GenesisConfigFile.fromResource( + Optional.ofNullable(network).orElse(MAINNET).getGenesisFile()); return effectiveGenesisFile.withOverrides(genesisConfigOverrides); } @@ -1820,7 +1620,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { logger, commandLine, "--p2p-enabled", - !p2PDiscoveryOptionGroup.p2pEnabled, + !p2PDiscoveryOptions.p2pEnabled, asList( "--bootnodes", "--discovery-enabled", @@ -1846,7 +1646,11 @@ public class BesuCommand implements DefaultCommandValues, Runnable { CommandLineUtils.failIfOptionDoesntMeetRequirement( commandLine, "--Xsnapsync-synchronizer-flat option can only be used when --Xbonsai-full-flat-db-enabled is true", - dataStorageOptions.toDomainObject().getUnstable().getBonsaiFullFlatDbEnabled(), + dataStorageOptions + .toDomainObject() + .getDiffBasedSubStorageConfiguration() + .getUnstable() + .getFullFlatDbEnabled(), asList( "--Xsnapsync-synchronizer-flat-account-healed-count-per-request", "--Xsnapsync-synchronizer-flat-slot-healed-count-per-request")); @@ -1861,6 +1665,8 @@ public class BesuCommand implements DefaultCommandValues, Runnable { } private void configure() throws Exception { + p2PDiscoveryConfig = p2PDiscoveryOptions.toDomainObject(); + engineRPCConfig = engineRPCOptions.toDomainObject(); checkPortClash(); checkIfRequiredPortsAreAvailable(); syncMode = getDefaultSyncModeIfNotSet(); @@ -1870,25 +1676,18 @@ public class BesuCommand implements DefaultCommandValues, Runnable { jsonRpcConfiguration = jsonRpcHttpOptions.jsonRpcConfiguration( - hostsAllowlist, - p2PDiscoveryOptionGroup.autoDiscoverDefaultIP().getHostAddress(), - unstableRPCOptions.getHttpTimeoutSec()); + hostsAllowlist, p2PDiscoveryOptions.p2pHost, unstableRPCOptions.getHttpTimeoutSec()); if (isEngineApiEnabled()) { - engineJsonRpcConfiguration = - createEngineJsonRpcConfiguration( - engineRPCOptionGroup.engineRpcPort, engineRPCOptionGroup.engineHostsAllowlist); + engineJsonRpcConfiguration = createEngineJsonRpcConfiguration(); } p2pTLSConfiguration = p2pTLSConfigOptions.p2pTLSConfiguration(commandLine); graphQLConfiguration = graphQlOptions.graphQLConfiguration( - hostsAllowlist, - p2PDiscoveryOptionGroup.autoDiscoverDefaultIP().getHostAddress(), - unstableRPCOptions.getHttpTimeoutSec()); + hostsAllowlist, p2PDiscoveryOptions.p2pHost, unstableRPCOptions.getHttpTimeoutSec()); + webSocketConfiguration = rpcWebsocketOptions.webSocketConfiguration( - hostsAllowlist, - p2PDiscoveryOptionGroup.autoDiscoverDefaultIP().getHostAddress(), - unstableRPCOptions.getWsTimeoutSec()); + hostsAllowlist, p2PDiscoveryConfig.p2pHost(), unstableRPCOptions.getWsTimeoutSec()); jsonRpcIpcConfiguration = jsonRpcIpcConfiguration( unstableIpcOptions.isEnabled(), @@ -1983,57 +1782,64 @@ public class BesuCommand implements DefaultCommandValues, Runnable { .withMiningParameters(miningParametersSupplier.get()) .withJsonRpcHttpOptions(jsonRpcHttpOptions); final KeyValueStorageProvider storageProvider = keyValueStorageProvider(keyValueStorageName); - return controllerBuilder - .fromEthNetworkConfig(updateNetworkConfig(network), getDefaultSyncModeIfNotSet()) - .synchronizerConfiguration(buildSyncConfig()) - .ethProtocolConfiguration(unstableEthProtocolOptions.toDomainObject()) - .networkConfiguration(unstableNetworkingOptions.toDomainObject()) - .dataDirectory(dataDir()) - .dataStorageConfiguration(getDataStorageConfiguration()) - .miningParameters(miningParametersSupplier.get()) - .transactionPoolConfiguration(buildTransactionPoolConfiguration()) - .nodeKey(new NodeKey(securityModule())) - .metricsSystem((ObservableMetricsSystem) besuComponent.getMetricsSystem()) - .messagePermissioningProviders(permissioningService.getMessagePermissioningProviders()) - .privacyParameters(privacyParameters()) - .clock(Clock.systemUTC()) - .isRevertReasonEnabled(isRevertReasonEnabled) - .isParallelTxProcessingEnabled( - dataStorageConfiguration.getUnstable().isParallelTxProcessingEnabled()) - .storageProvider(storageProvider) - .gasLimitCalculator( - miningParametersSupplier.get().getTargetGasLimit().isPresent() - ? new FrontierTargetingGasLimitCalculator() - : GasLimitCalculator.constant()) - .requiredBlocks(requiredBlocks) - .reorgLoggingThreshold(reorgLoggingThreshold) - .evmConfiguration(unstableEvmOptions.toDomainObject()) - .maxPeers(p2PDiscoveryOptionGroup.maxPeers) - .maxRemotelyInitiatedPeers(maxRemoteInitiatedPeers) - .randomPeerPriority(p2PDiscoveryOptionGroup.randomPeerPriority) - .chainPruningConfiguration(unstableChainPruningOptions.toDomainObject()) - .cacheLastBlocks(numberOfblocksToCache) - .genesisStateHashCacheEnabled(genesisStateHashCacheEnabled) - .besuComponent(besuComponent); - } - - private JsonRpcConfiguration createEngineJsonRpcConfiguration( - final Integer engineListenPort, final List allowCallsFrom) { + BesuControllerBuilder besuControllerBuilder = + controllerBuilder + .fromEthNetworkConfig(updateNetworkConfig(network), getDefaultSyncModeIfNotSet()) + .synchronizerConfiguration(buildSyncConfig()) + .ethProtocolConfiguration(unstableEthProtocolOptions.toDomainObject()) + .networkConfiguration(unstableNetworkingOptions.toDomainObject()) + .dataDirectory(dataDir()) + .dataStorageConfiguration(getDataStorageConfiguration()) + .miningParameters(miningParametersSupplier.get()) + .transactionPoolConfiguration(buildTransactionPoolConfiguration()) + .nodeKey(new NodeKey(securityModule())) + .metricsSystem((ObservableMetricsSystem) besuComponent.getMetricsSystem()) + .messagePermissioningProviders(permissioningService.getMessagePermissioningProviders()) + .privacyParameters(privacyParameters()) + .clock(Clock.systemUTC()) + .isRevertReasonEnabled(isRevertReasonEnabled) + .storageProvider(storageProvider) + .gasLimitCalculator( + miningParametersSupplier.get().getTargetGasLimit().isPresent() + ? new FrontierTargetingGasLimitCalculator() + : GasLimitCalculator.constant()) + .requiredBlocks(requiredBlocks) + .reorgLoggingThreshold(reorgLoggingThreshold) + .evmConfiguration(unstableEvmOptions.toDomainObject()) + .maxPeers(p2PDiscoveryOptions.maxPeers) + .maxRemotelyInitiatedPeers(maxRemoteInitiatedPeers) + .randomPeerPriority(p2PDiscoveryOptions.randomPeerPriority) + .chainPruningConfiguration(unstableChainPruningOptions.toDomainObject()) + .cacheLastBlocks(numberOfblocksToCache) + .genesisStateHashCacheEnabled(genesisStateHashCacheEnabled) + .besuComponent(besuComponent); + if (DataStorageFormat.BONSAI.equals(getDataStorageConfiguration().getDataStorageFormat())) { + final DiffBasedSubStorageConfiguration subStorageConfiguration = + getDataStorageConfiguration().getDiffBasedSubStorageConfiguration(); + if (subStorageConfiguration.getLimitTrieLogsEnabled()) { + besuControllerBuilder.isParallelTxProcessingEnabled( + subStorageConfiguration.getUnstable().isParallelTxProcessingEnabled()); + } + } + return besuControllerBuilder; + } + + private JsonRpcConfiguration createEngineJsonRpcConfiguration() { jsonRpcHttpOptions.checkDependencies(logger, commandLine); final JsonRpcConfiguration engineConfig = jsonRpcHttpOptions.jsonRpcConfiguration( - allowCallsFrom, - p2PDiscoveryOptionGroup.autoDiscoverDefaultIP().getHostAddress(), + engineRPCConfig.engineHostsAllowlist(), + p2PDiscoveryConfig.p2pHost(), unstableRPCOptions.getWsTimeoutSec()); - engineConfig.setPort(engineListenPort); + engineConfig.setPort(engineRPCConfig.engineRpcPort()); engineConfig.setRpcApis(Arrays.asList("ENGINE", "ETH")); engineConfig.setEnabled(isEngineApiEnabled()); - if (!engineRPCOptionGroup.isEngineAuthDisabled) { + if (!engineRPCConfig.isEngineAuthDisabled()) { engineConfig.setAuthenticationEnabled(true); engineConfig.setAuthenticationAlgorithm(JwtAlgorithm.HS256); - if (Objects.nonNull(engineRPCOptionGroup.engineJwtKeyFile) - && java.nio.file.Files.exists(engineRPCOptionGroup.engineJwtKeyFile)) { - engineConfig.setAuthenticationPublicKeyFile(engineRPCOptionGroup.engineJwtKeyFile.toFile()); + if (Objects.nonNull(engineRPCConfig.engineJwtKeyFile()) + && java.nio.file.Files.exists(engineRPCConfig.engineJwtKeyFile())) { + engineConfig.setAuthenticationPublicKeyFile(engineRPCConfig.engineJwtKeyFile().toFile()); } else { logger.warn( "Engine API authentication enabled without key file. Expect ephemeral jwt.hex file in datadir"); @@ -2060,7 +1866,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { * @return instance of MetricsConfiguration. */ public MetricsConfiguration metricsConfiguration() { - if (metricsOptionGroup.getMetricsEnabled() && metricsOptionGroup.getMetricsPushEnabled()) { + if (metricsOptions.getMetricsEnabled() && metricsOptions.getMetricsPushEnabled()) { throw new ParameterException( this.commandLine, "--metrics-enabled option and --metrics-push-enabled option can't be used at the same " @@ -2071,40 +1877,33 @@ public class BesuCommand implements DefaultCommandValues, Runnable { logger, commandLine, "--metrics-enabled", - !metricsOptionGroup.getMetricsEnabled(), + !metricsOptions.getMetricsEnabled(), asList("--metrics-host", "--metrics-port")); CommandLineUtils.checkOptionDependencies( logger, commandLine, "--metrics-push-enabled", - !metricsOptionGroup.getMetricsPushEnabled(), + !metricsOptions.getMetricsPushEnabled(), asList( "--metrics-push-host", "--metrics-push-port", "--metrics-push-interval", "--metrics-push-prometheus-job")); - return unstableMetricsCLIOptions - .toDomainObject() - .enabled(metricsOptionGroup.getMetricsEnabled()) + final MetricsConfiguration.Builder metricsConfigurationBuilder = + metricsOptions.toDomainObject(); + metricsConfigurationBuilder .host( - Strings.isNullOrEmpty(metricsOptionGroup.getMetricsHost()) - ? p2PDiscoveryOptionGroup.autoDiscoverDefaultIP().getHostAddress() - : metricsOptionGroup.getMetricsHost()) - .port(metricsOptionGroup.getMetricsPort()) - .protocol(metricsOptionGroup.getMetricsProtocol()) - .metricCategories(metricsOptionGroup.getMetricCategories()) - .pushEnabled(metricsOptionGroup.getMetricsPushEnabled()) + Strings.isNullOrEmpty(metricsOptions.getMetricsHost()) + ? p2PDiscoveryOptions.p2pHost + : metricsOptions.getMetricsHost()) .pushHost( - Strings.isNullOrEmpty(metricsOptionGroup.getMetricsPushHost()) - ? p2PDiscoveryOptionGroup.autoDiscoverDefaultIP().getHostAddress() - : metricsOptionGroup.getMetricsPushHost()) - .pushPort(metricsOptionGroup.getMetricsPushPort()) - .pushInterval(metricsOptionGroup.getMetricsPushInterval()) - .hostsAllowlist(hostsAllowlist) - .prometheusJob(metricsOptionGroup.getMetricsPrometheusJob()) - .build(); + Strings.isNullOrEmpty(metricsOptions.getMetricsPushHost()) + ? p2PDiscoveryOptions.autoDiscoverDefaultIP().getHostAddress() + : metricsOptions.getMetricsPushHost()) + .hostsAllowlist(hostsAllowlist); + return metricsConfigurationBuilder.build(); } private PrivacyParameters privacyParameters() { @@ -2342,29 +2141,34 @@ public class BesuCommand implements DefaultCommandValues, Runnable { } if (SyncMode.FULL.equals(getDefaultSyncModeIfNotSet()) - && DataStorageFormat.BONSAI.equals(dataStorageConfiguration.getDataStorageFormat()) - && dataStorageConfiguration.getBonsaiLimitTrieLogsEnabled()) { + && DataStorageFormat.BONSAI.equals(dataStorageConfiguration.getDataStorageFormat())) { + final DiffBasedSubStorageConfiguration diffBasedSubStorageConfiguration = + dataStorageConfiguration.getDiffBasedSubStorageConfiguration(); + if (diffBasedSubStorageConfiguration.getLimitTrieLogsEnabled()) { + if (CommandLineUtils.isOptionSet( + commandLine, DiffBasedSubStorageOptions.LIMIT_TRIE_LOGS_ENABLED)) { + throw new ParameterException( + commandLine, + String.format( + "Cannot enable %s with --sync-mode=%s and --data-storage-format=%s. You must set %s or use a different sync-mode", + DiffBasedSubStorageOptions.LIMIT_TRIE_LOGS_ENABLED, + SyncMode.FULL, + DataStorageFormat.BONSAI, + DiffBasedSubStorageOptions.LIMIT_TRIE_LOGS_ENABLED + "=false")); + } - if (CommandLineUtils.isOptionSet( - commandLine, DataStorageOptions.BONSAI_LIMIT_TRIE_LOGS_ENABLED)) { - throw new ParameterException( - commandLine, - String.format( - "Cannot enable %s with --sync-mode=%s and --data-storage-format=%s. You must set %s or use a different sync-mode", - DataStorageOptions.BONSAI_LIMIT_TRIE_LOGS_ENABLED, - SyncMode.FULL, - DataStorageFormat.BONSAI, - DataStorageOptions.BONSAI_LIMIT_TRIE_LOGS_ENABLED + "=false")); + dataStorageConfiguration = + ImmutableDataStorageConfiguration.copyOf(dataStorageConfiguration) + .withDiffBasedSubStorageConfiguration( + ImmutableDiffBasedSubStorageConfiguration.copyOf( + dataStorageConfiguration.getDiffBasedSubStorageConfiguration()) + .withLimitTrieLogsEnabled(false)); + logger.warn( + "Forcing {}, since it cannot be enabled with --sync-mode={} and --data-storage-format={}.", + DiffBasedSubStorageOptions.LIMIT_TRIE_LOGS_ENABLED + "=false", + SyncMode.FULL, + DataStorageFormat.BONSAI); } - - dataStorageConfiguration = - ImmutableDataStorageConfiguration.copyOf(dataStorageConfiguration) - .withBonsaiLimitTrieLogsEnabled(false); - logger.warn( - "Forcing {}, since it cannot be enabled with --sync-mode={} and --data-storage-format={}.", - DataStorageOptions.BONSAI_LIMIT_TRIE_LOGS_ENABLED + "=false", - SyncMode.FULL, - DataStorageFormat.BONSAI); } return dataStorageConfiguration; } @@ -2441,7 +2245,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { .apiConfiguration(apiConfiguration) .pidPath(pidPath) .dataDir(dataDir()) - .bannedNodeIds(p2PDiscoveryOptionGroup.bannedNodeIds) + .bannedNodeIds(p2PDiscoveryConfig.bannedNodeIds()) .metricsSystem((ObservableMetricsSystem) besuComponent.getMetricsSystem()) .permissioningService(permissioningService) .metricsConfiguration(metricsConfiguration) @@ -2453,8 +2257,8 @@ public class BesuCommand implements DefaultCommandValues, Runnable { .storageProvider(keyValueStorageProvider(keyValueStorageName)) .rpcEndpointService(rpcEndpointServiceImpl) .enodeDnsConfiguration(getEnodeDnsConfiguration()) - .allowedSubnets(p2PDiscoveryOptionGroup.allowedSubnets) - .poaDiscoveryRetryBootnodes(p2PDiscoveryOptionGroup.poaDiscoveryRetryBootnodes) + .allowedSubnets(p2PDiscoveryConfig.allowedSubnets()) + .poaDiscoveryRetryBootnodes(p2PDiscoveryConfig.poaDiscoveryRetryBootnodes()) .build(); addShutdownHook(runner); @@ -2477,7 +2281,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { return new VertxOptions() .setPreferNativeTransport(true) .setMetricsOptions( - new MetricsOptions() + new io.vertx.core.metrics.MetricsOptions() .setEnabled(true) .setFactory(new VertxMetricsAdapterFactory(metricsSystem))); } @@ -2529,7 +2333,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { } } - if (p2PDiscoveryOptionGroup.bootNodes == null) { + if (p2PDiscoveryOptions.bootNodes == null) { builder.setBootNodes(new ArrayList<>()); } builder.setDnsDiscoveryUrl(null); @@ -2540,9 +2344,13 @@ public class BesuCommand implements DefaultCommandValues, Runnable { if (networkId != null) { builder.setNetworkId(networkId); } - - if (p2PDiscoveryOptionGroup.discoveryDnsUrl != null) { - builder.setDnsDiscoveryUrl(p2PDiscoveryOptionGroup.discoveryDnsUrl); + // ChainId update is required for Ephemery network + if (network.equals(EPHEMERY)) { + String chainId = genesisConfigOverrides.get("chainId"); + builder.setNetworkId(new BigInteger(chainId)); + } + if (p2PDiscoveryOptions.discoveryDnsUrl != null) { + builder.setDnsDiscoveryUrl(p2PDiscoveryOptions.discoveryDnsUrl); } else { final Optional discoveryDnsUrlFromGenesis = genesisConfigOptionsSupplier.get().getDiscoveryOptions().getDiscoveryDnsUrl(); @@ -2550,9 +2358,9 @@ public class BesuCommand implements DefaultCommandValues, Runnable { } List listBootNodes = null; - if (p2PDiscoveryOptionGroup.bootNodes != null) { + if (p2PDiscoveryOptions.bootNodes != null) { try { - listBootNodes = buildEnodes(p2PDiscoveryOptionGroup.bootNodes, getEnodeDnsConfiguration()); + listBootNodes = buildEnodes(p2PDiscoveryOptions.bootNodes, getEnodeDnsConfiguration()); } catch (final IllegalArgumentException e) { throw new ParameterException(commandLine, e.getMessage()); } @@ -2564,7 +2372,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { } } if (listBootNodes != null) { - if (!p2PDiscoveryOptionGroup.peerDiscoveryEnabled) { + if (!p2PDiscoveryOptions.peerDiscoveryEnabled) { logger.warn("Discovery disabled: bootnodes will be ignored."); } DiscoveryConfiguration.assertValidBootnodes(listBootNodes); @@ -2699,12 +2507,12 @@ public class BesuCommand implements DefaultCommandValues, Runnable { .filter(port -> port > 0) .forEach( port -> { - if (port.equals(p2PDiscoveryOptionGroup.p2pPort) + if (port.equals(p2PDiscoveryConfig.p2pPort()) && (NetworkUtility.isPortUnavailableForTcp(port) || NetworkUtility.isPortUnavailableForUdp(port))) { unavailablePorts.add(port); } - if (!port.equals(p2PDiscoveryOptionGroup.p2pPort) + if (!port.equals(p2PDiscoveryConfig.p2pPort()) && NetworkUtility.isPortUnavailableForTcp(port)) { unavailablePorts.add(port); } @@ -2724,19 +2532,16 @@ public class BesuCommand implements DefaultCommandValues, Runnable { */ private List getEffectivePorts() { final List effectivePorts = new ArrayList<>(); - addPortIfEnabled( - effectivePorts, p2PDiscoveryOptionGroup.p2pPort, p2PDiscoveryOptionGroup.p2pEnabled); + addPortIfEnabled(effectivePorts, p2PDiscoveryOptions.p2pPort, p2PDiscoveryOptions.p2pEnabled); addPortIfEnabled( effectivePorts, graphQlOptions.getGraphQLHttpPort(), graphQlOptions.isGraphQLHttpEnabled()); addPortIfEnabled( effectivePorts, jsonRpcHttpOptions.getRpcHttpPort(), jsonRpcHttpOptions.isRpcHttpEnabled()); addPortIfEnabled( effectivePorts, rpcWebsocketOptions.getRpcWsPort(), rpcWebsocketOptions.isRpcWsEnabled()); - addPortIfEnabled(effectivePorts, engineRPCOptionGroup.engineRpcPort, isEngineApiEnabled()); + addPortIfEnabled(effectivePorts, engineRPCConfig.engineRpcPort(), isEngineApiEnabled()); addPortIfEnabled( - effectivePorts, - metricsOptionGroup.getMetricsPort(), - metricsOptionGroup.getMetricsEnabled()); + effectivePorts, metricsOptions.getMetricsPort(), metricsOptions.getMetricsEnabled()); addPortIfEnabled( effectivePorts, miningParametersSupplier.get().getStratumPort(), @@ -2810,7 +2615,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { } private void setMergeConfigOptions() { - MergeConfigOptions.setMergeEnabled( + MergeConfiguration.setMergeEnabled( genesisConfigOptionsSupplier.get().getTerminalTotalDifficulty().isPresent()); } @@ -2855,11 +2660,11 @@ public class BesuCommand implements DefaultCommandValues, Runnable { } private boolean isMergeEnabled() { - return MergeConfigOptions.isMergeEnabled(); + return MergeConfiguration.isMergeEnabled(); } private boolean isEngineApiEnabled() { - return engineRPCOptionGroup.overrideEngineRpcEnabled || isMergeEnabled(); + return engineRPCConfig.overrideEngineRpcEnabled() || isMergeEnabled(); } private SyncMode getDefaultSyncModeIfNotSet() { @@ -2902,7 +2707,8 @@ public class BesuCommand implements DefaultCommandValues, Runnable { builder .setDataStorage(dataStorageOptions.normalizeDataStorageFormat()) - .setSyncMode(syncMode.normalize()); + .setSyncMode(syncMode.normalize()) + .setSyncMinPeers(syncMinPeerCount); if (jsonRpcConfiguration != null && jsonRpcConfiguration.isEnabled()) { builder @@ -2929,12 +2735,14 @@ public class BesuCommand implements DefaultCommandValues, Runnable { builder.setHighSpecEnabled(); } - if (DataStorageFormat.BONSAI.equals(getDataStorageConfiguration().getDataStorageFormat()) - && getDataStorageConfiguration().getBonsaiLimitTrieLogsEnabled()) { - builder.setLimitTrieLogsEnabled(); - builder.setTrieLogRetentionLimit(getDataStorageConfiguration().getBonsaiMaxLayersToLoad()); - builder.setTrieLogsPruningWindowSize( - getDataStorageConfiguration().getBonsaiTrieLogPruningWindowSize()); + if (DataStorageFormat.BONSAI.equals(getDataStorageConfiguration().getDataStorageFormat())) { + final DiffBasedSubStorageConfiguration subStorageConfiguration = + getDataStorageConfiguration().getDiffBasedSubStorageConfiguration(); + if (subStorageConfiguration.getLimitTrieLogsEnabled()) { + builder.setLimitTrieLogsEnabled(); + builder.setTrieLogRetentionLimit(subStorageConfiguration.getMaxLayersToLoad()); + builder.setTrieLogsPruningWindowSize(subStorageConfiguration.getTrieLogPruningWindowSize()); + } } builder.setSnapServerEnabled(this.unstableSynchronizerOptions.isSnapsyncServerEnabled()); @@ -2949,11 +2757,20 @@ public class BesuCommand implements DefaultCommandValues, Runnable { } /** - * Returns the plugin context. + * 2 Returns the plugin context. * * @return the plugin context. */ public BesuPluginContextImpl getBesuPluginContext() { return besuPluginContext; } + + /** + * Returns the metrics options + * + * @return the metrics options + */ + public MetricsOptions getMetricsOptions() { + return metricsOptions; + } } diff --git a/besu/src/main/java/org/hyperledger/besu/cli/ConfigurationOverviewBuilder.java b/besu/src/main/java/org/hyperledger/besu/cli/ConfigurationOverviewBuilder.java index b2f89a349e..b3dfa2a054 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/ConfigurationOverviewBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/ConfigurationOverviewBuilder.java @@ -46,13 +46,14 @@ public class ConfigurationOverviewBuilder { private String customGenesisFileName; private String dataStorage; private String syncMode; + private Integer syncMinPeers; private Integer rpcPort; private Collection rpcHttpApis; private Integer enginePort; private Collection engineApis; private String engineJwtFilePath; private boolean isHighSpec = false; - private boolean isBonsaiLimitTrieLogsEnabled = false; + private boolean isLimitTrieLogsEnabled = false; private long trieLogRetentionLimit = 0; private Integer trieLogsPruningWindowSize = null; private boolean isSnapServerEnabled = false; @@ -148,6 +149,17 @@ public class ConfigurationOverviewBuilder { return this; } + /** + * Sets sync min peers. + * + * @param syncMinPeers number of min peers for sync + * @return the builder + */ + public ConfigurationOverviewBuilder setSyncMinPeers(final int syncMinPeers) { + this.syncMinPeers = syncMinPeers; + return this; + } + /** * Sets rpc port. * @@ -208,7 +220,7 @@ public class ConfigurationOverviewBuilder { * @return the builder */ public ConfigurationOverviewBuilder setLimitTrieLogsEnabled() { - isBonsaiLimitTrieLogsEnabled = true; + isLimitTrieLogsEnabled = true; return this; } @@ -340,6 +352,10 @@ public class ConfigurationOverviewBuilder { lines.add("Sync mode: " + syncMode); } + if (syncMinPeers != null) { + lines.add("Sync min peers: " + syncMinPeers); + } + if (rpcHttpApis != null) { lines.add("RPC HTTP APIs: " + String.join(",", rpcHttpApis)); } @@ -373,7 +389,7 @@ public class ConfigurationOverviewBuilder { lines.add("Experimental Snap Sync for BFT enabled"); } - if (isBonsaiLimitTrieLogsEnabled) { + if (isLimitTrieLogsEnabled) { final StringBuilder trieLogPruningString = new StringBuilder(); trieLogPruningString .append("Limit trie logs enabled: retention: ") diff --git a/besu/src/main/java/org/hyperledger/besu/cli/config/EthNetworkConfig.java b/besu/src/main/java/org/hyperledger/besu/cli/config/EthNetworkConfig.java index dd5e43e63f..dab3a4c227 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/config/EthNetworkConfig.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/config/EthNetworkConfig.java @@ -77,6 +77,7 @@ public record EthNetworkConfig( strings -> strings.stream().map(EnodeURLImpl::fromString).collect(Collectors.toList())) .orElse(Collections.emptyList()); + return new EthNetworkConfig( genesisConfigFile, networkName.getNetworkId(), diff --git a/besu/src/main/java/org/hyperledger/besu/cli/config/NetworkName.java b/besu/src/main/java/org/hyperledger/besu/cli/config/NetworkName.java index 01b810ab33..d78bd6ac8f 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/config/NetworkName.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/config/NetworkName.java @@ -32,6 +32,12 @@ public enum NetworkName { /** LUKSO mainnet network name. */ LUKSO("/lukso.json", BigInteger.valueOf(42)), + /** + * EPHEMERY network name. The actual networkId used is calculated based on this default value and + * the current time. https://ephemery.dev/ + */ + EPHEMERY("/ephemery.json", BigInteger.valueOf(39438135)), + /** Verkle testnet */ KAUSTINEN("/kaustinen.json", BigInteger.valueOf(69420)), diff --git a/besu/src/main/java/org/hyperledger/besu/cli/options/stable/ApiConfigurationOptions.java b/besu/src/main/java/org/hyperledger/besu/cli/options/stable/ApiConfigurationOptions.java index fbed68de0c..d6bc17026c 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/options/stable/ApiConfigurationOptions.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/options/stable/ApiConfigurationOptions.java @@ -28,6 +28,7 @@ import picocli.CommandLine; * Handles configuration options for the API in Besu, including gas price settings, RPC log range, * and trace filter range. */ +// TODO: implement CLIOption public class ApiConfigurationOptions { /** Default constructor. */ public ApiConfigurationOptions() {} diff --git a/besu/src/main/java/org/hyperledger/besu/cli/options/stable/DataStorageOptions.java b/besu/src/main/java/org/hyperledger/besu/cli/options/stable/DataStorageOptions.java deleted file mode 100644 index 3d53a595ec..0000000000 --- a/besu/src/main/java/org/hyperledger/besu/cli/options/stable/DataStorageOptions.java +++ /dev/null @@ -1,249 +0,0 @@ -/* - * Copyright ConsenSys AG. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - */ -package org.hyperledger.besu.cli.options.stable; - -import static org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration.DEFAULT_BONSAI_LIMIT_TRIE_LOGS_ENABLED; -import static org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration.DEFAULT_BONSAI_MAX_LAYERS_TO_LOAD; -import static org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration.DEFAULT_BONSAI_TRIE_LOG_PRUNING_WINDOW_SIZE; -import static org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration.DEFAULT_RECEIPT_COMPACTION_ENABLED; -import static org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration.MINIMUM_BONSAI_TRIE_LOG_RETENTION_LIMIT; -import static org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration.Unstable.DEFAULT_BONSAI_CODE_USING_CODE_HASH_ENABLED; -import static org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration.Unstable.DEFAULT_BONSAI_FULL_FLAT_DB_ENABLED; - -import org.hyperledger.besu.cli.options.CLIOptions; -import org.hyperledger.besu.cli.util.CommandLineUtils; -import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; -import org.hyperledger.besu.ethereum.worldstate.ImmutableDataStorageConfiguration; -import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; - -import java.util.List; -import java.util.Locale; - -import org.apache.commons.lang3.StringUtils; -import picocli.CommandLine; -import picocli.CommandLine.Option; - -/** The Data storage CLI options. */ -public class DataStorageOptions implements CLIOptions { - - private static final String DATA_STORAGE_FORMAT = "--data-storage-format"; - - /** The maximum number of historical layers to load. */ - public static final String BONSAI_STORAGE_FORMAT_MAX_LAYERS_TO_LOAD = - "--bonsai-historical-block-limit"; - - // Use Bonsai DB - @Option( - names = {DATA_STORAGE_FORMAT}, - description = - "Format to store trie data in. Either FOREST or BONSAI (default: ${DEFAULT-VALUE}).", - arity = "1") - private DataStorageFormat dataStorageFormat = DataStorageFormat.BONSAI; - - @Option( - names = {BONSAI_STORAGE_FORMAT_MAX_LAYERS_TO_LOAD, "--bonsai-maximum-back-layers-to-load"}, - paramLabel = "", - description = - "Limit of historical layers that can be loaded with BONSAI (default: ${DEFAULT-VALUE}). When using " - + BONSAI_LIMIT_TRIE_LOGS_ENABLED - + " it will also be used as the number of layers of trie logs to retain.", - arity = "1") - private Long bonsaiMaxLayersToLoad = DEFAULT_BONSAI_MAX_LAYERS_TO_LOAD; - - /** The bonsai limit trie logs enabled option name */ - public static final String BONSAI_LIMIT_TRIE_LOGS_ENABLED = "--bonsai-limit-trie-logs-enabled"; - - /** The bonsai trie logs pruning window size. */ - public static final String BONSAI_TRIE_LOG_PRUNING_WINDOW_SIZE = - "--bonsai-trie-logs-pruning-window-size"; - - // TODO --Xbonsai-limit-trie-logs-enabled and --Xbonsai-trie-log-pruning-enabled are deprecated, - // remove in a future release - @SuppressWarnings("ExperimentalCliOptionMustBeCorrectlyDisplayed") - @CommandLine.Option( - names = { - BONSAI_LIMIT_TRIE_LOGS_ENABLED, - "--Xbonsai-limit-trie-logs-enabled", // deprecated - "--Xbonsai-trie-log-pruning-enabled" // deprecated - }, - fallbackValue = "true", - description = "Limit the number of trie logs that are retained. (default: ${DEFAULT-VALUE})") - private Boolean bonsaiLimitTrieLogsEnabled = DEFAULT_BONSAI_LIMIT_TRIE_LOGS_ENABLED; - - // TODO --Xbonsai-trie-logs-pruning-window-size is deprecated, remove in a future release - @SuppressWarnings("ExperimentalCliOptionMustBeCorrectlyDisplayed") - @CommandLine.Option( - names = { - BONSAI_TRIE_LOG_PRUNING_WINDOW_SIZE, - "--Xbonsai-trie-logs-pruning-window-size" // deprecated - }, - description = - "The max number of blocks to load and prune trie logs for at startup. (default: ${DEFAULT-VALUE})") - private Integer bonsaiTrieLogPruningWindowSize = DEFAULT_BONSAI_TRIE_LOG_PRUNING_WINDOW_SIZE; - - @Option( - names = "--receipt-compaction-enabled", - description = "Enables compact storing of receipts (default: ${DEFAULT-VALUE})", - fallbackValue = "true") - private Boolean receiptCompactionEnabled = DEFAULT_RECEIPT_COMPACTION_ENABLED; - - @CommandLine.ArgGroup(validate = false) - private final DataStorageOptions.Unstable unstableOptions = new Unstable(); - - /** Default Constructor. */ - DataStorageOptions() {} - - /** The unstable options for data storage. */ - public static class Unstable { - - // TODO: --Xsnapsync-synchronizer-flat-db-healing-enabled is deprecated, remove it in a future - // release - @CommandLine.Option( - hidden = true, - names = { - "--Xbonsai-full-flat-db-enabled", - "--Xsnapsync-synchronizer-flat-db-healing-enabled" - }, - arity = "1", - description = "Enables bonsai full flat database strategy. (default: ${DEFAULT-VALUE})") - private Boolean bonsaiFullFlatDbEnabled = DEFAULT_BONSAI_FULL_FLAT_DB_ENABLED; - - @CommandLine.Option( - hidden = true, - names = {"--Xbonsai-code-using-code-hash-enabled"}, - arity = "1", - description = - "Enables code storage using code hash instead of by account hash. (default: ${DEFAULT-VALUE})") - 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. */ - Unstable() {} - } - - /** - * Create data storage options. - * - * @return the data storage options - */ - public static DataStorageOptions create() { - return new DataStorageOptions(); - } - - /** - * Validates the data storage options - * - * @param commandLine the full commandLine to check all the options specified by the user - */ - public void validate(final CommandLine commandLine) { - if (DataStorageFormat.BONSAI == dataStorageFormat) { - if (bonsaiLimitTrieLogsEnabled) { - if (bonsaiMaxLayersToLoad < MINIMUM_BONSAI_TRIE_LOG_RETENTION_LIMIT) { - throw new CommandLine.ParameterException( - commandLine, - String.format( - BONSAI_STORAGE_FORMAT_MAX_LAYERS_TO_LOAD + " minimum value is %d", - MINIMUM_BONSAI_TRIE_LOG_RETENTION_LIMIT)); - } - if (bonsaiTrieLogPruningWindowSize <= 0) { - throw new CommandLine.ParameterException( - commandLine, - String.format( - 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)); - } - } - } else { - if (unstableOptions.isParallelTxProcessingEnabled) { - throw new CommandLine.ParameterException( - commandLine, - "Transaction parallelization is not supported unless operating in a 'diffbased' mode, such as Bonsai."); - } - } - } - - /** - * Converts to options from the configuration - * - * @param domainObject to be reversed - * @return the options that correspond to the configuration - */ - public static DataStorageOptions fromConfig(final DataStorageConfiguration domainObject) { - final DataStorageOptions dataStorageOptions = DataStorageOptions.create(); - dataStorageOptions.dataStorageFormat = domainObject.getDataStorageFormat(); - dataStorageOptions.bonsaiMaxLayersToLoad = domainObject.getBonsaiMaxLayersToLoad(); - dataStorageOptions.receiptCompactionEnabled = domainObject.getReceiptCompactionEnabled(); - dataStorageOptions.bonsaiLimitTrieLogsEnabled = domainObject.getBonsaiLimitTrieLogsEnabled(); - dataStorageOptions.bonsaiTrieLogPruningWindowSize = - domainObject.getBonsaiTrieLogPruningWindowSize(); - dataStorageOptions.unstableOptions.bonsaiFullFlatDbEnabled = - domainObject.getUnstable().getBonsaiFullFlatDbEnabled(); - dataStorageOptions.unstableOptions.bonsaiCodeUsingCodeHashEnabled = - domainObject.getUnstable().getBonsaiCodeStoredByCodeHashEnabled(); - dataStorageOptions.unstableOptions.isParallelTxProcessingEnabled = - domainObject.getUnstable().isParallelTxProcessingEnabled(); - - return dataStorageOptions; - } - - @Override - public DataStorageConfiguration toDomainObject() { - return ImmutableDataStorageConfiguration.builder() - .dataStorageFormat(dataStorageFormat) - .bonsaiMaxLayersToLoad(bonsaiMaxLayersToLoad) - .receiptCompactionEnabled(receiptCompactionEnabled) - .bonsaiLimitTrieLogsEnabled(bonsaiLimitTrieLogsEnabled) - .bonsaiTrieLogPruningWindowSize(bonsaiTrieLogPruningWindowSize) - .unstable( - ImmutableDataStorageConfiguration.Unstable.builder() - .bonsaiFullFlatDbEnabled(unstableOptions.bonsaiFullFlatDbEnabled) - .bonsaiCodeStoredByCodeHashEnabled(unstableOptions.bonsaiCodeUsingCodeHashEnabled) - .isParallelTxProcessingEnabled(unstableOptions.isParallelTxProcessingEnabled) - .build()) - .build(); - } - - @Override - public List getCLIOptions() { - return CommandLineUtils.getCLIOptions(this, new DataStorageOptions()); - } - - /** - * Normalize data storage format string. - * - * @return the normalized string - */ - public String normalizeDataStorageFormat() { - return StringUtils.capitalize(dataStorageFormat.toString().toLowerCase(Locale.ROOT)); - } -} diff --git a/besu/src/main/java/org/hyperledger/besu/cli/options/stable/EngineRPCConfiguration.java b/besu/src/main/java/org/hyperledger/besu/cli/options/stable/EngineRPCConfiguration.java new file mode 100644 index 0000000000..c0eb9d1be0 --- /dev/null +++ b/besu/src/main/java/org/hyperledger/besu/cli/options/stable/EngineRPCConfiguration.java @@ -0,0 +1,36 @@ +/* + * 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.cli.options.stable; + +import org.hyperledger.besu.cli.custom.JsonRPCAllowlistHostsProperty; + +import java.nio.file.Path; + +/** + * Command line options for configuring Engine RPC on the node. + * + * @param overrideEngineRpcEnabled enable the engine api, even in the absence of merge-specific + * configurations. + * @param engineRpcPort Port to provide consensus client APIS on + * @param engineJwtKeyFile Path to file containing shared secret key for JWT signature verification + * @param isEngineAuthDisabled Disable authentication for Engine APIs + * @param engineHostsAllowlist List of hosts to allowlist for Engine APIs + */ +public record EngineRPCConfiguration( + Boolean overrideEngineRpcEnabled, + Integer engineRpcPort, + Path engineJwtKeyFile, + Boolean isEngineAuthDisabled, + JsonRPCAllowlistHostsProperty engineHostsAllowlist) {} diff --git a/besu/src/main/java/org/hyperledger/besu/cli/options/stable/EngineRPCOptions.java b/besu/src/main/java/org/hyperledger/besu/cli/options/stable/EngineRPCOptions.java new file mode 100644 index 0000000000..1aa5b3d326 --- /dev/null +++ b/besu/src/main/java/org/hyperledger/besu/cli/options/stable/EngineRPCOptions.java @@ -0,0 +1,81 @@ +/* + * 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.cli.options.stable; + +import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration.DEFAULT_ENGINE_JSON_RPC_PORT; + +import org.hyperledger.besu.cli.DefaultCommandValues; +import org.hyperledger.besu.cli.custom.JsonRPCAllowlistHostsProperty; +import org.hyperledger.besu.cli.options.CLIOptions; +import org.hyperledger.besu.cli.util.CommandLineUtils; + +import java.nio.file.Path; +import java.util.List; + +import picocli.CommandLine; + +/** Command line options for configuring Engine RPC on the node. */ +public class EngineRPCOptions implements CLIOptions { + + /** Default constructor */ + public EngineRPCOptions() {} + + @CommandLine.Option( + names = {"--engine-rpc-enabled"}, + description = "enable the engine api, even in the absence of merge-specific configurations.") + private final Boolean overrideEngineRpcEnabled = false; + + @CommandLine.Option( + names = {"--engine-rpc-port", "--engine-rpc-http-port"}, + paramLabel = DefaultCommandValues.MANDATORY_PORT_FORMAT_HELP, + description = "Port to provide consensus client APIS on (default: ${DEFAULT-VALUE})", + arity = "1") + private final Integer engineRpcPort = DEFAULT_ENGINE_JSON_RPC_PORT; + + @CommandLine.Option( + names = {"--engine-jwt-secret"}, + paramLabel = DefaultCommandValues.MANDATORY_FILE_FORMAT_HELP, + description = "Path to file containing shared secret key for JWT signature verification") + private final Path engineJwtKeyFile = null; + + @CommandLine.Option( + names = {"--engine-jwt-disabled"}, + description = "Disable authentication for Engine APIs (default: ${DEFAULT-VALUE})") + private final Boolean isEngineAuthDisabled = false; + + @CommandLine.Option( + names = {"--engine-host-allowlist"}, + paramLabel = "[,...]... or * or all", + description = + "Comma separated list of hostnames to allow for ENGINE API access (applies to both HTTP and websockets), or * to accept any host (default: ${DEFAULT-VALUE})", + defaultValue = "localhost,127.0.0.1") + private final JsonRPCAllowlistHostsProperty engineHostsAllowlist = + new JsonRPCAllowlistHostsProperty(); + + @Override + public EngineRPCConfiguration toDomainObject() { + return new EngineRPCConfiguration( + overrideEngineRpcEnabled, + engineRpcPort, + engineJwtKeyFile, + isEngineAuthDisabled, + engineHostsAllowlist); + } + + @Override + public List getCLIOptions() { + return CommandLineUtils.getCLIOptions(this, new EngineRPCOptions()); + } +} diff --git a/besu/src/main/java/org/hyperledger/besu/cli/options/stable/GraphQlOptions.java b/besu/src/main/java/org/hyperledger/besu/cli/options/stable/GraphQlOptions.java index 77cc170305..6aac24a6fb 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/options/stable/GraphQlOptions.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/options/stable/GraphQlOptions.java @@ -29,6 +29,7 @@ import org.slf4j.Logger; import picocli.CommandLine; /** Handles configuration options for the GraphQL HTTP service in Besu. */ +// TODO: implement CLIOptions public class GraphQlOptions { @CommandLine.Option( names = {"--graphql-http-enabled"}, diff --git a/besu/src/main/java/org/hyperledger/besu/cli/options/stable/JsonRpcHttpOptions.java b/besu/src/main/java/org/hyperledger/besu/cli/options/stable/JsonRpcHttpOptions.java index 026b83b553..7d08a6f9aa 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/options/stable/JsonRpcHttpOptions.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/options/stable/JsonRpcHttpOptions.java @@ -15,6 +15,7 @@ package org.hyperledger.besu.cli.options.stable; import static java.util.Arrays.asList; +import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration.DEFAULT_JSON_RPC_HOST; import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration.DEFAULT_JSON_RPC_PORT; import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration.DEFAULT_PRETTY_JSON_ENABLED; import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis.DEFAULT_RPC_APIS; @@ -52,6 +53,7 @@ import picocli.CommandLine; * Handles configuration options for the JSON-RPC HTTP service, including validation and creation of * a JSON-RPC configuration. */ +// TODO: implement CLIOption public class JsonRpcHttpOptions { @CommandLine.Option( names = {"--rpc-http-enabled"}, @@ -64,7 +66,7 @@ public class JsonRpcHttpOptions { paramLabel = DefaultCommandValues.MANDATORY_HOST_FORMAT_HELP, description = "Host for JSON-RPC HTTP to listen on (default: ${DEFAULT-VALUE})", arity = "1") - private String rpcHttpHost; + private String rpcHttpHost = DEFAULT_JSON_RPC_HOST; @CommandLine.Option( names = {"--rpc-http-port"}, @@ -265,37 +267,50 @@ public class JsonRpcHttpOptions { /** * Creates a JsonRpcConfiguration based on the provided options. * - * @param hostsAllowlist List of hosts allowed - * @param defaultHostAddress Default host address - * @param timoutSec timeout in seconds - * @return A JsonRpcConfiguration instance + * @return configuration populated from options or defaults */ - public JsonRpcConfiguration jsonRpcConfiguration( - final List hostsAllowlist, final String defaultHostAddress, final Long timoutSec) { + public JsonRpcConfiguration jsonRpcConfiguration() { final JsonRpcConfiguration jsonRpcConfiguration = JsonRpcConfiguration.createDefault(); jsonRpcConfiguration.setEnabled(isRpcHttpEnabled); - jsonRpcConfiguration.setHost( - Strings.isNullOrEmpty(rpcHttpHost) ? defaultHostAddress : rpcHttpHost); jsonRpcConfiguration.setPort(rpcHttpPort); jsonRpcConfiguration.setMaxActiveConnections(rpcHttpMaxConnections); jsonRpcConfiguration.setCorsAllowedDomains(rpcHttpCorsAllowedOrigins); jsonRpcConfiguration.setRpcApis(rpcHttpApis.stream().distinct().collect(Collectors.toList())); jsonRpcConfiguration.setNoAuthRpcApis( rpcHttpApiMethodsNoAuth.stream().distinct().collect(Collectors.toList())); - jsonRpcConfiguration.setHostsAllowlist(hostsAllowlist); jsonRpcConfiguration.setAuthenticationEnabled(isRpcHttpAuthenticationEnabled); jsonRpcConfiguration.setAuthenticationCredentialsFile(rpcHttpAuthenticationCredentialsFile); jsonRpcConfiguration.setAuthenticationPublicKeyFile(rpcHttpAuthenticationPublicKeyFile); jsonRpcConfiguration.setAuthenticationAlgorithm(rpcHttpAuthenticationAlgorithm); jsonRpcConfiguration.setTlsConfiguration(rpcHttpTlsConfiguration()); - jsonRpcConfiguration.setHttpTimeoutSec(timoutSec); jsonRpcConfiguration.setMaxBatchSize(rpcHttpMaxBatchSize); jsonRpcConfiguration.setMaxRequestContentLength(rpcHttpMaxRequestContentLength); jsonRpcConfiguration.setPrettyJsonEnabled(prettyJsonEnabled); return jsonRpcConfiguration; } + /** + * Creates a JsonRpcConfiguration based on the provided options. + * + * @param hostsAllowlist List of hosts allowed + * @param defaultHostAddress Default host address + * @param timoutSec timeout in seconds + * @return A JsonRpcConfiguration instance + */ + public JsonRpcConfiguration jsonRpcConfiguration( + final List hostsAllowlist, final String defaultHostAddress, final Long timoutSec) { + + final JsonRpcConfiguration jsonRpcConfiguration = this.jsonRpcConfiguration(); + + jsonRpcConfiguration.setHost( + Strings.isNullOrEmpty(rpcHttpHost) ? defaultHostAddress : rpcHttpHost); + jsonRpcConfiguration.setHostsAllowlist(hostsAllowlist); + ; + jsonRpcConfiguration.setHttpTimeoutSec(timoutSec); + return jsonRpcConfiguration; + } + /** * Checks dependencies between options. * diff --git a/besu/src/main/java/org/hyperledger/besu/cli/options/stable/MetricsOptionGroup.java b/besu/src/main/java/org/hyperledger/besu/cli/options/stable/MetricsOptions.java similarity index 57% rename from besu/src/main/java/org/hyperledger/besu/cli/options/stable/MetricsOptionGroup.java rename to besu/src/main/java/org/hyperledger/besu/cli/options/stable/MetricsOptions.java index add2bf1655..4906cf538e 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/options/stable/MetricsOptionGroup.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/options/stable/MetricsOptions.java @@ -22,19 +22,80 @@ import static org.hyperledger.besu.metrics.MetricsProtocol.PROMETHEUS; import static org.hyperledger.besu.metrics.prometheus.MetricsConfiguration.DEFAULT_METRICS_PORT; import static org.hyperledger.besu.metrics.prometheus.MetricsConfiguration.DEFAULT_METRICS_PUSH_PORT; +import org.hyperledger.besu.cli.options.CLIOptions; +import org.hyperledger.besu.cli.util.CommandLineUtils; import org.hyperledger.besu.metrics.MetricsProtocol; +import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration; import org.hyperledger.besu.plugin.services.metrics.MetricCategory; +import java.util.List; import java.util.Set; import picocli.CommandLine; /** Command line options for configuring metrics. */ -public class MetricsOptionGroup { +// TODO: implement CLIOption +public class MetricsOptions implements CLIOptions { + + /** + * Returns a MetricsConfiguration.Builder because fields are often overridden from other domains, + * like using P2P settings as defaults. + * + * @return a newly created {@link MetricsOptions} with default values + */ + @Override + public MetricsConfiguration.Builder toDomainObject() { + MetricsConfiguration.Builder builder = MetricsConfiguration.builder(); + builder + .timersEnabled(unstableOptions.timersEnabled) + .idleTimeout(unstableOptions.idleTimeout) + .enabled(getMetricsEnabled()) + .host(getMetricsHost()) + .port(getMetricsPort()) + .protocol(getMetricsProtocol()) + .metricCategories(getMetricCategories()) + .pushEnabled(getMetricsPushEnabled()) + .pushHost(getMetricsPushHost()) + .pushPort(getMetricsPushPort()) + .pushInterval(getMetricsPushInterval()) + .prometheusJob(getMetricsPrometheusJob()); + return builder; + } + + // TODO: why do we need to be able to reverse this? + /** + * Returns a newly created {@link MetricsOptions} reversed from the supplied MetricsConfiguration + * + * @param config the metrics configuration + * @return a newly created {@link MetricsOptions} reversed from the supplied MetricsConfiguration + */ + public static MetricsOptions fromConfiguration(final MetricsConfiguration config) { + final MetricsOptions metricsOptions = create(); + metricsOptions.unstableOptions.timersEnabled = config.isTimersEnabled(); + metricsOptions.unstableOptions.idleTimeout = config.getIdleTimeout(); + metricsOptions.isMetricsEnabled = config.isEnabled(); + metricsOptions.metricsHost = config.getHost(); + metricsOptions.metricsPort = config.getPort(); + metricsOptions.metricsProtocol = config.getProtocol(); + metricsOptions.metricCategories = config.getMetricCategories(); + metricsOptions.metricsPrometheusJob = config.getPrometheusJob(); + metricsOptions.isMetricsPushEnabled = config.isPushEnabled(); + metricsOptions.metricsPushHost = config.getPushHost(); + metricsOptions.metricsPushPort = config.getPushPort(); + metricsOptions.metricsPushInterval = config.getPushInterval(); + + return metricsOptions; + } + + @Override + public List getCLIOptions() { + return CommandLineUtils.getCLIOptions(this, new MetricsOptions()); + } + @CommandLine.Option( names = {"--metrics-enabled"}, description = "Set to start the metrics exporter (default: ${DEFAULT-VALUE})") - private final Boolean isMetricsEnabled = false; + private Boolean isMetricsEnabled = false; @SuppressWarnings({"FieldCanBeFinal", "FieldMayBeFinal"}) // PicoCLI requires non-final Strings. @CommandLine.Option( @@ -49,14 +110,14 @@ public class MetricsOptionGroup { paramLabel = MANDATORY_HOST_FORMAT_HELP, description = "Host for the metrics exporter to listen on (default: ${DEFAULT-VALUE})", arity = "1") - private String metricsHost; + private String metricsHost = MetricsConfiguration.DEFAULT_METRICS_HOST; @CommandLine.Option( names = {"--metrics-port"}, paramLabel = MANDATORY_PORT_FORMAT_HELP, description = "Port for the metrics exporter to listen on (default: ${DEFAULT-VALUE})", arity = "1") - private final Integer metricsPort = DEFAULT_METRICS_PORT; + private Integer metricsPort = DEFAULT_METRICS_PORT; @CommandLine.Option( names = {"--metrics-category", "--metrics-categories"}, @@ -65,12 +126,12 @@ public class MetricsOptionGroup { arity = "1..*", description = "Comma separated list of categories to track metrics for (default: ${DEFAULT-VALUE})") - private final Set metricCategories = DEFAULT_METRIC_CATEGORIES; + private Set metricCategories = DEFAULT_METRIC_CATEGORIES; @CommandLine.Option( names = {"--metrics-push-enabled"}, description = "Enable the metrics push gateway integration (default: ${DEFAULT-VALUE})") - private final Boolean isMetricsPushEnabled = false; + private Boolean isMetricsPushEnabled = false; @SuppressWarnings({"FieldCanBeFinal", "FieldMayBeFinal"}) // PicoCLI requires non-final Strings. @CommandLine.Option( @@ -78,14 +139,14 @@ public class MetricsOptionGroup { paramLabel = MANDATORY_HOST_FORMAT_HELP, description = "Host of the Prometheus Push Gateway for push mode (default: ${DEFAULT-VALUE})", arity = "1") - private String metricsPushHost; + private String metricsPushHost = MetricsConfiguration.DEFAULT_METRICS_PUSH_HOST; @CommandLine.Option( names = {"--metrics-push-port"}, paramLabel = MANDATORY_PORT_FORMAT_HELP, description = "Port of the Prometheus Push Gateway for push mode (default: ${DEFAULT-VALUE})", arity = "1") - private final Integer metricsPushPort = DEFAULT_METRICS_PUSH_PORT; + private Integer metricsPushPort = DEFAULT_METRICS_PUSH_PORT; @CommandLine.Option( names = {"--metrics-push-interval"}, @@ -93,7 +154,7 @@ public class MetricsOptionGroup { description = "Interval in seconds to push metrics when in push mode (default: ${DEFAULT-VALUE})", arity = "1") - private final Integer metricsPushInterval = 15; + private Integer metricsPushInterval = 15; @SuppressWarnings({"FieldCanBeFinal", "FieldMayBeFinal"}) // PicoCLI requires non-final Strings. @CommandLine.Option( @@ -102,8 +163,16 @@ public class MetricsOptionGroup { arity = "1") private String metricsPrometheusJob = "besu-client"; - /** Returns a newly created {@link MetricsOptionGroup} with default values. */ - public MetricsOptionGroup() {} + /** + * Returns a newly created {@link MetricsOptions} with default values. + * + * @return new instance + */ + public static MetricsOptions create() { + return new MetricsOptions(); + } + + private MetricsOptions() {} /** * Returns whether metrics are enabled. @@ -194,4 +263,26 @@ public class MetricsOptionGroup { public String getMetricsPrometheusJob() { return metricsPrometheusJob; } + + @CommandLine.ArgGroup(validate = false) + private final MetricsOptions.Unstable unstableOptions = new MetricsOptions.Unstable(); + + static class Unstable { + private static final String TIMERS_ENABLED_FLAG = "--Xmetrics-timers-enabled"; + private static final String IDLE_TIMEOUT_FLAG = "--Xmetrics-idle-timeout"; + + @CommandLine.Option( + names = TIMERS_ENABLED_FLAG, + hidden = true, + description = "Whether to enable timer metrics (default: ${DEFAULT-VALUE}).") + private Boolean timersEnabled = MetricsConfiguration.DEFAULT_METRICS_TIMERS_ENABLED; + + @CommandLine.Option( + hidden = true, + names = {IDLE_TIMEOUT_FLAG}, + paramLabel = "", + description = "Timeout for metrics TCP connections, in seconds (default: ${DEFAULT-VALUE})", + arity = "1") + private int idleTimeout = MetricsConfiguration.DEFAULT_METRICS_IDLE_TIMEOUT_SECONDS; + } } diff --git a/besu/src/main/java/org/hyperledger/besu/cli/options/stable/P2PDiscoveryOptions.java b/besu/src/main/java/org/hyperledger/besu/cli/options/stable/P2PDiscoveryOptions.java new file mode 100644 index 0000000000..a15be99dc7 --- /dev/null +++ b/besu/src/main/java/org/hyperledger/besu/cli/options/stable/P2PDiscoveryOptions.java @@ -0,0 +1,225 @@ +/* + * 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.cli.options.stable; + +import org.hyperledger.besu.cli.DefaultCommandValues; +import org.hyperledger.besu.cli.converter.PercentageConverter; +import org.hyperledger.besu.cli.converter.SubnetInfoConverter; +import org.hyperledger.besu.cli.options.CLIOptions; +import org.hyperledger.besu.cli.util.CommandLineUtils; +import org.hyperledger.besu.ethereum.p2p.discovery.P2PDiscoveryConfiguration; +import org.hyperledger.besu.ethereum.p2p.peers.EnodeURLImpl; +import org.hyperledger.besu.util.NetworkUtility; +import org.hyperledger.besu.util.number.Fraction; +import org.hyperledger.besu.util.number.Percentage; + +import java.net.InetAddress; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import org.apache.commons.net.util.SubnetUtils; +import org.apache.tuweni.bytes.Bytes; +import picocli.CommandLine; + +/** Command line options for configuring P2P discovery on the node. */ +public class P2PDiscoveryOptions implements CLIOptions { + + /** Default constructor */ + public P2PDiscoveryOptions() {} + + // Public IP stored to prevent having to research it each time we need it. + private InetAddress autoDiscoveredDefaultIP = null; + + /** Completely disables P2P within Besu. */ + @CommandLine.Option( + names = {"--p2p-enabled"}, + description = "Enable P2P functionality (default: ${DEFAULT-VALUE})", + arity = "1") + public final Boolean p2pEnabled = true; + + /** Boolean option to indicate if peers should be discovered. */ + @CommandLine.Option( + names = {"--discovery-enabled"}, + description = "Enable P2P discovery (default: ${DEFAULT-VALUE})", + arity = "1") + public final Boolean peerDiscoveryEnabled = true; + + /** + * A list of bootstrap nodes can be passed and a hardcoded list will be used otherwise by the + * Runner. + */ + // NOTE: we have no control over default value here. + @CommandLine.Option( + names = {"--bootnodes"}, + paramLabel = "", + description = + "Comma separated enode URLs for P2P discovery bootstrap. " + + "Default is a predefined list.", + split = ",", + arity = "0..*") + public final List bootNodes = null; + + /** The IP the node advertises to peers for P2P communication. */ + @SuppressWarnings({"FieldCanBeFinal", "FieldMayBeFinal"}) // PicoCLI requires non-final Strings. + @CommandLine.Option( + names = {"--p2p-host"}, + paramLabel = DefaultCommandValues.MANDATORY_HOST_FORMAT_HELP, + description = "IP address this node advertises to its peers (default: ${DEFAULT-VALUE})", + arity = "1") + public String p2pHost = autoDiscoverDefaultIP().getHostAddress(); + + /** The network interface address on which this node listens for P2P communication. */ + @SuppressWarnings({"FieldCanBeFinal", "FieldMayBeFinal"}) // PicoCLI requires non-final Strings. + @CommandLine.Option( + names = {"--p2p-interface"}, + paramLabel = DefaultCommandValues.MANDATORY_HOST_FORMAT_HELP, + description = + "The network interface address on which this node listens for P2P communication (default: ${DEFAULT-VALUE})", + arity = "1") + public String p2pInterface = NetworkUtility.INADDR_ANY; + + /** The port on which this node listens for P2P communication. */ + @CommandLine.Option( + names = {"--p2p-port"}, + paramLabel = DefaultCommandValues.MANDATORY_PORT_FORMAT_HELP, + description = "Port on which to listen for P2P communication (default: ${DEFAULT-VALUE})", + arity = "1") + public final Integer p2pPort = EnodeURLImpl.DEFAULT_LISTENING_PORT; + + /** The maximum number of peers this node can connect to. */ + @CommandLine.Option( + names = {"--max-peers", "--p2p-peer-upper-bound"}, + paramLabel = DefaultCommandValues.MANDATORY_INTEGER_FORMAT_HELP, + description = "Maximum P2P connections that can be established (default: ${DEFAULT-VALUE})") + public final Integer maxPeers = DefaultCommandValues.DEFAULT_MAX_PEERS; + + /** Boolean option to limit the number of P2P connections initiated remotely. */ + @CommandLine.Option( + names = {"--remote-connections-limit-enabled"}, + description = + "Whether to limit the number of P2P connections initiated remotely. (default: ${DEFAULT-VALUE})") + public final Boolean isLimitRemoteWireConnectionsEnabled = true; + + /** The maximum percentage of P2P connections that can be initiated remotely. */ + @CommandLine.Option( + names = {"--remote-connections-max-percentage"}, + paramLabel = DefaultCommandValues.MANDATORY_DOUBLE_FORMAT_HELP, + description = + "The maximum percentage of P2P connections that can be initiated remotely. Must be between 0 and 100 inclusive. (default: ${DEFAULT-VALUE})", + arity = "1", + converter = PercentageConverter.class) + public final Percentage maxRemoteConnectionsPercentage = + Fraction.fromFloat(DefaultCommandValues.DEFAULT_FRACTION_REMOTE_WIRE_CONNECTIONS_ALLOWED) + .toPercentage(); + + /** The URL to use for DNS discovery. */ + @SuppressWarnings({"FieldCanBeFinal", "FieldMayBeFinal"}) // PicoCLI requires non-final Strings. + @CommandLine.Option( + names = {"--discovery-dns-url"}, + description = "Specifies the URL to use for DNS discovery") + public String discoveryDnsUrl = null; + + /** Boolean option to allow for incoming connections to be prioritized randomly. */ + @CommandLine.Option( + names = {"--random-peer-priority-enabled"}, + description = + "Allow for incoming connections to be prioritized randomly. This will prevent (typically small, stable) networks from forming impenetrable peer cliques. (default: ${DEFAULT-VALUE})") + public final Boolean randomPeerPriority = Boolean.FALSE; + + /** A list of node IDs to ban from the P2P network. */ + @CommandLine.Option( + names = {"--banned-node-ids", "--banned-node-id"}, + paramLabel = DefaultCommandValues.MANDATORY_NODE_ID_FORMAT_HELP, + description = "A list of node IDs to ban from the P2P network.", + split = ",", + arity = "1..*") + void setBannedNodeIds(final List values) { + try { + bannedNodeIds = + values.stream() + .filter(value -> !value.isEmpty()) + .map(EnodeURLImpl::parseNodeId) + .collect(Collectors.toList()); + } catch (final IllegalArgumentException e) { + throw new CommandLine.ParameterException( + new CommandLine(this), "Invalid ids supplied to '--banned-node-ids'. " + e.getMessage()); + } + } + + // Boolean option to set that in a PoA network the bootnodes should always be queried during + // peer table refresh. If this flag is disabled bootnodes are only sent FINDN requests on first + // startup, meaning that an offline bootnode or network outage at the client can prevent it + // discovering any peers without a restart. + @CommandLine.Option( + names = {"--poa-discovery-retry-bootnodes"}, + description = + "Always use of bootnodes for discovery in PoA networks. Disabling this reverts " + + " to the same behaviour as non-PoA networks, where neighbours are only discovered from bootnodes on first startup." + + "(default: ${DEFAULT-VALUE})", + arity = "1") + private final Boolean poaDiscoveryRetryBootnodes = true; + + private Collection bannedNodeIds = new ArrayList<>(); + + /** + * Auto-discovers the default IP of the client. + * + * @return machine loopback address + */ + // Loopback IP is used by default as this is how smokeTests require it to be + // and it's probably a good security behaviour to default only on the localhost. + public InetAddress autoDiscoverDefaultIP() { + autoDiscoveredDefaultIP = + Optional.ofNullable(autoDiscoveredDefaultIP).orElseGet(InetAddress::getLoopbackAddress); + + return autoDiscoveredDefaultIP; + } + + @CommandLine.Option( + names = {"--net-restrict"}, + arity = "1..*", + split = ",", + converter = SubnetInfoConverter.class, + description = + "Comma-separated list of allowed IP subnets (e.g., '192.168.1.0/24,10.0.0.0/8').") + private List allowedSubnets; + + @Override + public P2PDiscoveryConfiguration toDomainObject() { + return new P2PDiscoveryConfiguration( + p2pEnabled, + peerDiscoveryEnabled, + p2pHost, + p2pInterface, + p2pPort, + maxPeers, + isLimitRemoteWireConnectionsEnabled, + maxRemoteConnectionsPercentage, + randomPeerPriority, + bannedNodeIds, + allowedSubnets, + poaDiscoveryRetryBootnodes, + bootNodes, + discoveryDnsUrl); + } + + @Override + public List getCLIOptions() { + return CommandLineUtils.getCLIOptions(this, new P2PDiscoveryOptions()); + } +} diff --git a/besu/src/main/java/org/hyperledger/besu/cli/options/stable/PermissionsOptions.java b/besu/src/main/java/org/hyperledger/besu/cli/options/stable/PermissionsOptions.java index f1eafaab16..4dc693d36e 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/options/stable/PermissionsOptions.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/options/stable/PermissionsOptions.java @@ -30,6 +30,7 @@ import org.slf4j.Logger; import picocli.CommandLine; /** Handles configuration options for permissions in Besu. */ +// TODO: implement CLIOption public class PermissionsOptions { @CommandLine.Option( names = {"--permissions-nodes-config-file-enabled"}, diff --git a/besu/src/main/java/org/hyperledger/besu/cli/options/storage/DataStorageOptions.java b/besu/src/main/java/org/hyperledger/besu/cli/options/storage/DataStorageOptions.java new file mode 100644 index 0000000000..fbc57f50de --- /dev/null +++ b/besu/src/main/java/org/hyperledger/besu/cli/options/storage/DataStorageOptions.java @@ -0,0 +1,121 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.cli.options.storage; + +import static org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration.DEFAULT_RECEIPT_COMPACTION_ENABLED; + +import org.hyperledger.besu.cli.options.CLIOptions; +import org.hyperledger.besu.cli.util.CommandLineUtils; +import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; +import org.hyperledger.besu.ethereum.worldstate.ImmutableDataStorageConfiguration; +import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; + +import java.util.List; +import java.util.Locale; + +import org.apache.commons.lang3.StringUtils; +import picocli.CommandLine; +import picocli.CommandLine.Mixin; +import picocli.CommandLine.Option; + +/** The Data storage CLI options. */ +public class DataStorageOptions implements CLIOptions { + + private static final String DATA_STORAGE_FORMAT = "--data-storage-format"; + + // Use Bonsai DB + @Option( + names = {DATA_STORAGE_FORMAT}, + description = + "Format to store trie data in. Either FOREST or BONSAI (default: ${DEFAULT-VALUE}).", + arity = "1") + private DataStorageFormat dataStorageFormat = DataStorageFormat.BONSAI; + + @Option( + names = "--receipt-compaction-enabled", + description = "Enables compact storing of receipts (default: ${DEFAULT-VALUE})", + fallbackValue = "true") + private Boolean receiptCompactionEnabled = DEFAULT_RECEIPT_COMPACTION_ENABLED; + + /** + * Options specific to diff-based storage modes. Holds the necessary parameters to configure + * diff-based storage, such as the Bonsai mode or Verkle in the future. + */ + @Mixin + private DiffBasedSubStorageOptions diffBasedSubStorageOptions = + DiffBasedSubStorageOptions.create(); + + /** Default Constructor. */ + DataStorageOptions() {} + + /** + * Create data storage options. + * + * @return the data storage options + */ + public static DataStorageOptions create() { + return new DataStorageOptions(); + } + + /** + * Validates the data storage options + * + * @param commandLine the full commandLine to check all the options specified by the user + */ + public void validate(final CommandLine commandLine) { + diffBasedSubStorageOptions.validate(commandLine, dataStorageFormat); + } + + /** + * Converts to options from the configuration + * + * @param domainObject to be reversed + * @return the options that correspond to the configuration + */ + public static DataStorageOptions fromConfig(final DataStorageConfiguration domainObject) { + final DataStorageOptions dataStorageOptions = DataStorageOptions.create(); + dataStorageOptions.dataStorageFormat = domainObject.getDataStorageFormat(); + dataStorageOptions.receiptCompactionEnabled = domainObject.getReceiptCompactionEnabled(); + dataStorageOptions.diffBasedSubStorageOptions = + DiffBasedSubStorageOptions.fromConfig(domainObject.getDiffBasedSubStorageConfiguration()); + return dataStorageOptions; + } + + @Override + public DataStorageConfiguration toDomainObject() { + final ImmutableDataStorageConfiguration.Builder builder = + ImmutableDataStorageConfiguration.builder() + .dataStorageFormat(dataStorageFormat) + .receiptCompactionEnabled(receiptCompactionEnabled) + .diffBasedSubStorageConfiguration(diffBasedSubStorageOptions.toDomainObject()); + return builder.build(); + } + + @Override + public List getCLIOptions() { + final List cliOptions = CommandLineUtils.getCLIOptions(this, new DataStorageOptions()); + cliOptions.addAll(diffBasedSubStorageOptions.getCLIOptions()); + return cliOptions; + } + + /** + * Normalize data storage format string. + * + * @return the normalized string + */ + public String normalizeDataStorageFormat() { + return StringUtils.capitalize(dataStorageFormat.toString().toLowerCase(Locale.ROOT)); + } +} diff --git a/besu/src/main/java/org/hyperledger/besu/cli/options/storage/DiffBasedSubStorageOptions.java b/besu/src/main/java/org/hyperledger/besu/cli/options/storage/DiffBasedSubStorageOptions.java new file mode 100644 index 0000000000..c95a766827 --- /dev/null +++ b/besu/src/main/java/org/hyperledger/besu/cli/options/storage/DiffBasedSubStorageOptions.java @@ -0,0 +1,217 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.cli.options.storage; + +import static org.hyperledger.besu.ethereum.worldstate.DiffBasedSubStorageConfiguration.DEFAULT_LIMIT_TRIE_LOGS_ENABLED; +import static org.hyperledger.besu.ethereum.worldstate.DiffBasedSubStorageConfiguration.DEFAULT_MAX_LAYERS_TO_LOAD; +import static org.hyperledger.besu.ethereum.worldstate.DiffBasedSubStorageConfiguration.DEFAULT_TRIE_LOG_PRUNING_WINDOW_SIZE; +import static org.hyperledger.besu.ethereum.worldstate.DiffBasedSubStorageConfiguration.DiffBasedUnstable.DEFAULT_CODE_USING_CODE_HASH_ENABLED; +import static org.hyperledger.besu.ethereum.worldstate.DiffBasedSubStorageConfiguration.DiffBasedUnstable.DEFAULT_FULL_FLAT_DB_ENABLED; +import static org.hyperledger.besu.ethereum.worldstate.DiffBasedSubStorageConfiguration.MINIMUM_TRIE_LOG_RETENTION_LIMIT; + +import org.hyperledger.besu.cli.options.CLIOptions; +import org.hyperledger.besu.cli.util.CommandLineUtils; +import org.hyperledger.besu.ethereum.worldstate.DiffBasedSubStorageConfiguration; +import org.hyperledger.besu.ethereum.worldstate.ImmutableDiffBasedSubStorageConfiguration; +import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; + +import java.util.List; + +import picocli.CommandLine; +import picocli.CommandLine.Option; + +/** The Data storage CLI options. */ +public class DiffBasedSubStorageOptions implements CLIOptions { + + /** The maximum number of historical layers to load. */ + public static final String MAX_LAYERS_TO_LOAD = "--bonsai-historical-block-limit"; + + @Option( + names = {MAX_LAYERS_TO_LOAD, "--bonsai-maximum-back-layers-to-load"}, + paramLabel = "", + description = + "Limit of historical layers that can be loaded with BONSAI (default: ${DEFAULT-VALUE}). When using " + + LIMIT_TRIE_LOGS_ENABLED + + " it will also be used as the number of layers of trie logs to retain.", + arity = "1") + private Long maxLayersToLoad = DEFAULT_MAX_LAYERS_TO_LOAD; + + /** The bonsai limit trie logs enabled option name */ + public static final String LIMIT_TRIE_LOGS_ENABLED = "--bonsai-limit-trie-logs-enabled"; + + /** The bonsai trie logs pruning window size. */ + public static final String TRIE_LOG_PRUNING_WINDOW_SIZE = + "--bonsai-trie-logs-pruning-window-size"; + + // TODO --Xbonsai-limit-trie-logs-enabled and --Xbonsai-trie-log-pruning-enabled are deprecated, + // remove in a future release + @SuppressWarnings("ExperimentalCliOptionMustBeCorrectlyDisplayed") + @Option( + names = { + LIMIT_TRIE_LOGS_ENABLED, + "--Xbonsai-limit-trie-logs-enabled", // deprecated + "--Xbonsai-trie-log-pruning-enabled" // deprecated + }, + fallbackValue = "true", + description = "Limit the number of trie logs that are retained. (default: ${DEFAULT-VALUE})") + private Boolean limitTrieLogsEnabled = DEFAULT_LIMIT_TRIE_LOGS_ENABLED; + + // TODO --Xbonsai-trie-logs-pruning-window-size is deprecated, remove in a future release + @SuppressWarnings("ExperimentalCliOptionMustBeCorrectlyDisplayed") + @Option( + names = { + TRIE_LOG_PRUNING_WINDOW_SIZE, + "--Xbonsai-trie-logs-pruning-window-size" // deprecated + }, + description = + "The max number of blocks to load and prune trie logs for at startup. (default: ${DEFAULT-VALUE})") + private Integer trieLogPruningWindowSize = DEFAULT_TRIE_LOG_PRUNING_WINDOW_SIZE; + + @CommandLine.ArgGroup(validate = false) + private final DiffBasedSubStorageOptions.Unstable unstableOptions = new Unstable(); + + /** Default Constructor. */ + DiffBasedSubStorageOptions() {} + + /** The unstable options for data storage. */ + public static class Unstable { + + // TODO: --Xsnapsync-synchronizer-flat-db-healing-enabled is deprecated, remove it in a future + // release + @Option( + hidden = true, + names = { + "--Xbonsai-full-flat-db-enabled", + "--Xsnapsync-synchronizer-flat-db-healing-enabled" + }, + arity = "1", + description = "Enables bonsai full flat database strategy. (default: ${DEFAULT-VALUE})") + private Boolean fullFlatDbEnabled = DEFAULT_FULL_FLAT_DB_ENABLED; + + @Option( + hidden = true, + names = {"--Xbonsai-code-using-code-hash-enabled"}, + arity = "1", + description = + "Enables code storage using code hash instead of by account hash. (default: ${DEFAULT-VALUE})") + private boolean codeUsingCodeHashEnabled = DEFAULT_CODE_USING_CODE_HASH_ENABLED; + + @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. */ + Unstable() {} + } + + /** + * Create data storage options. + * + * @return the data storage options + */ + public static DiffBasedSubStorageOptions create() { + return new DiffBasedSubStorageOptions(); + } + + /** + * Validates the data storage options + * + * @param commandLine the full commandLine to check all the options specified by the user + * @param dataStorageFormat the selected data storage format which determines the validation rules + * to apply. + */ + public void validate(final CommandLine commandLine, final DataStorageFormat dataStorageFormat) { + if (DataStorageFormat.BONSAI == dataStorageFormat) { + if (limitTrieLogsEnabled) { + if (maxLayersToLoad < MINIMUM_TRIE_LOG_RETENTION_LIMIT) { + throw new CommandLine.ParameterException( + commandLine, + String.format( + MAX_LAYERS_TO_LOAD + " minimum value is %d", MINIMUM_TRIE_LOG_RETENTION_LIMIT)); + } + if (trieLogPruningWindowSize <= 0) { + throw new CommandLine.ParameterException( + commandLine, + String.format( + TRIE_LOG_PRUNING_WINDOW_SIZE + "=%d must be greater than 0", + trieLogPruningWindowSize)); + } + if (trieLogPruningWindowSize <= maxLayersToLoad) { + throw new CommandLine.ParameterException( + commandLine, + String.format( + TRIE_LOG_PRUNING_WINDOW_SIZE + + "=%d must be greater than " + + MAX_LAYERS_TO_LOAD + + "=%d", + trieLogPruningWindowSize, + maxLayersToLoad)); + } + } + } else { + if (unstableOptions.isParallelTxProcessingEnabled) { + throw new CommandLine.ParameterException( + commandLine, + "Transaction parallelization is not supported unless operating in a 'diffbased' mode, such as Bonsai."); + } + } + } + + /** + * Converts to options from the configuration + * + * @param domainObject to be reversed + * @return the options that correspond to the configuration + */ + public static DiffBasedSubStorageOptions fromConfig( + final DiffBasedSubStorageConfiguration domainObject) { + final DiffBasedSubStorageOptions dataStorageOptions = DiffBasedSubStorageOptions.create(); + dataStorageOptions.maxLayersToLoad = domainObject.getMaxLayersToLoad(); + dataStorageOptions.limitTrieLogsEnabled = domainObject.getLimitTrieLogsEnabled(); + dataStorageOptions.trieLogPruningWindowSize = domainObject.getTrieLogPruningWindowSize(); + dataStorageOptions.unstableOptions.fullFlatDbEnabled = + domainObject.getUnstable().getFullFlatDbEnabled(); + dataStorageOptions.unstableOptions.codeUsingCodeHashEnabled = + domainObject.getUnstable().getCodeStoredByCodeHashEnabled(); + dataStorageOptions.unstableOptions.isParallelTxProcessingEnabled = + domainObject.getUnstable().isParallelTxProcessingEnabled(); + + return dataStorageOptions; + } + + @Override + public final DiffBasedSubStorageConfiguration toDomainObject() { + return ImmutableDiffBasedSubStorageConfiguration.builder() + .maxLayersToLoad(maxLayersToLoad) + .limitTrieLogsEnabled(limitTrieLogsEnabled) + .trieLogPruningWindowSize(trieLogPruningWindowSize) + .unstable( + ImmutableDiffBasedSubStorageConfiguration.DiffBasedUnstable.builder() + .fullFlatDbEnabled(unstableOptions.fullFlatDbEnabled) + .codeStoredByCodeHashEnabled(unstableOptions.codeUsingCodeHashEnabled) + .isParallelTxProcessingEnabled(unstableOptions.isParallelTxProcessingEnabled) + .build()) + .build(); + } + + @Override + public List getCLIOptions() { + return CommandLineUtils.getCLIOptions(this, new DiffBasedSubStorageOptions()); + } +} diff --git a/besu/src/main/java/org/hyperledger/besu/cli/options/unstable/MetricsCLIOptions.java b/besu/src/main/java/org/hyperledger/besu/cli/options/unstable/MetricsCLIOptions.java deleted file mode 100644 index 95164c31cc..0000000000 --- a/besu/src/main/java/org/hyperledger/besu/cli/options/unstable/MetricsCLIOptions.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright ConsenSys AG. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - */ -package org.hyperledger.besu.cli.options.unstable; - -import org.hyperledger.besu.cli.options.CLIOptions; -import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration; - -import java.util.Arrays; -import java.util.List; - -import picocli.CommandLine; - -/** The Metrics cli options. */ -public class MetricsCLIOptions implements CLIOptions { - private static final String TIMERS_ENABLED_FLAG = "--Xmetrics-timers-enabled"; - private static final String IDLE_TIMEOUT_FLAG = "--Xmetrics-idle-timeout"; - - @CommandLine.Option( - names = TIMERS_ENABLED_FLAG, - hidden = true, - description = "Whether to enable timer metrics (default: ${DEFAULT-VALUE}).") - private Boolean timersEnabled = MetricsConfiguration.DEFAULT_METRICS_TIMERS_ENABLED; - - @CommandLine.Option( - hidden = true, - names = {IDLE_TIMEOUT_FLAG}, - paramLabel = "", - description = "Timeout for metrics TCP connections, in seconds (default: ${DEFAULT-VALUE})", - arity = "1") - private int idleTimeout = MetricsConfiguration.DEFAULT_METRICS_IDLE_TIMEOUT_SECONDS; - - private MetricsCLIOptions() {} - - /** - * Create metrics cli options. - * - * @return the metrics cli options - */ - public static MetricsCLIOptions create() { - return new MetricsCLIOptions(); - } - - /** - * From configuration metrics cli options. - * - * @param config the config - * @return the metrics cli options - */ - public static MetricsCLIOptions fromConfiguration(final MetricsConfiguration config) { - final MetricsCLIOptions metricsOptions = create(); - metricsOptions.timersEnabled = config.isTimersEnabled(); - metricsOptions.idleTimeout = config.getIdleTimeout(); - return metricsOptions; - } - - @Override - public MetricsConfiguration.Builder toDomainObject() { - return MetricsConfiguration.builder().timersEnabled(timersEnabled).idleTimeout(idleTimeout); - } - - @Override - public List getCLIOptions() { - return Arrays.asList( - TIMERS_ENABLED_FLAG + "=" + timersEnabled.toString(), - IDLE_TIMEOUT_FLAG + "=" + idleTimeout); - } -} diff --git a/besu/src/main/java/org/hyperledger/besu/cli/options/stable/P2PTLSConfigOptions.java b/besu/src/main/java/org/hyperledger/besu/cli/options/unstable/P2PTLSConfigOptions.java similarity index 99% rename from besu/src/main/java/org/hyperledger/besu/cli/options/stable/P2PTLSConfigOptions.java rename to besu/src/main/java/org/hyperledger/besu/cli/options/unstable/P2PTLSConfigOptions.java index c3f8c56219..5939eb3d39 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/options/stable/P2PTLSConfigOptions.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/options/unstable/P2PTLSConfigOptions.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.cli.options.stable; +package org.hyperledger.besu.cli.options.unstable; import static java.util.Arrays.asList; import static org.hyperledger.besu.cli.DefaultCommandValues.DEFAULT_KEYSTORE_TYPE; diff --git a/besu/src/main/java/org/hyperledger/besu/cli/subcommands/PasswordSubCommand.java b/besu/src/main/java/org/hyperledger/besu/cli/subcommands/PasswordSubCommand.java index b35cc2f5cf..5f5e8c3fca 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/subcommands/PasswordSubCommand.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/subcommands/PasswordSubCommand.java @@ -23,6 +23,7 @@ import org.hyperledger.besu.cli.util.VersionProvider; import java.io.PrintWriter; +import jakarta.validation.constraints.NotEmpty; import org.springframework.security.crypto.bcrypt.BCrypt; import picocli.CommandLine.Command; import picocli.CommandLine.Model.CommandSpec; @@ -75,6 +76,7 @@ public class PasswordSubCommand implements Runnable { static class HashSubCommand implements Runnable { @SuppressWarnings({"FieldCanBeFinal", "FieldMayBeFinal"}) // PicoCLI requires non-final Strings. + @NotEmpty @Option( names = "--password", arity = "1..1", diff --git a/besu/src/main/java/org/hyperledger/besu/cli/subcommands/blocks/BlocksSubCommand.java b/besu/src/main/java/org/hyperledger/besu/cli/subcommands/blocks/BlocksSubCommand.java index 9a0a453768..5bd0aacee2 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/subcommands/blocks/BlocksSubCommand.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/subcommands/blocks/BlocksSubCommand.java @@ -54,6 +54,7 @@ import java.util.function.Function; import java.util.function.Supplier; import io.vertx.core.Vertx; +import jakarta.validation.constraints.NotBlank; import org.apache.tuweni.bytes.Bytes; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -335,6 +336,7 @@ public class BlocksSubCommand implements Runnable { arity = "1..1") private final BlockExportFormat format = BlockExportFormat.RLP; + @NotBlank @Option( names = "--to", required = true, diff --git a/besu/src/main/java/org/hyperledger/besu/cli/subcommands/operator/BackupState.java b/besu/src/main/java/org/hyperledger/besu/cli/subcommands/operator/BackupState.java index 793c817e52..efd924e5e2 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/subcommands/operator/BackupState.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/subcommands/operator/BackupState.java @@ -33,6 +33,7 @@ import java.util.Optional; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.LockSupport; +import jakarta.validation.constraints.NotBlank; import picocli.CommandLine.Command; import picocli.CommandLine.Option; import picocli.CommandLine.ParentCommand; @@ -55,6 +56,7 @@ public class BackupState implements Runnable { arity = "1..1") private final Long block = Long.MAX_VALUE; + @NotBlank @Option( names = "--backup-path", required = true, diff --git a/besu/src/main/java/org/hyperledger/besu/cli/subcommands/operator/GenerateBlockchainConfig.java b/besu/src/main/java/org/hyperledger/besu/cli/subcommands/operator/GenerateBlockchainConfig.java index f53f3a8057..d71cf652a5 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/subcommands/operator/GenerateBlockchainConfig.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/subcommands/operator/GenerateBlockchainConfig.java @@ -52,6 +52,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.common.base.Supplier; import com.google.common.base.Suppliers; import com.google.common.io.Resources; +import jakarta.validation.constraints.NotBlank; import org.apache.tuweni.bytes.Bytes; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -70,6 +71,7 @@ class GenerateBlockchainConfig implements Runnable { private final Supplier SIGNATURE_ALGORITHM = Suppliers.memoize(SignatureAlgorithmFactory::getInstance); + @NotBlank @Option( required = true, names = "--config-file", @@ -78,6 +80,7 @@ class GenerateBlockchainConfig implements Runnable { arity = "1..1") private final File configurationFile = null; + @NotBlank @Option( required = true, names = "--to", diff --git a/besu/src/main/java/org/hyperledger/besu/cli/subcommands/operator/RestoreState.java b/besu/src/main/java/org/hyperledger/besu/cli/subcommands/operator/RestoreState.java index 52ee255d4f..6480380240 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/subcommands/operator/RestoreState.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/subcommands/operator/RestoreState.java @@ -46,6 +46,7 @@ import java.util.ArrayList; import java.util.List; import com.fasterxml.jackson.databind.node.ObjectNode; +import jakarta.validation.constraints.NotBlank; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; import org.slf4j.Logger; @@ -64,6 +65,7 @@ public class RestoreState implements Runnable { private static final Logger LOG = LoggerFactory.getLogger(RestoreState.class); + @NotBlank @Option( names = "--backup-path", required = true, diff --git a/besu/src/main/java/org/hyperledger/besu/cli/subcommands/storage/TrieLogHelper.java b/besu/src/main/java/org/hyperledger/besu/cli/subcommands/storage/TrieLogHelper.java index 6bcfe4d353..b96fdaca10 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/subcommands/storage/TrieLogHelper.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/subcommands/storage/TrieLogHelper.java @@ -15,21 +15,22 @@ package org.hyperledger.besu.cli.subcommands.storage; import static com.google.common.base.Preconditions.checkArgument; -import static org.hyperledger.besu.cli.options.stable.DataStorageOptions.BONSAI_STORAGE_FORMAT_MAX_LAYERS_TO_LOAD; +import static org.hyperledger.besu.cli.options.storage.DiffBasedSubStorageOptions.MAX_LAYERS_TO_LOAD; +import static org.hyperledger.besu.cli.options.storage.DiffBasedSubStorageOptions.TRIE_LOG_PRUNING_WINDOW_SIZE; import static org.hyperledger.besu.controller.BesuController.DATABASE_PATH; -import static org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration.DEFAULT_BONSAI_TRIE_LOG_PRUNING_WINDOW_SIZE; +import static org.hyperledger.besu.ethereum.worldstate.DiffBasedSubStorageConfiguration.DEFAULT_TRIE_LOG_PRUNING_WINDOW_SIZE; -import org.hyperledger.besu.cli.options.stable.DataStorageOptions; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.chain.Blockchain; import org.hyperledger.besu.ethereum.chain.MutableBlockchain; import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.rlp.BytesValueRLPInput; import org.hyperledger.besu.ethereum.rlp.RLP; -import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.BonsaiWorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.trielog.TrieLogFactoryImpl; +import org.hyperledger.besu.ethereum.trie.diffbased.common.storage.DiffBasedWorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.trie.diffbased.common.trielog.TrieLogLayer; import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; +import org.hyperledger.besu.ethereum.worldstate.DiffBasedSubStorageConfiguration; import java.io.File; import java.io.FileInputStream; @@ -64,7 +65,7 @@ public class TrieLogHelper { boolean prune( final DataStorageConfiguration config, - final BonsaiWorldStateKeyValueStorage rootWorldStateStorage, + final DiffBasedWorldStateKeyValueStorage rootWorldStateStorage, final MutableBlockchain blockchain, final Path dataDirectoryPath) { @@ -73,7 +74,7 @@ public class TrieLogHelper { validatePruneConfiguration(config); - final long layersToRetain = config.getBonsaiMaxLayersToLoad(); + final long layersToRetain = config.getDiffBasedSubStorageConfiguration().getMaxLayersToLoad(); final long chainHeight = blockchain.getChainHeadBlockNumber(); @@ -102,7 +103,7 @@ public class TrieLogHelper { // Should only be layersToRetain left but loading extra just in case of an unforeseen bug final long countAfterPrune = rootWorldStateStorage - .streamTrieLogKeys(layersToRetain + DEFAULT_BONSAI_TRIE_LOG_PRUNING_WINDOW_SIZE) + .streamTrieLogKeys(layersToRetain + DEFAULT_TRIE_LOG_PRUNING_WINDOW_SIZE) .count(); if (countAfterPrune == layersToRetain) { if (deleteFiles(batchFileNameBase, numberOfBatches)) { @@ -115,15 +116,12 @@ public class TrieLogHelper { throw new IllegalStateException( String.format( "Remaining trie logs (%d) did not match %s (%d). Trie logs backup files (in %s) have not been deleted, it is safe to rerun the subcommand.", - countAfterPrune, - BONSAI_STORAGE_FORMAT_MAX_LAYERS_TO_LOAD, - layersToRetain, - batchFileNameBase)); + countAfterPrune, MAX_LAYERS_TO_LOAD, layersToRetain, batchFileNameBase)); } } private void processTrieLogBatches( - final BonsaiWorldStateKeyValueStorage rootWorldStateStorage, + final DiffBasedWorldStateKeyValueStorage rootWorldStateStorage, final MutableBlockchain blockchain, final long chainHeight, final long lastBlockNumberToRetainTrieLogsFor, @@ -152,7 +150,7 @@ public class TrieLogHelper { private void saveTrieLogBatches( final String batchFileName, - final BonsaiWorldStateKeyValueStorage rootWorldStateStorage, + final DiffBasedWorldStateKeyValueStorage rootWorldStateStorage, final List trieLogKeys) { try { @@ -164,7 +162,7 @@ public class TrieLogHelper { } private void restoreTrieLogBatches( - final BonsaiWorldStateKeyValueStorage rootWorldStateStorage, + final DiffBasedWorldStateKeyValueStorage rootWorldStateStorage, final long batchNumber, final String batchFileNameBase) { @@ -217,7 +215,7 @@ public class TrieLogHelper { final MutableBlockchain blockchain, final long chainHeight, final long lastBlockNumberToRetainTrieLogsFor, - final BonsaiWorldStateKeyValueStorage rootWorldStateStorage, + final DiffBasedWorldStateKeyValueStorage rootWorldStateStorage, final long layersToRetain) { if (lastBlockNumberToRetainTrieLogsFor < 0) { @@ -231,7 +229,7 @@ public class TrieLogHelper { // plus extra threshold to account forks and orphans final long clampedCountBeforePruning = rootWorldStateStorage - .streamTrieLogKeys(layersToRetain + DEFAULT_BONSAI_TRIE_LOG_PRUNING_WINDOW_SIZE) + .streamTrieLogKeys(layersToRetain + DEFAULT_TRIE_LOG_PRUNING_WINDOW_SIZE) .count(); if (clampedCountBeforePruning < layersToRetain) { throw new IllegalArgumentException( @@ -257,7 +255,7 @@ public class TrieLogHelper { } private void recreateTrieLogs( - final BonsaiWorldStateKeyValueStorage rootWorldStateStorage, + final DiffBasedWorldStateKeyValueStorage rootWorldStateStorage, final long batchNumber, final String batchFileNameBase) throws IOException { @@ -277,7 +275,7 @@ public class TrieLogHelper { final int chunkSize, final List keys, final IdentityHashMap trieLogsToRetain, - final BonsaiWorldStateKeyValueStorage rootWorldStateStorage) { + final DiffBasedWorldStateKeyValueStorage rootWorldStateStorage) { var updater = rootWorldStateStorage.updater(); int endIndex = Math.min(startIndex + chunkSize, keys.size()); @@ -294,31 +292,31 @@ public class TrieLogHelper { @VisibleForTesting void validatePruneConfiguration(final DataStorageConfiguration config) { + final DiffBasedSubStorageConfiguration subStorageConfiguration = + config.getDiffBasedSubStorageConfiguration(); checkArgument( - config.getBonsaiMaxLayersToLoad() - >= DataStorageConfiguration.MINIMUM_BONSAI_TRIE_LOG_RETENTION_LIMIT, + subStorageConfiguration.getMaxLayersToLoad() + >= DiffBasedSubStorageConfiguration.MINIMUM_TRIE_LOG_RETENTION_LIMIT, String.format( - BONSAI_STORAGE_FORMAT_MAX_LAYERS_TO_LOAD + " minimum value is %d", - DataStorageConfiguration.MINIMUM_BONSAI_TRIE_LOG_RETENTION_LIMIT)); + MAX_LAYERS_TO_LOAD + " minimum value is %d", + DiffBasedSubStorageConfiguration.MINIMUM_TRIE_LOG_RETENTION_LIMIT)); checkArgument( - config.getBonsaiTrieLogPruningWindowSize() > 0, + subStorageConfiguration.getTrieLogPruningWindowSize() > 0, String.format( - DataStorageOptions.BONSAI_TRIE_LOG_PRUNING_WINDOW_SIZE + "=%d must be greater than 0", - config.getBonsaiTrieLogPruningWindowSize())); + TRIE_LOG_PRUNING_WINDOW_SIZE + "=%d must be greater than 0", + subStorageConfiguration.getTrieLogPruningWindowSize())); checkArgument( - config.getBonsaiTrieLogPruningWindowSize() > config.getBonsaiMaxLayersToLoad(), + subStorageConfiguration.getTrieLogPruningWindowSize() + > subStorageConfiguration.getMaxLayersToLoad(), String.format( - DataStorageOptions.BONSAI_TRIE_LOG_PRUNING_WINDOW_SIZE - + "=%d must be greater than " - + BONSAI_STORAGE_FORMAT_MAX_LAYERS_TO_LOAD - + "=%d", - config.getBonsaiTrieLogPruningWindowSize(), - config.getBonsaiMaxLayersToLoad())); + TRIE_LOG_PRUNING_WINDOW_SIZE + "=%d must be greater than " + MAX_LAYERS_TO_LOAD + "=%d", + subStorageConfiguration.getTrieLogPruningWindowSize(), + subStorageConfiguration.getMaxLayersToLoad())); } private void saveTrieLogsInFile( final List trieLogsKeys, - final BonsaiWorldStateKeyValueStorage rootWorldStateStorage, + final DiffBasedWorldStateKeyValueStorage rootWorldStateStorage, final String batchFileName) throws IOException { @@ -355,7 +353,7 @@ public class TrieLogHelper { private void saveTrieLogsAsRlpInFile( final List trieLogsKeys, - final BonsaiWorldStateKeyValueStorage rootWorldStateStorage, + final DiffBasedWorldStateKeyValueStorage rootWorldStateStorage, final String batchFileName) { File file = new File(batchFileName); if (file.exists()) { @@ -400,7 +398,8 @@ public class TrieLogHelper { } private IdentityHashMap getTrieLogs( - final List trieLogKeys, final BonsaiWorldStateKeyValueStorage rootWorldStateStorage) { + final List trieLogKeys, + final DiffBasedWorldStateKeyValueStorage rootWorldStateStorage) { IdentityHashMap trieLogsToRetain = new IdentityHashMap<>(); LOG.info("Obtaining trielogs from db, this may take a few minutes..."); @@ -413,7 +412,7 @@ public class TrieLogHelper { } TrieLogCount getCount( - final BonsaiWorldStateKeyValueStorage rootWorldStateStorage, + final DiffBasedWorldStateKeyValueStorage rootWorldStateStorage, final int limit, final Blockchain blockchain) { final AtomicInteger total = new AtomicInteger(); @@ -454,7 +453,7 @@ public class TrieLogHelper { } void importTrieLog( - final BonsaiWorldStateKeyValueStorage rootWorldStateStorage, final Path trieLogFilePath) { + final DiffBasedWorldStateKeyValueStorage rootWorldStateStorage, final Path trieLogFilePath) { var trieLog = readTrieLogsAsRlpFromFile(trieLogFilePath.toString()); @@ -464,7 +463,7 @@ public class TrieLogHelper { } void exportTrieLog( - final BonsaiWorldStateKeyValueStorage rootWorldStateStorage, + final DiffBasedWorldStateKeyValueStorage rootWorldStateStorage, final List trieLogHash, final Path directoryPath) throws IOException { diff --git a/besu/src/main/java/org/hyperledger/besu/cli/subcommands/storage/TrieLogSubCommand.java b/besu/src/main/java/org/hyperledger/besu/cli/subcommands/storage/TrieLogSubCommand.java index 6fe6d058b3..24636a01de 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/subcommands/storage/TrieLogSubCommand.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/subcommands/storage/TrieLogSubCommand.java @@ -29,6 +29,7 @@ import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.BonsaiWorldSt import org.hyperledger.besu.ethereum.trie.diffbased.common.trielog.TrieLogPruner; import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; import org.hyperledger.besu.ethereum.worldstate.ImmutableDataStorageConfiguration; +import org.hyperledger.besu.ethereum.worldstate.ImmutableDiffBasedSubStorageConfiguration; import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; import java.io.IOException; @@ -89,7 +90,11 @@ public class TrieLogSubCommand implements Runnable { .besuCommand .setupControllerBuilder() .dataStorageConfiguration( - ImmutableDataStorageConfiguration.copyOf(config).withBonsaiLimitTrieLogsEnabled(false)) + ImmutableDataStorageConfiguration.copyOf(config) + .withDiffBasedSubStorageConfiguration( + ImmutableDiffBasedSubStorageConfiguration.copyOf( + config.getDiffBasedSubStorageConfiguration()) + .withLimitTrieLogsEnabled(false))) .build(); } diff --git a/besu/src/main/java/org/hyperledger/besu/components/BesuCommandModule.java b/besu/src/main/java/org/hyperledger/besu/components/BesuCommandModule.java index 59e2d60bf3..e757fd62a2 100644 --- a/besu/src/main/java/org/hyperledger/besu/components/BesuCommandModule.java +++ b/besu/src/main/java/org/hyperledger/besu/components/BesuCommandModule.java @@ -20,7 +20,10 @@ import org.hyperledger.besu.chainexport.RlpBlockExporter; import org.hyperledger.besu.chainimport.JsonBlockImporter; import org.hyperledger.besu.chainimport.RlpBlockImporter; import org.hyperledger.besu.cli.BesuCommand; +import org.hyperledger.besu.cli.options.stable.P2PDiscoveryOptions; +import org.hyperledger.besu.cli.options.unstable.RPCOptions; import org.hyperledger.besu.controller.BesuController; +import org.hyperledger.besu.ethereum.p2p.discovery.P2PDiscoveryConfiguration; import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration; import org.hyperledger.besu.services.BesuPluginContextImpl; @@ -53,7 +56,6 @@ public class BesuCommandModule { new BesuPluginContextImpl(), System.getenv(), commandLogger); - besuCommand.toCommandLine(); return besuCommand; } @@ -63,6 +65,18 @@ public class BesuCommandModule { return provideFrom.metricsConfiguration(); } + @Provides + @Singleton + RPCOptions provideRPCOptions() { + return RPCOptions.create(); + } + + @Provides + @Singleton + P2PDiscoveryConfiguration provideP2PDiscoveryConfiguration() { + return new P2PDiscoveryOptions().toDomainObject(); + } + @Provides @Named("besuCommandLogger") @Singleton diff --git a/besu/src/main/java/org/hyperledger/besu/controller/BesuControllerBuilder.java b/besu/src/main/java/org/hyperledger/besu/controller/BesuControllerBuilder.java index 3dbd116b08..c9a0fb05d3 100644 --- a/besu/src/main/java/org/hyperledger/besu/controller/BesuControllerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/controller/BesuControllerBuilder.java @@ -91,6 +91,7 @@ import org.hyperledger.besu.ethereum.trie.diffbased.verkle.VerkleWorldStateProvi import org.hyperledger.besu.ethereum.trie.diffbased.verkle.storage.VerkleWorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.trie.forest.ForestWorldStateArchive; import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; +import org.hyperledger.besu.ethereum.worldstate.DiffBasedSubStorageConfiguration; import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; import org.hyperledger.besu.ethereum.worldstate.WorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.worldstate.WorldStatePreimageStorage; @@ -719,7 +720,7 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides ethPeers.snapServerPeersNeeded(false); } - protocolContext.setSynchronizer(Optional.of(synchronizer)); + protocolContext.setSynchronizer(synchronizer); final Optional maybeSnapProtocolManager = createSnapProtocolManager( @@ -743,15 +744,18 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides final JsonRpcMethods additionalJsonRpcMethodFactory = createAdditionalJsonRpcMethodFactory(protocolContext, protocolSchedule, miningParameters); - if (dataStorageConfiguration.getBonsaiLimitTrieLogsEnabled() - && DataStorageFormat.BONSAI.equals(dataStorageConfiguration.getDataStorageFormat())) { - final TrieLogManager trieLogManager = - ((BonsaiWorldStateProvider) worldStateArchive).getTrieLogManager(); - final BonsaiWorldStateKeyValueStorage worldStateKeyValueStorage = - worldStateStorageCoordinator.getStrategy(BonsaiWorldStateKeyValueStorage.class); - final TrieLogPruner trieLogPruner = - createTrieLogPruner(worldStateKeyValueStorage, blockchain, scheduler); - trieLogManager.subscribe(trieLogPruner); + if (DataStorageFormat.BONSAI.equals(dataStorageConfiguration.getDataStorageFormat())) { + final DiffBasedSubStorageConfiguration subStorageConfiguration = + dataStorageConfiguration.getDiffBasedSubStorageConfiguration(); + if (subStorageConfiguration.getLimitTrieLogsEnabled()) { + final TrieLogManager trieLogManager = + ((BonsaiWorldStateProvider) worldStateArchive).getTrieLogManager(); + final BonsaiWorldStateKeyValueStorage worldStateKeyValueStorage = + worldStateStorageCoordinator.getStrategy(BonsaiWorldStateKeyValueStorage.class); + final TrieLogPruner trieLogPruner = + createTrieLogPruner(worldStateKeyValueStorage, blockchain, scheduler); + trieLogManager.subscribe(trieLogPruner); + } } final List closeables = new ArrayList<>(); @@ -805,14 +809,15 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides final Blockchain blockchain, final EthScheduler scheduler) { final boolean isProofOfStake = genesisConfigOptions.getTerminalTotalDifficulty().isPresent(); - + final DiffBasedSubStorageConfiguration subStorageConfiguration = + dataStorageConfiguration.getDiffBasedSubStorageConfiguration(); final TrieLogPruner trieLogPruner = new TrieLogPruner( (BonsaiWorldStateKeyValueStorage) worldStateStorage, blockchain, scheduler::executeServiceTask, - dataStorageConfiguration.getBonsaiMaxLayersToLoad(), - dataStorageConfiguration.getBonsaiTrieLogPruningWindowSize(), + subStorageConfiguration.getMaxLayersToLoad(), + subStorageConfiguration.getTrieLogPruningWindowSize(), isProofOfStake, metricsSystem); trieLogPruner.initialize(); @@ -1094,10 +1099,14 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides case BONSAI -> { final BonsaiWorldStateKeyValueStorage worldStateKeyValueStorage = worldStateStorageCoordinator.getStrategy(BonsaiWorldStateKeyValueStorage.class); + yield new BonsaiWorldStateProvider( worldStateKeyValueStorage, blockchain, - Optional.of(dataStorageConfiguration.getBonsaiMaxLayersToLoad()), + Optional.of( + dataStorageConfiguration + .getDiffBasedSubStorageConfiguration() + .getMaxLayersToLoad()), bonsaiCachedMerkleTrieLoader, besuComponent.map(BesuComponent::getBesuPluginContext).orElse(null), evmConfiguration); @@ -1109,8 +1118,9 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides worldStateKeyValueStorage, blockchain, Optional.of( - dataStorageConfiguration - .getBonsaiMaxLayersToLoad()), // TODO having verkle configuration or generic + dataStorageConfiguration + .getDiffBasedSubStorageConfiguration() + .getMaxLayersToLoad()), besuComponent.map(BesuComponent::getBesuPluginContext).orElse(null), evmConfiguration); } diff --git a/besu/src/main/java/org/hyperledger/besu/controller/IbftBesuControllerBuilder.java b/besu/src/main/java/org/hyperledger/besu/controller/IbftBesuControllerBuilder.java index 58412029fc..738dcfc596 100644 --- a/besu/src/main/java/org/hyperledger/besu/controller/IbftBesuControllerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/controller/IbftBesuControllerBuilder.java @@ -253,9 +253,18 @@ public class IbftBesuControllerBuilder extends BftBesuControllerBuilder { .getValue() .getBlockPeriodSeconds())); - if (syncState.isInitialSyncPhaseDone()) { - ibftMiningCoordinator.enable(); - } + syncState.subscribeSyncStatus( + syncStatus -> { + if (syncState.syncTarget().isPresent()) { + // We're syncing so stop doing other stuff + LOG.info("Stopping IBFT mining coordinator while we are syncing"); + ibftMiningCoordinator.stop(); + } else { + LOG.info("Starting IBFT mining coordinator following sync"); + ibftMiningCoordinator.enable(); + ibftMiningCoordinator.start(); + } + }); syncState.subscribeCompletionReached( new BesuEvents.InitialSyncCompletionListener() { diff --git a/besu/src/main/java/org/hyperledger/besu/controller/QbftBesuControllerBuilder.java b/besu/src/main/java/org/hyperledger/besu/controller/QbftBesuControllerBuilder.java index 60eac17996..498435e4af 100644 --- a/besu/src/main/java/org/hyperledger/besu/controller/QbftBesuControllerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/controller/QbftBesuControllerBuilder.java @@ -301,9 +301,18 @@ public class QbftBesuControllerBuilder extends BftBesuControllerBuilder { .getEmptyBlockPeriodSeconds()); }); - if (syncState.isInitialSyncPhaseDone()) { - miningCoordinator.enable(); - } + syncState.subscribeSyncStatus( + syncStatus -> { + if (syncState.syncTarget().isPresent()) { + // We're syncing so stop doing other stuff + LOG.info("Stopping QBFT mining coordinator while we are syncing"); + miningCoordinator.stop(); + } else { + LOG.info("Starting QBFT mining coordinator following sync"); + miningCoordinator.enable(); + miningCoordinator.start(); + } + }); syncState.subscribeCompletionReached( new BesuEvents.InitialSyncCompletionListener() { diff --git a/besu/src/main/java/org/hyperledger/besu/services/BesuEventsImpl.java b/besu/src/main/java/org/hyperledger/besu/services/BesuEventsImpl.java index aeb7025872..1f1b7644f3 100644 --- a/besu/src/main/java/org/hyperledger/besu/services/BesuEventsImpl.java +++ b/besu/src/main/java/org/hyperledger/besu/services/BesuEventsImpl.java @@ -133,7 +133,7 @@ public class BesuEventsImpl implements BesuEvents { public long addTransactionDroppedListener( final TransactionDroppedListener transactionDroppedListener) { return transactionPool.subscribeDroppedTransactions( - transactionDroppedListener::onTransactionDropped); + (transaction, reason) -> transactionDroppedListener.onTransactionDropped(transaction)); } @Override diff --git a/besu/src/main/java/org/hyperledger/besu/services/TransactionPoolServiceImpl.java b/besu/src/main/java/org/hyperledger/besu/services/TransactionPoolServiceImpl.java index 16d033ac9e..b720b60b7c 100644 --- a/besu/src/main/java/org/hyperledger/besu/services/TransactionPoolServiceImpl.java +++ b/besu/src/main/java/org/hyperledger/besu/services/TransactionPoolServiceImpl.java @@ -14,9 +14,12 @@ */ package org.hyperledger.besu.services; +import org.hyperledger.besu.datatypes.PendingTransaction; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool; import org.hyperledger.besu.plugin.services.transactionpool.TransactionPoolService; +import java.util.Collection; + /** Service to enable and disable the transaction pool. */ public class TransactionPoolServiceImpl implements TransactionPoolService { @@ -40,4 +43,9 @@ public class TransactionPoolServiceImpl implements TransactionPoolService { public void enableTransactionPool() { transactionPool.setEnabled(); } + + @Override + public Collection getPendingTransactions() { + return transactionPool.getPendingTransactions(); + } } diff --git a/besu/src/main/java/org/hyperledger/besu/util/EphemeryGenesisUpdater.java b/besu/src/main/java/org/hyperledger/besu/util/EphemeryGenesisUpdater.java new file mode 100644 index 0000000000..0b970a6809 --- /dev/null +++ b/besu/src/main/java/org/hyperledger/besu/util/EphemeryGenesisUpdater.java @@ -0,0 +1,81 @@ +/* + * 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.util; + +import static org.hyperledger.besu.cli.config.NetworkName.EPHEMERY; + +import org.hyperledger.besu.config.GenesisConfigFile; + +import java.io.IOException; +import java.math.BigInteger; +import java.time.Instant; +import java.time.temporal.ChronoUnit; +import java.util.Map; +import java.util.Optional; + +/** + * The Generate Ephemery Genesis Updater. Checks for update based on the set period and update the + * Ephemery genesis in memory + */ +public class EphemeryGenesisUpdater { + private static final int PERIOD_IN_DAYS = 28; + private static final long PERIOD_IN_SECONDS = (PERIOD_IN_DAYS * 24 * 60 * 60); + + /** + * Constructor for EphemeryGenesisUpdater. Initializes the genesis updater for the Ephemery + * network. + */ + public EphemeryGenesisUpdater() {} + + /** + * Updates the Ephemery genesis configuration based on the predefined period. + * + * @param overrides a map of configuration overrides + * @return the updated GenesisConfigFile + * @throws RuntimeException if an error occurs during the update process + */ + public static GenesisConfigFile updateGenesis(final Map overrides) + throws RuntimeException { + GenesisConfigFile genesisConfigFile; + try { + if (EPHEMERY.getGenesisFile() == null) { + throw new IOException("Genesis file or config options are null"); + } + genesisConfigFile = GenesisConfigFile.fromResource(EPHEMERY.getGenesisFile()); + long genesisTimestamp = genesisConfigFile.getTimestamp(); + Optional genesisChainId = genesisConfigFile.getConfigOptions().getChainId(); + long currentTimestamp = Instant.now().getEpochSecond(); + long periodsSinceGenesis = + ChronoUnit.DAYS.between(Instant.ofEpochSecond(genesisTimestamp), Instant.now()) + / PERIOD_IN_DAYS; + + long updatedTimestamp = genesisTimestamp + (periodsSinceGenesis * PERIOD_IN_SECONDS); + BigInteger updatedChainId = + genesisChainId + .orElseThrow(() -> new IllegalStateException("ChainId not present")) + .add(BigInteger.valueOf(periodsSinceGenesis)); + // has a period elapsed since original ephemery genesis time? if so, override chainId and + // timestamp + if (currentTimestamp > (genesisTimestamp + PERIOD_IN_SECONDS)) { + overrides.put("chainId", String.valueOf(updatedChainId)); + overrides.put("timestamp", String.valueOf(updatedTimestamp)); + genesisConfigFile = genesisConfigFile.withOverrides(overrides); + } + return genesisConfigFile.withOverrides(overrides); + } catch (IOException e) { + throw new RuntimeException("Error updating ephemery genesis: " + e.getMessage(), e); + } + } +} diff --git a/besu/src/main/scripts/besu-entry.sh b/besu/src/main/scripts/besu-entry.sh index ee11bfbffc..55935504b0 100755 --- a/besu/src/main/scripts/besu-entry.sh +++ b/besu/src/main/scripts/besu-entry.sh @@ -1,6 +1,6 @@ #!/bin/bash ## -## Copyright contributors to Hyperledger Besu. +## Copyright contributors to 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 diff --git a/besu/src/test/java/org/hyperledger/besu/ForkIdsNetworkConfigTest.java b/besu/src/test/java/org/hyperledger/besu/ForkIdsNetworkConfigTest.java index 28d4c77036..5a58091577 100644 --- a/besu/src/test/java/org/hyperledger/besu/ForkIdsNetworkConfigTest.java +++ b/besu/src/test/java/org/hyperledger/besu/ForkIdsNetworkConfigTest.java @@ -15,6 +15,7 @@ package org.hyperledger.besu; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -46,20 +47,14 @@ import java.util.stream.Stream; import com.google.common.collect.Streams; import org.apache.tuweni.bytes.Bytes; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; +import org.mockito.junit.jupiter.MockitoExtension; -@RunWith(Parameterized.class) +@ExtendWith(MockitoExtension.class) public class ForkIdsNetworkConfigTest { - @Parameterized.Parameter public NetworkName chainName; - - @Parameterized.Parameter(1) - public List expectedForkIds; - - @Parameterized.Parameters(name = "{0}") public static Collection parameters() { return List.of( new Object[] { @@ -149,8 +144,8 @@ public class ForkIdsNetworkConfigTest { final AtomicLong blockNumber = new AtomicLong(); when(mockBlockchain.getChainHeadHeader()).thenReturn(mockBlockHeader); - when(mockBlockHeader.getNumber()).thenAnswer(o -> blockNumber.get()); - when(mockBlockHeader.getTimestamp()).thenAnswer(o -> blockNumber.get()); + lenient().when(mockBlockHeader.getNumber()).thenAnswer(o -> blockNumber.get()); + lenient().when(mockBlockHeader.getTimestamp()).thenAnswer(o -> blockNumber.get()); final ForkIdManager forkIdManager = new ForkIdManager( diff --git a/besu/src/test/java/org/hyperledger/besu/RunnerBuilderTest.java b/besu/src/test/java/org/hyperledger/besu/RunnerBuilderTest.java index c7180b958c..7c5579d471 100644 --- a/besu/src/test/java/org/hyperledger/besu/RunnerBuilderTest.java +++ b/besu/src/test/java/org/hyperledger/besu/RunnerBuilderTest.java @@ -24,7 +24,7 @@ import static org.mockito.Mockito.when; import org.hyperledger.besu.cli.config.EthNetworkConfig; import org.hyperledger.besu.config.GenesisConfigOptions; -import org.hyperledger.besu.config.MergeConfigOptions; +import org.hyperledger.besu.config.MergeConfiguration; import org.hyperledger.besu.consensus.common.bft.BftEventQueue; import org.hyperledger.besu.consensus.common.bft.network.PeerConnectionTracker; import org.hyperledger.besu.consensus.common.bft.protocol.BftProtocolManager; @@ -250,7 +250,7 @@ public final class RunnerBuilderTest { engine.setEnabled(true); final EthNetworkConfig mockMainnet = mock(EthNetworkConfig.class); when(mockMainnet.networkId()).thenReturn(BigInteger.ONE); - MergeConfigOptions.setMergeEnabled(true); + MergeConfiguration.setMergeEnabled(true); when(besuController.getMiningCoordinator()).thenReturn(mock(MergeMiningCoordinator.class)); final Runner runner = @@ -292,7 +292,7 @@ public final class RunnerBuilderTest { wsRpc.setEnabled(true); final EthNetworkConfig mockMainnet = mock(EthNetworkConfig.class); when(mockMainnet.networkId()).thenReturn(BigInteger.ONE); - MergeConfigOptions.setMergeEnabled(true); + MergeConfiguration.setMergeEnabled(true); when(besuController.getMiningCoordinator()).thenReturn(mock(MergeMiningCoordinator.class)); final JsonRpcConfiguration engineConf = JsonRpcConfiguration.createEngineDefault(); engineConf.setEnabled(true); @@ -335,7 +335,7 @@ public final class RunnerBuilderTest { wsRpc.setEnabled(true); final EthNetworkConfig mockMainnet = mock(EthNetworkConfig.class); when(mockMainnet.networkId()).thenReturn(BigInteger.ONE); - MergeConfigOptions.setMergeEnabled(true); + MergeConfiguration.setMergeEnabled(true); when(besuController.getMiningCoordinator()).thenReturn(mock(MergeMiningCoordinator.class)); final JsonRpcConfiguration engineConf = JsonRpcConfiguration.createEngineDefault(); engineConf.setEnabled(true); @@ -383,7 +383,7 @@ public final class RunnerBuilderTest { defaultWebSockConfig.setEnabled(true); final EthNetworkConfig mockMainnet = mock(EthNetworkConfig.class); when(mockMainnet.networkId()).thenReturn(BigInteger.ONE); - MergeConfigOptions.setMergeEnabled(true); + MergeConfiguration.setMergeEnabled(true); final Runner runner = new RunnerBuilder() diff --git a/besu/src/test/java/org/hyperledger/besu/RunnerTest.java b/besu/src/test/java/org/hyperledger/besu/RunnerTest.java index 5fefc7ef22..cbbf980408 100644 --- a/besu/src/test/java/org/hyperledger/besu/RunnerTest.java +++ b/besu/src/test/java/org/hyperledger/besu/RunnerTest.java @@ -28,7 +28,7 @@ import org.hyperledger.besu.cli.config.EthNetworkConfig; import org.hyperledger.besu.components.BesuComponent; import org.hyperledger.besu.config.GenesisConfigFile; import org.hyperledger.besu.config.JsonUtil; -import org.hyperledger.besu.config.MergeConfigOptions; +import org.hyperledger.besu.config.MergeConfiguration; import org.hyperledger.besu.controller.BesuController; import org.hyperledger.besu.controller.MainnetBesuControllerBuilder; import org.hyperledger.besu.crypto.KeyPairUtil; @@ -151,7 +151,7 @@ public final class RunnerTest { @Test public void fullSyncFromGenesis() throws Exception { // set merge flag to false, otherwise this test can fail if a merge test runs first - MergeConfigOptions.setMergeEnabled(false); + MergeConfiguration.setMergeEnabled(false); syncFromGenesis(SyncMode.FULL, getFastSyncGenesis()); } @@ -159,7 +159,7 @@ public final class RunnerTest { @Test public void fastSyncFromGenesis() throws Exception { // set merge flag to false, otherwise this test can fail if a merge test runs first - MergeConfigOptions.setMergeEnabled(false); + MergeConfiguration.setMergeEnabled(false); syncFromGenesis(SyncMode.FAST, getFastSyncGenesis()); } diff --git a/besu/src/test/java/org/hyperledger/besu/chainimport/RlpBlockImporterTest.java b/besu/src/test/java/org/hyperledger/besu/chainimport/RlpBlockImporterTest.java index 7d4fabb222..2d9e587c3f 100644 --- a/besu/src/test/java/org/hyperledger/besu/chainimport/RlpBlockImporterTest.java +++ b/besu/src/test/java/org/hyperledger/besu/chainimport/RlpBlockImporterTest.java @@ -21,7 +21,7 @@ import static org.mockito.Mockito.mock; import org.hyperledger.besu.cli.config.EthNetworkConfig; import org.hyperledger.besu.cli.config.NetworkName; import org.hyperledger.besu.components.BesuComponent; -import org.hyperledger.besu.config.MergeConfigOptions; +import org.hyperledger.besu.config.MergeConfiguration; import org.hyperledger.besu.controller.BesuController; import org.hyperledger.besu.cryptoservices.NodeKeyUtils; import org.hyperledger.besu.ethereum.GasLimitCalculator; @@ -91,7 +91,7 @@ public final class RlpBlockImporterTest { @Test public void blockImportRejectsBadPow() throws IOException { // set merge flag to false, otherwise this test can fail if a merge test runs first - MergeConfigOptions.setMergeEnabled(false); + MergeConfiguration.setMergeEnabled(false); final Path source = dataDir.resolve("badpow.blocks"); BlockTestUtil.writeBadPowBlocks(source); diff --git a/besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java b/besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java index 99b45ada1b..019e8d83cd 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java @@ -16,9 +16,9 @@ package org.hyperledger.besu.cli; import static java.nio.charset.StandardCharsets.UTF_8; import static org.assertj.core.api.Assertions.assertThat; -import static org.hamcrest.Matchers.is; import static org.hyperledger.besu.cli.config.NetworkName.CLASSIC; import static org.hyperledger.besu.cli.config.NetworkName.DEV; +import static org.hyperledger.besu.cli.config.NetworkName.EPHEMERY; import static org.hyperledger.besu.cli.config.NetworkName.EXPERIMENTAL_EIPS; import static org.hyperledger.besu.cli.config.NetworkName.FUTURE_EIPS; import static org.hyperledger.besu.cli.config.NetworkName.HOLESKY; @@ -32,7 +32,7 @@ import static org.hyperledger.besu.ethereum.p2p.config.DefaultDiscoveryConfigura import static org.hyperledger.besu.ethereum.p2p.config.DefaultDiscoveryConfiguration.SEPOLIA_BOOTSTRAP_NODES; import static org.hyperledger.besu.ethereum.p2p.config.DefaultDiscoveryConfiguration.SEPOLIA_DISCOVERY_URL; import static org.hyperledger.besu.plugin.services.storage.DataStorageFormat.BONSAI; -import static org.junit.Assume.assumeThat; +import static org.junit.jupiter.api.Assumptions.assumeTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.contains; import static org.mockito.ArgumentMatchers.eq; @@ -43,8 +43,9 @@ import static org.mockito.Mockito.verify; import org.hyperledger.besu.BesuInfo; import org.hyperledger.besu.cli.config.EthNetworkConfig; +import org.hyperledger.besu.cli.config.NetworkName; import org.hyperledger.besu.config.GenesisConfigFile; -import org.hyperledger.besu.config.MergeConfigOptions; +import org.hyperledger.besu.config.MergeConfiguration; import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.Wei; @@ -162,13 +163,13 @@ public class BesuCommandTest extends CommandTestAbstract { // and ignore errors in case no trusted setup was already loaded } - MergeConfigOptions.setMergeEnabled(false); + MergeConfiguration.setMergeEnabled(false); } @AfterEach public void tearDown() { - MergeConfigOptions.setMergeEnabled(false); + MergeConfiguration.setMergeEnabled(false); } @Test @@ -1012,7 +1013,7 @@ public class BesuCommandTest extends CommandTestAbstract { } @Test - public void p2pHostAndPortOptionsAreRespected() { + public void p2pHostAndPortOptionsAreRespectedAndNotLeaked() { final String host = "1.2.3.4"; final int port = 1234; @@ -1020,6 +1021,8 @@ public class BesuCommandTest extends CommandTestAbstract { verify(mockRunnerBuilder).p2pAdvertisedHost(stringArgumentCaptor.capture()); verify(mockRunnerBuilder).p2pListenPort(intArgumentCaptor.capture()); + verify(mockRunnerBuilder).metricsConfiguration(metricsConfigArgumentCaptor.capture()); + verify(mockRunnerBuilder).jsonRpcConfiguration(jsonRpcConfigArgumentCaptor.capture()); verify(mockRunnerBuilder).build(); assertThat(stringArgumentCaptor.getValue()).isEqualTo(host); @@ -1027,6 +1030,48 @@ public class BesuCommandTest extends CommandTestAbstract { assertThat(commandOutput.toString(UTF_8)).isEmpty(); assertThat(commandErrorOutput.toString(UTF_8)).isEmpty(); + + // all other port values remain default + assertThat(metricsConfigArgumentCaptor.getValue().getPort()).isEqualTo(9545); + assertThat(metricsConfigArgumentCaptor.getValue().getPushPort()).isEqualTo(9001); + assertThat(jsonRpcConfigArgumentCaptor.getValue().getPort()).isEqualTo(8545); + + // all other host values remain default + final String defaultHost = "127.0.0.1"; + assertThat(metricsConfigArgumentCaptor.getValue().getHost()).isEqualTo(defaultHost); + assertThat(metricsConfigArgumentCaptor.getValue().getPushHost()).isEqualTo(defaultHost); + assertThat(jsonRpcConfigArgumentCaptor.getValue().getHost()).isEqualTo(defaultHost); + } + + @Test + public void p2pHostAndPortOptionsAreRespectedAndNotLeakedWithMetricsEnabled() { + + final String host = "1.2.3.4"; + final int port = 1234; + parseCommand("--p2p-host", host, "--p2p-port", String.valueOf(port), "--metrics-enabled"); + + verify(mockRunnerBuilder).p2pAdvertisedHost(stringArgumentCaptor.capture()); + verify(mockRunnerBuilder).p2pListenPort(intArgumentCaptor.capture()); + verify(mockRunnerBuilder).metricsConfiguration(metricsConfigArgumentCaptor.capture()); + verify(mockRunnerBuilder).jsonRpcConfiguration(jsonRpcConfigArgumentCaptor.capture()); + verify(mockRunnerBuilder).build(); + + assertThat(stringArgumentCaptor.getValue()).isEqualTo(host); + assertThat(intArgumentCaptor.getValue()).isEqualTo(port); + + assertThat(commandOutput.toString(UTF_8)).isEmpty(); + assertThat(commandErrorOutput.toString(UTF_8)).isEmpty(); + + // all other port values remain default + assertThat(metricsConfigArgumentCaptor.getValue().getPort()).isEqualTo(9545); + assertThat(metricsConfigArgumentCaptor.getValue().getPushPort()).isEqualTo(9001); + assertThat(jsonRpcConfigArgumentCaptor.getValue().getPort()).isEqualTo(8545); + + // all other host values remain default + final String defaultHost = "127.0.0.1"; + assertThat(metricsConfigArgumentCaptor.getValue().getHost()).isEqualTo(defaultHost); + assertThat(metricsConfigArgumentCaptor.getValue().getPushHost()).isEqualTo(defaultHost); + assertThat(jsonRpcConfigArgumentCaptor.getValue().getHost()).isEqualTo(defaultHost); } @Test @@ -1345,7 +1390,7 @@ public class BesuCommandTest extends CommandTestAbstract { } @Test - public void bonsaiLimitTrieLogsEnabledByDefault() { + public void diffbasedLimitTrieLogsEnabledByDefault() { parseCommand(); verify(mockControllerBuilder) .dataStorageConfiguration(dataStorageConfigurationArgumentCaptor.capture()); @@ -1353,7 +1398,11 @@ public class BesuCommandTest extends CommandTestAbstract { final DataStorageConfiguration dataStorageConfiguration = dataStorageConfigurationArgumentCaptor.getValue(); assertThat(dataStorageConfiguration.getDataStorageFormat()).isEqualTo(BONSAI); - assertThat(dataStorageConfiguration.getBonsaiLimitTrieLogsEnabled()).isTrue(); + assertThat( + dataStorageConfiguration + .getDiffBasedSubStorageConfiguration() + .getLimitTrieLogsEnabled()) + .isTrue(); assertThat(commandOutput.toString(UTF_8)).isEmpty(); assertThat(commandErrorOutput.toString(UTF_8)).isEmpty(); } @@ -1368,7 +1417,11 @@ public class BesuCommandTest extends CommandTestAbstract { final DataStorageConfiguration dataStorageConfiguration = dataStorageConfigurationArgumentCaptor.getValue(); assertThat(dataStorageConfiguration.getDataStorageFormat()).isEqualTo(BONSAI); - assertThat(dataStorageConfiguration.getBonsaiLimitTrieLogsEnabled()).isFalse(); + assertThat( + dataStorageConfiguration + .getDiffBasedSubStorageConfiguration() + .getLimitTrieLogsEnabled()) + .isFalse(); verify(mockLogger) .warn( "Forcing {}, since it cannot be enabled with --sync-mode={} and --data-storage-format={}.", @@ -1403,7 +1456,8 @@ public class BesuCommandTest extends CommandTestAbstract { final DataStorageConfiguration dataStorageConfiguration = dataStorageConfigurationArgumentCaptor.getValue(); assertThat(dataStorageConfiguration.getDataStorageFormat()).isEqualTo(BONSAI); - assertThat(dataStorageConfiguration.getBonsaiMaxLayersToLoad()).isEqualTo(11); + assertThat(dataStorageConfiguration.getDiffBasedSubStorageConfiguration().getMaxLayersToLoad()) + .isEqualTo(11); assertThat(commandOutput.toString(UTF_8)).isEmpty(); assertThat(commandErrorOutput.toString(UTF_8)).isEmpty(); } @@ -1863,6 +1917,20 @@ public class BesuCommandTest extends CommandTestAbstract { assertThat(commandErrorOutput.toString(UTF_8)).isEmpty(); } + @Test + public void ephemeryValuesAreUsed() { + parseCommand("--network", "ephemery"); + + final ArgumentCaptor networkArg = + ArgumentCaptor.forClass(EthNetworkConfig.class); + + verify(mockControllerBuilderFactory).fromEthNetworkConfig(networkArg.capture(), any()); + verify(mockControllerBuilder).build(); + assertThat(NetworkName.valueOf(String.valueOf(EPHEMERY))).isEqualTo(EPHEMERY); + assertThat(commandOutput.toString(UTF_8)).isEmpty(); + assertThat(commandErrorOutput.toString(UTF_8)).isEmpty(); + } + @Test public void classicValuesAreUsed() { parseCommand("--network", "classic"); @@ -2263,7 +2331,7 @@ public class BesuCommandTest extends CommandTestAbstract { } @Test - public void staticNodesFileOptionValidParamenter() throws IOException { + public void staticNodesFileOptionValidParameter() throws IOException { final Path staticNodeTempFile = createTempFile( "static-nodes-goodformat.json", @@ -2332,7 +2400,7 @@ public class BesuCommandTest extends CommandTestAbstract { @Test public void logsWarningWhenFailToLoadJemalloc() { - assumeThat(PlatformDetector.getOSType(), is("linux")); + assumeTrue(PlatformDetector.getOSType().equals("linux")); setEnvironmentVariable("BESU_USING_JEMALLOC", "true"); parseCommand(); verify(mockLogger) @@ -2344,7 +2412,7 @@ public class BesuCommandTest extends CommandTestAbstract { @Test public void logsSuggestInstallingJemallocWhenEnvVarNotPresent() { - assumeThat(PlatformDetector.getOSType(), is("linux")); + assumeTrue(PlatformDetector.getOSType().equals("linux")); parseCommand(); verify(mockLogger) .info("jemalloc library not found, memory usage may be reduced by installing it"); @@ -2492,8 +2560,9 @@ public class BesuCommandTest extends CommandTestAbstract { besuCommand .getDataStorageOptions() .toDomainObject() + .getDiffBasedSubStorageConfiguration() .getUnstable() - .getBonsaiFullFlatDbEnabled()) + .getFullFlatDbEnabled()) .isTrue(); } @@ -2504,8 +2573,9 @@ public class BesuCommandTest extends CommandTestAbstract { besuCommand .dataStorageOptions .toDomainObject() + .getDiffBasedSubStorageConfiguration() .getUnstable() - .getBonsaiFullFlatDbEnabled()) + .getFullFlatDbEnabled()) .isFalse(); } diff --git a/besu/src/test/java/org/hyperledger/besu/cli/CommandTestAbstract.java b/besu/src/test/java/org/hyperledger/besu/cli/CommandTestAbstract.java index 65e51c9213..5c7bf3ce88 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/CommandTestAbstract.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/CommandTestAbstract.java @@ -36,10 +36,9 @@ import org.hyperledger.besu.chainimport.RlpBlockImporter; import org.hyperledger.besu.cli.config.EthNetworkConfig; import org.hyperledger.besu.cli.options.MiningOptions; import org.hyperledger.besu.cli.options.TransactionPoolOptions; -import org.hyperledger.besu.cli.options.stable.DataStorageOptions; import org.hyperledger.besu.cli.options.stable.EthstatsOptions; +import org.hyperledger.besu.cli.options.storage.DataStorageOptions; import org.hyperledger.besu.cli.options.unstable.EthProtocolOptions; -import org.hyperledger.besu.cli.options.unstable.MetricsCLIOptions; import org.hyperledger.besu.cli.options.unstable.NetworkingOptions; import org.hyperledger.besu.cli.options.unstable.SynchronizerOptions; import org.hyperledger.besu.components.BesuComponent; @@ -114,6 +113,7 @@ import io.opentelemetry.api.GlobalOpenTelemetry; import io.vertx.core.Vertx; import io.vertx.core.VertxOptions; import io.vertx.core.json.JsonObject; +import jakarta.validation.constraints.NotEmpty; import org.apache.commons.net.util.SubnetUtils.SubnetInfo; import org.apache.commons.text.StringEscapeUtils; import org.apache.tuweni.bytes.Bytes; @@ -610,10 +610,6 @@ public abstract class CommandTestAbstract { return dataStorageOptions; } - public MetricsCLIOptions getMetricsCLIOptions() { - return unstableMetricsCLIOptions; - } - public void close() { if (vertx != null) { final AtomicBoolean closed = new AtomicBoolean(false); @@ -626,6 +622,7 @@ public abstract class CommandTestAbstract { @CommandLine.Command public static class TestBesuCommandWithRequiredOption extends TestBesuCommand { + @NotEmpty @CommandLine.Option( names = {"--accept-terms-and-conditions"}, description = "You must explicitly accept terms and conditions", diff --git a/besu/src/test/java/org/hyperledger/besu/cli/ConfigurationOverviewBuilderTest.java b/besu/src/test/java/org/hyperledger/besu/cli/ConfigurationOverviewBuilderTest.java index 841c668000..c2717afc0a 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/ConfigurationOverviewBuilderTest.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/ConfigurationOverviewBuilderTest.java @@ -95,6 +95,16 @@ class ConfigurationOverviewBuilderTest { assertThat(syncModeSet).contains("Sync mode: fast"); } + @Test + void setSyncMinPeers() { + final String noSyncMinPeersSet = builder.build(); + assertThat(noSyncMinPeersSet).doesNotContain("Sync min peers:"); + + builder.setSyncMinPeers(3); + final String syncMinPeersSet = builder.build(); + assertThat(syncMinPeersSet).contains("Sync min peers: 3"); + } + @Test void setRpcPort() { final String noRpcPortSet = builder.build(); @@ -152,7 +162,7 @@ class ConfigurationOverviewBuilderTest { } @Test - void setBonsaiLimitTrieLogsEnabled() { + void setDiffbasedLimitTrieLogsEnabled() { final String noTrieLogRetentionLimitSet = builder.build(); assertThat(noTrieLogRetentionLimitSet).doesNotContain("Limit trie logs enabled"); diff --git a/besu/src/test/java/org/hyperledger/besu/cli/NetworkDeprecationMessageTest.java b/besu/src/test/java/org/hyperledger/besu/cli/NetworkDeprecationMessageTest.java index 87be2a699e..649560d111 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/NetworkDeprecationMessageTest.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/NetworkDeprecationMessageTest.java @@ -39,9 +39,7 @@ class NetworkDeprecationMessageTest { @ParameterizedTest @EnumSource( value = NetworkName.class, - names = { - "MAINNET", "SEPOLIA", "DEV", "CLASSIC", "MORDOR", "HOLESKY", "LUKSO", - }) + names = {"MAINNET", "SEPOLIA", "DEV", "CLASSIC", "MORDOR", "HOLESKY", "LUKSO", "EPHEMERY"}) void shouldThrowErrorForNonDeprecatedNetworks(final NetworkName network) { assertThatThrownBy(() -> NetworkDeprecationMessage.generate(network)) .isInstanceOf(AssertionError.class); diff --git a/besu/src/test/java/org/hyperledger/besu/cli/PrivacyOptionsTest.java b/besu/src/test/java/org/hyperledger/besu/cli/PrivacyOptionsTest.java index af43535a8f..6a2c376436 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/PrivacyOptionsTest.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/PrivacyOptionsTest.java @@ -16,8 +16,7 @@ package org.hyperledger.besu.cli; import static java.nio.charset.StandardCharsets.UTF_8; import static org.assertj.core.api.Assertions.assertThat; -import static org.hamcrest.Matchers.startsWith; -import static org.junit.Assume.assumeThat; +import static org.junit.jupiter.api.Assumptions.assumeTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -415,10 +414,9 @@ public class PrivacyOptionsTest extends CommandTestAbstract { @Test public void privEnclaveKeyFileDoesNotExist() { - assumeThat( - "Ignored if system language is not English", - System.getProperty("user.language"), - startsWith("en")); + assumeTrue( + System.getProperty("user.language").startsWith("en"), + "Ignored if system language is not English"); parseCommand("--privacy-enabled=true", "--privacy-public-key-file", "/non/existent/file"); assertThat(commandOutput.toString(UTF_8)).isEmpty(); diff --git a/besu/src/test/java/org/hyperledger/besu/cli/options/AbstractCLIOptionsTest.java b/besu/src/test/java/org/hyperledger/besu/cli/options/AbstractCLIOptionsTest.java index 1760b957ec..b88491451f 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/options/AbstractCLIOptionsTest.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/options/AbstractCLIOptionsTest.java @@ -64,7 +64,6 @@ public abstract class AbstractCLIOptionsTest> private void getCLIOptions(final D domainObject) { T options = optionsFromDomainObject(domainObject); final String[] cliOptions = options.getCLIOptions().toArray(new String[0]); - final TestBesuCommand cmd = parseCommand(cliOptions); final T optionsFromCommand = getOptionsFromBesuCommand(cmd); diff --git a/besu/src/test/java/org/hyperledger/besu/cli/options/MetricsCLIOptionsTest.java b/besu/src/test/java/org/hyperledger/besu/cli/options/MetricsOptionsTest.java similarity index 78% rename from besu/src/test/java/org/hyperledger/besu/cli/options/MetricsCLIOptionsTest.java rename to besu/src/test/java/org/hyperledger/besu/cli/options/MetricsOptionsTest.java index e88462216f..992dcc437d 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/options/MetricsCLIOptionsTest.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/options/MetricsOptionsTest.java @@ -14,15 +14,15 @@ */ package org.hyperledger.besu.cli.options; -import org.hyperledger.besu.cli.options.unstable.MetricsCLIOptions; +import org.hyperledger.besu.cli.options.stable.MetricsOptions; import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.junit.jupiter.MockitoExtension; @ExtendWith(MockitoExtension.class) -public class MetricsCLIOptionsTest - extends AbstractCLIOptionsTest { +public class MetricsOptionsTest + extends AbstractCLIOptionsTest { @Override protected MetricsConfiguration.Builder createDefaultDomainObject() { @@ -37,13 +37,13 @@ public class MetricsCLIOptionsTest } @Override - protected MetricsCLIOptions optionsFromDomainObject( + protected MetricsOptions optionsFromDomainObject( final MetricsConfiguration.Builder domainObject) { - return MetricsCLIOptions.fromConfiguration(domainObject.build()); + return MetricsOptions.fromConfiguration(domainObject.build()); } @Override - protected MetricsCLIOptions getOptionsFromBesuCommand(final TestBesuCommand besuCommand) { - return besuCommand.getMetricsCLIOptions(); + protected MetricsOptions getOptionsFromBesuCommand(final TestBesuCommand besuCommand) { + return besuCommand.getMetricsOptions(); } } diff --git a/besu/src/test/java/org/hyperledger/besu/cli/options/stable/DataStorageOptionsTest.java b/besu/src/test/java/org/hyperledger/besu/cli/options/stable/DataStorageOptionsTest.java index 29fa3d6607..b9dc4fa927 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/options/stable/DataStorageOptionsTest.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/options/stable/DataStorageOptionsTest.java @@ -15,11 +15,13 @@ package org.hyperledger.besu.cli.options.stable; import static org.assertj.core.api.Assertions.assertThat; -import static org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration.MINIMUM_BONSAI_TRIE_LOG_RETENTION_LIMIT; +import static org.hyperledger.besu.ethereum.worldstate.DiffBasedSubStorageConfiguration.MINIMUM_TRIE_LOG_RETENTION_LIMIT; import org.hyperledger.besu.cli.options.AbstractCLIOptionsTest; +import org.hyperledger.besu.cli.options.storage.DataStorageOptions; import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; import org.hyperledger.besu.ethereum.worldstate.ImmutableDataStorageConfiguration; +import org.hyperledger.besu.ethereum.worldstate.ImmutableDiffBasedSubStorageConfiguration; import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; import org.junit.jupiter.api.Test; @@ -31,7 +33,11 @@ public class DataStorageOptionsTest public void bonsaiTrieLogPruningLimitOption() { internalTestSuccess( dataStorageConfiguration -> - assertThat(dataStorageConfiguration.getBonsaiTrieLogPruningWindowSize()).isEqualTo(600), + assertThat( + dataStorageConfiguration + .getDiffBasedSubStorageConfiguration() + .getTrieLogPruningWindowSize()) + .isEqualTo(600), "--bonsai-limit-trie-logs-enabled", "--bonsai-trie-logs-pruning-window-size", "600"); @@ -41,7 +47,11 @@ public class DataStorageOptionsTest public void bonsaiTrieLogPruningLimitLegacyOption() { internalTestSuccess( dataStorageConfiguration -> - assertThat(dataStorageConfiguration.getBonsaiTrieLogPruningWindowSize()).isEqualTo(600), + assertThat( + dataStorageConfiguration + .getDiffBasedSubStorageConfiguration() + .getTrieLogPruningWindowSize()) + .isEqualTo(600), "--Xbonsai-limit-trie-logs-enabled", "--Xbonsai-trie-logs-pruning-window-size", "600"); @@ -51,12 +61,16 @@ public class DataStorageOptionsTest public void bonsaiTrieLogsEnabled_explicitlySetToFalse() { internalTestSuccess( dataStorageConfiguration -> - assertThat(dataStorageConfiguration.getBonsaiLimitTrieLogsEnabled()).isEqualTo(false), + assertThat( + dataStorageConfiguration + .getDiffBasedSubStorageConfiguration() + .getLimitTrieLogsEnabled()) + .isEqualTo(false), "--bonsai-limit-trie-logs-enabled=false"); } @Test - public void bonsaiTrieLogPruningWindowSizeShouldBePositive() { + public void diffbasedTrieLogPruningWindowSizeShouldBePositive() { internalTestFailure( "--bonsai-trie-logs-pruning-window-size=0 must be greater than 0", "--bonsai-limit-trie-logs-enabled", @@ -65,7 +79,7 @@ public class DataStorageOptionsTest } @Test - public void bonsaiTrieLogPruningWindowSizeShouldBeAboveRetentionLimit() { + public void diffbasedTrieLogPruningWindowSizeShouldBeAboveRetentionLimit() { internalTestFailure( "--bonsai-trie-logs-pruning-window-size=512 must be greater than --bonsai-historical-block-limit=512", "--bonsai-limit-trie-logs-enabled", @@ -77,8 +91,11 @@ public class DataStorageOptionsTest public void bonsaiTrieLogRetentionLimitOption() { internalTestSuccess( dataStorageConfiguration -> - assertThat(dataStorageConfiguration.getBonsaiMaxLayersToLoad()) - .isEqualTo(MINIMUM_BONSAI_TRIE_LOG_RETENTION_LIMIT + 1), + assertThat( + dataStorageConfiguration + .getDiffBasedSubStorageConfiguration() + .getMaxLayersToLoad()) + .isEqualTo(MINIMUM_TRIE_LOG_RETENTION_LIMIT + 1), "--bonsai-limit-trie-logs-enabled", "--bonsai-historical-block-limit", "513"); @@ -88,8 +105,11 @@ public class DataStorageOptionsTest public void bonsaiTrieLogRetentionLimitOption_boundaryTest() { internalTestSuccess( dataStorageConfiguration -> - assertThat(dataStorageConfiguration.getBonsaiMaxLayersToLoad()) - .isEqualTo(MINIMUM_BONSAI_TRIE_LOG_RETENTION_LIMIT), + assertThat( + dataStorageConfiguration + .getDiffBasedSubStorageConfiguration() + .getMaxLayersToLoad()) + .isEqualTo(MINIMUM_TRIE_LOG_RETENTION_LIMIT), "--bonsai-limit-trie-logs-enabled", "--bonsai-historical-block-limit", "512"); @@ -105,22 +125,28 @@ public class DataStorageOptionsTest } @Test - public void bonsaiCodeUsingCodeHashEnabledCanBeEnabled() { + public void diffbasedCodeUsingCodeHashEnabledCanBeEnabled() { internalTestSuccess( dataStorageConfiguration -> assertThat( - dataStorageConfiguration.getUnstable().getBonsaiCodeStoredByCodeHashEnabled()) + dataStorageConfiguration + .getDiffBasedSubStorageConfiguration() + .getUnstable() + .getCodeStoredByCodeHashEnabled()) .isEqualTo(true), "--Xbonsai-code-using-code-hash-enabled", "true"); } @Test - public void bonsaiCodeUsingCodeHashEnabledCanBeDisabled() { + public void diffbasedCodeUsingCodeHashEnabledCanBeDisabled() { internalTestSuccess( dataStorageConfiguration -> assertThat( - dataStorageConfiguration.getUnstable().getBonsaiCodeStoredByCodeHashEnabled()) + dataStorageConfiguration + .getDiffBasedSubStorageConfiguration() + .getUnstable() + .getCodeStoredByCodeHashEnabled()) .isEqualTo(false), "--Xbonsai-code-using-code-hash-enabled", "false"); @@ -159,9 +185,12 @@ public class DataStorageOptionsTest protected DataStorageConfiguration createCustomizedDomainObject() { return ImmutableDataStorageConfiguration.builder() .dataStorageFormat(DataStorageFormat.BONSAI) - .bonsaiMaxLayersToLoad(513L) - .bonsaiLimitTrieLogsEnabled(true) - .bonsaiTrieLogPruningWindowSize(514) + .diffBasedSubStorageConfiguration( + ImmutableDiffBasedSubStorageConfiguration.builder() + .maxLayersToLoad(513L) + .limitTrieLogsEnabled(true) + .trieLogPruningWindowSize(514) + .build()) .build(); } diff --git a/besu/src/test/java/org/hyperledger/besu/cli/subcommands/storage/TrieLogHelperTest.java b/besu/src/test/java/org/hyperledger/besu/cli/subcommands/storage/TrieLogHelperTest.java index 2f3a693f3d..fef10457ca 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/subcommands/storage/TrieLogHelperTest.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/subcommands/storage/TrieLogHelperTest.java @@ -17,7 +17,7 @@ package org.hyperledger.besu.cli.subcommands.storage; import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration.DEFAULT_BONSAI_TRIE_LOG_PRUNING_WINDOW_SIZE; +import static org.hyperledger.besu.ethereum.worldstate.DiffBasedSubStorageConfiguration.DEFAULT_TRIE_LOG_PRUNING_WINDOW_SIZE; import static org.hyperledger.besu.plugin.services.storage.DataStorageFormat.BONSAI; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.spy; @@ -35,6 +35,7 @@ import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.trielog.TrieLogFactor import org.hyperledger.besu.ethereum.trie.diffbased.common.trielog.TrieLogLayer; import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; import org.hyperledger.besu.ethereum.worldstate.ImmutableDataStorageConfiguration; +import org.hyperledger.besu.ethereum.worldstate.ImmutableDiffBasedSubStorageConfiguration; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import java.io.FileNotFoundException; @@ -134,8 +135,11 @@ class TrieLogHelperTest { DataStorageConfiguration dataStorageConfiguration = ImmutableDataStorageConfiguration.builder() .dataStorageFormat(BONSAI) - .bonsaiMaxLayersToLoad(3L) - .bonsaiLimitTrieLogsEnabled(true) + .diffBasedSubStorageConfiguration( + ImmutableDiffBasedSubStorageConfiguration.builder() + .maxLayersToLoad(3L) + .limitTrieLogsEnabled(true) + .build()) .build(); mockBlockchainBase(); @@ -172,8 +176,11 @@ class TrieLogHelperTest { DataStorageConfiguration dataStorageConfiguration = ImmutableDataStorageConfiguration.builder() .dataStorageFormat(BONSAI) - .bonsaiMaxLayersToLoad(2L) - .bonsaiLimitTrieLogsEnabled(true) + .diffBasedSubStorageConfiguration( + ImmutableDiffBasedSubStorageConfiguration.builder() + .maxLayersToLoad(2L) + .limitTrieLogsEnabled(true) + .build()) .build(); when(blockchain.getChainHeadBlockNumber()).thenReturn(5L); @@ -192,8 +199,11 @@ class TrieLogHelperTest { DataStorageConfiguration dataStorageConfiguration = ImmutableDataStorageConfiguration.builder() .dataStorageFormat(BONSAI) - .bonsaiMaxLayersToLoad(10L) - .bonsaiLimitTrieLogsEnabled(true) + .diffBasedSubStorageConfiguration( + ImmutableDiffBasedSubStorageConfiguration.builder() + .maxLayersToLoad(10L) + .limitTrieLogsEnabled(true) + .build()) .build(); when(blockchain.getChainHeadBlockNumber()).thenReturn(5L); @@ -212,8 +222,11 @@ class TrieLogHelperTest { DataStorageConfiguration dataStorageConfiguration = ImmutableDataStorageConfiguration.builder() .dataStorageFormat(BONSAI) - .bonsaiMaxLayersToLoad(2L) - .bonsaiLimitTrieLogsEnabled(true) + .diffBasedSubStorageConfiguration( + ImmutableDiffBasedSubStorageConfiguration.builder() + .maxLayersToLoad(2L) + .limitTrieLogsEnabled(true) + .build()) .build(); mockBlockchainBase(); @@ -233,8 +246,11 @@ class TrieLogHelperTest { DataStorageConfiguration dataStorageConfiguration = ImmutableDataStorageConfiguration.builder() .dataStorageFormat(BONSAI) - .bonsaiMaxLayersToLoad(6L) - .bonsaiLimitTrieLogsEnabled(true) + .diffBasedSubStorageConfiguration( + ImmutableDiffBasedSubStorageConfiguration.builder() + .maxLayersToLoad(6L) + .limitTrieLogsEnabled(true) + .build()) .build(); when(blockchain.getChainHeadBlockNumber()).thenReturn(5L); @@ -255,8 +271,11 @@ class TrieLogHelperTest { DataStorageConfiguration dataStorageConfiguration = ImmutableDataStorageConfiguration.builder() .dataStorageFormat(BONSAI) - .bonsaiMaxLayersToLoad(3L) - .bonsaiLimitTrieLogsEnabled(true) + .diffBasedSubStorageConfiguration( + ImmutableDiffBasedSubStorageConfiguration.builder() + .maxLayersToLoad(3L) + .limitTrieLogsEnabled(true) + .build()) .build(); mockBlockchainBase(); @@ -266,7 +285,7 @@ class TrieLogHelperTest { final BonsaiWorldStateKeyValueStorage inMemoryWorldStateSpy = spy(inMemoryWorldState); // force a different value the second time the trie log count is called - when(inMemoryWorldStateSpy.streamTrieLogKeys(3L + DEFAULT_BONSAI_TRIE_LOG_PRUNING_WINDOW_SIZE)) + when(inMemoryWorldStateSpy.streamTrieLogKeys(3L + DEFAULT_TRIE_LOG_PRUNING_WINDOW_SIZE)) .thenCallRealMethod() .thenReturn(Stream.empty()); assertThatThrownBy( @@ -284,8 +303,11 @@ class TrieLogHelperTest { DataStorageConfiguration dataStorageConfiguration = ImmutableDataStorageConfiguration.builder() .dataStorageFormat(BONSAI) - .bonsaiMaxLayersToLoad(511L) - .bonsaiLimitTrieLogsEnabled(true) + .diffBasedSubStorageConfiguration( + ImmutableDiffBasedSubStorageConfiguration.builder() + .maxLayersToLoad(511L) + .limitTrieLogsEnabled(true) + .build()) .build(); TrieLogHelper helper = new TrieLogHelper(); @@ -302,9 +324,12 @@ class TrieLogHelperTest { DataStorageConfiguration dataStorageConfiguration = ImmutableDataStorageConfiguration.builder() .dataStorageFormat(BONSAI) - .bonsaiMaxLayersToLoad(512L) - .bonsaiLimitTrieLogsEnabled(true) - .bonsaiTrieLogPruningWindowSize(0) + .diffBasedSubStorageConfiguration( + ImmutableDiffBasedSubStorageConfiguration.builder() + .maxLayersToLoad(512L) + .limitTrieLogsEnabled(true) + .trieLogPruningWindowSize(0) + .build()) .build(); TrieLogHelper helper = new TrieLogHelper(); @@ -320,9 +345,12 @@ class TrieLogHelperTest { DataStorageConfiguration dataStorageConfiguration = ImmutableDataStorageConfiguration.builder() .dataStorageFormat(BONSAI) - .bonsaiMaxLayersToLoad(512L) - .bonsaiLimitTrieLogsEnabled(true) - .bonsaiTrieLogPruningWindowSize(512) + .diffBasedSubStorageConfiguration( + ImmutableDiffBasedSubStorageConfiguration.builder() + .maxLayersToLoad(512L) + .limitTrieLogsEnabled(true) + .trieLogPruningWindowSize(512) + .build()) .build(); TrieLogHelper helper = new TrieLogHelper(); @@ -340,8 +368,11 @@ class TrieLogHelperTest { DataStorageConfiguration dataStorageConfiguration = ImmutableDataStorageConfiguration.builder() .dataStorageFormat(BONSAI) - .bonsaiMaxLayersToLoad(3L) - .bonsaiLimitTrieLogsEnabled(true) + .diffBasedSubStorageConfiguration( + ImmutableDiffBasedSubStorageConfiguration.builder() + .maxLayersToLoad(3L) + .limitTrieLogsEnabled(true) + .build()) .build(); mockBlockchainBase(); diff --git a/besu/src/test/java/org/hyperledger/besu/cli/subcommands/storage/TrieLogSubCommandTest.java b/besu/src/test/java/org/hyperledger/besu/cli/subcommands/storage/TrieLogSubCommandTest.java index 66536070a7..8e701ec67f 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/subcommands/storage/TrieLogSubCommandTest.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/subcommands/storage/TrieLogSubCommandTest.java @@ -58,8 +58,10 @@ class TrieLogSubCommandTest extends CommandTestAbstract { .dataStorageConfiguration(dataStorageConfigurationArgumentCaptor.capture()); final List configs = dataStorageConfigurationArgumentCaptor.getAllValues(); - assertThat(configs.get(0).getBonsaiLimitTrieLogsEnabled()).isTrue(); - assertThat(configs.get(1).getBonsaiLimitTrieLogsEnabled()).isFalse(); + assertThat(configs.get(0).getDiffBasedSubStorageConfiguration().getLimitTrieLogsEnabled()) + .isTrue(); + assertThat(configs.get(1).getDiffBasedSubStorageConfiguration().getLimitTrieLogsEnabled()) + .isFalse(); } @Test @@ -69,6 +71,11 @@ class TrieLogSubCommandTest extends CommandTestAbstract { .dataStorageConfiguration(dataStorageConfigurationArgumentCaptor.capture()); final List configs = dataStorageConfigurationArgumentCaptor.getAllValues(); - assertThat(configs).allMatch(DataStorageConfiguration::getBonsaiLimitTrieLogsEnabled); + assertThat(configs) + .allMatch( + dataStorageConfiguration -> + dataStorageConfiguration + .getDiffBasedSubStorageConfiguration() + .getLimitTrieLogsEnabled()); } } diff --git a/besu/src/test/java/org/hyperledger/besu/services/RlpConverterServiceImplTest.java b/besu/src/test/java/org/hyperledger/besu/services/RlpConverterServiceImplTest.java index 7a3bdbbfe6..b9ce7ccd5c 100644 --- a/besu/src/test/java/org/hyperledger/besu/services/RlpConverterServiceImplTest.java +++ b/besu/src/test/java/org/hyperledger/besu/services/RlpConverterServiceImplTest.java @@ -38,7 +38,7 @@ public class RlpConverterServiceImplTest { new BlockHeaderTestFixture() .timestamp(1710338135 + 1) .baseFeePerGas(Wei.of(1000)) - .requestsRoot(Hash.ZERO) + .requestsHash(Hash.ZERO) .withdrawalsRoot(Hash.ZERO) .blobGasUsed(500L) .excessBlobGas(BlobGas.of(500L)) diff --git a/besu/src/test/java/org/hyperledger/besu/util/EphemeryGenesisUpdaterTest.java b/besu/src/test/java/org/hyperledger/besu/util/EphemeryGenesisUpdaterTest.java new file mode 100644 index 0000000000..fe21c1e6d7 --- /dev/null +++ b/besu/src/test/java/org/hyperledger/besu/util/EphemeryGenesisUpdaterTest.java @@ -0,0 +1,139 @@ +/* + * 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.util; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.hyperledger.besu.config.GenesisConfigFile.fromConfig; + +import org.hyperledger.besu.config.GenesisConfigFile; + +import java.math.BigInteger; +import java.util.Map; +import java.util.Optional; +import java.util.TreeMap; + +import io.vertx.core.json.JsonObject; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +public class EphemeryGenesisUpdaterTest { + private static final int GENESIS_CONFIG_TEST_CHAINID = 39438135; + private static final long GENESIS_TEST_TIMESTAMP = 1720119600; + private static final long EARLIER_TIMESTAMP = 1712041200; + private static final long LATER_TIMESTAMP = 1922041200; + private static final long PERIOD_IN_SECONDS = 28 * 24 * 60 * 60; + private static final long PERIOD_SINCE_GENESIS = 3; + + private static final JsonObject VALID_GENESIS_JSON = + (new JsonObject()) + .put("config", (new JsonObject()).put("chainId", GENESIS_CONFIG_TEST_CHAINID)) + .put("timestamp", GENESIS_TEST_TIMESTAMP); + + private static final GenesisConfigFile INVALID_GENESIS_JSON = fromConfig("{}"); + private static final JsonObject INVALID_GENESIS_JSON_WITHOUT_CHAINID = + (new JsonObject()).put("timestamp", GENESIS_TEST_TIMESTAMP); + + private static final JsonObject INVALID_GENESIS_JSON_WITHOUT_TIMESTAMP = + new JsonObject() + .put("config", (new JsonObject()).put("chainId", GENESIS_CONFIG_TEST_CHAINID)); + + @Test + public void testEphemeryWhenChainIdIsAbsent() { + final GenesisConfigFile config = + GenesisConfigFile.fromConfig(INVALID_GENESIS_JSON_WITHOUT_CHAINID.toString()); + Optional chainId = config.getConfigOptions().getChainId(); + assertThat(chainId).isNotPresent(); + } + + @Test + public void testShouldDefaultTimestampToZero() { + final GenesisConfigFile config = + GenesisConfigFile.fromConfig(INVALID_GENESIS_JSON_WITHOUT_TIMESTAMP.toString()); + assertThat(config.getTimestamp()).isZero(); + } + + @Test + public void testEphemeryWhenGenesisJsonIsInvalid() { + assertThatThrownBy(INVALID_GENESIS_JSON::getDifficulty) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("Invalid genesis block configuration"); + } + + @Test + public void testEphemeryWhenGenesisJsonIsValid() { + final GenesisConfigFile config = GenesisConfigFile.fromConfig(VALID_GENESIS_JSON.toString()); + assertThat(String.valueOf(config.getTimestamp())) + .isEqualTo(String.valueOf(GENESIS_TEST_TIMESTAMP)); + assertThat(config.getConfigOptions().getChainId()) + .hasValue(BigInteger.valueOf(GENESIS_CONFIG_TEST_CHAINID)); + assertThat(String.valueOf(config.getTimestamp())).isNotNull(); + assertThat(String.valueOf(config.getTimestamp())).isNotEmpty(); + } + + @Test + public void testEphemeryNotYetDueForUpdate() { + final GenesisConfigFile config = GenesisConfigFile.fromConfig(VALID_GENESIS_JSON.toString()); + assertThat(EARLIER_TIMESTAMP).isLessThan(config.getTimestamp() + PERIOD_IN_SECONDS); + } + + @Test + void testOverrideWithUpdatedChainIdAndTimeStamp() { + BigInteger expectedChainId = + BigInteger.valueOf(GENESIS_CONFIG_TEST_CHAINID) + .add(BigInteger.valueOf(PERIOD_SINCE_GENESIS)); + + long expectedGenesisTimestamp = + GENESIS_TEST_TIMESTAMP + (PERIOD_SINCE_GENESIS * PERIOD_IN_SECONDS); + + final GenesisConfigFile config = GenesisConfigFile.fromResource("/ephemery.json"); + + final Map override = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); + override.put("chainId", String.valueOf(expectedChainId)); + override.put("timestamp", String.valueOf(expectedGenesisTimestamp)); + + assertThat(config.withOverrides(override).getConfigOptions().getChainId()).isPresent(); + assertThat(config.withOverrides(override).getConfigOptions().getChainId()) + .hasValue(expectedChainId); + assertThat(config.withOverrides(override).getTimestamp()).isNotNull(); + assertThat(expectedChainId).isEqualTo(override.get("chainId")); + assertThat(String.valueOf(expectedGenesisTimestamp)).isEqualTo(override.get("timestamp")); + } + + @Test + public void testEphemeryWhenSuccessful() { + final GenesisConfigFile config = GenesisConfigFile.fromConfig(VALID_GENESIS_JSON.toString()); + + BigInteger expectedChainId = + BigInteger.valueOf(GENESIS_CONFIG_TEST_CHAINID) + .add(BigInteger.valueOf(PERIOD_SINCE_GENESIS)); + + long expectedGenesisTimestamp = + GENESIS_TEST_TIMESTAMP + (PERIOD_SINCE_GENESIS * PERIOD_IN_SECONDS); + final Map override = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); + override.put("chainId", String.valueOf(expectedChainId)); + override.put("timestamp", String.valueOf(expectedGenesisTimestamp)); + final GenesisConfigFile updatedConfig = config.withOverrides(override); + + assertThat(LATER_TIMESTAMP) + .isGreaterThan(Long.parseLong(String.valueOf(GENESIS_TEST_TIMESTAMP + PERIOD_IN_SECONDS))); + assertThat(updatedConfig.getConfigOptions().getChainId()).hasValue(expectedChainId); + assertThat(updatedConfig.getTimestamp()).isEqualTo(expectedGenesisTimestamp); + assertThat(override.get("timestamp")).isEqualTo(String.valueOf(expectedGenesisTimestamp)); + assertThat(override.get("chainId")).isEqualTo(expectedChainId.toString()); + } +} diff --git a/build.gradle b/build.gradle index 5eea0ce8e0..09a600dd25 100644 --- a/build.gradle +++ b/build.gradle @@ -24,13 +24,13 @@ import java.util.regex.Pattern plugins { id 'com.diffplug.spotless' version '6.25.0' - id 'com.github.ben-manes.versions' version '0.51.0' id 'com.github.jk1.dependency-license-report' version '2.9' id 'com.jfrog.artifactory' version '5.2.5' - id 'io.spring.dependency-management' version '1.1.6' id 'me.champeau.jmh' version '0.7.2' apply false id 'net.ltgt.errorprone' version '4.0.1' id 'maven-publish' + id 'jacoco' + id 'jacoco-report-aggregation' id 'org.sonarqube' version '5.1.0.4882' } @@ -40,12 +40,12 @@ sonarqube { property "sonar.organization", "$System.env.SONAR_ORGANIZATION" property "sonar.gradle.skipCompile", "true" property "sonar.host.url", "https://sonarcloud.io" - property "sonar.coverage.jacoco.xmlReportPaths", "${buildDir}/reports/jacoco/jacocoRootReport/jacocoRootReport.xml" + property "sonar.coverage.jacoco.xmlReportPaths", "${buildDir}/reports/jacoco/testCodeCoverageReport/testCodeCoverageReport.xml" property "sonar.coverage.exclusions", "acceptance-tests/**/*" } } -project.tasks["sonarqube"].dependsOn "jacocoRootReport" +project.tasks["sonar"].dependsOn "testCodeCoverageReport" if (!JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_21)) { throw new GradleException("Java 21 or later is required to build Besu.\n" + @@ -118,12 +118,10 @@ licenseReport { ] } -allprojects { +configure(allprojects - project(':platform')) { apply plugin: 'java-library' - apply plugin: 'io.spring.dependency-management' apply plugin: 'jacoco' apply plugin: 'net.ltgt.errorprone' - apply from: "${rootDir}/gradle/versions.gradle" version = calculateVersion() @@ -184,6 +182,12 @@ allprojects { } dependencies { + api platform(project(':platform')) + + annotationProcessor(platform(project(':platform'))) + + testAnnotationProcessor(platform(project(':platform'))) + components.all(BouncyCastleCapability) errorprone 'com.google.errorprone:error_prone_core' // https://github.com/hyperledger/besu-errorprone-checks/ @@ -214,7 +218,7 @@ allprojects { // apply appropriate license header files. licenseHeaderFile("${rootDir}/gradle/spotless/java.former.license").named("older").onlyIfContentMatches("^/\\*\\r?\\n.*Copyright ConsenSys AG\\.") licenseHeaderFile("${rootDir}/gradle/spotless/java.former.date.license").named("older.year").onlyIfContentMatches("^/\\*\\r?\\n.* Copyright \\d{4} ConsenSys AG\\.") - licenseHeaderFile("${rootDir}/gradle/spotless/java.current.license").named("current").onlyIfContentMatches("^(?!/\\*\\r?\\n \\*.*ConsenSys AG\\.)") + licenseHeaderFile("${rootDir}/gradle/spotless/java.current.license").named("current").onlyIfContentMatches("^(?!/\\*\\r?\\n \\*.*(ConsenSys AG|Hyperledger Besu)\\.)") } // spotless check applied to build.gradle (groovy) files groovyGradle { @@ -239,7 +243,7 @@ allprojects { licenseHeaderFile("${rootDir}/gradle/spotless/java.former.license","^pragma solidity.+?").named("former").onlyIfContentMatches("^/\\*\\r?\\n.*Copyright ConsenSys AG\\.") licenseHeaderFile("${rootDir}/gradle/spotless/java.former.date.license","^pragma solidity.+?").named("former.date").onlyIfContentMatches("^/\\*\\r?\\n.* Copyright \\d{4} ConsenSys AG\\.") - licenseHeaderFile("${rootDir}/gradle/spotless/java.current.license","^pragma solidity.+?").named("current").onlyIfContentMatches("^(?!/\\*\\r?\\n \\*.*ConsenSys AG\\.)") + licenseHeaderFile("${rootDir}/gradle/spotless/java.current.license","^pragma solidity.+?").named("current").onlyIfContentMatches("^(?!/\\*\\r?\\n \\*.*(ConsenSys AG|Hyperledger Besu)\\.)") } } @@ -361,6 +365,7 @@ allprojects { } } useJUnitPlatform {} + finalizedBy jacocoTestReport // report is always generated after tests run } javadoc { @@ -440,14 +445,16 @@ task checkMavenCoordinateCollisions { doLast { def coordinates = [:] getAllprojects().forEach { - if (it.properties.containsKey('publishing') && it.jar?.enabled) { - def coordinate = it.publishing?.publications[0].coordinates - if (coordinate.toString().startsWith("org") && coordinates.containsKey(coordinate)) { - throw new GradleException("Duplicate maven coordinates detected, ${coordinate} is used by " + - "both ${coordinates[coordinate]} and ${it.path}.\n" + - "Please add a `publishing` script block to one or both subprojects.") + if (it.properties.containsKey('publishing')) { + if(!it.properties.containsKey('jar') || it.jar.enabled) { + def coordinate = it.publishing?.publications[0].coordinates + if (coordinate.toString().startsWith("org") && coordinates.containsKey(coordinate)) { + throw new GradleException("Duplicate maven coordinates detected, ${coordinate} is used by " + + "both ${coordinates[coordinate]} and ${it.path}.\n" + + "Please add a `publishing` script block to one or both subprojects.") + } + coordinates[coordinate] = it.path } - coordinates[coordinate] = it.path } } } @@ -520,7 +527,8 @@ subprojects { return result } - if (sourceSetIsPopulated("main") || sourceSetIsPopulated("testSupport")) { + + if (sourceSetIsPopulated("main") || sourceSetIsPopulated("testSupport") || project.name == "platform") { apply plugin: 'com.jfrog.artifactory' apply plugin: 'maven-publish' @@ -595,7 +603,9 @@ subprojects { configurations { + testSupportAnnotationProcessor.extendsFrom annotationProcessor testSupportImplementation.extendsFrom implementation + integrationTestAnnotationProcessor.extendsFrom annotationProcessor integrationTestImplementation.extendsFrom implementation testSupportArtifacts } @@ -620,7 +630,10 @@ subprojects { duplicateClassesStrategy = DuplicatesStrategy.WARN } - dependencies { jmh 'org.slf4j:slf4j-api' } + dependencies { + jmhAnnotationProcessor(platform(project(':platform'))) + jmh 'org.slf4j:slf4j-api' + } } // making sure assemble task invokes integration test compile @@ -963,19 +976,6 @@ jacocoTestReport { } } -task jacocoRootReport(type: org.gradle.testing.jacoco.tasks.JacocoReport) { - additionalSourceDirs.from files(subprojects.sourceSets.main.allSource.srcDirs) - sourceDirectories.from files(subprojects.sourceSets.main.allSource.srcDirs) - classDirectories.from files(subprojects.sourceSets.main.output).asFileTree.matching { exclude 'org/hyperledger/besu/tests/acceptance/**' } - executionData.from fileTree(dir: '.', includes: ['**/jacoco/*.exec']) - reports { - xml.required = true - csv.required = true - html.destination file("build/reports/jacocoHtml") - } - onlyIf = { true } -} - // http://label-schema.org/rc1/ // using the RFC3339 format "2016-04-12T23:20:50.52Z" def buildTime() { diff --git a/config/src/main/java/org/hyperledger/besu/config/GenesisConfigFile.java b/config/src/main/java/org/hyperledger/besu/config/GenesisConfigFile.java index 453c38dac2..eae9bc3d10 100644 --- a/config/src/main/java/org/hyperledger/besu/config/GenesisConfigFile.java +++ b/config/src/main/java/org/hyperledger/besu/config/GenesisConfigFile.java @@ -265,6 +265,17 @@ public class GenesisConfigFile { "0x0000000000000000000000000000000000000000000000000000000000000000"); } + /** + * Gets target blob count. + * + * @return the target blob count + */ + public Optional getTargetBlobCount() { + // TODO SLD EIP-7742 not sure if we should use a default value here or enforce any + // "pragueAtGenesis" genesis file (used in devnets) to have this value + return JsonUtil.getValueAsString(genesisRoot, "targetblobcount"); + } + /** * Gets coinbase. * @@ -280,6 +291,9 @@ public class GenesisConfigFile { * @return the timestamp */ public long getTimestamp() { + if (overrides != null && overrides.containsKey("timestamp")) { + return Long.parseLong(overrides.get("timestamp")); + } return parseLong("timestamp", JsonUtil.getValueAsString(genesisRoot, "timestamp", "0x0")); } diff --git a/config/src/main/java/org/hyperledger/besu/config/GenesisConfigOptions.java b/config/src/main/java/org/hyperledger/besu/config/GenesisConfigOptions.java index 07ddd0d7ea..e2458c9324 100644 --- a/config/src/main/java/org/hyperledger/besu/config/GenesisConfigOptions.java +++ b/config/src/main/java/org/hyperledger/besu/config/GenesisConfigOptions.java @@ -257,11 +257,11 @@ public interface GenesisConfigOptions { OptionalLong getPragueTime(); /** - * Gets Prague EOF time. + * Gets Osaka time. * - * @return the prague time + * @return the osaka time */ - OptionalLong getPragueEOFTime(); + OptionalLong getOsakaTime(); /** * Gets future eips time. diff --git a/config/src/main/java/org/hyperledger/besu/config/JsonGenesisConfigOptions.java b/config/src/main/java/org/hyperledger/besu/config/JsonGenesisConfigOptions.java index 83b1f48fb4..51f85f0ec8 100644 --- a/config/src/main/java/org/hyperledger/besu/config/JsonGenesisConfigOptions.java +++ b/config/src/main/java/org/hyperledger/besu/config/JsonGenesisConfigOptions.java @@ -308,8 +308,8 @@ public class JsonGenesisConfigOptions implements GenesisConfigOptions { } @Override - public OptionalLong getPragueEOFTime() { - return getOptionalLong("pragueeoftime"); + public OptionalLong getOsakaTime() { + return getOptionalLong("osakatime"); } @Override @@ -486,7 +486,7 @@ public class JsonGenesisConfigOptions implements GenesisConfigOptions { getCancunTime().ifPresent(l -> builder.put("cancunTime", l)); getCancunEOFTime().ifPresent(l -> builder.put("cancunEOFTime", l)); getPragueTime().ifPresent(l -> builder.put("pragueTime", l)); - getPragueEOFTime().ifPresent(l -> builder.put("pragueEOFTime", l)); + getOsakaTime().ifPresent(l -> builder.put("osakaTime", l)); getTerminalBlockNumber().ifPresent(l -> builder.put("terminalBlockNumber", l)); getTerminalBlockHash().ifPresent(h -> builder.put("terminalBlockHash", h.toHexString())); getFutureEipsTime().ifPresent(l -> builder.put("futureEipsTime", l)); @@ -640,7 +640,7 @@ public class JsonGenesisConfigOptions implements GenesisConfigOptions { getCancunTime(), getCancunEOFTime(), getPragueTime(), - getPragueEOFTime(), + getOsakaTime(), getFutureEipsTime(), getExperimentalEipsTime()); // when adding forks add an entry to ${REPO_ROOT}/config/src/test/resources/all_forks.json diff --git a/config/src/main/java/org/hyperledger/besu/config/MergeConfigOptions.java b/config/src/main/java/org/hyperledger/besu/config/MergeConfiguration.java similarity index 91% rename from config/src/main/java/org/hyperledger/besu/config/MergeConfigOptions.java rename to config/src/main/java/org/hyperledger/besu/config/MergeConfiguration.java index 53faf69052..5ab6444209 100644 --- a/config/src/main/java/org/hyperledger/besu/config/MergeConfigOptions.java +++ b/config/src/main/java/org/hyperledger/besu/config/MergeConfiguration.java @@ -16,12 +16,14 @@ package org.hyperledger.besu.config; import java.util.concurrent.atomic.AtomicBoolean; -/** The Merge config options. */ -public class MergeConfigOptions { +/** The Merge configuration. */ + +// use picocli +public class MergeConfiguration { private static final AtomicBoolean mergeEnabled = new AtomicBoolean(false); /** Default constructor. */ - private MergeConfigOptions() {} + private MergeConfiguration() {} /** * Enables merge. diff --git a/config/src/main/java/org/hyperledger/besu/config/StubGenesisConfigOptions.java b/config/src/main/java/org/hyperledger/besu/config/StubGenesisConfigOptions.java index ee9584fd3a..c9c8dad795 100644 --- a/config/src/main/java/org/hyperledger/besu/config/StubGenesisConfigOptions.java +++ b/config/src/main/java/org/hyperledger/besu/config/StubGenesisConfigOptions.java @@ -50,7 +50,7 @@ public class StubGenesisConfigOptions implements GenesisConfigOptions, Cloneable private OptionalLong cancunTime = OptionalLong.empty(); private OptionalLong cancunEOFTime = OptionalLong.empty(); private OptionalLong pragueTime = OptionalLong.empty(); - private OptionalLong pragueEOFTime = OptionalLong.empty(); + private OptionalLong osakaTime = OptionalLong.empty(); private OptionalLong futureEipsTime = OptionalLong.empty(); private OptionalLong experimentalEipsTime = OptionalLong.empty(); private OptionalLong terminalBlockNumber = OptionalLong.empty(); @@ -252,8 +252,8 @@ public class StubGenesisConfigOptions implements GenesisConfigOptions, Cloneable } @Override - public OptionalLong getPragueEOFTime() { - return pragueEOFTime; + public OptionalLong getOsakaTime() { + return osakaTime; } @Override @@ -671,14 +671,13 @@ public class StubGenesisConfigOptions implements GenesisConfigOptions, Cloneable } /** - * PragueEOF time. + * Osaka time. * * @param timestamp the timestamp * @return the stub genesis config options */ - public StubGenesisConfigOptions pragueEOFTime(final long timestamp) { - pragueTime = OptionalLong.of(timestamp); - pragueEOFTime = pragueTime; + public StubGenesisConfigOptions osakaTime(final long timestamp) { + osakaTime = OptionalLong.of(timestamp); return this; } diff --git a/config/src/main/resources/ephemery.json b/config/src/main/resources/ephemery.json new file mode 100644 index 0000000000..5c73756fb5 --- /dev/null +++ b/config/src/main/resources/ephemery.json @@ -0,0 +1,916 @@ +{ + "config": { + "chainId": 39438135, + "homesteadBlock": 0, + "eip150Block": 0, + "eip155Block": 0, + "eip158Block": 0, + "byzantiumBlock": 0, + "constantinopleBlock": 0, + "petersburgBlock": 0, + "istanbulBlock": 0, + "berlinBlock": 0, + "londonBlock": 0, + "mergeNetsplitBlock": 0, + "terminalTotalDifficulty": 0, + "terminalTotalDifficultyPassed": true, + "shanghaiTime": 0, + "cancunTime": 0, + "depositContractAddress": "0x4242424242424242424242424242424242424242", + "ethash" : {}, + "discovery" : { + "bootnodes" : [ + "enode://50a54ecbd2175497640bcf46a25bbe9bb4fae51d7cc2a29ef4947a7ee17496cf39a699b7fe6b703ed0feb9dbaae7e44fc3827fcb7435ca9ac6de4daa4d983b3d@137.74.203.240:30303", + "enode://0f2c301a9a3f9fa2ccfa362b79552c052905d8c2982f707f46cd29ece5a9e1c14ecd06f4ac951b228f059a43c6284a1a14fce709e8976cac93b50345218bf2e9@135.181.140.168:30343" ] + } + }, + "alloc": { + "0x0000000000000000000000000000000000000000": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000001": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000002": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000003": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000004": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000005": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000006": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000007": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000008": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000009": { + "balance": "1" + }, + "0x000000000000000000000000000000000000000a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000000b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000000c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000000d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000000e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000000f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000010": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000011": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000012": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000013": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000014": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000015": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000016": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000017": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000018": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000019": { + "balance": "1" + }, + "0x000000000000000000000000000000000000001a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000001b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000001c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000001d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000001e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000001f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000020": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000021": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000022": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000023": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000024": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000025": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000026": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000027": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000028": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000029": { + "balance": "1" + }, + "0x000000000000000000000000000000000000002a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000002b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000002c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000002d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000002e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000002f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000030": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000031": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000032": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000033": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000034": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000035": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000036": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000037": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000038": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000039": { + "balance": "1" + }, + "0x000000000000000000000000000000000000003a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000003b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000003c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000003d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000003e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000003f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000040": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000041": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000042": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000043": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000044": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000045": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000046": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000047": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000048": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000049": { + "balance": "1" + }, + "0x000000000000000000000000000000000000004a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000004b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000004c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000004d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000004e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000004f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000050": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000051": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000052": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000053": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000054": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000055": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000056": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000057": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000058": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000059": { + "balance": "1" + }, + "0x000000000000000000000000000000000000005a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000005b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000005c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000005d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000005e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000005f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000060": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000061": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000062": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000063": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000064": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000065": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000066": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000067": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000068": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000069": { + "balance": "1" + }, + "0x000000000000000000000000000000000000006a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000006b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000006c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000006d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000006e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000006f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000070": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000071": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000072": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000073": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000074": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000075": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000076": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000077": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000078": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000079": { + "balance": "1" + }, + "0x000000000000000000000000000000000000007a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000007b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000007c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000007d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000007e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000007f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000080": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000081": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000082": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000083": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000084": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000085": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000086": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000087": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000088": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000089": { + "balance": "1" + }, + "0x000000000000000000000000000000000000008a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000008b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000008c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000008d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000008e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000008f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000090": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000091": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000092": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000093": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000094": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000095": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000096": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000097": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000098": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000099": { + "balance": "1" + }, + "0x000000000000000000000000000000000000009a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000009b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000009c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000009d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000009e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000009f": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a0": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a1": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a2": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a3": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a4": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a5": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a6": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a7": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a8": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a9": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000aa": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ab": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ac": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ad": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ae": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000af": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b0": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b1": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b2": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b3": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b4": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b5": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b6": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b7": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b8": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b9": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ba": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000bb": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000bc": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000bd": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000be": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000bf": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c0": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c1": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c2": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c3": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c4": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c5": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c6": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c7": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c8": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c9": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ca": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000cb": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000cc": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000cd": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ce": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000cf": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d0": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d1": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d2": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d3": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d4": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d5": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d6": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d7": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d8": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d9": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000da": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000db": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000dc": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000dd": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000de": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000df": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e0": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e1": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e2": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e3": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e4": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e5": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e6": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e7": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e8": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e9": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ea": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000eb": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ec": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ed": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ee": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ef": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f0": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f1": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f2": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f3": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f4": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f5": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f6": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f7": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f8": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f9": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000fa": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000fb": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000fc": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000fd": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000fe": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ff": { + "balance": "1" + }, + "0x4242424242424242424242424242424242424242": { + "balance": "0", + "code": "0x60806040526004361061003f5760003560e01c806301ffc9a71461004457806322895118146100a4578063621fd130146101ba578063c5f2892f14610244575b600080fd5b34801561005057600080fd5b506100906004803603602081101561006757600080fd5b50357fffffffff000000000000000000000000000000000000000000000000000000001661026b565b604080519115158252519081900360200190f35b6101b8600480360360808110156100ba57600080fd5b8101906020810181356401000000008111156100d557600080fd5b8201836020820111156100e757600080fd5b8035906020019184600183028401116401000000008311171561010957600080fd5b91939092909160208101903564010000000081111561012757600080fd5b82018360208201111561013957600080fd5b8035906020019184600183028401116401000000008311171561015b57600080fd5b91939092909160208101903564010000000081111561017957600080fd5b82018360208201111561018b57600080fd5b803590602001918460018302840111640100000000831117156101ad57600080fd5b919350915035610304565b005b3480156101c657600080fd5b506101cf6110b5565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102095781810151838201526020016101f1565b50505050905090810190601f1680156102365780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561025057600080fd5b506102596110c7565b60408051918252519081900360200190f35b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a70000000000000000000000000000000000000000000000000000000014806102fe57507fffffffff0000000000000000000000000000000000000000000000000000000082167f8564090700000000000000000000000000000000000000000000000000000000145b92915050565b6030861461035d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118056026913960400191505060405180910390fd5b602084146103b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603681526020018061179c6036913960400191505060405180910390fd5b6060821461040f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260298152602001806118786029913960400191505060405180910390fd5b670de0b6b3a7640000341015610470576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118526026913960400191505060405180910390fd5b633b9aca003406156104cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260338152602001806117d26033913960400191505060405180910390fd5b633b9aca00340467ffffffffffffffff811115610535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602781526020018061182b6027913960400191505060405180910390fd5b6060610540826114ba565b90507f649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c589898989858a8a6105756020546114ba565b6040805160a0808252810189905290819060208201908201606083016080840160c085018e8e80828437600083820152601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690910187810386528c815260200190508c8c808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690920188810386528c5181528c51602091820193918e019250908190849084905b83811015610648578181015183820152602001610630565b50505050905090810190601f1680156106755780820380516001836020036101000a031916815260200191505b5086810383528881526020018989808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169092018881038452895181528951602091820193918b019250908190849084905b838110156106ef5781810151838201526020016106d7565b50505050905090810190601f16801561071c5780820380516001836020036101000a031916815260200191505b509d505050505050505050505050505060405180910390a1600060028a8a600060801b604051602001808484808284377fffffffffffffffffffffffffffffffff0000000000000000000000000000000090941691909301908152604080517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0818403018152601090920190819052815191955093508392506020850191508083835b602083106107fc57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016107bf565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610859573d6000803e3d6000fd5b5050506040513d602081101561086e57600080fd5b5051905060006002806108846040848a8c6116fe565b6040516020018083838082843780830192505050925050506040516020818303038152906040526040518082805190602001908083835b602083106108f857805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016108bb565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610955573d6000803e3d6000fd5b5050506040513d602081101561096a57600080fd5b5051600261097b896040818d6116fe565b60405160009060200180848480828437919091019283525050604080518083038152602092830191829052805190945090925082918401908083835b602083106109f457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016109b7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610a51573d6000803e3d6000fd5b5050506040513d6020811015610a6657600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610ada57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610a9d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610b37573d6000803e3d6000fd5b5050506040513d6020811015610b4c57600080fd5b50516040805160208101858152929350600092600292839287928f928f92018383808284378083019250505093505050506040516020818303038152906040526040518082805190602001908083835b60208310610bd957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610b9c565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610c36573d6000803e3d6000fd5b5050506040513d6020811015610c4b57600080fd5b50516040518651600291889160009188916020918201918291908601908083835b60208310610ca957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610c6c565b6001836020036101000a0380198251168184511680821785525050505050509050018367ffffffffffffffff191667ffffffffffffffff1916815260180182815260200193505050506040516020818303038152906040526040518082805190602001908083835b60208310610d4e57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610d11565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610dab573d6000803e3d6000fd5b5050506040513d6020811015610dc057600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610e3457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610df7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610e91573d6000803e3d6000fd5b5050506040513d6020811015610ea657600080fd5b50519050858114610f02576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260548152602001806117486054913960600191505060405180910390fd5b60205463ffffffff11610f60576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806117276021913960400191505060405180910390fd5b602080546001019081905560005b60208110156110a9578160011660011415610fa0578260008260208110610f9157fe5b0155506110ac95505050505050565b600260008260208110610faf57fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061102557805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610fe8565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015611082573d6000803e3d6000fd5b5050506040513d602081101561109757600080fd5b50519250600282049150600101610f6e565b50fe5b50505050505050565b60606110c26020546114ba565b905090565b6020546000908190815b60208110156112f05781600116600114156111e6576002600082602081106110f557fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061116b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161112e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156111c8573d6000803e3d6000fd5b5050506040513d60208110156111dd57600080fd5b505192506112e2565b600283602183602081106111f657fe5b015460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061126b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161122e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156112c8573d6000803e3d6000fd5b5050506040513d60208110156112dd57600080fd5b505192505b6002820491506001016110d1565b506002826112ff6020546114ba565b600060401b6040516020018084815260200183805190602001908083835b6020831061135a57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161131d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790527fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000095909516920191825250604080518083037ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8018152601890920190819052815191955093508392850191508083835b6020831061143f57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611402565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa15801561149c573d6000803e3d6000fd5b5050506040513d60208110156114b157600080fd5b50519250505090565b60408051600880825281830190925260609160208201818036833701905050905060c082901b8060071a60f81b826000815181106114f457fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060061a60f81b8260018151811061153757fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060051a60f81b8260028151811061157a57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060041a60f81b826003815181106115bd57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060031a60f81b8260048151811061160057fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060021a60f81b8260058151811061164357fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060011a60f81b8260068151811061168657fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060001a60f81b826007815181106116c957fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535050919050565b6000808585111561170d578182fd5b83861115611719578182fd5b505082019391909203915056fe4465706f736974436f6e74726163743a206d65726b6c6520747265652066756c6c4465706f736974436f6e74726163743a207265636f6e7374727563746564204465706f7369744461746120646f6573206e6f74206d6174636820737570706c696564206465706f7369745f646174615f726f6f744465706f736974436f6e74726163743a20696e76616c6964207769746864726177616c5f63726564656e7469616c73206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c7565206e6f74206d756c7469706c65206f6620677765694465706f736974436f6e74726163743a20696e76616c6964207075626b6579206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f20686967684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f206c6f774465706f736974436f6e74726163743a20696e76616c6964207369676e6174757265206c656e677468a2646970667358221220dceca8706b29e917dacf25fceef95acac8d90d765ac926663ce4096195952b6164736f6c634300060b0033", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000022": "0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b", + "0x0000000000000000000000000000000000000000000000000000000000000023": "0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71", + "0x0000000000000000000000000000000000000000000000000000000000000024": "0xc78009fdf07fc56a11f122370658a353aaa542ed63e44c4bc15ff4cd105ab33c", + "0x0000000000000000000000000000000000000000000000000000000000000025": "0x536d98837f2dd165a55d5eeae91485954472d56f246df256bf3cae19352a123c", + "0x0000000000000000000000000000000000000000000000000000000000000026": "0x9efde052aa15429fae05bad4d0b1d7c64da64d03d7a1854a588c2cb8430c0d30", + "0x0000000000000000000000000000000000000000000000000000000000000027": "0xd88ddfeed400a8755596b21942c1497e114c302e6118290f91e6772976041fa1", + "0x0000000000000000000000000000000000000000000000000000000000000028": "0x87eb0ddba57e35f6d286673802a4af5975e22506c7cf4c64bb6be5ee11527f2c", + "0x0000000000000000000000000000000000000000000000000000000000000029": "0x26846476fd5fc54a5d43385167c95144f2643f533cc85bb9d16b782f8d7db193", + "0x000000000000000000000000000000000000000000000000000000000000002a": "0x506d86582d252405b840018792cad2bf1259f1ef5aa5f887e13cb2f0094f51e1", + "0x000000000000000000000000000000000000000000000000000000000000002b": "0xffff0ad7e659772f9534c195c815efc4014ef1e1daed4404c06385d11192e92b", + "0x000000000000000000000000000000000000000000000000000000000000002c": "0x6cf04127db05441cd833107a52be852868890e4317e6a02ab47683aa75964220", + "0x000000000000000000000000000000000000000000000000000000000000002d": "0xb7d05f875f140027ef5118a2247bbb84ce8f2f0f1123623085daf7960c329f5f", + "0x000000000000000000000000000000000000000000000000000000000000002e": "0xdf6af5f5bbdb6be9ef8aa618e4bf8073960867171e29676f8b284dea6a08a85e", + "0x000000000000000000000000000000000000000000000000000000000000002f": "0xb58d900f5e182e3c50ef74969ea16c7726c549757cc23523c369587da7293784", + "0x0000000000000000000000000000000000000000000000000000000000000030": "0xd49a7502ffcfb0340b1d7885688500ca308161a7f96b62df9d083b71fcc8f2bb", + "0x0000000000000000000000000000000000000000000000000000000000000031": "0x8fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb", + "0x0000000000000000000000000000000000000000000000000000000000000032": "0x8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab", + "0x0000000000000000000000000000000000000000000000000000000000000033": "0x95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4", + "0x0000000000000000000000000000000000000000000000000000000000000034": "0xf893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17f", + "0x0000000000000000000000000000000000000000000000000000000000000035": "0xcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa", + "0x0000000000000000000000000000000000000000000000000000000000000036": "0x8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9c", + "0x0000000000000000000000000000000000000000000000000000000000000037": "0xfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167", + "0x0000000000000000000000000000000000000000000000000000000000000038": "0xe71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d7", + "0x0000000000000000000000000000000000000000000000000000000000000039": "0x31206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc0", + "0x000000000000000000000000000000000000000000000000000000000000003a": "0x21352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544", + "0x000000000000000000000000000000000000000000000000000000000000003b": "0x619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a46765", + "0x000000000000000000000000000000000000000000000000000000000000003c": "0x7cdd2986268250628d0c10e385c58c6191e6fbe05191bcc04f133f2cea72c1c4", + "0x000000000000000000000000000000000000000000000000000000000000003d": "0x848930bd7ba8cac54661072113fb278869e07bb8587f91392933374d017bcbe1", + "0x000000000000000000000000000000000000000000000000000000000000003e": "0x8869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636", + "0x000000000000000000000000000000000000000000000000000000000000003f": "0xb5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c", + "0x0000000000000000000000000000000000000000000000000000000000000040": "0x985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7" + } + }, + "0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02": { + "balance": "0", + "nonce": "1", + "code": "0x3373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500" + }, + "0xa2A6d93439144FFE4D27c9E088dCD8b783946263": { + "balance": "1000000000000000000000000" + }, + "0xBc11295936Aa79d594139de1B2e12629414F3BDB": { + "balance": "1000000000000000000000000" + }, + "0x7cF5b79bfe291A67AB02b393E456cCc4c266F753": { + "balance": "1000000000000000000000000" + }, + "0xaaec86394441f915bce3e6ab399977e9906f3b69": { + "balance": "1000000000000000000000000" + }, + "0xF47CaE1CF79ca6758Bfc787dbD21E6bdBe7112B8": { + "balance": "1000000000000000000000000" + }, + "0xd7eDDB78ED295B3C9629240E8924fb8D8874ddD8": { + "balance": "1000000000000000000000000" + }, + "0x8b7F0977Bb4f0fBE7076FA22bC24acA043583F5e": { + "balance": "1000000000000000000000000" + }, + "0xe2e2659028143784d557bcec6ff3a0721048880a": { + "balance": "1000000000000000000000000" + }, + "0xd9a5179f091d85051d3c982785efd1455cec8699": { + "balance": "1000000000000000000000000" + }, + "0xbeef32ca5b9a198d27B4e02F4c70439fE60356Cf": { + "balance": "1000000000000000000000000" + }, + "0x0000006916a87b82333f4245046623b23794c65c": { + "balance": "10000000000000000000000000" + }, + "0xb21c33de1fab3fa15499c62b59fe0cc3250020d1": { + "balance": "100000000000000000000000000" + }, + "0x10F5d45854e038071485AC9e402308cF80D2d2fE": { + "balance": "100000000000000000000000000" + }, + "0xd7d76c58b3a519e9fA6Cc4D22dC017259BC49F1E": { + "balance": "100000000000000000000000000" + }, + "0x799D329e5f583419167cD722962485926E338F4a": { + "balance": "1000000000000000000" + }, + "0x4c2ae482593505f0163cdefc073e81c63cda4107": { + "balance": "1000000000000000000000000" + }, + "0xa8e8f14732658e4b51e8711931053a8a69baf2b1": { + "balance": "1000000000000000000000000" + }, + "0xe0a2bd4258d2768837baa26a28fe71dc079f84c7": { + "balance": "100000000000000000000000000" + }, + "0x1eA692E68a7765dE26FC03A6D74EE5B56A7e2b4d": { + "balance": "100000000000000000000000000" + }, + "0x57c3dfd40A86628B67721115d7A03C9F341d7718": { + "balance": "100000000000000000000000000" + }, + "0xc90E920F4DCfd4954230edCaB168D0C5B9561e03": { + "balance": "1000000000000000000000000000" + }, + "0x6Cc9397c3B38739daCbfaA68EaD5F5D77Ba5F455": { + "balance": "10000000000000000000000000" + }, + "0x992775d32fd0ec76b95C5E76CeEA92ED5a4bE1F9": { + "balance": "10000000000000000000000000" + } + }, + "coinbase": "0x0000000000000000000000000000000000000000", + "difficulty": "0x01", + "extraData": "", + "gasLimit": "0x1c9c380", + "nonce": "0x1234", + "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "timestamp": "1720119600" +} diff --git a/config/src/test/java/org/hyperledger/besu/config/GenesisConfigOptionsTest.java b/config/src/test/java/org/hyperledger/besu/config/GenesisConfigOptionsTest.java index 69494a9c9c..fe8149cc65 100644 --- a/config/src/test/java/org/hyperledger/besu/config/GenesisConfigOptionsTest.java +++ b/config/src/test/java/org/hyperledger/besu/config/GenesisConfigOptionsTest.java @@ -207,10 +207,9 @@ class GenesisConfigOptionsTest { } @Test - void shouldGetPragueEOFTime() { - final GenesisConfigOptions config = - fromConfigOptions(singletonMap("pragueEOFTime", 1670470143)); - assertThat(config.getPragueEOFTime()).hasValue(1670470143); + void shouldGetOsakaTime() { + final GenesisConfigOptions config = fromConfigOptions(singletonMap("osakaTime", 1670470143)); + assertThat(config.getOsakaTime()).hasValue(1670470143); } @Test @@ -247,7 +246,7 @@ class GenesisConfigOptionsTest { assertThat(config.getCancunTime()).isEmpty(); assertThat(config.getCancunEOFTime()).isEmpty(); assertThat(config.getPragueTime()).isEmpty(); - assertThat(config.getPragueEOFTime()).isEmpty(); + assertThat(config.getOsakaTime()).isEmpty(); assertThat(config.getFutureEipsTime()).isEmpty(); assertThat(config.getExperimentalEipsTime()).isEmpty(); } diff --git a/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/BlockHeaderValidationRulesetFactory.java b/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/BlockHeaderValidationRulesetFactory.java index 0274736c0f..563f31f597 100644 --- a/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/BlockHeaderValidationRulesetFactory.java +++ b/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/BlockHeaderValidationRulesetFactory.java @@ -17,7 +17,7 @@ package org.hyperledger.besu.consensus.clique; import static org.hyperledger.besu.ethereum.mainnet.AbstractGasLimitSpecification.DEFAULT_MAX_GAS_LIMIT; import static org.hyperledger.besu.ethereum.mainnet.AbstractGasLimitSpecification.DEFAULT_MIN_GAS_LIMIT; -import org.hyperledger.besu.config.MergeConfigOptions; +import org.hyperledger.besu.config.MergeConfiguration; import org.hyperledger.besu.consensus.clique.headervalidationrules.CliqueDifficultyValidationRule; import org.hyperledger.besu.consensus.clique.headervalidationrules.CliqueExtraDataValidationRule; import org.hyperledger.besu.consensus.clique.headervalidationrules.CliqueNoEmptyBlockValidationRule; @@ -69,7 +69,7 @@ public class BlockHeaderValidationRulesetFactory { createEmptyBlocks, epochManager, baseFeeMarket, - MergeConfigOptions.isMergeEnabled()); + MergeConfiguration.isMergeEnabled()); } /** diff --git a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BftEventQueue.java b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BftEventQueue.java index 4221fd1fac..8f6190c4cf 100644 --- a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BftEventQueue.java +++ b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BftEventQueue.java @@ -48,6 +48,11 @@ public class BftEventQueue { started.set(true); } + /** Stop the event queue. No events will be queued for processing until it is started. */ + public void stop() { + started.set(false); + } + private boolean isStarted() { return started.get(); } diff --git a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BftExecutors.java b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BftExecutors.java index 30038add3d..709d65faaa 100644 --- a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BftExecutors.java +++ b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BftExecutors.java @@ -78,7 +78,7 @@ public class BftExecutors { /** Start. */ public synchronized void start() { - if (state != State.IDLE) { + if (state != State.IDLE && state != State.STOPPED) { // Nothing to do return; } diff --git a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BftProcessor.java b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BftProcessor.java index 93df77ea77..81be83b469 100644 --- a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BftProcessor.java +++ b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BftProcessor.java @@ -44,8 +44,13 @@ public class BftProcessor implements Runnable { this.eventMultiplexer = eventMultiplexer; } + /** Indicate to the processor that it can be started */ + public synchronized void start() { + shutdown = false; + } + /** Indicate to the processor that it should gracefully stop at its next opportunity */ - public void stop() { + public synchronized void stop() { shutdown = true; } @@ -67,6 +72,8 @@ public class BftProcessor implements Runnable { while (!shutdown) { nextEvent().ifPresent(eventMultiplexer::handleBftEvent); } + + incomingQueue.stop(); } catch (final Throwable t) { LOG.error("BFT Mining thread has suffered a fatal error, mining has been halted", t); } diff --git a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftMiningCoordinator.java b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftMiningCoordinator.java index 83cd61beb3..795a064b6b 100644 --- a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftMiningCoordinator.java +++ b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftMiningCoordinator.java @@ -93,7 +93,9 @@ public class BftMiningCoordinator implements MiningCoordinator, BlockAddedObserv @Override public void start() { - if (state.compareAndSet(State.IDLE, State.RUNNING)) { + if (state.compareAndSet(State.IDLE, State.RUNNING) + || state.compareAndSet(State.STOPPED, State.RUNNING)) { + bftProcessor.start(); bftExecutors.start(); blockAddedObserverId = blockchain.observeBlockAdded(this); eventHandler.start(); @@ -110,7 +112,7 @@ public class BftMiningCoordinator implements MiningCoordinator, BlockAddedObserv try { bftProcessor.awaitStop(); } catch (final InterruptedException e) { - LOG.debug("Interrupted while waiting for IbftProcessor to stop.", e); + LOG.debug("Interrupted while waiting for BftProcessor to stop.", e); Thread.currentThread().interrupt(); } bftExecutors.stop(); @@ -135,12 +137,17 @@ public class BftMiningCoordinator implements MiningCoordinator, BlockAddedObserv @Override public boolean disable() { + if (state.get() == State.PAUSED + || state.compareAndSet(State.IDLE, State.PAUSED) + || state.compareAndSet(State.RUNNING, State.PAUSED)) { + return true; + } return false; } @Override public boolean isMining() { - return true; + return state.get() == State.RUNNING; } @Override diff --git a/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/BftEventQueueTest.java b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/BftEventQueueTest.java index b39bef3a43..6fbf701bc1 100644 --- a/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/BftEventQueueTest.java +++ b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/BftEventQueueTest.java @@ -134,6 +134,40 @@ public class BftEventQueueTest { assertThat(queue.poll(0, TimeUnit.MICROSECONDS)).isNull(); } + @Test + public void supportsStopAndRestart() throws InterruptedException { + final BftEventQueue queue = new BftEventQueue(MAX_QUEUE_SIZE); + queue.start(); + + assertThat(queue.poll(0, TimeUnit.MICROSECONDS)).isNull(); + final DummyBftEvent dummyMessageEvent = new DummyBftEvent(); + final DummyRoundExpiryBftEvent dummyRoundTimerEvent = new DummyRoundExpiryBftEvent(); + final DummyNewChainHeadBftEvent dummyNewChainHeadEvent = new DummyNewChainHeadBftEvent(); + + queue.add(dummyMessageEvent); + queue.add(dummyRoundTimerEvent); + queue.add(dummyNewChainHeadEvent); + assertThat(queue.poll(0, TimeUnit.MICROSECONDS)).isNotNull(); + assertThat(queue.poll(0, TimeUnit.MICROSECONDS)).isNotNull(); + assertThat(queue.poll(0, TimeUnit.MICROSECONDS)).isNotNull(); + assertThat(queue.poll(0, TimeUnit.MICROSECONDS)).isNull(); + + queue.stop(); + queue.add(dummyMessageEvent); + queue.add(dummyRoundTimerEvent); + queue.add(dummyNewChainHeadEvent); + assertThat(queue.poll(0, TimeUnit.MICROSECONDS)).isNull(); + + queue.start(); + queue.add(dummyMessageEvent); + queue.add(dummyRoundTimerEvent); + queue.add(dummyNewChainHeadEvent); + assertThat(queue.poll(0, TimeUnit.MICROSECONDS)).isNotNull(); + assertThat(queue.poll(0, TimeUnit.MICROSECONDS)).isNotNull(); + assertThat(queue.poll(0, TimeUnit.MICROSECONDS)).isNotNull(); + assertThat(queue.poll(0, TimeUnit.MICROSECONDS)).isNull(); + } + @Test public void alwaysAddBlockTimerExpiryEvents() throws InterruptedException { final BftEventQueue queue = new BftEventQueue(MAX_QUEUE_SIZE); diff --git a/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftMiningCoordinatorTest.java b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftMiningCoordinatorTest.java index cb0dffba9b..328f9fd7b7 100644 --- a/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftMiningCoordinatorTest.java +++ b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftMiningCoordinatorTest.java @@ -19,6 +19,7 @@ import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import static org.mockito.internal.verification.VerificationModeFactory.times; import org.hyperledger.besu.consensus.common.bft.BftEventQueue; import org.hyperledger.besu.consensus.common.bft.BftExecutors; @@ -82,6 +83,28 @@ public class BftMiningCoordinatorTest { verify(bftProcessor).stop(); } + @Test + public void restartsMiningAfterStop() { + assertThat(bftMiningCoordinator.isMining()).isFalse(); + bftMiningCoordinator.stop(); + verify(bftProcessor, never()).stop(); + + bftMiningCoordinator.enable(); + bftMiningCoordinator.start(); + assertThat(bftMiningCoordinator.isMining()).isTrue(); + + bftMiningCoordinator.stop(); + assertThat(bftMiningCoordinator.isMining()).isFalse(); + verify(bftProcessor).stop(); + + bftMiningCoordinator.start(); + assertThat(bftMiningCoordinator.isMining()).isTrue(); + + // BFT processor should be started once for every time the mining + // coordinator is restarted + verify(bftProcessor, times(2)).start(); + } + @Test public void getsMinTransactionGasPrice() { final Wei minGasPrice = Wei.of(10); diff --git a/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/PayloadWrapper.java b/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/PayloadWrapper.java index 4a8588f84e..603834c869 100644 --- a/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/PayloadWrapper.java +++ b/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/PayloadWrapper.java @@ -18,12 +18,17 @@ import org.hyperledger.besu.consensus.merge.blockcreation.PayloadIdentifier; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.core.BlockValueCalculator; import org.hyperledger.besu.ethereum.core.BlockWithReceipts; +import org.hyperledger.besu.ethereum.core.Request; + +import java.util.List; +import java.util.Optional; /** Wrapper for payload plus extra info. */ public class PayloadWrapper { private final PayloadIdentifier payloadIdentifier; private final BlockWithReceipts blockWithReceipts; private final Wei blockValue; + private final Optional> requests; /** * Construct a wrapper with the following fields. @@ -32,10 +37,13 @@ public class PayloadWrapper { * @param blockWithReceipts Block with receipts */ public PayloadWrapper( - final PayloadIdentifier payloadIdentifier, final BlockWithReceipts blockWithReceipts) { + final PayloadIdentifier payloadIdentifier, + final BlockWithReceipts blockWithReceipts, + final Optional> requests) { this.blockWithReceipts = blockWithReceipts; this.payloadIdentifier = payloadIdentifier; this.blockValue = BlockValueCalculator.calculateBlockValue(blockWithReceipts); + this.requests = requests; } /** @@ -64,4 +72,13 @@ public class PayloadWrapper { public BlockWithReceipts blockWithReceipts() { return blockWithReceipts; } + + /** + * Get the requests + * + * @return requests + */ + public Optional> requests() { + return requests; + } } diff --git a/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeCoordinator.java b/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeCoordinator.java index 00af6c2785..a3f9a4b69f 100644 --- a/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeCoordinator.java +++ b/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeCoordinator.java @@ -302,7 +302,9 @@ public class MergeCoordinator implements MergeMiningCoordinator, BadChainListene if (result.isSuccessful()) { mergeContext.putPayloadById( new PayloadWrapper( - payloadIdentifier, new BlockWithReceipts(emptyBlock, result.getReceipts()))); + payloadIdentifier, + new BlockWithReceipts(emptyBlock, result.getReceipts()), + result.getRequests())); LOG.info( "Start building proposals for block {} identified by {}", emptyBlock.getHeader().getNumber(), @@ -469,7 +471,9 @@ public class MergeCoordinator implements MergeMiningCoordinator, BadChainListene mergeContext.putPayloadById( new PayloadWrapper( - payloadIdentifier, new BlockWithReceipts(bestBlock, resultBest.getReceipts()))); + payloadIdentifier, + new BlockWithReceipts(bestBlock, resultBest.getReceipts()), + resultBest.getRequests())); LOG.atDebug() .setMessage( "Successfully built block {} for proposal identified by {}, with {} transactions, in {}ms") diff --git a/consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeCoordinatorTest.java b/consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeCoordinatorTest.java index 9c1a3df075..4efcdc1e0f 100644 --- a/consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeCoordinatorTest.java +++ b/consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeCoordinatorTest.java @@ -32,7 +32,7 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import org.hyperledger.besu.config.MergeConfigOptions; +import org.hyperledger.besu.config.MergeConfiguration; import org.hyperledger.besu.consensus.merge.MergeContext; import org.hyperledger.besu.consensus.merge.PayloadWrapper; import org.hyperledger.besu.consensus.merge.blockcreation.MergeMiningCoordinator.ForkchoiceResult; @@ -59,6 +59,7 @@ import org.hyperledger.besu.ethereum.core.ImmutableMiningParameters; import org.hyperledger.besu.ethereum.core.ImmutableMiningParameters.MutableInitValues; import org.hyperledger.besu.ethereum.core.ImmutableMiningParameters.Unstable; import org.hyperledger.besu.ethereum.core.MiningParameters; +import org.hyperledger.besu.ethereum.core.Synchronizer; import org.hyperledger.besu.ethereum.core.TransactionTestFixture; import org.hyperledger.besu.ethereum.eth.manager.EthContext; import org.hyperledger.besu.ethereum.eth.manager.EthScheduler; @@ -189,6 +190,7 @@ public class MergeCoordinatorTest implements MergeGenesisConfigHelper { protocolContext = new ProtocolContext(blockchain, worldStateArchive, mergeContext, badBlockManager); + protocolContext.setSynchronizer(mock(Synchronizer.class)); var mutable = worldStateArchive.getMutable(); genesisState.writeStateTo(mutable); mutable.persist(null); @@ -204,7 +206,7 @@ public class MergeCoordinatorTest implements MergeGenesisConfigHelper { return blockCreationTask; }); - MergeConfigOptions.setMergeEnabled(true); + MergeConfiguration.setMergeEnabled(true); when(ethContext.getEthPeers().subscribeConnect(any())).thenReturn(1L); this.transactionPool = diff --git a/consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeReorgTest.java b/consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeReorgTest.java index 9b6cf907d2..7b111268e0 100644 --- a/consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeReorgTest.java +++ b/consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeReorgTest.java @@ -19,7 +19,7 @@ import static org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider import static org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider.createInMemoryWorldStateArchive; import static org.mockito.Mockito.mock; -import org.hyperledger.besu.config.MergeConfigOptions; +import org.hyperledger.besu.config.MergeConfiguration; import org.hyperledger.besu.consensus.merge.MergeContext; import org.hyperledger.besu.consensus.merge.PostMergeContext; import org.hyperledger.besu.datatypes.Address; @@ -89,7 +89,7 @@ public class MergeReorgTest implements MergeGenesisConfigHelper { genesisState.writeStateTo(mutable); mutable.persist(null); mergeContext.setTerminalTotalDifficulty(Difficulty.of(1001)); - MergeConfigOptions.setMergeEnabled(true); + MergeConfiguration.setMergeEnabled(true); this.coordinator = new MergeCoordinator( protocolContext, diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/messagewrappers/ProposalTest.java b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/messagewrappers/ProposalTest.java index b3c462656a..5b7314f94a 100644 --- a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/messagewrappers/ProposalTest.java +++ b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/messagewrappers/ProposalTest.java @@ -54,8 +54,7 @@ public class ProposalTest { new BlockBody( Collections.emptyList(), Collections.emptyList(), - Optional.of(Collections.emptyList()), - Optional.empty())); + Optional.of(Collections.emptyList()))); @Test public void canRoundTripProposalMessage() { diff --git a/datatypes/src/main/java/org/hyperledger/besu/datatypes/HardforkId.java b/datatypes/src/main/java/org/hyperledger/besu/datatypes/HardforkId.java index 85ec84b4ad..d8b938a1b3 100644 --- a/datatypes/src/main/java/org/hyperledger/besu/datatypes/HardforkId.java +++ b/datatypes/src/main/java/org/hyperledger/besu/datatypes/HardforkId.java @@ -81,8 +81,6 @@ public interface HardforkId { CANCUN_EOF(false, "Cancun + EOF"), /** Prague fork. */ PRAGUE(false, "Prague"), - /** Prague + EOF fork. */ - PRAGUE_EOF(false, "Prague + EOF"), /** Osaka fork. */ OSAKA(false, "Osaka"), /** Amsterdam fork. */ diff --git a/datatypes/src/main/java/org/hyperledger/besu/datatypes/Hash.java b/datatypes/src/main/java/org/hyperledger/besu/datatypes/Hash.java index a53843a247..3777169ed4 100644 --- a/datatypes/src/main/java/org/hyperledger/besu/datatypes/Hash.java +++ b/datatypes/src/main/java/org/hyperledger/besu/datatypes/Hash.java @@ -15,6 +15,7 @@ package org.hyperledger.besu.datatypes; import static org.hyperledger.besu.crypto.Hash.keccak256; +import static org.hyperledger.besu.crypto.Hash.sha256; import org.hyperledger.besu.ethereum.rlp.RLP; @@ -50,6 +51,17 @@ public class Hash extends DelegatingBytes32 { */ public static final Hash EMPTY = hash(Bytes.EMPTY); + /** + * Hash of empty requests or "0x6036c41849da9c076ed79654d434017387a88fb833c2856b32e18218b3341c5f" + */ + public static final Hash EMPTY_REQUESTS_HASH = + Hash.wrap( + sha256( + Bytes.concatenate( + sha256(Bytes.of(RequestType.DEPOSIT.getSerializedType())), + sha256(Bytes.of(RequestType.WITHDRAWAL.getSerializedType())), + sha256(Bytes.of(RequestType.CONSOLIDATION.getSerializedType()))))); + /** * Instantiates a new Hash. * diff --git a/datatypes/src/test/java/org/hyperledger/besu/datatypes/HashTest.java b/datatypes/src/test/java/org/hyperledger/besu/datatypes/HashTest.java index 1ae3b8c14e..a2ef3fe559 100644 --- a/datatypes/src/test/java/org/hyperledger/besu/datatypes/HashTest.java +++ b/datatypes/src/test/java/org/hyperledger/besu/datatypes/HashTest.java @@ -26,4 +26,12 @@ public class HashTest { .isEqualTo( Hash.fromHexString("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470")); } + + @Test + public void shouldGetExpectedValueForEmptyRequestsHash() { + assertThat(Hash.EMPTY_REQUESTS_HASH) + .isEqualTo( + Hash.fromHexString( + "0x6036c41849da9c076ed79654d434017387a88fb833c2856b32e18218b3341c5f")); + } } diff --git a/docker/test.sh b/docker/test.sh index e230f79ad1..2cc49bdb2c 100755 --- a/docker/test.sh +++ b/docker/test.sh @@ -1,6 +1,6 @@ #!/bin/bash ## -## Copyright contributors to Hyperledger Besu. +## Copyright contributors to 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 diff --git a/enclave/build.gradle b/enclave/build.gradle index 25aeb466d7..24aa1b2e64 100644 --- a/enclave/build.gradle +++ b/enclave/build.gradle @@ -24,5 +24,4 @@ dependencies { integrationTestImplementation 'org.awaitility:awaitility' integrationTestImplementation 'org.junit.jupiter:junit-jupiter-api' integrationTestImplementation 'org.mockito:mockito-core' - integrationTestImplementation 'org.testcontainers:testcontainers' } diff --git a/ethereum/api/build.gradle b/ethereum/api/build.gradle index 3269812fec..6bbfa531a9 100644 --- a/ethereum/api/build.gradle +++ b/ethereum/api/build.gradle @@ -121,7 +121,6 @@ dependencies { integrationTestImplementation 'org.junit.jupiter:junit-jupiter' integrationTestImplementation 'org.mockito:mockito-core' integrationTestImplementation 'org.mockito:mockito-junit-jupiter' - integrationTestImplementation 'org.testcontainers:testcontainers' integrationTestRuntimeOnly 'org.junit.jupiter:junit-jupiter' } @@ -130,41 +129,44 @@ artifacts { testSupportArtifacts testSupportJar } tasks.register('generateTestBlockchain') { def srcFiles = 'src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/trace/chain-data' - def dataPath = "$buildDir/generated/data" + def dataPath = new File("$buildDir/generated/data") def blocksBin = "$buildDir/resources/test/org/hyperledger/besu/ethereum/api/jsonrpc/trace/chain-data/blocks.bin" inputs.dir(srcFiles) outputs.file(blocksBin) dependsOn(configurations.testResourceGeneration) dependsOn(processTestResources) doLast { - mkdir(dataPath) - javaexec { - main = 'org.hyperledger.besu.Besu' - classpath = configurations.testResourceGeneration - args = [ - "--logging=ERROR", - "--data-path=$dataPath", - "--genesis-file=$srcFiles/genesis.json", - "blocks", - "import", - "--format=JSON", - "--from=$srcFiles/blocks.json", - "--start-time=1438269971" - ] - } - javaexec { - main = 'org.hyperledger.besu.Besu' - classpath = configurations.testResourceGeneration - args = [ - "--logging=ERROR", - "--data-path=$dataPath", - "--genesis-file=$srcFiles/genesis.json", - "blocks", - "export", - "--format=RLP", - "--start-block=0", - "--to=$blocksBin" - ] + if(!dataPath.exists()) { + mkdir(dataPath) + + javaexec { + main = 'org.hyperledger.besu.Besu' + classpath = configurations.testResourceGeneration + args = [ + "--logging=ERROR", + "--data-path=$dataPath", + "--genesis-file=$srcFiles/genesis.json", + "blocks", + "import", + "--format=JSON", + "--from=$srcFiles/blocks.json", + "--start-time=1438269971" + ] + } + javaexec { + main = 'org.hyperledger.besu.Besu' + classpath = configurations.testResourceGeneration + args = [ + "--logging=ERROR", + "--data-path=$dataPath", + "--genesis-file=$srcFiles/genesis.json", + "blocks", + "export", + "--format=RLP", + "--start-block=0", + "--to=$blocksBin" + ] + } } } } diff --git a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcResponseKey.java b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcResponseKey.java index a62cc06ec2..045b4ad02d 100644 --- a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcResponseKey.java +++ b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcResponseKey.java @@ -38,5 +38,6 @@ public enum JsonRpcResponseKey { TRANSACTION_ROOT, BASEFEE, WITHDRAWALS_ROOT, - REQUESTS_ROOT + REQUESTS_HASH, + TARGET_BLOB_COUNT } diff --git a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcResponseUtils.java b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcResponseUtils.java index 09235fbdb2..18208272d9 100644 --- a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcResponseUtils.java +++ b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcResponseUtils.java @@ -27,7 +27,7 @@ import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcResponseKey.NUMBE import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcResponseKey.OMMERS_HASH; import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcResponseKey.PARENT_HASH; import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcResponseKey.RECEIPTS_ROOT; -import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcResponseKey.REQUESTS_ROOT; +import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcResponseKey.REQUESTS_HASH; import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcResponseKey.SIZE; import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcResponseKey.STATE_ROOT; import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcResponseKey.TIMESTAMP; @@ -63,6 +63,7 @@ import java.util.Optional; import com.fasterxml.jackson.databind.JsonNode; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.units.bigints.UInt256; +import org.apache.tuweni.units.bigints.UInt64; public class JsonRpcResponseUtils { @@ -104,8 +105,12 @@ public class JsonRpcResponseUtils { final int size = unsignedInt(values.get(SIZE)); final Hash withdrawalsRoot = values.containsKey(WITHDRAWALS_ROOT) ? hash(values.get(WITHDRAWALS_ROOT)) : null; - final Hash requestsRoot = - values.containsKey(REQUESTS_ROOT) ? hash(values.get(REQUESTS_ROOT)) : null; + final Hash requestsHash = + values.containsKey(REQUESTS_HASH) ? hash(values.get(REQUESTS_HASH)) : null; + final UInt64 targetBlobCount = + values.containsKey(JsonRpcResponseKey.TARGET_BLOB_COUNT) + ? UInt64.fromHexString(values.get(JsonRpcResponseKey.TARGET_BLOB_COUNT)) + : null; final List ommers = new ArrayList<>(); final BlockHeader header = @@ -130,7 +135,8 @@ public class JsonRpcResponseUtils { null, // ToDo 4844: set with the value of blob_gas_used field null, // ToDo 4844: set with the value of excess_blob_gas field null, // TODO 4788: set with the value of the parent beacon block root field - requestsRoot, + requestsHash, + targetBlobCount, null, blockHeaderFunctions); diff --git a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcTestMethodsFactory.java b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcTestMethodsFactory.java index 538060a905..c7ba5a4f93 100644 --- a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcTestMethodsFactory.java +++ b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcTestMethodsFactory.java @@ -68,7 +68,6 @@ public class JsonRpcTestMethodsFactory { private static final String CLIENT_NODE_NAME = "TestClientVersion/0.1.0"; private static final String CLIENT_VERSION = "0.1.0"; private static final String CLIENT_COMMIT = "12345678"; - private static final BigInteger NETWORK_ID = BigInteger.valueOf(123); private final BlockchainImporter importer; private final MutableBlockchain blockchain; @@ -76,6 +75,7 @@ public class JsonRpcTestMethodsFactory { private final ProtocolContext context; private final BlockchainQueries blockchainQueries; private final Synchronizer synchronizer; + private final ProtocolSchedule protocolSchedule; public JsonRpcTestMethodsFactory(final BlockchainImporter importer) { this.importer = importer; @@ -84,7 +84,7 @@ public class JsonRpcTestMethodsFactory { this.importer.getGenesisState().writeStateTo(stateArchive.getMutable()); this.context = new ProtocolContext(blockchain, stateArchive, null, new BadBlockManager()); - final ProtocolSchedule protocolSchedule = importer.getProtocolSchedule(); + this.protocolSchedule = importer.getProtocolSchedule(); this.synchronizer = mock(Synchronizer.class); for (final Block block : importer.getBlocks()) { @@ -106,6 +106,7 @@ public class JsonRpcTestMethodsFactory { this.blockchain = blockchain; this.stateArchive = stateArchive; this.context = context; + this.protocolSchedule = importer.getProtocolSchedule(); this.blockchainQueries = new BlockchainQueries( importer.getProtocolSchedule(), @@ -126,6 +127,7 @@ public class JsonRpcTestMethodsFactory { this.stateArchive = stateArchive; this.context = context; this.synchronizer = synchronizer; + this.protocolSchedule = importer.getProtocolSchedule(); this.blockchainQueries = new BlockchainQueries( importer.getProtocolSchedule(), @@ -142,6 +144,10 @@ public class JsonRpcTestMethodsFactory { return stateArchive; } + public BigInteger getChainId() { + return protocolSchedule.getChainId().get(); + } + public Map methods() { final P2PNetwork peerDiscovery = mock(P2PNetwork.class); final EthPeers ethPeers = mock(EthPeers.class); @@ -183,7 +189,7 @@ public class JsonRpcTestMethodsFactory { CLIENT_NODE_NAME, CLIENT_VERSION, CLIENT_COMMIT, - NETWORK_ID, + getChainId(), new StubGenesisConfigOptions(), peerDiscovery, blockchainQueries, diff --git a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/london/EthCallIntegrationTest.java b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/london/EthCallIntegrationTest.java index 5f03d7f4d5..9fb692ef82 100644 --- a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/london/EthCallIntegrationTest.java +++ b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/london/EthCallIntegrationTest.java @@ -30,6 +30,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSucces import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.testutil.BlockTestUtil; +import java.math.BigInteger; import java.util.Map; import com.google.common.base.Charsets; @@ -142,6 +143,7 @@ public class EthCallIntegrationTest { public void shouldReturnSuccessWithValidMaxFeePerGas() { final JsonCallParameter callParameter = new JsonCallParameter.JsonCallParameterBuilder() + .withChainId(BLOCKCHAIN.getChainId()) .withFrom(Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b")) .withTo(Address.fromHexString("0x9b8397f1b0fecd3a1a40cdd5e8221fa461898517")) .withMaxFeePerGas(Wei.fromHexString("0x3B9ACA01")) @@ -158,6 +160,26 @@ public class EthCallIntegrationTest { assertThat(response).usingRecursiveComparison().isEqualTo(expectedResponse); } + @Test + public void shouldReturnErrorWithInvalidChainId() { + final JsonCallParameter callParameter = + new JsonCallParameter.JsonCallParameterBuilder() + .withChainId(BLOCKCHAIN.getChainId().add(BigInteger.ONE)) + .withFrom(Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b")) + .withTo(Address.fromHexString("0x9b8397f1b0fecd3a1a40cdd5e8221fa461898517")) + .withMaxFeePerGas(Wei.fromHexString("0x3B9ACA01")) + .withInput(Bytes.fromHexString("0x2e64cec1")) + .build(); + + final JsonRpcRequestContext request = requestWithParams(callParameter, "latest"); + final JsonRpcResponse expectedResponse = + new JsonRpcErrorResponse(null, RpcErrorType.WRONG_CHAIN_ID); + + final JsonRpcResponse response = method.response(request); + + assertThat(response).usingRecursiveComparison().isEqualTo(expectedResponse); + } + @Test public void shouldReturnSuccessWithValidMaxFeePerGasAndMaxPriorityFeePerGas() { final JsonCallParameter callParameter = diff --git a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/london/EthEstimateGasIntegrationTest.java b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/london/EthEstimateGasIntegrationTest.java index 84447dfc9d..5fde9ccecb 100644 --- a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/london/EthEstimateGasIntegrationTest.java +++ b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/london/EthEstimateGasIntegrationTest.java @@ -25,10 +25,15 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonCallParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; +import org.hyperledger.besu.ethereum.mainnet.ValidationResult; +import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason; import org.hyperledger.besu.testutil.BlockTestUtil; +import java.math.BigInteger; import java.util.List; import java.util.Map; @@ -112,6 +117,7 @@ public class EthEstimateGasIntegrationTest { public void shouldReturnExpectedValueForContractDeploy_WithAccessList() { final JsonCallParameter callParameter = new JsonCallParameter.JsonCallParameterBuilder() + .withChainId(BLOCKCHAIN.getChainId()) .withFrom(Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b")) .withInput( Bytes.fromHexString( @@ -124,6 +130,30 @@ public class EthEstimateGasIntegrationTest { assertThat(response).usingRecursiveComparison().isEqualTo(expectedResponse); } + @Test + public void shouldReturnErrorWithInvalidChainId() { + final JsonCallParameter callParameter = + new JsonCallParameter.JsonCallParameterBuilder() + .withChainId(BLOCKCHAIN.getChainId().add(BigInteger.ONE)) + .withFrom(Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b")) + .withTo(Address.fromHexString("0x8888f1f195afa192cfee860698584c030f4c9db1")) + .withValue(Wei.ONE) + .build(); + + final JsonRpcRequestContext request = requestWithParams(callParameter, "latest"); + final JsonRpcResponse expectedResponse = + new JsonRpcErrorResponse( + null, + JsonRpcError.from( + ValidationResult.invalid( + TransactionInvalidReason.WRONG_CHAIN_ID, + "transaction was meant for chain id 1983 and not this chain id 1982"))); + + final JsonRpcResponse response = method.response(request); + + assertThat(response).usingRecursiveComparison().isEqualTo(expectedResponse); + } + private List createAccessList() { return List.of( new AccessListEntry( diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcConfiguration.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcConfiguration.java index 2ed9c56d54..726e205d1c 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcConfiguration.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcConfiguration.java @@ -32,7 +32,7 @@ import java.util.Optional; import com.google.common.base.MoreObjects; public class JsonRpcConfiguration { - private static final String DEFAULT_JSON_RPC_HOST = "127.0.0.1"; + public static final String DEFAULT_JSON_RPC_HOST = "127.0.0.1"; public static final int DEFAULT_JSON_RPC_PORT = 8545; public static final int DEFAULT_ENGINE_JSON_RPC_PORT = 8551; public static final int DEFAULT_MAX_ACTIVE_CONNECTIONS = 80; diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/execution/TracedJsonRpcProcessor.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/execution/TracedJsonRpcProcessor.java index ec0e6aef64..2a38afd630 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/execution/TracedJsonRpcProcessor.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/execution/TracedJsonRpcProcessor.java @@ -79,6 +79,7 @@ public class TracedJsonRpcProcessor implements JsonRpcProcessor { case INVALID_ENGINE_PREPARE_PAYLOAD_PARAMS: case INVALID_ENODE_PARAMS: case INVALID_EXCESS_BLOB_GAS_PARAMS: + case INVALID_EXECUTION_REQUESTS_PARAMS: case INVALID_EXTRA_DATA_PARAMS: case INVALID_FILTER_PARAMS: case INVALID_GAS_PRICE_PARAMS: diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AbstractEstimateGas.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AbstractEstimateGas.java index 4cbfb818db..8e826caf9e 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AbstractEstimateGas.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AbstractEstimateGas.java @@ -103,6 +103,7 @@ public abstract class AbstractEstimateGas extends AbstractBlockParameterMethod { protected CallParameter overrideGasLimitAndPrice( final JsonCallParameter callParams, final long gasLimit) { return new CallParameter( + callParams.getChainId(), callParams.getFrom(), callParams.getTo(), gasLimit, @@ -111,7 +112,9 @@ public abstract class AbstractEstimateGas extends AbstractBlockParameterMethod { callParams.getMaxFeePerGas(), callParams.getValue(), callParams.getPayload(), - callParams.getAccessList()); + callParams.getAccessList(), + callParams.getMaxFeePerBlobGas(), + callParams.getBlobVersionedHashes()); } /** diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthFeeHistory.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthFeeHistory.java index b95746dad9..2c5c6afd05 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthFeeHistory.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthFeeHistory.java @@ -14,7 +14,6 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; -import static java.util.stream.Collectors.toUnmodifiableList; import static org.hyperledger.besu.ethereum.mainnet.feemarket.ExcessBlobGasCalculator.calculateExcessBlobGasForParent; import org.hyperledger.besu.datatypes.Hash; @@ -32,6 +31,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSucces import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.FeeHistory; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.ImmutableFeeHistory; +import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; import org.hyperledger.besu.ethereum.blockcreation.MiningCoordinator; import org.hyperledger.besu.ethereum.chain.Blockchain; import org.hyperledger.besu.ethereum.core.Block; @@ -57,9 +57,11 @@ import com.github.benmanes.caffeine.cache.Cache; import com.github.benmanes.caffeine.cache.Caffeine; import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.Streams; +import org.apache.tuweni.units.bigints.UInt256s; public class EthFeeHistory implements JsonRpcMethod { private final ProtocolSchedule protocolSchedule; + private final BlockchainQueries blockchainQueries; private final Blockchain blockchain; private final MiningCoordinator miningCoordinator; private final ApiConfiguration apiConfiguration; @@ -70,13 +72,14 @@ public class EthFeeHistory implements JsonRpcMethod { public EthFeeHistory( final ProtocolSchedule protocolSchedule, - final Blockchain blockchain, + final BlockchainQueries blockchainQueries, final MiningCoordinator miningCoordinator, final ApiConfiguration apiConfiguration) { this.protocolSchedule = protocolSchedule; - this.blockchain = blockchain; + this.blockchainQueries = blockchainQueries; this.miningCoordinator = miningCoordinator; this.apiConfiguration = apiConfiguration; + this.blockchain = blockchainQueries.getBlockchain(); this.cache = Caffeine.newBuilder().maximumSize(MAXIMUM_CACHE_SIZE).build(); } @@ -136,7 +139,8 @@ public class EthFeeHistory implements JsonRpcMethod { final List gasUsedRatios = getGasUsedRatios(blockHeaderRange); final List blobGasUsedRatios = getBlobGasUsedRatios(blockHeaderRange); final Optional>> maybeRewards = - maybeRewardPercentiles.map(rewards -> getRewards(rewards, blockHeaderRange)); + maybeRewardPercentiles.map( + percentiles -> getRewards(percentiles, blockHeaderRange, nextBaseFee)); return new JsonRpcSuccessResponse( requestId, createFeeHistoryResult( @@ -203,17 +207,19 @@ public class EthFeeHistory implements JsonRpcMethod { } private List> getRewards( - final List rewardPercentiles, final List blockHeaders) { + final List rewardPercentiles, + final List blockHeaders, + final Wei nextBaseFee) { var sortedPercentiles = rewardPercentiles.stream().sorted().toList(); return blockHeaders.stream() .parallel() - .map(blockHeader -> calculateBlockHeaderReward(sortedPercentiles, blockHeader)) + .map(blockHeader -> calculateBlockHeaderReward(sortedPercentiles, blockHeader, nextBaseFee)) .flatMap(Optional::stream) .toList(); } private Optional> calculateBlockHeaderReward( - final List sortedPercentiles, final BlockHeader blockHeader) { + final List sortedPercentiles, final BlockHeader blockHeader, final Wei nextBaseFee) { // Create a new key for the reward cache final RewardCacheKey key = new RewardCacheKey(blockHeader.getBlockHash(), sortedPercentiles); @@ -226,7 +232,7 @@ public class EthFeeHistory implements JsonRpcMethod { Optional block = blockchain.getBlockByHash(blockHeader.getBlockHash()); return block.map( b -> { - List rewards = computeRewards(sortedPercentiles, b); + List rewards = computeRewards(sortedPercentiles, b, nextBaseFee); // Put the computed rewards in the cache for future use cache.put(key, rewards); return rewards; @@ -237,7 +243,8 @@ public class EthFeeHistory implements JsonRpcMethod { record TransactionInfo(Transaction transaction, Long gasUsed, Wei effectivePriorityFeePerGas) {} @VisibleForTesting - public List computeRewards(final List rewardPercentiles, final Block block) { + public List computeRewards( + final List rewardPercentiles, final Block block, final Wei nextBaseFee) { final List transactions = block.getBody().getTransactions(); if (transactions.isEmpty()) { // all 0's for empty block @@ -253,7 +260,7 @@ public class EthFeeHistory implements JsonRpcMethod { // If the priority fee boundary is set, return the bounded rewards. Otherwise, return the real // rewards. if (apiConfiguration.isGasAndPriorityFeeLimitingEnabled()) { - return boundRewards(realRewards); + return boundRewards(realRewards, nextBaseFee); } else { return realRewards; } @@ -292,16 +299,20 @@ public class EthFeeHistory implements JsonRpcMethod { * This method returns a list of bounded rewards. * * @param rewards The list of rewards to be bounded. + * @param nextBaseFee The base fee of the next block. * @return The list of bounded rewards. */ - private List boundRewards(final List rewards) { - Wei minPriorityFee = miningCoordinator.getMinPriorityFeePerGas(); - Wei lowerBound = - minPriorityFee + private List boundRewards(final List rewards, final Wei nextBaseFee) { + final Wei lowerBoundGasPrice = blockchainQueries.gasPriceLowerBound(); + final Wei lowerBoundPriorityFee = lowerBoundGasPrice.subtract(nextBaseFee); + final Wei minPriorityFee = miningCoordinator.getMinPriorityFeePerGas(); + final Wei forcedMinPriorityFee = UInt256s.max(minPriorityFee, lowerBoundPriorityFee); + final Wei lowerBound = + forcedMinPriorityFee .multiply(apiConfiguration.getLowerBoundGasAndPriorityFeeCoefficient()) .divide(100); - Wei upperBound = - minPriorityFee + final Wei upperBound = + forcedMinPriorityFee .multiply(apiConfiguration.getUpperBoundGasAndPriorityFeeCoefficient()) .divide(100); @@ -438,7 +449,7 @@ public class EthFeeHistory implements JsonRpcMethod { .oldestBlock(oldestBlock) .baseFeePerGas( Stream.concat(explicitlyRequestedBaseFees.stream(), Stream.of(nextBaseFee)) - .collect(toUnmodifiableList())) + .toList()) .baseFeePerBlobGas(requestedBlobBaseFees) .gasUsedRatio(gasUsedRatios) .blobGasUsedRatio(blobGasUsedRatio) diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockReceipts.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockReceipts.java index a113e4ee8e..819ac5e1eb 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockReceipts.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockReceipts.java @@ -95,7 +95,8 @@ public class EthGetBlockReceipts extends AbstractBlockParameterOrBlockHashMethod .map( block -> block.getTransactions().stream() - .map(tx -> txReceipt(tx).get()) + .map(this::txReceipt) + .flatMap(Optional::stream) .collect(Collectors.toList())) .orElse(new ArrayList<>()); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayload.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayload.java index 91a5ee55ab..6369a53cdf 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayload.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayload.java @@ -21,15 +21,14 @@ import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.Executi import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod.EngineStatus.SYNCING; import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod.EngineStatus.VALID; import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.ExecutionWitnessValidatorProvider.getExecutionWitnessValidator; -import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.RequestValidatorProvider.getConsolidationRequestValidator; -import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.RequestValidatorProvider.getDepositRequestValidator; -import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.RequestValidatorProvider.getWithdrawalRequestValidator; +import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.RequestValidatorProvider.getRequestsValidator; import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.WithdrawalsValidatorProvider.getWithdrawalsValidator; import org.hyperledger.besu.consensus.merge.blockcreation.MergeMiningCoordinator; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.BlobGas; import org.hyperledger.besu.datatypes.Hash; +import org.hyperledger.besu.datatypes.RequestType; import org.hyperledger.besu.datatypes.VersionedHash; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.BlockProcessingResult; @@ -37,13 +36,10 @@ import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcRequestException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.ConsolidationRequestParameter; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.DepositRequestParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.EnginePayloadParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.ExecutionWitnessParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.WithdrawalParameter; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.WithdrawalRequestParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; @@ -68,7 +64,6 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; import org.hyperledger.besu.ethereum.mainnet.ValidationResult; import org.hyperledger.besu.ethereum.mainnet.feemarket.ExcessBlobGasCalculator; -import org.hyperledger.besu.ethereum.mainnet.requests.RequestUtil; import org.hyperledger.besu.ethereum.rlp.RLPException; import org.hyperledger.besu.ethereum.trie.MerkleTrieException; import org.hyperledger.besu.plugin.services.exception.StorageException; @@ -79,6 +74,7 @@ import java.util.Collections; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; +import java.util.stream.IntStream; import io.vertx.core.Vertx; import io.vertx.core.json.Json; @@ -145,8 +141,22 @@ public abstract class AbstractEngineNewPayload extends ExecutionEngineJsonRpcMet final Optional maybeParentBeaconBlockRoot = maybeParentBeaconBlockRootParam.map(Bytes32::fromHexString); + final Optional> maybeRequestsParam; + try { + maybeRequestsParam = requestContext.getOptionalList(3, String.class); + } catch (JsonRpcParameterException e) { + throw new InvalidJsonRpcRequestException( + "Invalid execution request parameters (index 3)", + RpcErrorType.INVALID_EXECUTION_REQUESTS_PARAMS, + e); + } + final ValidationResult parameterValidationResult = - validateParameters(blockParam, maybeVersionedHashParam, maybeParentBeaconBlockRootParam); + validateParameters( + blockParam, + maybeVersionedHashParam, + maybeParentBeaconBlockRootParam, + maybeRequestsParam); if (!parameterValidationResult.isValid()) { return new JsonRpcErrorResponse(reqId, parameterValidationResult); } @@ -187,39 +197,22 @@ public abstract class AbstractEngineNewPayload extends ExecutionEngineJsonRpcMet return new JsonRpcErrorResponse(reqId, RpcErrorType.INVALID_WITHDRAWALS_PARAMS); } - final Optional> maybeDepositRequests = - Optional.ofNullable(blockParam.getDepositRequests()) - .map(ds -> ds.stream().map(DepositRequestParameter::toDeposit).collect(toList())); - if (!getDepositRequestValidator( - protocolSchedule.get(), blockParam.getTimestamp(), blockParam.getBlockNumber()) - .validateParameter(maybeDepositRequests)) { - return new JsonRpcErrorResponse(reqId, RpcErrorType.INVALID_DEPOSIT_REQUEST_PARAMS); - } - - final Optional> maybeWithdrawalRequests = - Optional.ofNullable(blockParam.getWithdrawalRequests()) - .map( - withdrawalRequest -> - withdrawalRequest.stream() - .map(WithdrawalRequestParameter::toWithdrawalRequest) - .collect(toList())); - if (!getWithdrawalRequestValidator( - protocolSchedule.get(), blockParam.getTimestamp(), blockParam.getBlockNumber()) - .validateParameter(maybeWithdrawalRequests)) { - return new JsonRpcErrorResponse(reqId, RpcErrorType.INVALID_WITHDRAWALS_PARAMS); + final Optional> maybeRequests; + try { + maybeRequests = extractRequests(maybeRequestsParam); + } catch (RuntimeException ex) { + return respondWithInvalid( + reqId, + blockParam, + mergeCoordinator.getLatestValidAncestor(blockParam.getParentHash()).orElse(null), + INVALID, + "Invalid execution requests"); } - final Optional> maybeConsolidationRequests = - Optional.ofNullable(blockParam.getConsolidationRequests()) - .map( - consolidationRequest -> - consolidationRequest.stream() - .map(ConsolidationRequestParameter::toConsolidationRequest) - .collect(toList())); - if (!getConsolidationRequestValidator( + if (!getRequestsValidator( protocolSchedule.get(), blockParam.getTimestamp(), blockParam.getBlockNumber()) - .validateParameter(maybeConsolidationRequests)) { - return new JsonRpcErrorResponse(reqId, RpcErrorType.INVALID_CONSOLIDATION_REQUEST_PARAMS); + .validate(maybeRequests)) { + return new JsonRpcErrorResponse(reqId, RpcErrorType.INVALID_EXECUTION_REQUESTS_PARAMS); } final Optional maybeExecutionWitness = @@ -232,10 +225,6 @@ public abstract class AbstractEngineNewPayload extends ExecutionEngineJsonRpcMet reqId, new JsonRpcError(RpcErrorType.INVALID_PARAMS, "Invalid executionWitness")); } - Optional> maybeRequests = - RequestUtil.combine( - maybeDepositRequests, maybeWithdrawalRequests, maybeConsolidationRequests); - if (mergeContext.get().isSyncing()) { LOG.debug("We are syncing"); return respondWith(reqId, blockParam, null, SYNCING); @@ -303,7 +292,8 @@ public abstract class AbstractEngineNewPayload extends ExecutionEngineJsonRpcMet ? null : BlobGas.fromHexString(blockParam.getExcessBlobGas()), maybeParentBeaconBlockRoot.orElse(null), - maybeRequests.map(BodyValidation::requestsRoot).orElse(null), + maybeRequests.map(BodyValidation::requestsHash).orElse(null), + null, // TODO SLD EIP-7742 wiring in future PR maybeExecutionWitness.orElse(null), headerFunctions); @@ -366,8 +356,7 @@ public abstract class AbstractEngineNewPayload extends ExecutionEngineJsonRpcMet final var block = new Block( - newBlockHeader, - new BlockBody(transactions, Collections.emptyList(), maybeWithdrawals, maybeRequests)); + newBlockHeader, new BlockBody(transactions, Collections.emptyList(), maybeWithdrawals)); if (maybeParentHeader.isEmpty()) { LOG.atDebug() @@ -484,7 +473,8 @@ public abstract class AbstractEngineNewPayload extends ExecutionEngineJsonRpcMet protected ValidationResult validateParameters( final EnginePayloadParameter parameter, final Optional> maybeVersionedHashParam, - final Optional maybeBeaconBlockRootParam) { + final Optional maybeBeaconBlockRootParam, + final Optional> maybeRequestsParam) { return ValidationResult.valid(); } @@ -580,6 +570,18 @@ public abstract class AbstractEngineNewPayload extends ExecutionEngineJsonRpcMet .collect(Collectors.toList())); } + private Optional> extractRequests(final Optional> maybeRequestsParam) { + if (maybeRequestsParam.isEmpty()) { + return Optional.empty(); + } + + return maybeRequestsParam.map( + requests -> + IntStream.range(0, requests.size()) + .mapToObj(i -> new Request(RequestType.of(i), Bytes.fromHexString(requests.get(i)))) + .collect(Collectors.toList())); + } + private void logImportedBlockInfo(final Block block, final int blobCount, final double timeInS) { final StringBuilder message = new StringBuilder(); message.append("Imported #%,d / %d tx"); @@ -590,10 +592,6 @@ public abstract class AbstractEngineNewPayload extends ExecutionEngineJsonRpcMet message.append(" / %d ws"); messageArgs.add(block.getBody().getWithdrawals().get().size()); } - if (block.getBody().getRequests().isPresent()) { - message.append(" / %d rs"); - messageArgs.add(block.getBody().getRequests().get().size()); - } message.append(" / %d blobs / base fee %s / %,d (%01.1f%%) gas / (%s) in %01.3fs. Peers: %d"); messageArgs.addAll( List.of( diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetClientVersionV1.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetClientVersionV1.java index 149728186b..011ce577a6 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetClientVersionV1.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetClientVersionV1.java @@ -22,6 +22,9 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcRespon import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.EngineGetClientVersionResultV1; +import java.util.Collections; +import java.util.List; + import io.vertx.core.Vertx; public class EngineGetClientVersionV1 extends ExecutionEngineJsonRpcMethod { @@ -51,9 +54,10 @@ public class EngineGetClientVersionV1 extends ExecutionEngineJsonRpcMethod { public JsonRpcResponse syncResponse(final JsonRpcRequestContext request) { String safeCommit = (commit != null && commit.length() >= 8) ? commit.substring(0, 8) : "unknown"; - return new JsonRpcSuccessResponse( - request.getRequest().getId(), - new EngineGetClientVersionResultV1( - ENGINE_CLIENT_CODE, ENGINE_CLIENT_NAME, clientVersion, safeCommit)); + List versions = + Collections.singletonList( + new EngineGetClientVersionResultV1( + ENGINE_CLIENT_CODE, ENGINE_CLIENT_NAME, clientVersion, safeCommit)); + return new JsonRpcSuccessResponse(request.getRequest().getId(), versions); } } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV2.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV2.java index acb177c3e0..00b0f83054 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV2.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV2.java @@ -57,7 +57,8 @@ public class EngineNewPayloadV2 extends AbstractEngineNewPayload { protected ValidationResult validateParameters( final EnginePayloadParameter payloadParameter, final Optional> maybeVersionedHashParam, - final Optional maybeBeaconBlockRootParam) { + final Optional maybeBeaconBlockRootParam, + final Optional> maybeRequestsParam) { if (payloadParameter.getBlobGasUsed() != null) { return ValidationResult.invalid( RpcErrorType.INVALID_BLOB_GAS_USED_PARAMS, "Missing blob gas used field"); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV3.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV3.java index 7d13ecc02c..8710e43627 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV3.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV3.java @@ -55,7 +55,8 @@ public class EngineNewPayloadV3 extends AbstractEngineNewPayload { protected ValidationResult validateParameters( final EnginePayloadParameter payloadParameter, final Optional> maybeVersionedHashParam, - final Optional maybeBeaconBlockRootParam) { + final Optional maybeBeaconBlockRootParam, + final Optional> maybeRequestsParam) { if (payloadParameter.getBlobGasUsed() == null) { return ValidationResult.invalid( RpcErrorType.INVALID_BLOB_GAS_USED_PARAMS, "Missing blob gas used field"); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV4.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV4.java index 904ec08e5c..0155e3d721 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV4.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV4.java @@ -55,7 +55,8 @@ public class EngineNewPayloadV4 extends AbstractEngineNewPayload { protected ValidationResult validateParameters( final EnginePayloadParameter payloadParameter, final Optional> maybeVersionedHashParam, - final Optional maybeBeaconBlockRootParam) { + final Optional maybeBeaconBlockRootParam, + final Optional> maybeRequestsParam) { if (payloadParameter.getBlobGasUsed() == null) { return ValidationResult.invalid( RpcErrorType.INVALID_BLOB_GAS_USED_PARAMS, "Missing blob gas used field"); @@ -69,8 +70,9 @@ public class EngineNewPayloadV4 extends AbstractEngineNewPayload { return ValidationResult.invalid( RpcErrorType.INVALID_PARENT_BEACON_BLOCK_ROOT_PARAMS, "Missing parent beacon block root field"); - } else if (payloadParameter.getDepositRequests() == null) { - return ValidationResult.invalid(RpcErrorType.INVALID_PARAMS, "Missing deposit field"); + } else if (maybeRequestsParam.isEmpty()) { + return ValidationResult.invalid( + RpcErrorType.INVALID_EXECUTION_REQUESTS_PARAMS, "Missing execution requests field"); } else { return ValidationResult.valid(); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV6800.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV6800.java index 81c61befbc..efdd0be926 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV6800.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV6800.java @@ -51,9 +51,10 @@ public class EngineNewPayloadV6800 extends AbstractEngineNewPayload { @Override protected ValidationResult validateParameters( - final EnginePayloadParameter payloadParameter, - final Optional> maybeVersionedHashParam, - final Optional maybeBeaconBlockRootParam) { + final EnginePayloadParameter payloadParameter, + final Optional> maybeVersionedHashParam, + final Optional maybeBeaconBlockRootParam, + final Optional> maybeRequestsParam) { if (payloadParameter.getBlobGasUsed() != null) { return ValidationResult.invalid( RpcErrorType.INVALID_PARAMS, "non-null BlobGasUsed pre-cancun"); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/RequestValidatorProvider.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/RequestValidatorProvider.java index c3d9c8376b..046e630fcc 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/RequestValidatorProvider.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/RequestValidatorProvider.java @@ -14,64 +14,25 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine; -import org.hyperledger.besu.datatypes.RequestType; import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.BlockHeaderBuilder; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; -import org.hyperledger.besu.ethereum.mainnet.requests.ProhibitedRequestsValidator; -import org.hyperledger.besu.ethereum.mainnet.requests.RequestValidator; -import org.hyperledger.besu.ethereum.mainnet.requests.RequestsValidatorCoordinator; +import org.hyperledger.besu.ethereum.mainnet.requests.RequestsValidator; import java.util.Optional; public class RequestValidatorProvider { - public static RequestValidator getDepositRequestValidator( + public static RequestsValidator getRequestsValidator( final ProtocolSchedule protocolSchedule, final long blockTimestamp, final long blockNumber) { - return getRequestValidator(protocolSchedule, blockTimestamp, blockNumber, RequestType.DEPOSIT); - } - - public static RequestValidator getWithdrawalRequestValidator( - final ProtocolSchedule protocolSchedule, final long blockTimestamp, final long blockNumber) { - return getRequestValidator( - protocolSchedule, blockTimestamp, blockNumber, RequestType.WITHDRAWAL); - } - - public static RequestValidator getConsolidationRequestValidator( - final ProtocolSchedule protocolSchedule, final long blockTimestamp, final long blockNumber) { - return getRequestValidator( - protocolSchedule, blockTimestamp, blockNumber, RequestType.CONSOLIDATION); - } - - private static RequestValidator getRequestValidator( - final ProtocolSchedule protocolSchedule, - final long blockTimestamp, - final long blockNumber, - final RequestType requestType) { - - RequestsValidatorCoordinator requestsValidatorCoordinator = - getRequestValidatorCoordinator(protocolSchedule, blockTimestamp, blockNumber); - return requestsValidatorCoordinator - .getRequestValidator(requestType) - .orElse(new ProhibitedRequestsValidator()); - } - - private static RequestsValidatorCoordinator getRequestValidatorCoordinator( - final ProtocolSchedule protocolSchedule, final long blockTimestamp, final long blockNumber) { - final BlockHeader blockHeader = BlockHeaderBuilder.createDefault() .timestamp(blockTimestamp) .number(blockNumber) .buildBlockHeader(); - return getRequestValidatorCoordinator(protocolSchedule.getByBlockHeader(blockHeader)); - } - - private static RequestsValidatorCoordinator getRequestValidatorCoordinator( - final ProtocolSpec protocolSchedule) { - return Optional.ofNullable(protocolSchedule) - .map(ProtocolSpec::getRequestsValidatorCoordinator) - .orElseGet(RequestsValidatorCoordinator::empty); + return Optional.ofNullable(protocolSchedule.getByBlockHeader(blockHeader)) + .map(ProtocolSpec::getRequestsValidator) + .orElse(v -> true); } } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/ConsolidationRequestParameter.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/ConsolidationRequestParameter.java deleted file mode 100644 index c6c600329d..0000000000 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/ConsolidationRequestParameter.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * 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.api.jsonrpc.internal.parameters; - -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.BLSPublicKey; -import org.hyperledger.besu.ethereum.core.ConsolidationRequest; - -import java.util.Objects; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonGetter; -import com.fasterxml.jackson.annotation.JsonProperty; - -public class ConsolidationRequestParameter { - - private final String sourceAddress; - private final String sourcePubkey; - private final String targetPubkey; - - @JsonCreator - public ConsolidationRequestParameter( - @JsonProperty("sourceAddress") final String sourceAddress, - @JsonProperty("sourcePubkey") final String sourcePubkey, - @JsonProperty("targetPubkey") final String targetPubkey) { - this.sourceAddress = sourceAddress; - this.sourcePubkey = sourcePubkey; - this.targetPubkey = targetPubkey; - } - - public static ConsolidationRequestParameter fromConsolidationRequest( - final ConsolidationRequest consolidationRequest) { - return new ConsolidationRequestParameter( - consolidationRequest.getSourceAddress().toHexString(), - consolidationRequest.getSourcePubkey().toHexString(), - consolidationRequest.getTargetPubkey().toHexString()); - } - - public ConsolidationRequest toConsolidationRequest() { - return new ConsolidationRequest( - Address.fromHexString(sourceAddress), - BLSPublicKey.fromHexString(sourcePubkey), - BLSPublicKey.fromHexString(targetPubkey)); - } - - @JsonGetter - public String getSourceAddress() { - return sourceAddress; - } - - @JsonGetter - public String getSourcePubkey() { - return sourcePubkey; - } - - @JsonGetter - public String getTargetPubkey() { - return targetPubkey; - } - - @Override - public boolean equals(final Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - final ConsolidationRequestParameter that = (ConsolidationRequestParameter) o; - return Objects.equals(sourceAddress, that.sourceAddress) - && Objects.equals(sourcePubkey, that.sourcePubkey) - && Objects.equals(targetPubkey, that.targetPubkey); - } - - @Override - public int hashCode() { - return Objects.hash(sourceAddress, sourcePubkey, targetPubkey); - } - - @Override - public String toString() { - return "ConsolidationRequestParameter{" - + "sourceAddress='" - + sourceAddress - + '\'' - + ", sourcePubkey='" - + sourcePubkey - + '\'' - + ", targetPubkey='" - + targetPubkey - + '\'' - + '}'; - } -} diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/DepositRequestParameter.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/DepositRequestParameter.java deleted file mode 100644 index 39d6476ca4..0000000000 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/DepositRequestParameter.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * 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.api.jsonrpc.internal.parameters; - -import org.hyperledger.besu.datatypes.BLSPublicKey; -import org.hyperledger.besu.datatypes.BLSSignature; -import org.hyperledger.besu.datatypes.GWei; -import org.hyperledger.besu.ethereum.core.DepositRequest; - -import java.util.Objects; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonGetter; -import com.fasterxml.jackson.annotation.JsonProperty; -import io.vertx.core.json.JsonObject; -import org.apache.tuweni.bytes.Bytes32; -import org.apache.tuweni.units.bigints.UInt64; - -public class DepositRequestParameter { - - private final String pubkey; - - private final String withdrawalCredentials; - private final String amount; - - private final String signature; - private final String index; - - @JsonCreator - public DepositRequestParameter( - @JsonProperty("pubkey") final String pubkey, - @JsonProperty("withdrawalCredentials") final String withdrawalCredentials, - @JsonProperty("amount") final String amount, - @JsonProperty("signature") final String signature, - @JsonProperty("index") final String index) { - this.pubkey = pubkey; - this.withdrawalCredentials = withdrawalCredentials; - this.amount = amount; - this.signature = signature; - this.index = index; - } - - public static DepositRequestParameter fromDeposit(final DepositRequest depositRequest) { - return new DepositRequestParameter( - depositRequest.getPubkey().toString(), - depositRequest.getWithdrawalCredentials().toString(), - depositRequest.getAmount().toShortHexString(), - depositRequest.getSignature().toString(), - depositRequest.getIndex().toBytes().toQuantityHexString()); - } - - public DepositRequest toDeposit() { - return new DepositRequest( - BLSPublicKey.fromHexString(pubkey), - Bytes32.fromHexString(withdrawalCredentials), - GWei.fromHexString(amount), - BLSSignature.fromHexString(signature), - UInt64.fromHexString(index)); - } - - public JsonObject asJsonObject() { - return new JsonObject() - .put("pubkey", pubkey) - .put("withdrawalCredentials", withdrawalCredentials) - .put("amount", amount) - .put("signature", signature) - .put("index", index); - } - - @JsonGetter - public String getPubkey() { - return pubkey; - } - - @JsonGetter - public String getWithdrawalCredentials() { - return withdrawalCredentials; - } - - @JsonGetter - public String getAmount() { - return amount; - } - - @JsonGetter - public String getSignature() { - return signature; - } - - @JsonGetter - public String getIndex() { - return index; - } - - @Override - public boolean equals(final Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - final DepositRequestParameter that = (DepositRequestParameter) o; - return Objects.equals(pubkey, that.pubkey) - && Objects.equals(withdrawalCredentials, that.withdrawalCredentials) - && Objects.equals(amount, that.amount) - && Objects.equals(signature, that.signature) - && Objects.equals(index, that.index); - } - - @Override - public int hashCode() { - return Objects.hash(pubkey, withdrawalCredentials, amount, signature, index); - } - - @Override - public String toString() { - return "DepositRequestParameter{" - + "pubKey='" - + pubkey - + '\'' - + ", withdrawalCredentials='" - + withdrawalCredentials - + '\'' - + ", amount='" - + amount - + '\'' - + ", signature='" - + signature - + '\'' - + ", index='" - + index - + '\'' - + '}'; - } -} diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/EnginePayloadParameter.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/EnginePayloadParameter.java index ce2173c0f4..a673068968 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/EnginePayloadParameter.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/EnginePayloadParameter.java @@ -43,9 +43,6 @@ public class EnginePayloadParameter { private final List withdrawals; private final Long blobGasUsed; private final String excessBlobGas; - private final List depositRequests; - private final List withdrawalRequests; - private final List consolidationRequests; private final ExecutionWitnessParameter executionWitness; /** @@ -68,9 +65,6 @@ public class EnginePayloadParameter { * @param withdrawals Array of Withdrawal * @param blobGasUsed QUANTITY, 64 Bits * @param excessBlobGas QUANTITY, 64 Bits - * @param depositRequests List of deposit parameters. - * @param withdrawalRequestParameters List of withdrawal requests parameters. - * @param consolidationRequests List of consolidation requests parameters. * @param executionWitness OBJECT executionWitness. */ @JsonCreator @@ -92,11 +86,6 @@ public class EnginePayloadParameter { @JsonProperty("withdrawals") final List withdrawals, @JsonProperty("blobGasUsed") final UnsignedLongParameter blobGasUsed, @JsonProperty("excessBlobGas") final String excessBlobGas, - @JsonProperty("depositRequests") final List depositRequests, - @JsonProperty("withdrawalRequests") - final List withdrawalRequestParameters, - @JsonProperty("consolidationRequests") - final List consolidationRequests, @JsonProperty("executionWitness") final ExecutionWitnessParameter executionWitness) { this.blockHash = blockHash; this.parentHash = parentHash; @@ -115,9 +104,7 @@ public class EnginePayloadParameter { this.withdrawals = withdrawals; this.blobGasUsed = blobGasUsed == null ? null : blobGasUsed.getValue(); this.excessBlobGas = excessBlobGas; - this.depositRequests = depositRequests; - this.withdrawalRequests = withdrawalRequestParameters; - this.consolidationRequests = consolidationRequests; + this.executionWitness = executionWitness; } @@ -189,18 +176,6 @@ public class EnginePayloadParameter { return excessBlobGas; } - public List getDepositRequests() { - return depositRequests; - } - - public List getWithdrawalRequests() { - return withdrawalRequests; - } - - public List getConsolidationRequests() { - return consolidationRequests; - } - public ExecutionWitnessParameter getExecutionWitness() { return executionWitness; } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/JsonCallParameter.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/JsonCallParameter.java index 987b68c2e2..85dabda571 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/JsonCallParameter.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/JsonCallParameter.java @@ -18,10 +18,12 @@ import org.hyperledger.besu.datatypes.AccessListEntry; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.VersionedHash; import org.hyperledger.besu.datatypes.Wei; +import org.hyperledger.besu.ethereum.core.json.ChainIdDeserializer; import org.hyperledger.besu.ethereum.core.json.GasDeserializer; import org.hyperledger.besu.ethereum.core.json.HexStringDeserializer; import org.hyperledger.besu.ethereum.transaction.CallParameter; +import java.math.BigInteger; import java.util.List; import java.util.Optional; @@ -41,6 +43,7 @@ import org.slf4j.LoggerFactory; * *
{@code
  * JsonCallParameter param = new JsonCallParameter.JsonCallParameterBuilder()
+ *     .withChainId(Optional.of(BigInteger.ONE))
  *     .withFrom(Address.fromHexString("0x..."))
  *     .withTo(Address.fromHexString("0x..."))
  *     .withGas(21000L)
@@ -71,6 +74,7 @@ public class JsonCallParameter extends CallParameter {
   private final Optional strict;
 
   private JsonCallParameter(
+      final Optional chainId,
       final Address from,
       final Address to,
       final Long gasLimit,
@@ -85,6 +89,7 @@ public class JsonCallParameter extends CallParameter {
       final Optional> blobVersionedHashes) {
 
     super(
+        chainId,
         from,
         to,
         gasLimit,
@@ -115,6 +120,7 @@ public class JsonCallParameter extends CallParameter {
    */
   public static final class JsonCallParameterBuilder {
     private Optional strict = Optional.empty();
+    private Optional chainId = Optional.empty();
     private Address from;
     private Address to;
     private long gas = -1;
@@ -145,6 +151,18 @@ public class JsonCallParameter extends CallParameter {
       return this;
     }
 
+    /**
+     * Sets the optional "chainId" for the {@link JsonCallParameter}.
+     *
+     * @param chainId the chainId
+     * @return the {@link JsonCallParameterBuilder} instance for chaining
+     */
+    @JsonDeserialize(using = ChainIdDeserializer.class)
+    public JsonCallParameterBuilder withChainId(final BigInteger chainId) {
+      this.chainId = Optional.of(chainId);
+      return this;
+    }
+
     /**
      * Sets the "from" address for the {@link JsonCallParameter}. This address represents the sender
      * of the call.
@@ -346,6 +364,7 @@ public class JsonCallParameter extends CallParameter {
       final Bytes payload = input != null ? input : data;
 
       return new JsonCallParameter(
+          chainId,
           from,
           to,
           gas,
diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/WithdrawalRequestParameter.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/WithdrawalRequestParameter.java
deleted file mode 100644
index 3561da37a8..0000000000
--- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/WithdrawalRequestParameter.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * 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.api.jsonrpc.internal.parameters;
-
-import org.hyperledger.besu.datatypes.Address;
-import org.hyperledger.besu.datatypes.BLSPublicKey;
-import org.hyperledger.besu.datatypes.GWei;
-import org.hyperledger.besu.ethereum.core.WithdrawalRequest;
-
-import java.util.Objects;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonGetter;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-public class WithdrawalRequestParameter {
-
-  private final String sourceAddress;
-  private final String validatorPubkey;
-  private final String amount;
-
-  @JsonCreator
-  public WithdrawalRequestParameter(
-      @JsonProperty("sourceAddress") final String sourceAddress,
-      @JsonProperty("validatorPubkey") final String validatorPubkey,
-      @JsonProperty("amount") final String amount) {
-    this.sourceAddress = sourceAddress;
-    this.validatorPubkey = validatorPubkey;
-    this.amount = amount;
-  }
-
-  public static WithdrawalRequestParameter fromWithdrawalRequest(
-      final WithdrawalRequest withdrawalRequest) {
-    return new WithdrawalRequestParameter(
-        withdrawalRequest.getSourceAddress().toHexString(),
-        withdrawalRequest.getValidatorPubkey().toHexString(),
-        withdrawalRequest.getAmount().toShortHexString());
-  }
-
-  public WithdrawalRequest toWithdrawalRequest() {
-    return new WithdrawalRequest(
-        Address.fromHexString(sourceAddress),
-        BLSPublicKey.fromHexString(validatorPubkey),
-        GWei.fromHexString(amount));
-  }
-
-  @JsonGetter
-  public String getSourceAddress() {
-    return sourceAddress;
-  }
-
-  @JsonGetter
-  public String getValidatorPubkey() {
-    return validatorPubkey;
-  }
-
-  @JsonGetter
-  public String getAmount() {
-    return amount;
-  }
-
-  @Override
-  public boolean equals(final Object o) {
-    if (this == o) return true;
-    if (o == null || getClass() != o.getClass()) return false;
-    final WithdrawalRequestParameter that = (WithdrawalRequestParameter) o;
-    return Objects.equals(sourceAddress, that.sourceAddress)
-        && Objects.equals(validatorPubkey, that.validatorPubkey)
-        && Objects.equals(amount, that.amount);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(sourceAddress, validatorPubkey, amount);
-  }
-
-  @Override
-  public String toString() {
-    return "WithdrawalRequestParameter{"
-        + "sourceAddress='"
-        + sourceAddress
-        + '\''
-        + ", validatorPubkey='"
-        + validatorPubkey
-        + '\''
-        + ", amount='"
-        + amount
-        + '\''
-        + '}';
-  }
-}
diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/response/RpcErrorType.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/response/RpcErrorType.java
index 875eab601b..a2b7d17591 100644
--- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/response/RpcErrorType.java
+++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/response/RpcErrorType.java
@@ -62,6 +62,7 @@ public enum RpcErrorType implements RpcMethodError {
   INVALID_ENODE_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid enode params"),
   INVALID_EXCESS_BLOB_GAS_PARAMS(
       INVALID_PARAMS_ERROR_CODE, "Invalid excess blob gas params (missing or invalid)"),
+  INVALID_EXECUTION_REQUESTS_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid execution requests params"),
   INVALID_EXTRA_DATA_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid extra data params"),
   INVALID_FILTER_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid filter params"),
   INVALID_GAS_PRICE_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid gas price params"),
diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/BlockResult.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/BlockResult.java
index ed0b64d742..25e6763eda 100644
--- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/BlockResult.java
+++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/BlockResult.java
@@ -88,6 +88,7 @@ public class BlockResult implements JsonRpcResult {
   private final String blobGasUsed;
   private final String excessBlobGas;
   private final String parentBeaconBlockRoot;
+  private final String targetBlobCount;
 
   public BlockResult(
       final BlockHeader header,
@@ -138,6 +139,7 @@ public class BlockResult implements JsonRpcResult {
     this.excessBlobGas = header.getExcessBlobGas().map(Quantity::create).orElse(null);
     this.parentBeaconBlockRoot =
         header.getParentBeaconBlockRoot().map(Bytes32::toHexString).orElse(null);
+    this.targetBlobCount = header.getTargetBlobCount().map(Quantity::create).orElse(null);
   }
 
   @JsonGetter(value = "number")
@@ -275,4 +277,9 @@ public class BlockResult implements JsonRpcResult {
   public String getParentBeaconBlockRoot() {
     return parentBeaconBlockRoot;
   }
+
+  @JsonGetter(value = "targetBlobCount")
+  public String getTargetBlobCount() {
+    return targetBlobCount;
+  }
 }
diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/BlockResultFactory.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/BlockResultFactory.java
index b8111c00c7..66bb879569 100644
--- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/BlockResultFactory.java
+++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/BlockResultFactory.java
@@ -14,10 +14,6 @@
  */
 package org.hyperledger.besu.ethereum.api.jsonrpc.internal.results;
 
-import static org.hyperledger.besu.ethereum.mainnet.requests.RequestUtil.getConsolidationRequests;
-import static org.hyperledger.besu.ethereum.mainnet.requests.RequestUtil.getDepositRequests;
-import static org.hyperledger.besu.ethereum.mainnet.requests.RequestUtil.getWithdrawalRequests;
-
 import org.hyperledger.besu.consensus.merge.PayloadWrapper;
 import org.hyperledger.besu.datatypes.Hash;
 import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.EngineGetPayloadBodiesResultV1.PayloadBody;
@@ -26,10 +22,12 @@ import org.hyperledger.besu.ethereum.api.query.TransactionWithMetadata;
 import org.hyperledger.besu.ethereum.core.Block;
 import org.hyperledger.besu.ethereum.core.BlockBody;
 import org.hyperledger.besu.ethereum.core.BlockHeader;
+import org.hyperledger.besu.ethereum.core.Request;
 import org.hyperledger.besu.ethereum.core.encoding.EncodingContext;
 import org.hyperledger.besu.ethereum.core.encoding.TransactionEncoder;
 
 import java.util.ArrayList;
+import java.util.Comparator;
 import java.util.List;
 import java.util.Optional;
 import java.util.stream.Collectors;
@@ -162,6 +160,15 @@ public class BlockResultFactory {
                     TransactionEncoder.encodeOpaqueBytes(transaction, EncodingContext.BLOCK_BODY))
             .map(Bytes::toHexString)
             .collect(Collectors.toList());
+    final Optional> requestsWithoutRequestId =
+        payload
+            .requests()
+            .map(
+                rqs ->
+                    rqs.stream()
+                        .sorted(Comparator.comparing(Request::getType))
+                        .map(r -> r.getData().toHexString())
+                        .toList());
 
     final BlobsBundleV1 blobsBundleV1 =
         new BlobsBundleV1(blockWithReceipts.getBlock().getBody().getTransactions());
@@ -169,9 +176,7 @@ public class BlockResultFactory {
         blockWithReceipts.getHeader(),
         txs,
         blockWithReceipts.getBlock().getBody().getWithdrawals(),
-        getDepositRequests(blockWithReceipts.getBlock().getBody().getRequests()),
-        getWithdrawalRequests(blockWithReceipts.getBlock().getBody().getRequests()),
-        getConsolidationRequests(blockWithReceipts.getBlock().getBody().getRequests()),
+        requestsWithoutRequestId,
         Quantity.create(payload.blockValue()),
         blobsBundleV1);
   }
diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/EngineGetPayloadResultV4.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/EngineGetPayloadResultV4.java
index 39772ff7db..017de4653c 100644
--- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/EngineGetPayloadResultV4.java
+++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/EngineGetPayloadResultV4.java
@@ -14,15 +14,9 @@
  */
 package org.hyperledger.besu.ethereum.api.jsonrpc.internal.results;
 
-import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.ConsolidationRequestParameter;
-import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.DepositRequestParameter;
 import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.WithdrawalParameter;
-import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.WithdrawalRequestParameter;
 import org.hyperledger.besu.ethereum.core.BlockHeader;
-import org.hyperledger.besu.ethereum.core.ConsolidationRequest;
-import org.hyperledger.besu.ethereum.core.DepositRequest;
 import org.hyperledger.besu.ethereum.core.Withdrawal;
-import org.hyperledger.besu.ethereum.core.WithdrawalRequest;
 
 import java.util.List;
 import java.util.Optional;
@@ -33,33 +27,32 @@ import com.fasterxml.jackson.annotation.JsonInclude;
 import com.fasterxml.jackson.annotation.JsonPropertyOrder;
 import org.apache.tuweni.bytes.Bytes32;
 
-@JsonPropertyOrder({"executionPayload", "blockValue", "blobsBundle", "shouldOverrideBuilder"})
+@JsonPropertyOrder({
+  "executionPayload",
+  "blockValue",
+  "blobsBundle",
+  "shouldOverrideBuilder",
+  "executionRequests"
+})
 public class EngineGetPayloadResultV4 {
   protected final PayloadResult executionPayload;
   private final String blockValue;
   private final BlobsBundleV1 blobsBundle;
   private final boolean shouldOverrideBuilder;
+  private final List executionRequests;
 
   public EngineGetPayloadResultV4(
       final BlockHeader header,
       final List transactions,
       final Optional> withdrawals,
-      final Optional> depositRequests,
-      final Optional> withdrawalRequests,
-      final Optional> consolidationRequests,
+      final Optional> executionRequests,
       final String blockValue,
       final BlobsBundleV1 blobsBundle) {
-    this.executionPayload =
-        new PayloadResult(
-            header,
-            transactions,
-            withdrawals,
-            depositRequests,
-            withdrawalRequests,
-            consolidationRequests);
+    this.executionPayload = new PayloadResult(header, transactions, withdrawals);
     this.blockValue = blockValue;
     this.blobsBundle = blobsBundle;
     this.shouldOverrideBuilder = false;
+    this.executionRequests = executionRequests.orElse(null);
   }
 
   @JsonGetter(value = "executionPayload")
@@ -82,6 +75,11 @@ public class EngineGetPayloadResultV4 {
     return shouldOverrideBuilder;
   }
 
+  @JsonGetter(value = "executionRequests")
+  public List getExecutionRequests() {
+    return executionRequests;
+  }
+
   public static class PayloadResult {
 
     protected final String blockHash;
@@ -103,17 +101,11 @@ public class EngineGetPayloadResultV4 {
 
     protected final List transactions;
     private final List withdrawals;
-    private final List depositRequests;
-    private final List withdrawalRequests;
-    private final List consolidationRequests;
 
     public PayloadResult(
         final BlockHeader header,
         final List transactions,
-        final Optional> withdrawals,
-        final Optional> depositRequests,
-        final Optional> withdrawalRequests,
-        final Optional> consolidationRequests) {
+        final Optional> withdrawals) {
       this.blockNumber = Quantity.create(header.getNumber());
       this.blockHash = header.getHash().toString();
       this.parentHash = header.getParentHash().toString();
@@ -136,30 +128,6 @@ public class EngineGetPayloadResultV4 {
                           .map(WithdrawalParameter::fromWithdrawal)
                           .collect(Collectors.toList()))
               .orElse(null);
-      this.depositRequests =
-          depositRequests
-              .map(
-                  ds ->
-                      ds.stream()
-                          .map(DepositRequestParameter::fromDeposit)
-                          .collect(Collectors.toList()))
-              .orElse(null);
-      this.withdrawalRequests =
-          withdrawalRequests
-              .map(
-                  wr ->
-                      wr.stream()
-                          .map(WithdrawalRequestParameter::fromWithdrawalRequest)
-                          .collect(Collectors.toList()))
-              .orElse(null);
-      this.consolidationRequests =
-          consolidationRequests
-              .map(
-                  wr ->
-                      wr.stream()
-                          .map(ConsolidationRequestParameter::fromConsolidationRequest)
-                          .collect(Collectors.toList()))
-              .orElse(null);
       this.blobGasUsed = header.getBlobGasUsed().map(Quantity::create).orElse(Quantity.HEX_ZERO);
       this.excessBlobGas =
           header.getExcessBlobGas().map(Quantity::create).orElse(Quantity.HEX_ZERO);
@@ -237,21 +205,6 @@ public class EngineGetPayloadResultV4 {
       return withdrawals;
     }
 
-    @JsonGetter(value = "depositRequests")
-    public List getDepositRequests() {
-      return depositRequests;
-    }
-
-    @JsonGetter(value = "withdrawalRequests")
-    public List getWithdrawalRequests() {
-      return withdrawalRequests;
-    }
-
-    @JsonGetter(value = "consolidationRequests")
-    public List getConsolidationRequests() {
-      return consolidationRequests;
-    }
-
     @JsonGetter(value = "feeRecipient")
     @JsonInclude(JsonInclude.Include.NON_NULL)
     public String getFeeRecipient() {
diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/EthJsonRpcMethods.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/EthJsonRpcMethods.java
index 5baa110646..de5662692f 100644
--- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/EthJsonRpcMethods.java
+++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/EthJsonRpcMethods.java
@@ -132,11 +132,7 @@ public class EthJsonRpcMethods extends ApiGroupJsonRpcMethods {
                 blockchainQueries.getWorldStateArchive(),
                 protocolSchedule,
                 apiConfiguration.getGasCap())),
-        new EthFeeHistory(
-            protocolSchedule,
-            blockchainQueries.getBlockchain(),
-            miningCoordinator,
-            apiConfiguration),
+        new EthFeeHistory(protocolSchedule, blockchainQueries, miningCoordinator, apiConfiguration),
         new EthGetCode(blockchainQueries),
         new EthGetLogs(blockchainQueries, apiConfiguration.getMaxLogsRange()),
         new EthGetProof(blockchainQueries),
diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/ExecutionEngineJsonRpcMethods.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/ExecutionEngineJsonRpcMethods.java
index a3111c3d78..f81f77e5b0 100644
--- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/ExecutionEngineJsonRpcMethods.java
+++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/ExecutionEngineJsonRpcMethods.java
@@ -117,7 +117,7 @@ public class ExecutionEngineJsonRpcMethods extends ApiGroupJsonRpcMethods {
                   mergeCoordinator.get(),
                   ethPeers,
                   engineQosTimer),
-              new EngineNewPayloadV6800( // TODO replaced for verkle test
+              new EngineNewPayloadV6800( // TODO replaced for the verkle test
                   consensusEngineServer,
                   protocolSchedule,
                   protocolContext,
diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/subscription/pending/PendingTransactionDroppedSubscriptionService.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/subscription/pending/PendingTransactionDroppedSubscriptionService.java
index 6032183644..5ce2411b27 100644
--- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/subscription/pending/PendingTransactionDroppedSubscriptionService.java
+++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/subscription/pending/PendingTransactionDroppedSubscriptionService.java
@@ -20,6 +20,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.websocket.subscription.Subscrip
 import org.hyperledger.besu.ethereum.api.jsonrpc.websocket.subscription.request.SubscriptionType;
 import org.hyperledger.besu.ethereum.core.Transaction;
 import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactionDroppedListener;
+import org.hyperledger.besu.ethereum.eth.transactions.RemovalReason;
 
 import java.util.List;
 
@@ -34,7 +35,7 @@ public class PendingTransactionDroppedSubscriptionService
   }
 
   @Override
-  public void onTransactionDropped(final Transaction transaction) {
+  public void onTransactionDropped(final Transaction transaction, final RemovalReason reason) {
     notifySubscribers(transaction.getHash());
   }
 
diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCallTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCallTest.java
index 7570fe342c..8b8ff67cd8 100644
--- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCallTest.java
+++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCallTest.java
@@ -157,12 +157,12 @@ public class EthCallTest {
     when(result.isSuccessful()).thenReturn(true);
     when(result.getValidationResult()).thenReturn(ValidationResult.valid());
     when(result.getOutput()).thenReturn(Bytes.of(1));
-    verify(transactionSimulator).process(any(), any(), any(), mapperCaptor.capture(), any());
+    verify(transactionSimulator)
+        .process(eq(callParameter()), any(), any(), mapperCaptor.capture(), any());
     assertThat(mapperCaptor.getValue().apply(mock(MutableWorldState.class), Optional.of(result)))
         .isEqualTo(Optional.of(expectedResponse));
 
     assertThat(response).usingRecursiveComparison().isEqualTo(expectedResponse);
-    verify(transactionSimulator).process(eq(callParameter()), any(), any(), any(), any());
     verify(blockchainQueries, atLeastOnce()).getBlockchain();
     verifyNoMoreInteractions(blockchainQueries);
   }
@@ -174,10 +174,9 @@ public class EthCallTest {
     // Expect a revert error with no decoded reason (error doesn't begin "Error(string)" so ignored)
     final String abiHexString = "0x1234";
     final JsonRpcError expectedError = new JsonRpcError(REVERT_ERROR, abiHexString);
-    final JsonRpcResponse expectedResponse = new JsonRpcErrorResponse(null, expectedError);
+    final JsonRpcErrorResponse expectedResponse = new JsonRpcErrorResponse(null, expectedError);
 
-    assertThat(((JsonRpcErrorResponse) expectedResponse).getError().getMessage())
-        .isEqualTo("Execution reverted");
+    assertThat(expectedResponse.getError().getMessage()).isEqualTo("Execution reverted");
 
     mockTransactionProcessorSuccessResult(expectedResponse);
     when(blockchainQueries.getBlockchain()).thenReturn(blockchain);
@@ -214,9 +213,9 @@ public class EthCallTest {
     // bytes are invalid ABI)
     final String abiHexString = "0x08c379a002d36d";
     final JsonRpcError expectedError = new JsonRpcError(REVERT_ERROR, abiHexString);
-    final JsonRpcResponse expectedResponse = new JsonRpcErrorResponse(null, expectedError);
+    final JsonRpcErrorResponse expectedResponse = new JsonRpcErrorResponse(null, expectedError);
 
-    assertThat(((JsonRpcErrorResponse) expectedResponse).getError().getMessage())
+    assertThat(expectedResponse.getError().getMessage())
         .isEqualTo("Execution reverted: ABI decode error");
 
     mockTransactionProcessorSuccessResult(expectedResponse);
@@ -254,9 +253,9 @@ public class EthCallTest {
     final String abiHexString =
         "0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002545524332303a207472616e736665722066726f6d20746865207a65726f2061646472657373000000000000000000000000000000000000000000000000000000";
     final JsonRpcError expectedError = new JsonRpcError(REVERT_ERROR, abiHexString);
-    final JsonRpcResponse expectedResponse = new JsonRpcErrorResponse(null, expectedError);
+    final JsonRpcErrorResponse expectedResponse = new JsonRpcErrorResponse(null, expectedError);
 
-    assertThat(((JsonRpcErrorResponse) expectedResponse).getError().getMessage())
+    assertThat(expectedResponse.getError().getMessage())
         .isEqualTo("Execution reverted: ERC20: transfer from the zero address");
 
     mockTransactionProcessorSuccessResult(expectedResponse);
@@ -279,8 +278,6 @@ public class EthCallTest {
     when(result.result()).thenReturn(processingResult);
 
     verify(transactionSimulator).process(any(), any(), any(), mapperCaptor.capture(), any());
-    System.out.println(result);
-    System.out.println(expectedResponse);
     assertThat(mapperCaptor.getValue().apply(mock(MutableWorldState.class), Optional.of(result)))
         .isEqualTo(Optional.of(expectedResponse));
 
diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthFeeHistoryTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthFeeHistoryTest.java
index a04cb06c67..f34f336e03 100644
--- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthFeeHistoryTest.java
+++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthFeeHistoryTest.java
@@ -39,6 +39,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType;
 import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.FeeHistory;
 import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.ImmutableFeeHistory;
 import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.ImmutableFeeHistoryResult;
+import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
 import org.hyperledger.besu.ethereum.blockcreation.MiningCoordinator;
 import org.hyperledger.besu.ethereum.chain.Blockchain;
 import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
@@ -69,6 +70,7 @@ import org.junit.jupiter.api.Test;
 
 public class EthFeeHistoryTest {
   final BlockDataGenerator gen = new BlockDataGenerator();
+  private BlockchainQueries blockchainQueries;
   private MutableBlockchain blockchain;
   private EthFeeHistory method;
   private ProtocolSchedule protocolSchedule;
@@ -82,14 +84,15 @@ public class EthFeeHistoryTest {
     gen.blockSequence(genesisBlock, 10)
         .forEach(block -> blockchain.appendBlock(block, gen.receipts(block)));
     miningCoordinator = mock(MergeCoordinator.class);
-    when(miningCoordinator.getMinPriorityFeePerGas()).thenReturn(Wei.ONE);
+
+    blockchainQueries = mockBlockchainQueries(blockchain, Wei.of(7));
 
     mockFork();
 
     method =
         new EthFeeHistory(
             protocolSchedule,
-            blockchain,
+            blockchainQueries,
             miningCoordinator,
             ImmutableApiConfiguration.builder().build());
   }
@@ -139,11 +142,16 @@ public class EthFeeHistoryTest {
     Block block = mock(Block.class);
     Blockchain blockchain = mockBlockchainTransactionsWithPriorityFee(block);
 
+    final var blockchainQueries = mockBlockchainQueries(blockchain, Wei.of(7));
+
     EthFeeHistory ethFeeHistory =
         new EthFeeHistory(
-            null, blockchain, miningCoordinator, ImmutableApiConfiguration.builder().build());
+            null,
+            blockchainQueries,
+            miningCoordinator,
+            ImmutableApiConfiguration.builder().build());
 
-    List rewards = ethFeeHistory.computeRewards(rewardPercentiles, block);
+    List rewards = ethFeeHistory.computeRewards(rewardPercentiles, block, Wei.of(7));
 
     // Define the expected rewards for each percentile
     // The expected rewards match the fees of the transactions at each percentile in the
@@ -179,14 +187,51 @@ public class EthFeeHistoryTest {
             .upperBoundGasAndPriorityFeeCoefficient(500L)
             .build(); // Max reward = Wei.One * 500L / 100 = 5.0
 
+    final var blockchainQueries = mockBlockchainQueries(blockchain, Wei.of(7));
+    when(miningCoordinator.getMinPriorityFeePerGas()).thenReturn(Wei.ONE);
+
     EthFeeHistory ethFeeHistory =
-        new EthFeeHistory(null, blockchain, miningCoordinator, apiConfiguration);
+        new EthFeeHistory(null, blockchainQueries, miningCoordinator, apiConfiguration);
 
-    List rewards = ethFeeHistory.computeRewards(rewardPercentiles, block);
+    List rewards = ethFeeHistory.computeRewards(rewardPercentiles, block, Wei.of(7));
 
     // Define the expected bounded rewards for each percentile
     List expectedBoundedRewards = Stream.of(2, 2, 2, 4, 5, 5, 5, 5, 5).map(Wei::of).toList();
-    assertThat(expectedBoundedRewards).isEqualTo(rewards);
+    assertThat(rewards).isEqualTo(expectedBoundedRewards);
+  }
+
+  @Test
+  public void shouldApplyLowerBoundRewardsCorrectly() {
+    // This test checks that the rewards are correctly bounded by the lower and upper limits,
+    // when the calculated lower bound for the priority fee is greater than the configured one.
+    // Configured minPriorityFeePerGas is 0 wei, minGasPrice is 10 wei and baseFee is 8 wei,
+    // so for a tx to be mined the minPriorityFeePerGas is raised to 2 wei before applying the
+    // coefficients.
+
+    List rewardPercentiles =
+        Arrays.asList(0.0, 5.0, 10.0, 27.50, 31.0, 59.0, 60.0, 61.0, 100.0);
+
+    Block block = mock(Block.class);
+    Blockchain blockchain = mockBlockchainTransactionsWithPriorityFee(block);
+
+    ApiConfiguration apiConfiguration =
+        ImmutableApiConfiguration.builder()
+            .isGasAndPriorityFeeLimitingEnabled(true)
+            .lowerBoundGasAndPriorityFeeCoefficient(200L) // Min reward = 2 * 200L / 100 = 4.0
+            .upperBoundGasAndPriorityFeeCoefficient(300L)
+            .build(); // Max reward = 2 * 300L / 100 = 6.0
+
+    final var blockchainQueries = mockBlockchainQueries(blockchain, Wei.of(10));
+    when(miningCoordinator.getMinPriorityFeePerGas()).thenReturn(Wei.ZERO);
+
+    EthFeeHistory ethFeeHistory =
+        new EthFeeHistory(null, blockchainQueries, miningCoordinator, apiConfiguration);
+
+    List rewards = ethFeeHistory.computeRewards(rewardPercentiles, block, Wei.of(8));
+
+    // Define the expected bounded rewards for each percentile
+    List expectedBoundedRewards = Stream.of(4, 4, 4, 4, 5, 6, 6, 6, 6).map(Wei::of).toList();
+    assertThat(rewards).isEqualTo(expectedBoundedRewards);
   }
 
   private Blockchain mockBlockchainTransactionsWithPriorityFee(final Block block) {
@@ -399,4 +444,12 @@ public class EthFeeHistoryTest {
     return method.response(
         new JsonRpcRequestContext(new JsonRpcRequest("2.0", "eth_feeHistory", params)));
   }
+
+  private BlockchainQueries mockBlockchainQueries(
+      final Blockchain blockchain, final Wei gasPriceLowerBound) {
+    final var blockchainQueries = mock(BlockchainQueries.class);
+    when(blockchainQueries.getBlockchain()).thenReturn(blockchain);
+    when(blockchainQueries.gasPriceLowerBound()).thenReturn(gasPriceLowerBound);
+    return blockchainQueries;
+  }
 }
diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthMaxPriorityFeePerGasTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthMaxPriorityFeePerGasTest.java
index 886c8a1d03..d29a10a114 100644
--- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthMaxPriorityFeePerGasTest.java
+++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthMaxPriorityFeePerGasTest.java
@@ -207,6 +207,7 @@ public class EthMaxPriorityFeePerGasTest {
             null,
             null,
             null,
+            null,
             null),
         new BlockBody(
             IntStream.range(0, txsNum)
diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineGetPayloadTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineGetPayloadTest.java
index f18b5601cf..1cfc51396d 100644
--- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineGetPayloadTest.java
+++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineGetPayloadTest.java
@@ -99,32 +99,27 @@ public abstract class AbstractEngineGetPayloadTest extends AbstractScheduledApiT
   protected static final BlockWithReceipts mockBlockWithReceipts =
       new BlockWithReceipts(mockBlock, Collections.emptyList());
   protected static final PayloadWrapper mockPayload =
-      new PayloadWrapper(mockPid, mockBlockWithReceipts);
+      new PayloadWrapper(mockPid, mockBlockWithReceipts, Optional.empty());
   private static final Block mockBlockWithWithdrawals =
       new Block(
           mockHeader,
           new BlockBody(
               Collections.emptyList(),
               Collections.emptyList(),
-              Optional.of(Collections.emptyList()),
-              Optional.empty()));
+              Optional.of(Collections.emptyList())));
   private static final Block mockBlockWithDepositRequests =
       new Block(
           mockHeader,
-          new BlockBody(
-              Collections.emptyList(),
-              Collections.emptyList(),
-              Optional.empty(),
-              Optional.of(Collections.emptyList())));
+          new BlockBody(Collections.emptyList(), Collections.emptyList(), Optional.empty()));
   protected static final BlockWithReceipts mockBlockWithReceiptsAndWithdrawals =
       new BlockWithReceipts(mockBlockWithWithdrawals, Collections.emptyList());
   protected static final PayloadWrapper mockPayloadWithWithdrawals =
-      new PayloadWrapper(mockPid, mockBlockWithReceiptsAndWithdrawals);
+      new PayloadWrapper(mockPid, mockBlockWithReceiptsAndWithdrawals, Optional.empty());
 
   protected static final BlockWithReceipts mockBlockWithReceiptsAndDepositRequests =
       new BlockWithReceipts(mockBlockWithDepositRequests, Collections.emptyList());
   protected static final PayloadWrapper mockPayloadWithDepositRequests =
-      new PayloadWrapper(mockPid, mockBlockWithReceiptsAndDepositRequests);
+      new PayloadWrapper(mockPid, mockBlockWithReceiptsAndDepositRequests, Optional.empty());
 
   @Mock protected ProtocolContext protocolContext;
 
diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayloadTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayloadTest.java
index fcfae09a24..d4980263d4 100644
--- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayloadTest.java
+++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayloadTest.java
@@ -38,13 +38,10 @@ import org.hyperledger.besu.ethereum.ProtocolContext;
 import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest;
 import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
 import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod;
-import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.ConsolidationRequestParameter;
-import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.DepositRequestParameter;
 import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.EnginePayloadParameter;
 import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.ExecutionWitnessParameter;
 import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.UnsignedLongParameter;
 import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.WithdrawalParameter;
-import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.WithdrawalRequestParameter;
 import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError;
 import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse;
 import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse;
@@ -55,20 +52,17 @@ import org.hyperledger.besu.ethereum.core.Block;
 import org.hyperledger.besu.ethereum.core.BlockBody;
 import org.hyperledger.besu.ethereum.core.BlockHeader;
 import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
-import org.hyperledger.besu.ethereum.core.DepositRequest;
 import org.hyperledger.besu.ethereum.core.Request;
 import org.hyperledger.besu.ethereum.core.Withdrawal;
-import org.hyperledger.besu.ethereum.core.WithdrawalRequest;
 import org.hyperledger.besu.ethereum.eth.manager.EthPeers;
 import org.hyperledger.besu.ethereum.mainnet.BodyValidation;
 import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
 import org.hyperledger.besu.ethereum.mainnet.WithdrawalsValidator;
-import org.hyperledger.besu.ethereum.mainnet.requests.RequestsValidatorCoordinator;
+import org.hyperledger.besu.ethereum.mainnet.requests.ProhibitedRequestValidator;
 import org.hyperledger.besu.ethereum.trie.MerkleTrieException;
 import org.hyperledger.besu.plugin.services.exception.StorageException;
 import org.hyperledger.besu.plugin.services.rpc.RpcResponseType;
 
-import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Optional;
@@ -131,7 +125,6 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
         setupValidPayload(
             new BlockProcessingResult(Optional.of(new BlockProcessingOutputs(null, List.of()))),
             Optional.empty(),
-            Optional.empty(),
             Optional.empty());
     lenient()
         .when(blockchain.getBlockHeader(mockHeader.getParentHash()))
@@ -145,10 +138,7 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
   public void shouldReturnInvalidOnBlockExecutionError() {
     BlockHeader mockHeader =
         setupValidPayload(
-            new BlockProcessingResult("error 42"),
-            Optional.empty(),
-            Optional.empty(),
-            Optional.empty());
+            new BlockProcessingResult("error 42"), Optional.empty(), Optional.empty());
     lenient()
         .when(blockchain.getBlockHeader(mockHeader.getParentHash()))
         .thenReturn(Optional.of(mock(BlockHeader.class)));
@@ -163,8 +153,7 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
 
   @Test
   public void shouldReturnAcceptedOnLatestValidAncestorEmpty() {
-    BlockHeader mockHeader =
-        createBlockHeader(Optional.empty(), Optional.empty(), Optional.empty());
+    BlockHeader mockHeader = createBlockHeader(Optional.empty(), Optional.empty());
     when(blockchain.getBlockByHash(mockHeader.getHash())).thenReturn(Optional.empty());
     when(blockchain.getBlockHeader(mockHeader.getParentHash()))
         .thenReturn(Optional.of(mock(BlockHeader.class)));
@@ -182,8 +171,7 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
 
   @Test
   public void shouldReturnSuccessOnAlreadyPresent() {
-    BlockHeader mockHeader =
-        createBlockHeader(Optional.empty(), Optional.empty(), Optional.empty());
+    BlockHeader mockHeader = createBlockHeader(Optional.empty(), Optional.empty());
     Block mockBlock =
         new Block(mockHeader, new BlockBody(Collections.emptyList(), Collections.emptyList()));
 
@@ -196,8 +184,7 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
 
   @Test
   public void shouldReturnInvalidWithLatestValidHashIsABadBlock() {
-    BlockHeader mockHeader =
-        createBlockHeader(Optional.empty(), Optional.empty(), Optional.empty());
+    BlockHeader mockHeader = createBlockHeader(Optional.empty(), Optional.empty());
     Hash latestValidHash = Hash.hash(Bytes32.fromHexStringLenient("0xcafebabe"));
 
     when(blockchain.getBlockByHash(mockHeader.getHash())).thenReturn(Optional.empty());
@@ -219,7 +206,6 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
         setupValidPayload(
             new BlockProcessingResult(Optional.empty(), new StorageException("database bedlam")),
             Optional.empty(),
-            Optional.empty(),
             Optional.empty());
     lenient()
         .when(blockchain.getBlockHeader(mockHeader.getParentHash()))
@@ -236,7 +222,6 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
         setupValidPayload(
             new BlockProcessingResult(Optional.empty(), new MerkleTrieException("missing leaf")),
             Optional.empty(),
-            Optional.empty(),
             Optional.empty());
 
     lenient()
@@ -251,8 +236,7 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
 
   @Test
   public void shouldNotReturnInvalidOnThrownMerkleTrieException() {
-    BlockHeader mockHeader =
-        createBlockHeader(Optional.empty(), Optional.empty(), Optional.empty());
+    BlockHeader mockHeader = createBlockHeader(Optional.empty(), Optional.empty());
     when(blockchain.getBlockByHash(mockHeader.getHash())).thenReturn(Optional.empty());
     when(blockchain.getBlockHeader(mockHeader.getParentHash()))
         .thenReturn(Optional.of(mock(BlockHeader.class)));
@@ -269,8 +253,7 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
 
   @Test
   public void shouldReturnInvalidBlockHashOnBadHashParameter() {
-    BlockHeader mockHeader =
-        spy(createBlockHeader(Optional.empty(), Optional.empty(), Optional.empty()));
+    BlockHeader mockHeader = spy(createBlockHeader(Optional.empty(), Optional.empty()));
     lenient()
         .when(mergeCoordinator.getLatestValidAncestor(mockHeader.getBlockHash()))
         .thenReturn(Optional.empty());
@@ -287,8 +270,7 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
 
   @Test
   public void shouldCheckBlockValidityBeforeCheckingByHashForExisting() {
-    BlockHeader realHeader =
-        createBlockHeader(Optional.empty(), Optional.empty(), Optional.empty());
+    BlockHeader realHeader = createBlockHeader(Optional.empty(), Optional.empty());
     BlockHeader paramHeader = spy(realHeader);
     when(paramHeader.getHash()).thenReturn(Hash.fromHexStringLenient("0x1337"));
 
@@ -302,8 +284,7 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
 
   @Test
   public void shouldReturnInvalidOnMalformedTransactions() {
-    BlockHeader mockHeader =
-        createBlockHeader(Optional.empty(), Optional.empty(), Optional.empty());
+    BlockHeader mockHeader = createBlockHeader(Optional.empty(), Optional.empty());
     when(mergeCoordinator.getLatestValidAncestor(any(Hash.class)))
         .thenReturn(Optional.of(mockHash));
 
@@ -318,8 +299,7 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
 
   @Test
   public void shouldRespondWithSyncingDuringForwardSync() {
-    BlockHeader mockHeader =
-        createBlockHeader(Optional.empty(), Optional.empty(), Optional.empty());
+    BlockHeader mockHeader = createBlockHeader(Optional.empty(), Optional.empty());
     when(mergeContext.isSyncing()).thenReturn(Boolean.TRUE);
     var resp = resp(mockEnginePayload(mockHeader, Collections.emptyList()));
 
@@ -332,8 +312,7 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
 
   @Test
   public void shouldRespondWithSyncingDuringBackwardsSync() {
-    BlockHeader mockHeader =
-        createBlockHeader(Optional.empty(), Optional.empty(), Optional.empty());
+    BlockHeader mockHeader = createBlockHeader(Optional.empty(), Optional.empty());
     when(mergeCoordinator.appendNewPayloadToSync(any()))
         .thenReturn(CompletableFuture.completedFuture(null));
     var resp = resp(mockEnginePayload(mockHeader, Collections.emptyList()));
@@ -347,8 +326,7 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
 
   @Test
   public void shouldRespondWithInvalidIfExtraDataIsNull() {
-    BlockHeader realHeader =
-        createBlockHeader(Optional.empty(), Optional.empty(), Optional.empty());
+    BlockHeader realHeader = createBlockHeader(Optional.empty(), Optional.empty());
     BlockHeader paramHeader = spy(realHeader);
     when(paramHeader.getHash()).thenReturn(Hash.fromHexStringLenient("0x1337"));
     when(paramHeader.getExtraData().toHexString()).thenReturn(null);
@@ -365,8 +343,7 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
   @Test
   public void shouldReturnInvalidWhenBadBlock() {
     when(mergeCoordinator.isBadBlock(any(Hash.class))).thenReturn(true);
-    BlockHeader mockHeader =
-        createBlockHeader(Optional.empty(), Optional.empty(), Optional.empty());
+    BlockHeader mockHeader = createBlockHeader(Optional.empty(), Optional.empty());
     var resp = resp(mockEnginePayload(mockHeader, Collections.emptyList()));
     when(protocolSpec.getWithdrawalsValidator())
         .thenReturn(new WithdrawalsValidator.AllowedWithdrawals());
@@ -384,7 +361,6 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
         setupValidPayload(
             new BlockProcessingResult(Optional.of(new BlockProcessingOutputs(null, List.of()))),
             Optional.empty(),
-            Optional.empty(),
             Optional.empty());
     lenient()
         .when(blockchain.getBlockHeader(mockHeader.getParentHash()))
@@ -405,16 +381,13 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
 
   protected EnginePayloadParameter mockEnginePayload(
       final BlockHeader header, final List txs) {
-    return mockEnginePayload(header, txs, null, null, null, null, null);
+    return mockEnginePayload(header, txs, null, null);
   }
 
   protected EnginePayloadParameter mockEnginePayload(
       final BlockHeader header,
       final List txs,
       final List withdrawals,
-      final List depositRequests,
-      final List withdrawalRequests,
-      final List consolidationRequests,
       final ExecutionWitnessParameter executionWitness) {
     return new EnginePayloadParameter(
         header.getHash(),
@@ -434,23 +407,16 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
         withdrawals,
         header.getBlobGasUsed().map(UnsignedLongParameter::new).orElse(null),
         header.getExcessBlobGas().map(BlobGas::toHexString).orElse(null),
-        depositRequests,
-        withdrawalRequests,
-        consolidationRequests,
         executionWitness);
   }
 
   protected BlockHeader setupValidPayload(
       final BlockProcessingResult value,
       final Optional> maybeWithdrawals,
-      final Optional> maybeDepositRequests,
-      final Optional> maybeWithdrawalRequests) {
+      final Optional> maybeRequests) {
 
-    BlockHeader mockHeader =
-        createBlockHeader(maybeWithdrawals, maybeDepositRequests, maybeWithdrawalRequests);
+    BlockHeader mockHeader = createBlockHeader(maybeWithdrawals, maybeRequests);
     when(blockchain.getBlockByHash(mockHeader.getHash())).thenReturn(Optional.empty());
-    // when(blockchain.getBlockHeader(mockHeader.getParentHash()))
-    //  .thenReturn(Optional.of(mock(BlockHeader.class)));
     when(mergeCoordinator.getLatestValidAncestor(any(BlockHeader.class)))
         .thenReturn(Optional.of(mockHash));
     when(mergeCoordinator.rememberBlock(any())).thenReturn(value);
@@ -480,27 +446,8 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
 
   protected BlockHeader createBlockHeader(
       final Optional> maybeWithdrawals,
-      final Optional> maybeDepositRequests,
-      final Optional> maybeWithdrawalRequests) {
-    return createBlockHeaderFixture(maybeWithdrawals, maybeDepositRequests, maybeWithdrawalRequests)
-        .buildHeader();
-  }
-
-  protected BlockHeaderTestFixture createBlockHeaderFixture(
-      final Optional> maybeWithdrawals,
-      final Optional> maybeDepositRequests,
-      final Optional> maybeWithdrawalRequests) {
-
-    Optional> maybeRequests;
-    if (maybeDepositRequests.isPresent() || maybeWithdrawalRequests.isPresent()) {
-      List requests = new ArrayList<>();
-      maybeDepositRequests.ifPresent(requests::addAll);
-      maybeWithdrawalRequests.ifPresent(requests::addAll);
-      maybeRequests = Optional.of(requests);
-    } else {
-      maybeRequests = Optional.empty();
-    }
-    return createBlockHeaderFixture(maybeWithdrawals, maybeRequests);
+      final Optional> maybeRequests) {
+    return createBlockHeaderFixture(maybeWithdrawals, maybeRequests).buildHeader();
   }
 
   protected BlockHeaderTestFixture createBlockHeaderFixture(
@@ -515,7 +462,7 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
         .timestamp(parentBlockHeader.getTimestamp() + 1)
         .withdrawalsRoot(maybeWithdrawals.map(BodyValidation::withdrawalsRoot).orElse(null))
         .parentBeaconBlockRoot(maybeParentBeaconBlockRoot)
-        .requestsRoot(maybeRequests.map(BodyValidation::requestsRoot).orElse(null));
+        .requestsHash(maybeRequests.map(BodyValidation::requestsHash).orElse(null));
   }
 
   protected void assertValidResponse(final BlockHeader mockHeader, final JsonRpcResponse resp) {
@@ -527,7 +474,7 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
   }
 
   private void mockProhibitedRequestsValidator() {
-    var validator = RequestsValidatorCoordinator.empty();
-    when(protocolSpec.getRequestsValidatorCoordinator()).thenReturn(validator);
+    var validator = new ProhibitedRequestValidator();
+    when(protocolSpec.getRequestsValidator()).thenReturn(validator);
   }
 }
diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetClientVersionV1Test.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetClientVersionV1Test.java
index 1aa0def7e2..d1d53832c1 100644
--- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetClientVersionV1Test.java
+++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetClientVersionV1Test.java
@@ -23,6 +23,8 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcRespon
 import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
 import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.EngineGetClientVersionResultV1;
 
+import java.util.List;
+
 import io.vertx.core.Vertx;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
@@ -61,9 +63,18 @@ class EngineGetClientVersionV1Test {
 
     assertThat(actualResult).isInstanceOf(JsonRpcSuccessResponse.class);
     JsonRpcSuccessResponse successResponse = (JsonRpcSuccessResponse) actualResult;
-    assertThat(successResponse.getResult()).isInstanceOf(EngineGetClientVersionResultV1.class);
+
+    assertThat(successResponse.getResult()).isInstanceOf(List.class);
+
+    List resultList = (List) successResponse.getResult();
+    assertThat(resultList).hasSize(1);
+
+    Object firstElement = resultList.get(0);
+    assertThat(firstElement).isInstanceOf(EngineGetClientVersionResultV1.class);
+
     EngineGetClientVersionResultV1 actualEngineGetClientVersionResultV1 =
-        (EngineGetClientVersionResultV1) successResponse.getResult();
+        (EngineGetClientVersionResultV1) firstElement;
+
     assertThat(actualEngineGetClientVersionResultV1.getName()).isEqualTo(ENGINE_CLIENT_NAME);
     assertThat(actualEngineGetClientVersionResultV1.getCode()).isEqualTo(ENGINE_CLIENT_CODE);
     assertThat(actualEngineGetClientVersionResultV1.getVersion()).isEqualTo(CLIENT_VERSION);
diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadBodiesByHashV1Test.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadBodiesByHashV1Test.java
index 8a99fa9439..f7752a7977 100644
--- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadBodiesByHashV1Test.java
+++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadBodiesByHashV1Test.java
@@ -180,7 +180,6 @@ public class EngineGetPayloadBodiesByHashV1Test {
         new BlockBody(
             List.of(new TransactionTestFixture().createTransaction(sig.generateKeyPair())),
             Collections.emptyList(),
-            Optional.empty(),
             Optional.empty());
     when(blockchain.getBlockBody(blockHash1)).thenReturn(Optional.of(preShanghaiBlockBody));
     when(blockchain.getBlockBody(blockHash2)).thenReturn(Optional.of(preShanghaiBlockBody2));
@@ -211,15 +210,13 @@ public class EngineGetPayloadBodiesByHashV1Test {
                 new TransactionTestFixture().createTransaction(sig.generateKeyPair()),
                 new TransactionTestFixture().createTransaction(sig.generateKeyPair())),
             Collections.emptyList(),
-            Optional.of(List.of(withdrawal)),
-            Optional.empty());
+            Optional.of(List.of(withdrawal)));
 
     final BlockBody shanghaiBlockBody2 =
         new BlockBody(
             List.of(new TransactionTestFixture().createTransaction(sig.generateKeyPair())),
             Collections.emptyList(),
-            Optional.of(List.of(withdrawal2)),
-            Optional.empty());
+            Optional.of(List.of(withdrawal2)));
     when(blockchain.getBlockBody(blockHash1)).thenReturn(Optional.of(shanghaiBlockBody));
     when(blockchain.getBlockBody(blockHash2)).thenReturn(Optional.of(shanghaiBlockBody2));
 
diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadBodiesByRangeV1Test.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadBodiesByRangeV1Test.java
index 6bc89ba679..886903ee09 100644
--- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadBodiesByRangeV1Test.java
+++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadBodiesByRangeV1Test.java
@@ -179,7 +179,6 @@ public class EngineGetPayloadBodiesByRangeV1Test {
         new BlockBody(
             List.of(new TransactionTestFixture().createTransaction(sig.generateKeyPair())),
             Collections.emptyList(),
-            Optional.empty(),
             Optional.empty());
     when(blockchain.getChainHeadBlockNumber()).thenReturn(Long.valueOf(130));
     when(blockchain.getBlockBody(blockHash1)).thenReturn(Optional.of(preShanghaiBlockBody));
@@ -214,15 +213,13 @@ public class EngineGetPayloadBodiesByRangeV1Test {
                 new TransactionTestFixture().createTransaction(sig.generateKeyPair()),
                 new TransactionTestFixture().createTransaction(sig.generateKeyPair())),
             Collections.emptyList(),
-            Optional.of(List.of(withdrawal)),
-            Optional.empty());
+            Optional.of(List.of(withdrawal)));
 
     final BlockBody shanghaiBlockBody2 =
         new BlockBody(
             List.of(new TransactionTestFixture().createTransaction(sig.generateKeyPair())),
             Collections.emptyList(),
-            Optional.of(List.of(withdrawal2)),
-            Optional.empty());
+            Optional.of(List.of(withdrawal2)));
     when(blockchain.getChainHeadBlockNumber()).thenReturn(Long.valueOf(130));
     when(blockchain.getBlockBody(blockHash1)).thenReturn(Optional.of(shanghaiBlockBody));
     when(blockchain.getBlockBody(blockHash2)).thenReturn(Optional.of(shanghaiBlockBody2));
@@ -252,8 +249,7 @@ public class EngineGetPayloadBodiesByRangeV1Test {
                 new TransactionTestFixture().createTransaction(sig.generateKeyPair()),
                 new TransactionTestFixture().createTransaction(sig.generateKeyPair())),
             Collections.emptyList(),
-            Optional.of(List.of(withdrawal)),
-            Optional.empty());
+            Optional.of(List.of(withdrawal)));
     when(blockchain.getChainHeadBlockNumber()).thenReturn(Long.valueOf(123));
     when(blockchain.getBlockBody(blockHash1)).thenReturn(Optional.of(shanghaiBlockBody));
     when(blockchain.getBlockHashByNumber(123)).thenReturn(Optional.of(blockHash1));
@@ -276,20 +272,17 @@ public class EngineGetPayloadBodiesByRangeV1Test {
         new BlockBody(
             List.of(new TransactionTestFixture().createTransaction(sig.generateKeyPair())),
             Collections.emptyList(),
-            Optional.of(List.of(withdrawal)),
-            Optional.empty());
+            Optional.of(List.of(withdrawal)));
     final BlockBody shanghaiBlockBody2 =
         new BlockBody(
             List.of(new TransactionTestFixture().createTransaction(sig.generateKeyPair())),
             Collections.emptyList(),
-            Optional.of(List.of(withdrawal)),
-            Optional.empty());
+            Optional.of(List.of(withdrawal)));
     final BlockBody shanghaiBlockBody3 =
         new BlockBody(
             List.of(new TransactionTestFixture().createTransaction(sig.generateKeyPair())),
             Collections.emptyList(),
-            Optional.of(List.of(withdrawal)),
-            Optional.empty());
+            Optional.of(List.of(withdrawal)));
     when(blockchain.getChainHeadBlockNumber()).thenReturn(Long.valueOf(125));
     when(blockchain.getBlockBody(blockHash1)).thenReturn(Optional.of(shanghaiBlockBody));
     when(blockchain.getBlockBody(blockHash2)).thenReturn(Optional.of(shanghaiBlockBody2));
diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV2Test.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV2Test.java
index 5c455222f1..fcbe179a52 100644
--- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV2Test.java
+++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV2Test.java
@@ -124,7 +124,8 @@ public class EngineGetPayloadV2Test extends AbstractEngineGetPayloadTest {
         new Block(mockHeader, new BlockBody(Collections.emptyList(), Collections.emptyList()));
     final BlockWithReceipts mockBlockWithReceipts =
         new BlockWithReceipts(mockBlock, Collections.emptyList());
-    final PayloadWrapper mockPayload = new PayloadWrapper(mockPid, mockBlockWithReceipts);
+    final PayloadWrapper mockPayload =
+        new PayloadWrapper(mockPid, mockBlockWithReceipts, Optional.empty());
 
     when(mergeContext.retrievePayloadById(mockPid)).thenReturn(Optional.of(mockPayload));
 
diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV3Test.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV3Test.java
index ac589c1121..1fe3b44d45 100644
--- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV3Test.java
+++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV3Test.java
@@ -128,10 +128,10 @@ public class EngineGetPayloadV3Test extends AbstractEngineGetPayloadTest {
                 new BlockBody(
                     List.of(blobTx),
                     Collections.emptyList(),
-                    Optional.of(Collections.emptyList()),
                     Optional.of(Collections.emptyList()))),
             List.of(blobReceipt));
-    PayloadWrapper payloadPostCancun = new PayloadWrapper(postCancunPid, postCancunBlock);
+    PayloadWrapper payloadPostCancun =
+        new PayloadWrapper(postCancunPid, postCancunBlock, Optional.empty());
 
     when(mergeContext.retrievePayloadById(postCancunPid))
         .thenReturn(Optional.of(payloadPostCancun));
diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV4Test.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV4Test.java
index 134c7a2c0c..744600ddca 100644
--- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV4Test.java
+++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV4Test.java
@@ -14,6 +14,7 @@
  */
 package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine;
 
+import static java.util.Collections.emptyList;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Mockito.lenient;
 import static org.mockito.Mockito.mock;
@@ -27,6 +28,7 @@ import org.hyperledger.besu.datatypes.Address;
 import org.hyperledger.besu.datatypes.BlobGas;
 import org.hyperledger.besu.datatypes.BlobsWithCommitments;
 import org.hyperledger.besu.datatypes.Hash;
+import org.hyperledger.besu.datatypes.RequestType;
 import org.hyperledger.besu.datatypes.TransactionType;
 import org.hyperledger.besu.datatypes.Wei;
 import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod;
@@ -41,12 +43,13 @@ import org.hyperledger.besu.ethereum.core.BlockBody;
 import org.hyperledger.besu.ethereum.core.BlockHeader;
 import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
 import org.hyperledger.besu.ethereum.core.BlockWithReceipts;
+import org.hyperledger.besu.ethereum.core.Request;
 import org.hyperledger.besu.ethereum.core.Transaction;
 import org.hyperledger.besu.ethereum.core.TransactionReceipt;
 import org.hyperledger.besu.ethereum.core.TransactionTestFixture;
 
 import java.math.BigInteger;
-import java.util.Collections;
+import java.util.Comparator;
 import java.util.List;
 import java.util.Optional;
 
@@ -128,19 +131,24 @@ public class EngineGetPayloadV4Test extends AbstractEngineGetPayloadTest {
     BlockWithReceipts block =
         new BlockWithReceipts(
             new Block(
-                header,
-                new BlockBody(
-                    List.of(blobTx),
-                    Collections.emptyList(),
-                    Optional.of(Collections.emptyList()),
-                    Optional.of(Collections.emptyList()))),
+                header, new BlockBody(List.of(blobTx), emptyList(), Optional.of(emptyList()))),
             List.of(blobReceipt));
-    PayloadWrapper payload = new PayloadWrapper(payloadIdentifier, block);
+    final List requests =
+        List.of(
+            new Request(RequestType.DEPOSIT, Bytes.of(1)),
+            new Request(RequestType.WITHDRAWAL, Bytes.of(1)),
+            new Request(RequestType.CONSOLIDATION, Bytes.of(1)));
+    PayloadWrapper payload = new PayloadWrapper(payloadIdentifier, block, Optional.of(requests));
 
     when(mergeContext.retrievePayloadById(payloadIdentifier)).thenReturn(Optional.of(payload));
 
     final var resp = resp(RpcMethod.ENGINE_GET_PAYLOAD_V4.getMethodName(), payloadIdentifier);
     assertThat(resp).isInstanceOf(JsonRpcSuccessResponse.class);
+    final List requestsWithoutRequestId =
+        requests.stream()
+            .sorted(Comparator.comparing(Request::getType))
+            .map(r -> r.getData().toHexString())
+            .toList();
     Optional.of(resp)
         .map(JsonRpcSuccessResponse.class::cast)
         .ifPresent(
@@ -148,9 +156,6 @@ public class EngineGetPayloadV4Test extends AbstractEngineGetPayloadTest {
               assertThat(r.getResult()).isInstanceOf(EngineGetPayloadResultV4.class);
               final EngineGetPayloadResultV4 res = (EngineGetPayloadResultV4) r.getResult();
               assertThat(res.getExecutionPayload().getWithdrawals()).isNotNull();
-              assertThat(res.getExecutionPayload().getDepositRequests()).isNotNull();
-              assertThat(res.getExecutionPayload().getWithdrawalRequests()).isNotNull();
-              assertThat(res.getExecutionPayload().getConsolidationRequests()).isNotNull();
               assertThat(res.getExecutionPayload().getHash())
                   .isEqualTo(header.getHash().toString());
               assertThat(res.getBlockValue()).isEqualTo(Quantity.create(0));
@@ -161,6 +166,8 @@ public class EngineGetPayloadV4Test extends AbstractEngineGetPayloadTest {
               assertThat(res.getExecutionPayload().getExcessBlobGas()).isNotEmpty();
               assertThat(res.getExecutionPayload().getExcessBlobGas())
                   .isEqualTo(expectedQuantityOf10);
+              assertThat(res.getExecutionRequests()).isNotEmpty();
+              assertThat(res.getExecutionRequests()).isEqualTo(requestsWithoutRequestId);
             });
     verify(engineCallListener, times(1)).executionEngineCalled();
   }
diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV2Test.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV2Test.java
index 5eb2a392ea..76f7c7dfae 100644
--- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV2Test.java
+++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV2Test.java
@@ -83,16 +83,12 @@ public class EngineNewPayloadV2Test extends AbstractEngineNewPayloadTest {
         setupValidPayload(
             new BlockProcessingResult(Optional.of(new BlockProcessingOutputs(null, List.of()))),
             Optional.of(withdrawals),
-            Optional.empty(),
             Optional.empty());
     lenient()
         .when(blockchain.getBlockHeader(mockHeader.getParentHash()))
         .thenReturn(Optional.of(mock(BlockHeader.class)));
-    var resp =
-        resp(
-            mockEnginePayload(
-                mockHeader, Collections.emptyList(), withdrawalsParam, null, null, null, null));
 
+    var resp = resp(mockEnginePayload(mockHeader, Collections.emptyList(), withdrawalsParam, null));
     assertValidResponse(mockHeader, resp);
   }
 
@@ -105,15 +101,12 @@ public class EngineNewPayloadV2Test extends AbstractEngineNewPayloadTest {
         setupValidPayload(
             new BlockProcessingResult(Optional.of(new BlockProcessingOutputs(null, List.of()))),
             Optional.empty(),
-            Optional.empty(),
             Optional.empty());
     lenient()
         .when(blockchain.getBlockHeader(mockHeader.getParentHash()))
         .thenReturn(Optional.of(mock(BlockHeader.class)));
-    var resp =
-        resp(
-            mockEnginePayload(
-                mockHeader, Collections.emptyList(), withdrawals, null, null, null, null));
+
+    var resp = resp(mockEnginePayload(mockHeader, Collections.emptyList(), withdrawals, null));
 
     assertValidResponse(mockHeader, resp);
   }
@@ -128,13 +121,9 @@ public class EngineNewPayloadV2Test extends AbstractEngineNewPayloadTest {
     var resp =
         resp(
             mockEnginePayload(
-                createBlockHeader(
-                    Optional.of(Collections.emptyList()), Optional.empty(), Optional.empty()),
+                createBlockHeader(Optional.of(Collections.emptyList()), Optional.empty()),
                 Collections.emptyList(),
                 withdrawals,
-                null,
-                null,
-                null,
                 null));
 
     final JsonRpcError jsonRpcError = fromErrorResp(resp);
@@ -146,15 +135,11 @@ public class EngineNewPayloadV2Test extends AbstractEngineNewPayloadTest {
   public void shouldValidateBlobGasUsedCorrectly() {
     // V2 should return error if non-null blobGasUsed
     BlockHeader blockHeader =
-        createBlockHeaderFixture(
-                Optional.of(Collections.emptyList()), Optional.empty(), Optional.empty())
+        createBlockHeaderFixture(Optional.of(Collections.emptyList()), Optional.empty())
             .blobGasUsed(100L)
             .buildHeader();
 
-    var resp =
-        resp(
-            mockEnginePayload(
-                blockHeader, Collections.emptyList(), List.of(), null, null, null, null));
+    var resp = resp(mockEnginePayload(blockHeader, Collections.emptyList(), List.of(), null));
     final JsonRpcError jsonRpcError = fromErrorResp(resp);
     assertThat(jsonRpcError.getCode()).isEqualTo(INVALID_BLOB_GAS_USED_PARAMS.getCode());
     assertThat(jsonRpcError.getData()).isEqualTo("Missing blob gas used field");
@@ -165,15 +150,11 @@ public class EngineNewPayloadV2Test extends AbstractEngineNewPayloadTest {
   public void shouldValidateExcessBlobGasCorrectly() {
     // V2 should return error if non-null ExcessBlobGas
     BlockHeader blockHeader =
-        createBlockHeaderFixture(
-                Optional.of(Collections.emptyList()), Optional.empty(), Optional.empty())
+        createBlockHeaderFixture(Optional.of(Collections.emptyList()), Optional.empty())
             .excessBlobGas(BlobGas.MAX_BLOB_GAS)
             .buildHeader();
 
-    var resp =
-        resp(
-            mockEnginePayload(
-                blockHeader, Collections.emptyList(), List.of(), null, null, null, null));
+    var resp = resp(mockEnginePayload(blockHeader, Collections.emptyList(), List.of(), null));
 
     final JsonRpcError jsonRpcError = fromErrorResp(resp);
     assertThat(jsonRpcError.getCode()).isEqualTo(INVALID_PARAMS.getCode());
@@ -190,12 +171,9 @@ public class EngineNewPayloadV2Test extends AbstractEngineNewPayloadTest {
     var resp =
         resp(
             mockEnginePayload(
-                createBlockHeader(Optional.empty(), Optional.empty(), Optional.empty()),
+                createBlockHeader(Optional.empty(), Optional.empty()),
                 Collections.emptyList(),
                 withdrawals,
-                null,
-                null,
-                null,
                 null));
 
     assertThat(fromErrorResp(resp).getCode()).isEqualTo(INVALID_PARAMS.getCode());
@@ -207,15 +185,11 @@ public class EngineNewPayloadV2Test extends AbstractEngineNewPayloadTest {
     // Cancun starte at timestamp 30
     final long blockTimestamp = 31L;
     BlockHeader blockHeader =
-        createBlockHeaderFixture(
-                Optional.of(Collections.emptyList()), Optional.empty(), Optional.empty())
+        createBlockHeaderFixture(Optional.of(Collections.emptyList()), Optional.empty())
             .timestamp(blockTimestamp)
             .buildHeader();
 
-    var resp =
-        resp(
-            mockEnginePayload(
-                blockHeader, Collections.emptyList(), List.of(), null, null, null, null));
+    var resp = resp(mockEnginePayload(blockHeader, Collections.emptyList(), List.of(), null));
 
     final JsonRpcError jsonRpcError = fromErrorResp(resp);
     assertThat(jsonRpcError.getCode()).isEqualTo(UNSUPPORTED_FORK.getCode());
diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV3Test.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV3Test.java
index 3f75c62829..7ac4772ef9 100644
--- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV3Test.java
+++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV3Test.java
@@ -44,11 +44,10 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.EnginePayloadS
 import org.hyperledger.besu.ethereum.core.BlobTestFixture;
 import org.hyperledger.besu.ethereum.core.BlockHeader;
 import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
-import org.hyperledger.besu.ethereum.core.DepositRequest;
+import org.hyperledger.besu.ethereum.core.Request;
 import org.hyperledger.besu.ethereum.core.Transaction;
 import org.hyperledger.besu.ethereum.core.TransactionTestFixture;
 import org.hyperledger.besu.ethereum.core.Withdrawal;
-import org.hyperledger.besu.ethereum.core.WithdrawalRequest;
 import org.hyperledger.besu.ethereum.core.encoding.EncodingContext;
 import org.hyperledger.besu.ethereum.core.encoding.TransactionEncoder;
 import org.hyperledger.besu.ethereum.mainnet.BodyValidation;
@@ -135,24 +134,23 @@ public class EngineNewPayloadV3Test extends EngineNewPayloadV2Test {
         setupValidPayload(
             new BlockProcessingResult(Optional.of(new BlockProcessingOutputs(null, List.of()))),
             Optional.empty(),
-            Optional.empty(),
             Optional.empty());
     final EnginePayloadParameter payload =
-        mockEnginePayload(mockHeader, Collections.emptyList(), null, null, null, null, null);
+        mockEnginePayload(mockHeader, Collections.emptyList(), null, null);
 
     ValidationResult res =
         method.validateParameters(
             payload,
             Optional.of(List.of()),
-            Optional.of("0x0000000000000000000000000000000000000000000000000000000000000000"));
+            Optional.of("0x0000000000000000000000000000000000000000000000000000000000000000"),
+            Optional.empty());
     assertThat(res.isValid()).isTrue();
   }
 
   @Override
   protected BlockHeader createBlockHeader(
       final Optional> maybeWithdrawals,
-      final Optional> maybeDepositRequests,
-      final Optional> maybeWithdrawalRequests) {
+      final Optional> maybeRequests) {
     BlockHeader parentBlockHeader =
         new BlockHeaderTestFixture()
             .baseFeePerGas(Wei.ONE)
@@ -188,16 +186,12 @@ public class EngineNewPayloadV3Test extends EngineNewPayloadV2Test {
   public void shouldValidateBlobGasUsedCorrectly() {
     // V3 must return error if null blobGasUsed
     BlockHeader blockHeader =
-        createBlockHeaderFixture(
-                Optional.of(Collections.emptyList()), Optional.empty(), Optional.empty())
+        createBlockHeaderFixture(Optional.of(Collections.emptyList()), Optional.empty())
             .excessBlobGas(BlobGas.MAX_BLOB_GAS)
             .blobGasUsed(null)
             .buildHeader();
 
-    var resp =
-        resp(
-            mockEnginePayload(
-                blockHeader, Collections.emptyList(), List.of(), null, null, null, null));
+    var resp = resp(mockEnginePayload(blockHeader, Collections.emptyList(), List.of(), null));
 
     final JsonRpcError jsonRpcError = fromErrorResp(resp);
     assertThat(jsonRpcError.getCode()).isEqualTo(INVALID_PARAMS.getCode());
@@ -210,16 +204,12 @@ public class EngineNewPayloadV3Test extends EngineNewPayloadV2Test {
   public void shouldValidateExcessBlobGasCorrectly() {
     // V3 must return error if null excessBlobGas
     BlockHeader blockHeader =
-        createBlockHeaderFixture(
-                Optional.of(Collections.emptyList()), Optional.empty(), Optional.empty())
+        createBlockHeaderFixture(Optional.of(Collections.emptyList()), Optional.empty())
             .excessBlobGas(null)
             .blobGasUsed(100L)
             .buildHeader();
 
-    var resp =
-        resp(
-            mockEnginePayload(
-                blockHeader, Collections.emptyList(), List.of(), null, null, null, null));
+    var resp = resp(mockEnginePayload(blockHeader, Collections.emptyList(), List.of(), null));
 
     final JsonRpcError jsonRpcError = fromErrorResp(resp);
     assertThat(jsonRpcError.getCode()).isEqualTo(INVALID_PARAMS.getCode());
@@ -240,7 +230,6 @@ public class EngineNewPayloadV3Test extends EngineNewPayloadV2Test {
         setupValidPayload(
             new BlockProcessingResult(Optional.of(new BlockProcessingOutputs(null, List.of()))),
             Optional.empty(),
-            Optional.empty(),
             Optional.empty());
     var resp = resp(mockEnginePayload(mockHeader, transactions));
 
diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV4Test.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV4Test.java
index bc024785e6..73bd1b8035 100644
--- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV4Test.java
+++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV4Test.java
@@ -15,9 +15,7 @@
 package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine;
 
 import static org.assertj.core.api.Assertions.assertThat;
-import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.DepositParameterTestFixture.DEPOSIT_PARAM_1;
-import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.WithdrawalRequestTestFixture.WITHDRAWAL_REQUEST_PARAMETER_1;
-import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType.INVALID_PARAMS;
+import static org.hyperledger.besu.ethereum.api.graphql.internal.response.GraphQLError.INVALID_PARAMS;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.lenient;
 import static org.mockito.Mockito.mock;
@@ -25,7 +23,6 @@ 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.BlobGas;
 import org.hyperledger.besu.datatypes.RequestType;
 import org.hyperledger.besu.datatypes.Wei;
@@ -33,28 +30,24 @@ import org.hyperledger.besu.ethereum.BlockProcessingOutputs;
 import org.hyperledger.besu.ethereum.BlockProcessingResult;
 import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest;
 import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
-import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.DepositRequestParameter;
 import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.EnginePayloadParameter;
-import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.WithdrawalRequestParameter;
 import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError;
 import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse;
 import org.hyperledger.besu.ethereum.core.BlockHeader;
 import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
-import org.hyperledger.besu.ethereum.core.DepositRequest;
 import org.hyperledger.besu.ethereum.core.Request;
 import org.hyperledger.besu.ethereum.core.Withdrawal;
-import org.hyperledger.besu.ethereum.core.WithdrawalRequest;
 import org.hyperledger.besu.ethereum.mainnet.BodyValidation;
-import org.hyperledger.besu.ethereum.mainnet.requests.DepositRequestValidator;
-import org.hyperledger.besu.ethereum.mainnet.requests.RequestsValidatorCoordinator;
-import org.hyperledger.besu.ethereum.mainnet.requests.WithdrawalRequestValidator;
+import org.hyperledger.besu.ethereum.mainnet.requests.MainnetRequestsValidator;
+import org.hyperledger.besu.ethereum.mainnet.requests.ProhibitedRequestValidator;
 import org.hyperledger.besu.evm.gascalculator.PragueGasCalculator;
 
-import java.util.ArrayList;
 import java.util.Collections;
+import java.util.Comparator;
 import java.util.List;
 import java.util.Optional;
 
+import org.apache.tuweni.bytes.Bytes;
 import org.apache.tuweni.bytes.Bytes32;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
@@ -63,8 +56,6 @@ import org.mockito.junit.jupiter.MockitoExtension;
 
 @ExtendWith(MockitoExtension.class)
 public class EngineNewPayloadV4Test extends EngineNewPayloadV3Test {
-  private static final Address depositContractAddress =
-      Address.fromHexString("0x00000000219ab540356cbb839cbe05303d7705fa");
 
   public EngineNewPayloadV4Test() {}
 
@@ -92,8 +83,7 @@ public class EngineNewPayloadV4Test extends EngineNewPayloadV3Test {
   }
 
   @Test
-  public void shouldReturnValidIfDepositRequestsIsNull_WhenDepositRequestsProhibited() {
-    final List depositRequests = null;
+  public void shouldReturnValidIfRequestsIsNull_WhenRequestsProhibited() {
     mockProhibitedRequestsValidator();
 
     BlockHeader mockHeader =
@@ -101,181 +91,68 @@ public class EngineNewPayloadV4Test extends EngineNewPayloadV3Test {
             new BlockProcessingResult(
                 Optional.of(new BlockProcessingOutputs(null, List.of(), Optional.empty()))),
             Optional.empty(),
-            Optional.empty(),
             Optional.empty());
     when(blockchain.getBlockHeader(mockHeader.getParentHash()))
         .thenReturn(Optional.of(mock(BlockHeader.class)));
     when(mergeCoordinator.getLatestValidAncestor(mockHeader))
         .thenReturn(Optional.of(mockHeader.getHash()));
 
-    var resp =
-        resp(
-            mockEnginePayload(
-                mockHeader, Collections.emptyList(), null, depositRequests, null, null, null));
+    var resp = resp(mockEnginePayload(mockHeader, Collections.emptyList()));
 
     assertValidResponse(mockHeader, resp);
   }
 
   @Test
-  public void shouldReturnInvalidIfDepositRequestsIsNull_WhenDepositRequestsAllowed() {
-    final List depositRequests = null;
-    mockAllowedDepositRequestsRequestValidator();
+  public void shouldReturnInvalidIfRequestsIsNull_WhenRequestsAllowed() {
+    mockAllowedRequestsValidator();
     var resp =
         resp(
             mockEnginePayload(
-                createBlockHeader(Optional.empty(), Optional.empty(), Optional.empty()),
-                Collections.emptyList(),
-                null,
-                depositRequests,
-                null,
-                null,
-                null));
+                createBlockHeader(Optional.empty(), Optional.empty()), Collections.emptyList()));
 
     assertThat(fromErrorResp(resp).getCode()).isEqualTo(INVALID_PARAMS.getCode());
     verify(engineCallListener, times(1)).executionEngineCalled();
   }
 
-  @Test
-  public void shouldReturnValidIfDepositRequestsIsNotNull_WhenDepositRequestsAllowed() {
-    final List depositRequestsParam = List.of(DEPOSIT_PARAM_1);
-    final List depositRequests = List.of(DEPOSIT_PARAM_1.toDeposit());
+  public void shouldReturnValidIfRequestsIsNotNull_WhenRequestsAllowed() {
+    final List requests =
+        List.of(
+            new Request(RequestType.DEPOSIT, Bytes.of(1)),
+            new Request(RequestType.WITHDRAWAL, Bytes.of(1)),
+            new Request(RequestType.CONSOLIDATION, Bytes.of(1)));
 
-    mockAllowedDepositRequestsRequestValidator();
+    mockAllowedRequestsValidator();
     BlockHeader mockHeader =
         setupValidPayload(
             new BlockProcessingResult(
-                Optional.of(
-                    new BlockProcessingOutputs(null, List.of(), Optional.of(depositRequests)))),
+                Optional.of(new BlockProcessingOutputs(null, List.of(), Optional.of(requests)))),
             Optional.empty(),
-            Optional.of(List.of(DEPOSIT_PARAM_1.toDeposit())),
             Optional.empty());
     when(blockchain.getBlockHeader(mockHeader.getParentHash()))
         .thenReturn(Optional.of(mock(BlockHeader.class)));
     when(mergeCoordinator.getLatestValidAncestor(mockHeader))
         .thenReturn(Optional.of(mockHeader.getHash()));
-    var resp =
-        resp(
-            mockEnginePayload(
-                mockHeader, Collections.emptyList(), null, depositRequestsParam, null, null, null));
+    var resp = resp(mockEnginePayload(mockHeader, Collections.emptyList()), requests);
 
     assertValidResponse(mockHeader, resp);
   }
 
   @Test
-  public void shouldReturnInvalidIfDepositRequestsIsNotNull_WhenDepositRequestsProhibited() {
-    final List depositRequests = List.of();
-    lenient()
-        .when(protocolSpec.getRequestsValidatorCoordinator())
-        .thenReturn(RequestsValidatorCoordinator.empty());
+  public void shouldReturnInvalidIfRequestsIsNotNull_WhenRequestsProhibited() {
+    final List requests =
+        List.of(
+            new Request(RequestType.DEPOSIT, Bytes.of(1)),
+            new Request(RequestType.WITHDRAWAL, Bytes.of(1)),
+            new Request(RequestType.CONSOLIDATION, Bytes.of(1)));
 
-    var resp =
-        resp(
-            mockEnginePayload(
-                createBlockHeader(
-                    Optional.empty(), Optional.of(Collections.emptyList()), Optional.empty()),
-                Collections.emptyList(),
-                null,
-                depositRequests,
-                null,
-                null,
-                null));
-
-    final JsonRpcError jsonRpcError = fromErrorResp(resp);
-    assertThat(jsonRpcError.getCode()).isEqualTo(INVALID_PARAMS.getCode());
-    verify(engineCallListener, times(1)).executionEngineCalled();
-  }
-
-  @Test
-  public void shouldReturnValidIfWithdrawalRequestsIsNull_WhenWithdrawalRequestsAreProhibited() {
     mockProhibitedRequestsValidator();
 
-    BlockHeader mockHeader =
-        setupValidPayload(
-            new BlockProcessingResult(
-                Optional.of(new BlockProcessingOutputs(null, List.of(), Optional.empty()))),
-            Optional.empty(),
-            Optional.empty(),
-            Optional.empty());
-    when(blockchain.getBlockHeader(mockHeader.getParentHash()))
-        .thenReturn(Optional.of(mock(BlockHeader.class)));
-    when(mergeCoordinator.getLatestValidAncestor(mockHeader))
-        .thenReturn(Optional.of(mockHeader.getHash()));
-
-    var resp =
-        resp(mockEnginePayload(mockHeader, Collections.emptyList(), null, null, null, null, null));
-
-    assertValidResponse(mockHeader, resp);
-  }
-
-  @Test
-  public void shouldReturnInvalidIfWithdrawalRequestsIsNull_WhenWithdrawalRequestsAreAllowed() {
-    mockAllowedWithdrawalsRequestValidator();
-
     var resp =
         resp(
             mockEnginePayload(
-                createBlockHeader(Optional.empty(), Optional.empty(), Optional.empty()),
-                Collections.emptyList(),
-                null,
-                null,
-                null,
-                null,
-                null));
-
-    assertThat(fromErrorResp(resp).getCode()).isEqualTo(INVALID_PARAMS.getCode());
-    verify(engineCallListener, times(1)).executionEngineCalled();
-  }
-
-  @Test
-  public void shouldReturnValidIfWithdrawalRequestsIsNotNull_WhenWithdrawalRequestsAreAllowed() {
-    final List withdrawalRequestsParams =
-        List.of(WITHDRAWAL_REQUEST_PARAMETER_1);
-    final List withdrawalRequests =
-        List.of(WITHDRAWAL_REQUEST_PARAMETER_1.toWithdrawalRequest());
-    mockAllowedWithdrawalsRequestValidator();
-    BlockHeader mockHeader =
-        setupValidPayload(
-            new BlockProcessingResult(
-                Optional.of(
-                    new BlockProcessingOutputs(null, List.of(), Optional.of(withdrawalRequests)))),
-            Optional.empty(),
-            Optional.empty(),
-            Optional.of(List.of(WITHDRAWAL_REQUEST_PARAMETER_1.toWithdrawalRequest())));
-    when(blockchain.getBlockHeader(mockHeader.getParentHash()))
-        .thenReturn(Optional.of(mock(BlockHeader.class)));
-    when(mergeCoordinator.getLatestValidAncestor(mockHeader))
-        .thenReturn(Optional.of(mockHeader.getHash()));
-    var resp =
-        resp(
-            mockEnginePayload(
-                mockHeader,
-                Collections.emptyList(),
-                null,
-                null,
-                withdrawalRequestsParams,
-                null,
-                null));
-
-    assertValidResponse(mockHeader, resp);
-  }
-
-  @Test
-  public void
-      shouldReturnInvalidIfWithdrawalRequestsIsNotNull_WhenWithdrawalRequestsAreProhibited() {
-    final List withdrawalRequests = List.of();
-    mockProhibitedRequestsValidator();
-
-    var resp =
-        resp(
-            mockEnginePayload(
-                createBlockHeader(
-                    Optional.empty(), Optional.empty(), Optional.of(Collections.emptyList())),
-                Collections.emptyList(),
-                null,
-                null,
-                withdrawalRequests,
-                null,
-                null));
+                createBlockHeader(Optional.empty(), Optional.of(Collections.emptyList())),
+                Collections.emptyList()),
+            requests);
 
     final JsonRpcError jsonRpcError = fromErrorResp(resp);
     assertThat(jsonRpcError.getCode()).isEqualTo(INVALID_PARAMS.getCode());
@@ -285,8 +162,7 @@ public class EngineNewPayloadV4Test extends EngineNewPayloadV3Test {
   @Override
   protected BlockHeader createBlockHeader(
       final Optional> maybeWithdrawals,
-      final Optional> maybeDepositRequests,
-      final Optional> maybeWithdrawalRequests) {
+      final Optional> maybeRequests) {
     BlockHeader parentBlockHeader =
         new BlockHeaderTestFixture()
             .baseFeePerGas(Wei.ONE)
@@ -295,16 +171,6 @@ public class EngineNewPayloadV4Test extends EngineNewPayloadV3Test {
             .blobGasUsed(0L)
             .buildHeader();
 
-    Optional> maybeRequests;
-    if (maybeDepositRequests.isPresent() || maybeWithdrawalRequests.isPresent()) {
-      List requests = new ArrayList<>();
-      maybeDepositRequests.ifPresent(requests::addAll);
-      maybeWithdrawalRequests.ifPresent(requests::addAll);
-      maybeRequests = Optional.of(requests);
-    } else {
-      maybeRequests = Optional.empty();
-    }
-
     BlockHeader mockHeader =
         new BlockHeaderTestFixture()
             .baseFeePerGas(Wei.ONE)
@@ -314,7 +180,7 @@ public class EngineNewPayloadV4Test extends EngineNewPayloadV3Test {
             .withdrawalsRoot(maybeWithdrawals.map(BodyValidation::withdrawalsRoot).orElse(null))
             .excessBlobGas(BlobGas.ZERO)
             .blobGasUsed(0L)
-            .requestsRoot(maybeRequests.map(BodyValidation::requestsRoot).orElse(null))
+            .requestsHash(maybeRequests.map(BodyValidation::requestsHash).orElse(null))
             .parentBeaconBlockRoot(
                 maybeParentBeaconBlockRoot.isPresent() ? maybeParentBeaconBlockRoot : null)
             .buildHeader();
@@ -331,24 +197,35 @@ public class EngineNewPayloadV4Test extends EngineNewPayloadV3Test {
         new JsonRpcRequestContext(new JsonRpcRequest("2.0", this.method.getName(), params)));
   }
 
-  private void mockProhibitedRequestsValidator() {
-    var validator = RequestsValidatorCoordinator.empty();
-    when(protocolSpec.getRequestsValidatorCoordinator()).thenReturn(validator);
+  protected JsonRpcResponse resp(
+      final EnginePayloadParameter payload, final List requests) {
+    final List requestsWithoutRequestId =
+        requests.stream()
+            .sorted(Comparator.comparing(Request::getType))
+            .map(r -> r.getData().toHexString())
+            .toList();
+    Object[] params =
+        maybeParentBeaconBlockRoot
+            .map(
+                bytes32 ->
+                    new Object[] {
+                      payload,
+                      Collections.emptyList(),
+                      bytes32.toHexString(),
+                      requestsWithoutRequestId
+                    })
+            .orElseGet(() -> new Object[] {payload});
+    return method.response(
+        new JsonRpcRequestContext(new JsonRpcRequest("2.0", this.method.getName(), params)));
   }
 
-  private void mockAllowedDepositRequestsRequestValidator() {
-    var validator =
-        new RequestsValidatorCoordinator.Builder()
-            .addValidator(RequestType.DEPOSIT, new DepositRequestValidator(depositContractAddress))
-            .build();
-    when(protocolSpec.getRequestsValidatorCoordinator()).thenReturn(validator);
+  private void mockProhibitedRequestsValidator() {
+    var validator = new ProhibitedRequestValidator();
+    when(protocolSpec.getRequestsValidator()).thenReturn(validator);
   }
 
-  private void mockAllowedWithdrawalsRequestValidator() {
-    var validator =
-        new RequestsValidatorCoordinator.Builder()
-            .addValidator(RequestType.WITHDRAWAL, new WithdrawalRequestValidator())
-            .build();
-    when(protocolSpec.getRequestsValidatorCoordinator()).thenReturn(validator);
+  private void mockAllowedRequestsValidator() {
+    var validator = new MainnetRequestsValidator();
+    when(protocolSpec.getRequestsValidator()).thenReturn(validator);
   }
 }
diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/DepositParameterTestFixture.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/DepositParameterTestFixture.java
deleted file mode 100644
index f3f5f420bb..0000000000
--- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/DepositParameterTestFixture.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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.api.jsonrpc.internal.parameters;
-
-public class DepositParameterTestFixture {
-
-  public static final DepositRequestParameter DEPOSIT_PARAM_1 =
-      createDeposit(
-          "0xb10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e",
-          "0x0017a7fcf06faf493d30bbe2632ea7c2383cd86825e12797165de7aa35589483",
-          "0x773594000",
-          "0xa889db8300194050a2636c92a95bc7160515867614b7971a9500cdb62f9c0890217d2901c3241f86fac029428fc106930606154bd9e406d7588934a5f15b837180b17194d6e44bd6de23e43b163dfe12e369dcc75a3852cd997963f158217eb5",
-          "0x1");
-  static final DepositRequestParameter DEPOSIT_PARAM_2 =
-      createDeposit(
-          "0x8706d19a62f28a6a6549f96c5adaebac9124a61d44868ec94f6d2d707c6a2f82c9162071231dfeb40e24bfde4ffdf243",
-          "0x006a8dc800c6d8dd6977ef53264e2d030350f0145a91bcd167b4f1c3ea21b271",
-          "0x773594000",
-          "0x801b08ca107b623eca32ee9f9111b4e50eb9cfe19e38204b72de7dc04c5a5e00f61bab96f10842576f66020ce851083f1583dd9a6b73301bea6c245cf51f27cf96aeb018852c5f70bf485d16b957cfe49ca008913346b431e7653ae3ddb23b07",
-          "0x3");
-
-  private static DepositRequestParameter createDeposit(
-      final String pubKey,
-      final String withdrawalCredentials,
-      final String amount,
-      final String signature,
-      final String index) {
-    return new DepositRequestParameter(pubKey, withdrawalCredentials, amount, signature, index);
-  }
-}
diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/DepositRequestRequestParameterTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/DepositRequestRequestParameterTest.java
deleted file mode 100644
index ce5780641b..0000000000
--- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/DepositRequestRequestParameterTest.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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.api.jsonrpc.internal.parameters;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.DepositParameterTestFixture.DEPOSIT_PARAM_1;
-
-import org.hyperledger.besu.datatypes.BLSPublicKey;
-import org.hyperledger.besu.datatypes.BLSSignature;
-import org.hyperledger.besu.datatypes.GWei;
-import org.hyperledger.besu.ethereum.core.DepositRequest;
-
-import org.apache.tuweni.bytes.Bytes32;
-import org.apache.tuweni.units.bigints.UInt64;
-import org.junit.jupiter.api.Test;
-
-public class DepositRequestRequestParameterTest {
-
-  @Test
-  public void toDeposit() {
-    DepositRequest expected =
-        new DepositRequest(
-            BLSPublicKey.fromHexString(
-                "0xb10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e"),
-            Bytes32.fromHexString(
-                "0x0017a7fcf06faf493d30bbe2632ea7c2383cd86825e12797165de7aa35589483"),
-            GWei.of(32000000000L),
-            BLSSignature.fromHexString(
-                "0xa889db8300194050a2636c92a95bc7160515867614b7971a9500cdb62f9c0890217d2901c3241f86fac029428fc106930606154bd9e406d7588934a5f15b837180b17194d6e44bd6de23e43b163dfe12e369dcc75a3852cd997963f158217eb5"),
-            UInt64.ONE);
-    assertThat(DEPOSIT_PARAM_1.toDeposit()).isEqualTo(expected);
-  }
-
-  @Test
-  public void fromDeposit() {
-    DepositRequest depositRequest =
-        new DepositRequest(
-            BLSPublicKey.fromHexString(
-                "0xb10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e"),
-            Bytes32.fromHexString(
-                "0x0017a7fcf06faf493d30bbe2632ea7c2383cd86825e12797165de7aa35589483"),
-            GWei.of(32000000000L),
-            BLSSignature.fromHexString(
-                "0xa889db8300194050a2636c92a95bc7160515867614b7971a9500cdb62f9c0890217d2901c3241f86fac029428fc106930606154bd9e406d7588934a5f15b837180b17194d6e44bd6de23e43b163dfe12e369dcc75a3852cd997963f158217eb5"),
-            UInt64.ONE);
-
-    assertThat(DepositRequestParameter.fromDeposit(depositRequest)).isEqualTo(DEPOSIT_PARAM_1);
-  }
-}
diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/WithdrawalRequestParameterTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/WithdrawalRequestParameterTest.java
deleted file mode 100644
index e3e136cb7a..0000000000
--- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/WithdrawalRequestParameterTest.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * 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.api.jsonrpc.internal.parameters;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.WithdrawalRequestTestFixture.WITHDRAWAL_REQUEST_PARAMETER_1;
-
-import org.hyperledger.besu.datatypes.Address;
-import org.hyperledger.besu.datatypes.BLSPublicKey;
-import org.hyperledger.besu.datatypes.GWei;
-import org.hyperledger.besu.ethereum.core.WithdrawalRequest;
-
-import org.junit.jupiter.api.Test;
-
-public class WithdrawalRequestParameterTest {
-
-  @Test
-  public void toWithdrawalRequest() {
-    WithdrawalRequest expected =
-        new WithdrawalRequest(
-            Address.fromHexString("0x814FaE9f487206471B6B0D713cD51a2D35980000"),
-            BLSPublicKey.fromHexString(
-                "0xb10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e"),
-            GWei.ONE);
-    assertThat(WITHDRAWAL_REQUEST_PARAMETER_1.toWithdrawalRequest()).isEqualTo(expected);
-  }
-
-  @Test
-  public void fromWithdrawalRequest() {
-    WithdrawalRequest withdrawalRequest =
-        new WithdrawalRequest(
-            Address.fromHexString("0x814FaE9f487206471B6B0D713cD51a2D35980000"),
-            BLSPublicKey.fromHexString(
-                "0xb10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e"),
-            GWei.ONE);
-
-    assertThat(WithdrawalRequestParameter.fromWithdrawalRequest(withdrawalRequest))
-        .isEqualTo(WITHDRAWAL_REQUEST_PARAMETER_1);
-  }
-}
diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/WithdrawalRequestTestFixture.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/WithdrawalRequestTestFixture.java
deleted file mode 100644
index 2256cc3195..0000000000
--- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/WithdrawalRequestTestFixture.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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.api.jsonrpc.internal.parameters;
-
-import org.hyperledger.besu.datatypes.GWei;
-
-public class WithdrawalRequestTestFixture {
-
-  public static final WithdrawalRequestParameter WITHDRAWAL_REQUEST_PARAMETER_1 =
-      new WithdrawalRequestParameter(
-          "0x814fae9f487206471b6b0d713cd51a2d35980000",
-          "0xb10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e",
-          GWei.ONE.toShortHexString());
-  static final WithdrawalRequestParameter WITHDRAWAL_REQUEST_PARAMETER_2 =
-      new WithdrawalRequestParameter(
-          "0x758b8178a9a4b7206d1f648c4a77c515cbac7000",
-          "0x8706d19a62f28a6a6549f96c5adaebac9124a61d44868ec94f6d2d707c6a2f82c9162071231dfeb40e24bfde4ffdf243",
-          GWei.ONE.toShortHexString());
-}
diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/subscription/pending/PendingTransactionDroppedSubscriptionServiceTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/subscription/pending/PendingTransactionDroppedSubscriptionServiceTest.java
index 3b3faf5890..a86b603d4c 100644
--- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/subscription/pending/PendingTransactionDroppedSubscriptionServiceTest.java
+++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/subscription/pending/PendingTransactionDroppedSubscriptionServiceTest.java
@@ -30,6 +30,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.websocket.subscription.request.
 import org.hyperledger.besu.ethereum.chain.Blockchain;
 import org.hyperledger.besu.ethereum.core.Block;
 import org.hyperledger.besu.ethereum.core.Transaction;
+import org.hyperledger.besu.ethereum.eth.transactions.RemovalReason;
 
 import java.util.Arrays;
 import java.util.HashMap;
@@ -47,6 +48,18 @@ public class PendingTransactionDroppedSubscriptionServiceTest {
 
   private static final Hash TX_ONE =
       Hash.fromHexString("0x15876958423545c3c7b0fcf9be8ffb543305ee1b43db87ed380dcf0cd16589f7");
+  private static final RemovalReason DUMMY_REMOVAL_REASON =
+      new RemovalReason() {
+        @Override
+        public String label() {
+          return "";
+        }
+
+        @Override
+        public boolean stopTracking() {
+          return false;
+        }
+      };
 
   @Mock private SubscriptionManager subscriptionManager;
   @Mock private Blockchain blockchain;
@@ -65,7 +78,7 @@ public class PendingTransactionDroppedSubscriptionServiceTest {
     setUpSubscriptions(subscriptionIds);
     final Transaction pending = transaction(TX_ONE);
 
-    service.onTransactionDropped(pending);
+    service.onTransactionDropped(pending, DUMMY_REMOVAL_REASON);
 
     verifyNoInteractions(block);
     verifyNoInteractions(blockchain);
diff --git a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java
index b843389c0d..ad9489daf8 100644
--- a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java
+++ b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java
@@ -265,7 +265,7 @@ public abstract class AbstractBlockCreator implements AsyncBlockCreator {
               operationTracer);
 
       Optional> maybeRequests =
-          requestProcessor.flatMap(processor -> processor.process(context));
+          requestProcessor.map(processor -> processor.process(context));
 
       throwIfStopped();
 
@@ -304,7 +304,7 @@ public abstract class AbstractBlockCreator implements AsyncBlockCreator {
                   withdrawalsCanBeProcessed
                       ? BodyValidation.withdrawalsRoot(maybeWithdrawals.get())
                       : null)
-              .requestsRoot(maybeRequests.map(BodyValidation::requestsRoot).orElse(null));
+              .requestsHash(maybeRequests.map(BodyValidation::requestsHash).orElse(null));
       if (usage != null) {
         builder.blobGasUsed(usage.used.toLong()).excessBlobGas(usage.excessBlobGas);
       }
@@ -316,8 +316,7 @@ public abstract class AbstractBlockCreator implements AsyncBlockCreator {
       final Optional> withdrawals =
           withdrawalsCanBeProcessed ? maybeWithdrawals : Optional.empty();
       final BlockBody blockBody =
-          new BlockBody(
-              transactionResults.getSelectedTransactions(), ommers, withdrawals, maybeRequests);
+          new BlockBody(transactionResults.getSelectedTransactions(), ommers, withdrawals);
       final Block block = new Block(blockHeader, blockBody);
 
       operationTracer.traceEndBlock(blockHeader, blockBody);
diff --git a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreatorTest.java b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreatorTest.java
index ffab847bbd..d30349e3d0 100644
--- a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreatorTest.java
+++ b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreatorTest.java
@@ -14,9 +14,8 @@
  */
 package org.hyperledger.besu.ethereum.blockcreation;
 
-import static java.util.Collections.emptyList;
 import static org.assertj.core.api.Assertions.assertThat;
-import static org.hyperledger.besu.ethereum.mainnet.requests.DepositRequestProcessor.DEFAULT_DEPOSIT_CONTRACT_ADDRESS;
+import static org.hyperledger.besu.ethereum.mainnet.requests.RequestContractAddresses.DEFAULT_DEPOSIT_CONTRACT_ADDRESS;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
@@ -31,8 +30,6 @@ import org.hyperledger.besu.crypto.SECPPrivateKey;
 import org.hyperledger.besu.crypto.SignatureAlgorithm;
 import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
 import org.hyperledger.besu.datatypes.Address;
-import org.hyperledger.besu.datatypes.BLSPublicKey;
-import org.hyperledger.besu.datatypes.BLSSignature;
 import org.hyperledger.besu.datatypes.BlobGas;
 import org.hyperledger.besu.datatypes.BlobsWithCommitments;
 import org.hyperledger.besu.datatypes.GWei;
@@ -48,7 +45,6 @@ import org.hyperledger.besu.ethereum.core.BlobTestFixture;
 import org.hyperledger.besu.ethereum.core.BlockDataGenerator;
 import org.hyperledger.besu.ethereum.core.BlockHeader;
 import org.hyperledger.besu.ethereum.core.BlockHeaderBuilder;
-import org.hyperledger.besu.ethereum.core.DepositRequest;
 import org.hyperledger.besu.ethereum.core.Difficulty;
 import org.hyperledger.besu.ethereum.core.ExecutionContextTestFixture;
 import org.hyperledger.besu.ethereum.core.ImmutableMiningParameters;
@@ -81,10 +77,7 @@ import org.hyperledger.besu.ethereum.mainnet.TransactionValidatorFactory;
 import org.hyperledger.besu.ethereum.mainnet.ValidationResult;
 import org.hyperledger.besu.ethereum.mainnet.WithdrawalsProcessor;
 import org.hyperledger.besu.ethereum.mainnet.requests.DepositRequestProcessor;
-import org.hyperledger.besu.ethereum.mainnet.requests.DepositRequestValidator;
 import org.hyperledger.besu.ethereum.mainnet.requests.ProcessRequestContext;
-import org.hyperledger.besu.ethereum.mainnet.requests.RequestProcessorCoordinator;
-import org.hyperledger.besu.ethereum.mainnet.requests.RequestsValidatorCoordinator;
 import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason;
 import org.hyperledger.besu.evm.account.Account;
 import org.hyperledger.besu.evm.internal.EvmConfiguration;
@@ -141,83 +134,16 @@ abstract class AbstractBlockCreatorTest {
     List receipts =
         List.of(receiptWithoutDeposit1, receiptWithDeposit, receiptWithoutDeposit2);
 
-    DepositRequest expectedDepositRequest =
-        new DepositRequest(
-            BLSPublicKey.fromHexString(
-                "0xb10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e"),
-            Bytes32.fromHexString(
-                "0x0017a7fcf06faf493d30bbe2632ea7c2383cd86825e12797165de7aa35589483"),
-            GWei.of(32000000000L),
-            BLSSignature.fromHexString(
-                "0xa889db8300194050a2636c92a95bc7160515867614b7971a9500cdb62f9c0890217d2901c3241f86fac029428fc106930606154bd9e406d7588934a5f15b837180b17194d6e44bd6de23e43b163dfe12e369dcc75a3852cd997963f158217eb5"),
-            UInt64.valueOf(539967));
-    final List expectedDepositRequests = List.of(expectedDepositRequest);
+    Request expectedDepositRequest =
+        new Request(
+            RequestType.DEPOSIT,
+            Bytes.fromHexString(
+                "0xb10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e0017a7fcf06faf493d30bbe2632ea7c2383cd86825e12797165de7aa355894830040597307000000a889db8300194050a2636c92a95bc7160515867614b7971a9500cdb62f9c0890217d2901c3241f86fac029428fc106930606154bd9e406d7588934a5f15b837180b17194d6e44bd6de23e43b163dfe12e369dcc75a3852cd997963f158217eb53f3d080000000000"));
 
     var depositRequestsFromReceipts =
         new DepositRequestProcessor(DEFAULT_DEPOSIT_CONTRACT_ADDRESS)
             .process(new ProcessRequestContext(null, null, null, receipts, null, null));
-    assertThat(depositRequestsFromReceipts.get()).isEqualTo(expectedDepositRequests);
-  }
-
-  @Test
-  void withAllowedDepositRequestsAndContractAddress_DepositRequestsAreParsed() {
-    final CreateOn miningOn =
-        blockCreatorWithAllowedDepositRequests(DEFAULT_DEPOSIT_CONTRACT_ADDRESS);
-
-    final BlockCreationResult blockCreationResult =
-        miningOn.blockCreator.createBlock(
-            Optional.empty(),
-            Optional.empty(),
-            Optional.of(emptyList()),
-            Optional.empty(),
-            Optional.empty(),
-            1L,
-            false,
-            miningOn.parentHeader);
-
-    List depositRequests = emptyList();
-    final Hash requestsRoot = BodyValidation.requestsRoot(depositRequests);
-    assertThat(blockCreationResult.getBlock().getHeader().getRequestsRoot()).hasValue(requestsRoot);
-    assertThat(blockCreationResult.getBlock().getBody().getRequests()).hasValue(depositRequests);
-  }
-
-  @Test
-  void withAllowedDepositRequestsAndNoContractAddress_DepositRequestsAreNotParsed() {
-    final CreateOn miningOn = blockCreatorWithAllowedDepositRequests(null);
-
-    final BlockCreationResult blockCreationResult =
-        miningOn.blockCreator.createBlock(
-            Optional.empty(),
-            Optional.empty(),
-            Optional.of(emptyList()),
-            Optional.empty(),
-            Optional.empty(),
-            1L,
-            false,
-            miningOn.parentHeader);
-
-    assertThat(blockCreationResult.getBlock().getHeader().getRequestsRoot()).isEmpty();
-    assertThat(blockCreationResult.getBlock().getBody().getRequests()).isEmpty();
-  }
-
-  @Test
-  void withProhibitedDepositRequests_DepositRequestsAreNotParsed() {
-
-    final CreateOn miningOn = blockCreatorWithProhibitedDepositRequests();
-
-    final BlockCreationResult blockCreationResult =
-        miningOn.blockCreator.createBlock(
-            Optional.empty(),
-            Optional.empty(),
-            Optional.of(emptyList()),
-            Optional.empty(),
-            Optional.empty(),
-            1L,
-            false,
-            miningOn.parentHeader);
-
-    assertThat(blockCreationResult.getBlock().getHeader().getRequestsRoot()).isEmpty();
-    assertThat(blockCreationResult.getBlock().getBody().getRequests()).isEmpty();
+    assertThat(depositRequestsFromReceipts).isEqualTo(expectedDepositRequest);
   }
 
   @Test
@@ -355,12 +281,6 @@ abstract class AbstractBlockCreatorTest {
     return createBlockCreator(protocolSpecAdapters);
   }
 
-  private CreateOn blockCreatorWithProhibitedDepositRequests() {
-    final ProtocolSpecAdapters protocolSpecAdapters =
-        ProtocolSpecAdapters.create(0, specBuilder -> specBuilder);
-    return createBlockCreator(protocolSpecAdapters);
-  }
-
   private CreateOn blockCreatorWithWithdrawalsProcessor() {
     final ProtocolSpecAdapters protocolSpecAdapters =
         ProtocolSpecAdapters.create(
@@ -374,27 +294,6 @@ abstract class AbstractBlockCreatorTest {
     return createBlockCreator(protocolSpecAdapters);
   }
 
-  private CreateOn blockCreatorWithAllowedDepositRequests(final Address depositContractAddress) {
-    final ProtocolSpecAdapters protocolSpecAdapters =
-        ProtocolSpecAdapters.create(
-            0,
-            specBuilder ->
-                specBuilder
-                    .requestsValidator(
-                        new RequestsValidatorCoordinator.Builder()
-                            .addValidator(
-                                RequestType.DEPOSIT,
-                                new DepositRequestValidator((depositContractAddress)))
-                            .build())
-                    .requestProcessorCoordinator(
-                        new RequestProcessorCoordinator.Builder()
-                            .addProcessor(
-                                RequestType.DEPOSIT,
-                                new DepositRequestProcessor(depositContractAddress))
-                            .build()));
-    return createBlockCreator(protocolSpecAdapters);
-  }
-
   record CreateOn(AbstractBlockCreator blockCreator, BlockHeader parentHeader) {}
 
   private CreateOn createBlockCreator(final ProtocolSpecAdapters protocolSpecAdapters) {
diff --git a/ethereum/core/build.gradle b/ethereum/core/build.gradle
index b9cd1464e9..3056a5e105 100644
--- a/ethereum/core/build.gradle
+++ b/ethereum/core/build.gradle
@@ -98,7 +98,6 @@ dependencies {
   integrationTestImplementation 'org.assertj:assertj-core'
   integrationTestImplementation 'org.junit.jupiter:junit-jupiter-api'
   integrationTestImplementation 'org.mockito:mockito-core'
-  integrationTestImplementation 'org.testcontainers:testcontainers'
   integrationTestImplementation 'io.tmio:tuweni-bytes'
 
   integrationTestRuntimeOnly 'org.junit.jupiter:junit-jupiter'
diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/BlockProcessingResult.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/BlockProcessingResult.java
index 926dd13abd..f34bd056c6 100644
--- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/BlockProcessingResult.java
+++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/BlockProcessingResult.java
@@ -14,6 +14,7 @@
  */
 package org.hyperledger.besu.ethereum;
 
+import org.hyperledger.besu.ethereum.core.Request;
 import org.hyperledger.besu.ethereum.core.TransactionReceipt;
 
 import java.util.ArrayList;
@@ -134,4 +135,13 @@ public class BlockProcessingResult extends BlockValidationResult {
       return yield.get().getReceipts();
     }
   }
+
+  /**
+   * Gets the requests of the result.
+   *
+   * @return the requests of the result
+   */
+  public Optional> getRequests() {
+    return yield.flatMap(BlockProcessingOutputs::getRequests);
+  }
 }
diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/BlockValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/BlockValidator.java
index 8cfafee730..f74f4a9077 100644
--- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/BlockValidator.java
+++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/BlockValidator.java
@@ -15,13 +15,11 @@
 package org.hyperledger.besu.ethereum;
 
 import org.hyperledger.besu.ethereum.core.Block;
-import org.hyperledger.besu.ethereum.core.Request;
 import org.hyperledger.besu.ethereum.core.TransactionReceipt;
 import org.hyperledger.besu.ethereum.mainnet.BodyValidationMode;
 import org.hyperledger.besu.ethereum.mainnet.HeaderValidationMode;
 
 import java.util.List;
-import java.util.Optional;
 
 /**
  * The BlockValidator interface defines the methods for validating and processing blocks in the
@@ -90,7 +88,6 @@ public interface BlockValidator {
    * @param context the protocol context
    * @param block the block to validate
    * @param receipts the transaction receipts
-   * @param requests the requests
    * @param headerValidationMode the header validation mode
    * @param ommerValidationMode the ommer validation mode
    * @param bodyValidationMode the body validation mode
@@ -100,7 +97,6 @@ public interface BlockValidator {
       final ProtocolContext context,
       final Block block,
       final List receipts,
-      final Optional> requests,
       final HeaderValidationMode headerValidationMode,
       final HeaderValidationMode ommerValidationMode,
       final BodyValidationMode bodyValidationMode);
diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/MainnetBlockValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/MainnetBlockValidator.java
index 0c56a419e3..b218982c09 100644
--- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/MainnetBlockValidator.java
+++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/MainnetBlockValidator.java
@@ -171,7 +171,7 @@ public class MainnetBlockValidator implements BlockValidator {
         Optional> maybeRequests =
             result.getYield().flatMap(BlockProcessingOutputs::getRequests);
         if (!blockBodyValidator.validateBody(
-            context, block, receipts, maybeRequests, worldState.rootHash(), ommerValidationMode)) {
+            context, block, receipts, worldState.rootHash(), ommerValidationMode)) {
           result = new BlockProcessingResult("failed to validate output of imported block");
           handleFailedBlockProcessing(block, result, shouldRecordBadBlock);
           return result;
@@ -181,16 +181,7 @@ public class MainnetBlockValidator implements BlockValidator {
             Optional.of(new BlockProcessingOutputs(worldState, receipts, maybeRequests)));
       }
     } catch (MerkleTrieException ex) {
-      context
-          .getSynchronizer()
-          .ifPresentOrElse(
-              synchronizer -> synchronizer.healWorldState(ex.getMaybeAddress(), ex.getLocation()),
-              () ->
-                  handleFailedBlockProcessing(
-                      block,
-                      new BlockProcessingResult(Optional.empty(), ex),
-                      // Do not record bad black due to missing data
-                      false));
+      context.getSynchronizer().healWorldState(ex.getMaybeAddress(), ex.getLocation());
       return new BlockProcessingResult(Optional.empty(), ex);
     } catch (StorageException ex) {
       var retval = new BlockProcessingResult(Optional.empty(), ex);
@@ -252,7 +243,6 @@ public class MainnetBlockValidator implements BlockValidator {
       final ProtocolContext context,
       final Block block,
       final List receipts,
-      final Optional> requests,
       final HeaderValidationMode headerValidationMode,
       final HeaderValidationMode ommerValidationMode,
       final BodyValidationMode bodyValidationMode) {
@@ -264,7 +254,7 @@ public class MainnetBlockValidator implements BlockValidator {
     }
 
     if (!blockBodyValidator.validateBodyLight(
-        context, block, receipts, requests, ommerValidationMode, bodyValidationMode)) {
+        context, block, receipts, ommerValidationMode, bodyValidationMode)) {
       badBlockManager.addBadBlock(
           block, BadBlockCause.fromValidationFailure("Failed body validation (light)"));
       return false;
diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/ProtocolContext.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/ProtocolContext.java
index e5ec5ae092..4ca40bc0a9 100644
--- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/ProtocolContext.java
+++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/ProtocolContext.java
@@ -32,8 +32,7 @@ public class ProtocolContext {
   private final WorldStateArchive worldStateArchive;
   private final BadBlockManager badBlockManager;
   private final ConsensusContext consensusContext;
-
-  private Optional synchronizer;
+  private Synchronizer synchronizer;
 
   /**
    * Constructs a new ProtocolContext with the given blockchain, world state archive, consensus
@@ -52,7 +51,6 @@ public class ProtocolContext {
     this.blockchain = blockchain;
     this.worldStateArchive = worldStateArchive;
     this.consensusContext = consensusContext;
-    this.synchronizer = Optional.empty();
     this.badBlockManager = badBlockManager;
   }
 
@@ -85,7 +83,7 @@ public class ProtocolContext {
    *
    * @return the synchronizer of the protocol context
    */
-  public Optional getSynchronizer() {
+  public Synchronizer getSynchronizer() {
     return synchronizer;
   }
 
@@ -94,7 +92,7 @@ public class ProtocolContext {
    *
    * @param synchronizer the synchronizer to set
    */
-  public void setSynchronizer(final Optional synchronizer) {
+  public void setSynchronizer(final Synchronizer synchronizer) {
     this.synchronizer = synchronizer;
   }
 
diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/chain/GenesisState.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/chain/GenesisState.java
index 00b20a0170..b27023776f 100644
--- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/chain/GenesisState.java
+++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/chain/GenesisState.java
@@ -28,7 +28,6 @@ import org.hyperledger.besu.ethereum.core.BlockHeader;
 import org.hyperledger.besu.ethereum.core.BlockHeaderBuilder;
 import org.hyperledger.besu.ethereum.core.Difficulty;
 import org.hyperledger.besu.ethereum.core.MutableWorldState;
-import org.hyperledger.besu.ethereum.core.Request;
 import org.hyperledger.besu.ethereum.core.Withdrawal;
 import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
 import org.hyperledger.besu.ethereum.mainnet.ScheduleBasedBlockHeaderFunctions;
@@ -49,6 +48,7 @@ import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.MoreObjects;
 import org.apache.tuweni.bytes.Bytes;
 import org.apache.tuweni.bytes.Bytes32;
+import org.apache.tuweni.units.bigints.UInt64;
 
 public final class GenesisState {
 
@@ -145,10 +145,8 @@ public final class GenesisState {
   private static BlockBody buildBody(final GenesisConfigFile config) {
     final Optional> withdrawals =
         isShanghaiAtGenesis(config) ? Optional.of(emptyList()) : Optional.empty();
-    final Optional> requests =
-        isPragueAtGenesis(config) ? Optional.of(emptyList()) : Optional.empty();
 
-    return new BlockBody(emptyList(), emptyList(), withdrawals, requests);
+    return new BlockBody(emptyList(), emptyList(), withdrawals);
   }
 
   public Block getBlock() {
@@ -220,7 +218,13 @@ public final class GenesisState {
         .excessBlobGas(isCancunAtGenesis(genesis) ? parseExcessBlobGas(genesis) : null)
         .parentBeaconBlockRoot(
             (isCancunAtGenesis(genesis) ? parseParentBeaconBlockRoot(genesis) : null))
-        .requestsRoot(isPragueAtGenesis(genesis) ? Hash.EMPTY_TRIE_HASH : null)
+        .requestsHash(isPragueAtGenesis(genesis) ? Hash.EMPTY_REQUESTS_HASH : null)
+        .targetBlobCount(
+            isPragueAtGenesis(genesis)
+                // TODO SLD EIP-7742 Currently defaulting to null due to dependency on web3j
+                // BlockHeader in CodeDelegationTransactionAcceptanceTest
+                ? genesis.getTargetBlobCount().map(UInt64::fromHexString).orElse(null)
+                : null)
         .buildBlockHeader();
   }
 
@@ -312,7 +316,7 @@ public final class GenesisState {
     if (cancunEOFTimestamp.isPresent()) {
       return genesis.getTimestamp() >= cancunEOFTimestamp.getAsLong();
     }
-    return isPragueEOFAtGenesis(genesis);
+    return false;
   }
 
   private static boolean isPragueAtGenesis(final GenesisConfigFile genesis) {
@@ -320,13 +324,13 @@ public final class GenesisState {
     if (pragueTimestamp.isPresent()) {
       return genesis.getTimestamp() >= pragueTimestamp.getAsLong();
     }
-    return isPragueEOFAtGenesis(genesis);
+    return isOsakaAtGenesis(genesis);
   }
 
-  private static boolean isPragueEOFAtGenesis(final GenesisConfigFile genesis) {
-    final OptionalLong pragueEOFTimestamp = genesis.getConfigOptions().getPragueEOFTime();
-    if (pragueEOFTimestamp.isPresent()) {
-      return genesis.getTimestamp() >= pragueEOFTimestamp.getAsLong();
+  private static boolean isOsakaAtGenesis(final GenesisConfigFile genesis) {
+    final OptionalLong osakaTimestamp = genesis.getConfigOptions().getOsakaTime();
+    if (osakaTimestamp.isPresent()) {
+      return genesis.getTimestamp() >= osakaTimestamp.getAsLong();
     }
     return isFutureEipsTimeAtGenesis(genesis);
   }
diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Block.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Block.java
index 3c90f77d32..41db458334 100644
--- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Block.java
+++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Block.java
@@ -62,7 +62,6 @@ public class Block {
     out.writeList(body.getTransactions(), Transaction::writeTo);
     out.writeList(body.getOmmers(), BlockHeader::writeTo);
     body.getWithdrawals().ifPresent(withdrawals -> out.writeList(withdrawals, Withdrawal::writeTo));
-    body.getRequests().ifPresent(requests -> out.writeList(requests, Request::writeTo));
 
     out.endList();
   }
@@ -74,11 +73,9 @@ public class Block {
     final List ommers = in.readList(rlp -> BlockHeader.readFrom(rlp, hashFunction));
     final Optional> withdrawals =
         in.isEndOfCurrentList() ? Optional.empty() : Optional.of(in.readList(Withdrawal::readFrom));
-    final Optional> requests =
-        in.isEndOfCurrentList() ? Optional.empty() : Optional.of(in.readList(Request::readFrom));
     in.leaveList();
 
-    return new Block(header, new BlockBody(transactions, ommers, withdrawals, requests));
+    return new Block(header, new BlockBody(transactions, ommers, withdrawals));
   }
 
   @Override
diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockBody.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockBody.java
index 4b8ab92613..7eb49dc04d 100644
--- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockBody.java
+++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockBody.java
@@ -37,24 +37,20 @@ public class BlockBody implements org.hyperledger.besu.plugin.data.BlockBody {
 
   private final List ommers;
   private final Optional> withdrawals;
-  private final Optional> requests;
 
   public BlockBody(final List transactions, final List ommers) {
     this.transactions = transactions;
     this.ommers = ommers;
     this.withdrawals = Optional.empty();
-    this.requests = Optional.empty();
   }
 
   public BlockBody(
       final List transactions,
       final List ommers,
-      final Optional> withdrawals,
-      final Optional> requests) {
+      final Optional> withdrawals) {
     this.transactions = transactions;
     this.ommers = ommers;
     this.withdrawals = withdrawals;
-    this.requests = requests;
   }
 
   public static BlockBody empty() {
@@ -87,16 +83,6 @@ public class BlockBody implements org.hyperledger.besu.plugin.data.BlockBody {
     return withdrawals;
   }
 
-  /**
-   * Returns the withdrawal requests of the block.
-   *
-   * @return The optional list of withdrawal requests included in the block.
-   */
-  @Override
-  public Optional> getRequests() {
-    return requests;
-  }
-
   /**
    * Writes Block to {@link RLPOutput}.
    *
@@ -112,7 +98,6 @@ public class BlockBody implements org.hyperledger.besu.plugin.data.BlockBody {
     output.writeList(getTransactions(), Transaction::writeTo);
     output.writeList(getOmmers(), BlockHeader::writeTo);
     withdrawals.ifPresent(withdrawals -> output.writeList(withdrawals, Withdrawal::writeTo));
-    requests.ifPresent(requests -> output.writeList(requests, Request::writeTo));
   }
 
   public static BlockBody readWrappedBodyFrom(
@@ -161,10 +146,7 @@ public class BlockBody implements org.hyperledger.besu.plugin.data.BlockBody {
         input.readList(rlp -> BlockHeader.readFrom(rlp, blockHeaderFunctions)),
         input.isEndOfCurrentList()
             ? Optional.empty()
-            : Optional.of(input.readList(Withdrawal::readFrom)),
-        input.isEndOfCurrentList()
-            ? Optional.empty()
-            : Optional.of(input.readList(Request::readFrom)));
+            : Optional.of(input.readList(Withdrawal::readFrom)));
   }
 
   @Override
@@ -174,20 +156,16 @@ public class BlockBody implements org.hyperledger.besu.plugin.data.BlockBody {
     BlockBody blockBody = (BlockBody) o;
     return Objects.equals(transactions, blockBody.transactions)
         && Objects.equals(ommers, blockBody.ommers)
-        && Objects.equals(withdrawals, blockBody.withdrawals)
-        && Objects.equals(requests, blockBody.requests);
+        && Objects.equals(withdrawals, blockBody.withdrawals);
   }
 
   @Override
   public int hashCode() {
-    return Objects.hash(transactions, ommers, withdrawals, requests);
+    return Objects.hash(transactions, ommers, withdrawals);
   }
 
   public boolean isEmpty() {
-    return transactions.isEmpty()
-        && ommers.isEmpty()
-        && withdrawals.isEmpty()
-        && requests.isEmpty();
+    return transactions.isEmpty() && ommers.isEmpty() && withdrawals.isEmpty();
   }
 
   @Override
@@ -199,8 +177,6 @@ public class BlockBody implements org.hyperledger.besu.plugin.data.BlockBody {
         + ommers
         + ", withdrawals="
         + withdrawals
-        + ", withdrawal_requests="
-        + requests
         + '}';
   }
 }
diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeader.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeader.java
index bd6d5da3dd..67801d474f 100644
--- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeader.java
+++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeader.java
@@ -29,6 +29,7 @@ import java.util.function.Supplier;
 import com.google.common.base.Suppliers;
 import org.apache.tuweni.bytes.Bytes;
 import org.apache.tuweni.bytes.Bytes32;
+import org.apache.tuweni.units.bigints.UInt64;
 
 /** A mined Ethereum block header. */
 public class BlockHeader extends SealableBlockHeader
@@ -65,7 +66,8 @@ public class BlockHeader extends SealableBlockHeader
       final Long blobGasUsed,
       final BlobGas excessBlobGas,
       final Bytes32 parentBeaconBlockRoot,
-      final Hash requestsRoot,
+      final Hash requestsHash,
+      final UInt64 targetBlobCount,
       final ExecutionWitness executionWitness,
       final BlockHeaderFunctions blockHeaderFunctions) {
     super(
@@ -88,13 +90,27 @@ public class BlockHeader extends SealableBlockHeader
         blobGasUsed,
         excessBlobGas,
         parentBeaconBlockRoot,
-        requestsRoot,
+        requestsHash,
+        targetBlobCount,
         executionWitness);
     this.nonce = nonce;
     this.hash = Suppliers.memoize(() -> blockHeaderFunctions.hash(this));
     this.parsedExtraData = Suppliers.memoize(() -> blockHeaderFunctions.parseExtraData(this));
   }
 
+  public static boolean hasEmptyBlock(final BlockHeader blockHeader) {
+    return blockHeader.getOmmersHash().equals(Hash.EMPTY_LIST_HASH)
+        && blockHeader.getTransactionsRoot().equals(Hash.EMPTY_TRIE_HASH)
+        && blockHeader
+            .getWithdrawalsRoot()
+            .map(wsRoot -> wsRoot.equals(Hash.EMPTY_TRIE_HASH))
+            .orElse(true)
+        && blockHeader
+            .getRequestsHash()
+            .map(reqHash -> reqHash.equals(Hash.EMPTY_REQUESTS_HASH))
+            .orElse(true);
+  }
+
   /**
    * Returns the block mixed hash.
    *
@@ -175,8 +191,11 @@ public class BlockHeader extends SealableBlockHeader
       if (parentBeaconBlockRoot == null) break;
       out.writeBytes(parentBeaconBlockRoot);
 
-      if (requestsRoot == null) break;
-      out.writeBytes(requestsRoot);*/
+      if (requestsHash == null) break;
+      out.writeBytes(requestsHash);
+
+      if (targetBlobCount == null) break;
+      out.writeUInt64Scalar(targetBlobCount);*/
     } while (false);
     out.endList();
   }
@@ -211,11 +230,14 @@ public class BlockHeader extends SealableBlockHeader
     final BlobGas excessBlobGas =
         !input.isEndOfCurrentList() ? BlobGas.of(input.readUInt64Scalar()) : null;
     final Bytes32 parentBeaconBlockRoot = !input.isEndOfCurrentList() ? input.readBytes32() : null;
-    final Hash requestsRoot = !input.isEndOfCurrentList() ? Hash.wrap(input.readBytes32()) : null;
+
+     final Hash requestsHash = !input.isEndOfCurrentList() ? Hash.wrap(input.readBytes32()) : null;
+    final UInt64 targetBlobCount = !input.isEndOfCurrentList() ? input.readUInt64Scalar() : null;
         */
 
     final ExecutionWitness executionWitness =
         !input.isEndOfCurrentList() ? ExecutionWitness.readFrom(input) : null;
+
     input.leaveList();
     return new BlockHeader(
         parentHash,
@@ -239,6 +261,7 @@ public class BlockHeader extends SealableBlockHeader
         null,
         null,
         null,
+        null,
         executionWitness,
         blockHeaderFunctions);
   }
@@ -290,8 +313,11 @@ public class BlockHeader extends SealableBlockHeader
     if (parentBeaconBlockRoot != null) {
       sb.append("parentBeaconBlockRoot=").append(parentBeaconBlockRoot).append(", ");
     }
-    if (requestsRoot != null) {
-      sb.append("requestsRoot=").append(requestsRoot);
+    if (requestsHash != null) {
+      sb.append("requestsHash=").append(requestsHash);
+    }
+    if (targetBlobCount != null) {
+      sb.append("targetBlobCount=").append(targetBlobCount);
     }
     return sb.append("}").toString();
   }
@@ -324,9 +350,10 @@ public class BlockHeader extends SealableBlockHeader
         pluginBlockHeader.getExcessBlobGas().map(BlobGas.class::cast).orElse(null),
         pluginBlockHeader.getParentBeaconBlockRoot().orElse(null),
         pluginBlockHeader
-            .getRequestsRoot()
+            .getRequestsHash()
             .map(h -> Hash.fromHexString(h.toHexString()))
             .orElse(null),
+        pluginBlockHeader.getTargetBlobCount().orElse(null),
         (ExecutionWitness) pluginBlockHeader.getExecutionWitness().orElse(null),
         blockHeaderFunctions);
   }
diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeaderBuilder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeaderBuilder.java
index d65b99f0b1..a78dd28157 100644
--- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeaderBuilder.java
+++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeaderBuilder.java
@@ -31,6 +31,7 @@ import java.util.OptionalLong;
 
 import org.apache.tuweni.bytes.Bytes;
 import org.apache.tuweni.bytes.Bytes32;
+import org.apache.tuweni.units.bigints.UInt64;
 
 /** A utility class for building block headers. */
 public class BlockHeaderBuilder {
@@ -46,7 +47,7 @@ public class BlockHeaderBuilder {
   private Hash transactionsRoot;
 
   private Hash withdrawalsRoot = null;
-  private Hash requestsRoot = null;
+  private Hash requestsHash = null;
 
   private Hash receiptsRoot;
 
@@ -77,6 +78,7 @@ public class BlockHeaderBuilder {
   private Long blobGasUsed = null;
   private BlobGas excessBlobGas = null;
   private Bytes32 parentBeaconBlockRoot = null;
+  private UInt64 targetBlobCount = null;
   private ExecutionWitness executionWitness = null;
 
   public static BlockHeaderBuilder create() {
@@ -126,7 +128,8 @@ public class BlockHeaderBuilder {
         .blobGasUsed(header.getBlobGasUsed().orElse(null))
         .excessBlobGas(header.getExcessBlobGas().orElse(null))
         .parentBeaconBlockRoot(header.getParentBeaconBlockRoot().orElse(null))
-        .requestsRoot(header.getRequestsRoot().orElse(null))
+        .requestsHash(header.getRequestsHash().orElse(null))
+        .targetBlobCount(header.getTargetBlobCount().orElse(null))
         .executionWitness(header.getExecutionWitness().orElse(null));
   }
 
@@ -151,7 +154,8 @@ public class BlockHeaderBuilder {
             .withdrawalsRoot(fromBuilder.withdrawalsRoot)
             .excessBlobGas(fromBuilder.excessBlobGas)
             .parentBeaconBlockRoot(fromBuilder.parentBeaconBlockRoot)
-            .requestsRoot(fromBuilder.requestsRoot)
+            .requestsHash(fromBuilder.requestsHash)
+            .targetBlobCount(fromBuilder.targetBlobCount)
             .executionWitness(fromBuilder.executionWitness)
             .blockHeaderFunctions(fromBuilder.blockHeaderFunctions);
     toBuilder.nonce = fromBuilder.nonce;
@@ -182,7 +186,8 @@ public class BlockHeaderBuilder {
         blobGasUsed,
         excessBlobGas,
         parentBeaconBlockRoot,
-        requestsRoot,
+        requestsHash,
+        targetBlobCount,
         executionWitness,
         blockHeaderFunctions);
   }
@@ -199,7 +204,8 @@ public class BlockHeaderBuilder {
         timestamp,
         baseFee,
         mixHashOrPrevRandao,
-        parentBeaconBlockRoot);
+        parentBeaconBlockRoot,
+        targetBlobCount);
   }
 
   public SealableBlockHeader buildSealableBlockHeader() {
@@ -225,7 +231,8 @@ public class BlockHeaderBuilder {
         blobGasUsed,
         excessBlobGas,
         parentBeaconBlockRoot,
-        requestsRoot,
+        requestsHash,
+        targetBlobCount,
         executionWitness);
   }
 
@@ -266,6 +273,7 @@ public class BlockHeaderBuilder {
     baseFee(processableBlockHeader.getBaseFee().orElse(null));
     processableBlockHeader.getPrevRandao().ifPresent(this::prevRandao);
     processableBlockHeader.getParentBeaconBlockRoot().ifPresent(this::parentBeaconBlockRoot);
+    processableBlockHeader.getTargetBlobCount().ifPresent(this::targetBlobCount);
     return this;
   }
 
@@ -290,7 +298,8 @@ public class BlockHeaderBuilder {
     sealableBlockHeader.getBlobGasUsed().ifPresent(this::blobGasUsed);
     sealableBlockHeader.getExcessBlobGas().ifPresent(this::excessBlobGas);
     sealableBlockHeader.getParentBeaconBlockRoot().ifPresent(this::parentBeaconBlockRoot);
-    requestsRoot(sealableBlockHeader.getRequestsRoot().orElse(null));
+    requestsHash(sealableBlockHeader.getRequestsHash().orElse(null));
+    sealableBlockHeader.getTargetBlobCount().ifPresent(this::targetBlobCount);
     executionWitness(sealableBlockHeader.getExecutionWitness().orElse(null));
     return this;
   }
@@ -406,8 +415,8 @@ public class BlockHeaderBuilder {
     return this;
   }
 
-  public BlockHeaderBuilder requestsRoot(final Hash hash) {
-    this.requestsRoot = hash;
+  public BlockHeaderBuilder requestsHash(final Hash hash) {
+    this.requestsHash = hash;
     return this;
   }
 
@@ -426,6 +435,11 @@ public class BlockHeaderBuilder {
     return this;
   }
 
+  public BlockHeaderBuilder targetBlobCount(final UInt64 targetBlobCount) {
+    this.targetBlobCount = targetBlobCount;
+    return this;
+  }
+
   public BlockHeaderBuilder executionWitness(final ExecutionWitness executionWitness) {
     this.executionWitness = executionWitness;
     return this;
diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/ConsolidationRequest.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/ConsolidationRequest.java
deleted file mode 100644
index 38345d1a31..0000000000
--- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/ConsolidationRequest.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * 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.core;
-
-import org.hyperledger.besu.datatypes.Address;
-import org.hyperledger.besu.datatypes.BLSPublicKey;
-import org.hyperledger.besu.datatypes.PublicKey;
-import org.hyperledger.besu.datatypes.RequestType;
-
-import java.util.Objects;
-
-public class ConsolidationRequest extends Request
-    implements org.hyperledger.besu.plugin.data.ConsolidationRequest {
-
-  private final Address sourceAddress;
-  private final BLSPublicKey sourcePubkey;
-  private final BLSPublicKey targetPubkey;
-
-  public ConsolidationRequest(
-      final Address sourceAddress,
-      final BLSPublicKey sourcePubkey,
-      final BLSPublicKey targetPubkey) {
-    this.sourceAddress = sourceAddress;
-    this.sourcePubkey = sourcePubkey;
-    this.targetPubkey = targetPubkey;
-  }
-
-  @Override
-  public RequestType getType() {
-    return RequestType.CONSOLIDATION;
-  }
-
-  @Override
-  public Address getSourceAddress() {
-    return sourceAddress;
-  }
-
-  @Override
-  public PublicKey getSourcePubkey() {
-    return sourcePubkey;
-  }
-
-  @Override
-  public PublicKey getTargetPubkey() {
-    return targetPubkey;
-  }
-
-  @Override
-  public String toString() {
-    return "ConsolidationRequest{"
-        + "sourceAddress="
-        + sourceAddress
-        + " sourcePubkey="
-        + sourcePubkey
-        + " targetPubkey="
-        + targetPubkey
-        + '}';
-  }
-
-  @Override
-  public boolean equals(final Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    final ConsolidationRequest that = (ConsolidationRequest) o;
-    return Objects.equals(sourceAddress, that.sourceAddress)
-        && Objects.equals(sourcePubkey, that.sourcePubkey)
-        && Objects.equals(targetPubkey, that.targetPubkey);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(sourceAddress, sourcePubkey, targetPubkey);
-  }
-}
diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/DepositRequest.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/DepositRequest.java
deleted file mode 100644
index a005fa831e..0000000000
--- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/DepositRequest.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * 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.core;
-
-import org.hyperledger.besu.datatypes.BLSPublicKey;
-import org.hyperledger.besu.datatypes.BLSSignature;
-import org.hyperledger.besu.datatypes.GWei;
-import org.hyperledger.besu.datatypes.PublicKey;
-import org.hyperledger.besu.datatypes.RequestType;
-
-import java.util.Objects;
-
-import org.apache.tuweni.bytes.Bytes32;
-import org.apache.tuweni.units.bigints.UInt64;
-
-public class DepositRequest extends Request
-    implements org.hyperledger.besu.plugin.data.DepositRequest {
-
-  private final BLSPublicKey pubkey;
-  private final Bytes32 depositWithdrawalCredentials;
-  private final GWei amount;
-  private final BLSSignature signature;
-  private final UInt64 index;
-
-  public DepositRequest(
-      final BLSPublicKey pubkey,
-      final Bytes32 depositWithdrawalCredentials,
-      final GWei amount,
-      final BLSSignature signature,
-      final UInt64 index) {
-    this.pubkey = pubkey;
-    this.depositWithdrawalCredentials = depositWithdrawalCredentials;
-    this.amount = amount;
-    this.signature = signature;
-    this.index = index;
-  }
-
-  @Override
-  public RequestType getType() {
-    return RequestType.DEPOSIT;
-  }
-
-  @Override
-  public PublicKey getPubkey() {
-    return pubkey;
-  }
-
-  @Override
-  public Bytes32 getWithdrawalCredentials() {
-    return depositWithdrawalCredentials;
-  }
-
-  @Override
-  public GWei getAmount() {
-    return amount;
-  }
-
-  @Override
-  public BLSSignature getSignature() {
-    return signature;
-  }
-
-  @Override
-  public UInt64 getIndex() {
-    return index;
-  }
-
-  @Override
-  public String toString() {
-    return "Deposit{"
-        + "pubKey="
-        + pubkey
-        + ", withdrawalCredentials="
-        + depositWithdrawalCredentials
-        + ", amount="
-        + amount
-        + ", signature="
-        + signature
-        + ", index="
-        + index
-        + '}';
-  }
-
-  @Override
-  public boolean equals(final Object o) {
-    if (this == o) return true;
-    if (o == null || getClass() != o.getClass()) return false;
-    final DepositRequest that = (DepositRequest) o;
-    return Objects.equals(pubkey, that.pubkey)
-        && Objects.equals(depositWithdrawalCredentials, that.depositWithdrawalCredentials)
-        && Objects.equals(amount, that.amount)
-        && Objects.equals(signature, that.signature)
-        && Objects.equals(index, that.index);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(pubkey, depositWithdrawalCredentials, amount, signature, index);
-  }
-}
diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/ProcessableBlockHeader.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/ProcessableBlockHeader.java
index 036a33af97..7e037dff3a 100644
--- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/ProcessableBlockHeader.java
+++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/ProcessableBlockHeader.java
@@ -23,6 +23,7 @@ import java.util.Optional;
 
 import org.apache.tuweni.bytes.Bytes;
 import org.apache.tuweni.bytes.Bytes32;
+import org.apache.tuweni.units.bigints.UInt64;
 
 /** A block header capable of being processed. */
 public class ProcessableBlockHeader
@@ -46,6 +47,8 @@ public class ProcessableBlockHeader
   protected final Bytes32 mixHashOrPrevRandao;
   // parentBeaconBlockRoot is included for Cancun
   protected final Bytes32 parentBeaconBlockRoot;
+  // TODO SLD Quantity or UInt64Value instead?
+  protected final UInt64 targetBlobCount;
 
   protected ProcessableBlockHeader(
       final Hash parentHash,
@@ -56,7 +59,8 @@ public class ProcessableBlockHeader
       final long timestamp,
       final Wei baseFee,
       final Bytes32 mixHashOrPrevRandao,
-      final Bytes32 parentBeaconBlockRoot) {
+      final Bytes32 parentBeaconBlockRoot,
+      final UInt64 targetBlobCount) {
     this.parentHash = parentHash;
     this.coinbase = coinbase;
     this.difficulty = difficulty;
@@ -66,6 +70,7 @@ public class ProcessableBlockHeader
     this.baseFee = baseFee;
     this.mixHashOrPrevRandao = mixHashOrPrevRandao;
     this.parentBeaconBlockRoot = parentBeaconBlockRoot;
+    this.targetBlobCount = targetBlobCount;
   }
 
   /**
@@ -178,6 +183,16 @@ public class ProcessableBlockHeader
     return Optional.ofNullable(parentBeaconBlockRoot);
   }
 
+  /**
+   * Returns the target blob count if available.
+   *
+   * @return the target blob count if available.
+   */
+  @Override
+  public Optional getTargetBlobCount() {
+    return Optional.ofNullable(targetBlobCount);
+  }
+
   public String toLogString() {
     return getNumber() + " (time: " + getTimestamp() + ")";
   }
diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Request.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Request.java
index 8f4ea64e31..7d485336ad 100644
--- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Request.java
+++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Request.java
@@ -15,27 +15,18 @@
 package org.hyperledger.besu.ethereum.core;
 
 import org.hyperledger.besu.datatypes.RequestType;
-import org.hyperledger.besu.ethereum.core.encoding.RequestDecoder;
-import org.hyperledger.besu.ethereum.core.encoding.RequestEncoder;
-import org.hyperledger.besu.ethereum.rlp.RLP;
-import org.hyperledger.besu.ethereum.rlp.RLPInput;
-import org.hyperledger.besu.ethereum.rlp.RLPOutput;
 
 import org.apache.tuweni.bytes.Bytes;
 
-public abstract class Request implements org.hyperledger.besu.plugin.data.Request {
+public record Request(RequestType type, Bytes data)
+    implements org.hyperledger.besu.plugin.data.Request {
   @Override
-  public abstract RequestType getType();
-
-  public static Request readFrom(final Bytes rlpBytes) {
-    return readFrom(RLP.input(rlpBytes));
-  }
-
-  public static Request readFrom(final RLPInput rlpInput) {
-    return RequestDecoder.decode(rlpInput);
+  public RequestType getType() {
+    return type();
   }
 
-  public void writeTo(final RLPOutput out) {
-    RequestEncoder.encode(this, out);
+  @Override
+  public Bytes getData() {
+    return data();
   }
 }
diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/SealableBlockHeader.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/SealableBlockHeader.java
index 1b3d2dc646..0eefee7d18 100644
--- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/SealableBlockHeader.java
+++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/SealableBlockHeader.java
@@ -25,6 +25,7 @@ import java.util.Optional;
 
 import org.apache.tuweni.bytes.Bytes;
 import org.apache.tuweni.bytes.Bytes32;
+import org.apache.tuweni.units.bigints.UInt64;
 
 /** A block header capable of being sealed. */
 public class SealableBlockHeader extends ProcessableBlockHeader {
@@ -44,7 +45,7 @@ public class SealableBlockHeader extends ProcessableBlockHeader {
 
   protected final Hash withdrawalsRoot;
 
-  protected final Hash requestsRoot;
+  protected final Hash requestsHash;
 
   protected final Long blobGasUsed;
 
@@ -71,7 +72,8 @@ public class SealableBlockHeader extends ProcessableBlockHeader {
       final Long blobGasUsed,
       final BlobGas excessBlobGas,
       final Bytes32 parentBeaconBlockRoot,
-      final Hash requestsRoot,
+      final Hash requestsHash,
+      final UInt64 targetBlobCount,
       final ExecutionWitness executionWitness) {
     super(
         parentHash,
@@ -82,13 +84,14 @@ public class SealableBlockHeader extends ProcessableBlockHeader {
         timestamp,
         baseFee,
         mixHashOrPrevRandao,
-        parentBeaconBlockRoot);
+        parentBeaconBlockRoot,
+        targetBlobCount);
     this.ommersHash = ommersHash;
     this.stateRoot = stateRoot;
     this.transactionsRoot = transactionsRoot;
     this.withdrawalsRoot = withdrawalsRoot;
     this.receiptsRoot = receiptsRoot;
-    this.requestsRoot = requestsRoot;
+    this.requestsHash = requestsHash;
     this.logsBloom = logsBloom;
     this.gasUsed = gasUsed;
     this.extraData = extraData;
@@ -170,12 +173,12 @@ public class SealableBlockHeader extends ProcessableBlockHeader {
   }
 
   /**
-   * Returns the block requests root hash.
+   * Returns the block requests hash.
    *
-   * @return the block requests root hash
+   * @return the block requests hash
    */
-  public Optional getRequestsRoot() {
-    return Optional.ofNullable(requestsRoot);
+  public Optional getRequestsHash() {
+    return Optional.ofNullable(requestsHash);
   }
 
   /**
diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Synchronizer.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Synchronizer.java
index 7d60c4d357..4a5d3c7ca1 100644
--- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Synchronizer.java
+++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Synchronizer.java
@@ -17,6 +17,7 @@ package org.hyperledger.besu.ethereum.core;
 import org.hyperledger.besu.datatypes.Address;
 import org.hyperledger.besu.plugin.data.SyncStatus;
 import org.hyperledger.besu.plugin.services.BesuEvents;
+import org.hyperledger.besu.plugin.services.BesuEvents.InitialSyncCompletionListener;
 
 import java.util.Optional;
 import java.util.concurrent.CompletableFuture;
@@ -82,6 +83,22 @@ public interface Synchronizer {
    */
   boolean unsubscribeInSync(final long listenerId);
 
+  /**
+   * Add a listener that will be notified when this node initial sync status changes.
+   *
+   * @param listener The callback to invoke when the initial sync status changes
+   * @return A subscription id that can be used to unsubscribe from these events
+   */
+  long subscribeInitialSync(final InitialSyncCompletionListener listener);
+
+  /**
+   * Unsubscribe from initial sync events.
+   *
+   * @param listenerId The id returned when subscribing
+   * @return {@code true} if a subscription was cancelled
+   */
+  boolean unsubscribeInitialSync(final long listenerId);
+
   @FunctionalInterface
   interface InSyncListener {
     void onInSyncStatusChange(boolean newSyncStatus);
diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/WithdrawalRequest.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/WithdrawalRequest.java
deleted file mode 100644
index 0e7afc1595..0000000000
--- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/WithdrawalRequest.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * 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.core;
-
-import org.hyperledger.besu.datatypes.Address;
-import org.hyperledger.besu.datatypes.BLSPublicKey;
-import org.hyperledger.besu.datatypes.GWei;
-import org.hyperledger.besu.datatypes.PublicKey;
-import org.hyperledger.besu.datatypes.RequestType;
-
-import java.util.Objects;
-
-public class WithdrawalRequest extends Request
-    implements org.hyperledger.besu.plugin.data.WithdrawalRequest {
-
-  private final Address sourceAddress;
-  private final BLSPublicKey validatorPubkey;
-  private final GWei amount;
-
-  public WithdrawalRequest(
-      final Address sourceAddress, final BLSPublicKey validatorPubkey, final GWei amount) {
-    this.sourceAddress = sourceAddress;
-    this.validatorPubkey = validatorPubkey;
-    this.amount = amount;
-  }
-
-  @Override
-  public RequestType getType() {
-    return RequestType.WITHDRAWAL;
-  }
-
-  @Override
-  public Address getSourceAddress() {
-    return sourceAddress;
-  }
-
-  @Override
-  public PublicKey getValidatorPubkey() {
-    return validatorPubkey;
-  }
-
-  @Override
-  public GWei getAmount() {
-    return amount;
-  }
-
-  @Override
-  public String toString() {
-    return "WithdrawalRequest{"
-        + "sourceAddress="
-        + sourceAddress
-        + " validatorPubkey="
-        + validatorPubkey
-        + " amount="
-        + amount
-        + '}';
-  }
-
-  @Override
-  public boolean equals(final Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    final WithdrawalRequest that = (WithdrawalRequest) o;
-    return Objects.equals(sourceAddress, that.sourceAddress)
-        && Objects.equals(validatorPubkey, that.validatorPubkey)
-        && Objects.equals(amount, that.amount);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(sourceAddress, validatorPubkey, amount);
-  }
-}
diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/ConsolidationRequestDecoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/ConsolidationRequestDecoder.java
deleted file mode 100644
index 29be31f46d..0000000000
--- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/ConsolidationRequestDecoder.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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.core.encoding;
-
-import org.hyperledger.besu.datatypes.Address;
-import org.hyperledger.besu.datatypes.BLSPublicKey;
-import org.hyperledger.besu.ethereum.core.ConsolidationRequest;
-import org.hyperledger.besu.ethereum.rlp.RLP;
-import org.hyperledger.besu.ethereum.rlp.RLPInput;
-
-import org.apache.tuweni.bytes.Bytes;
-
-public class ConsolidationRequestDecoder {
-
-  public static ConsolidationRequest decode(final RLPInput rlpInput) {
-    rlpInput.enterList();
-    final Address sourceAddress = Address.readFrom(rlpInput);
-    final BLSPublicKey sourcePublicKey = BLSPublicKey.readFrom(rlpInput);
-    final BLSPublicKey targetPublicKey = BLSPublicKey.readFrom(rlpInput);
-    rlpInput.leaveList();
-
-    return new ConsolidationRequest(sourceAddress, sourcePublicKey, targetPublicKey);
-  }
-
-  public static ConsolidationRequest decodeOpaqueBytes(final Bytes input) {
-    return decode(RLP.input(input));
-  }
-}
diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/ConsolidationRequestEncoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/ConsolidationRequestEncoder.java
deleted file mode 100644
index 9551f7b974..0000000000
--- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/ConsolidationRequestEncoder.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * 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.core.encoding;
-
-import org.hyperledger.besu.datatypes.RequestType;
-import org.hyperledger.besu.ethereum.core.ConsolidationRequest;
-import org.hyperledger.besu.ethereum.core.Request;
-import org.hyperledger.besu.ethereum.rlp.RLP;
-import org.hyperledger.besu.ethereum.rlp.RLPOutput;
-
-import org.apache.tuweni.bytes.Bytes;
-
-public class ConsolidationRequestEncoder {
-
-  /**
-   * Encodes a Request into RLP format if it is a ConsolidationRequest.
-   *
-   * @param request The Request to encode, which must be a ConsolidationRequest.
-   * @param rlpOutput The RLPOutput to write the encoded data to.
-   * @throws IllegalArgumentException if the provided request is not a ConsolidationRequest.
-   */
-  public static void encode(final Request request, final RLPOutput rlpOutput) {
-    if (!request.getType().equals(RequestType.CONSOLIDATION)) {
-      throw new IllegalArgumentException(
-          "The provided request is not of type ConsolidationRequest.");
-    }
-    encodeConsolidationRequest((ConsolidationRequest) request, rlpOutput);
-  }
-
-  /**
-   * Encodes the details of a ConsolidationRequest into RLP format.
-   *
-   * @param consolidationRequest The ConsolidationRequest to encode.
-   * @param rlpOutput The RLPOutput to write the encoded data to.
-   */
-  private static void encodeConsolidationRequest(
-      final ConsolidationRequest consolidationRequest, final RLPOutput rlpOutput) {
-    rlpOutput.startList();
-    rlpOutput.writeBytes(consolidationRequest.getSourceAddress());
-    rlpOutput.writeBytes(consolidationRequest.getSourcePubkey());
-    rlpOutput.writeBytes(consolidationRequest.getTargetPubkey());
-    rlpOutput.endList();
-  }
-
-  public static Bytes encodeOpaqueBytes(final Request consolidationRequest) {
-    return RLP.encode(rlpOutput -> encode(consolidationRequest, rlpOutput));
-  }
-}
diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/DepositLogDecoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/DepositLogDecoder.java
new file mode 100644
index 0000000000..655ee63120
--- /dev/null
+++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/DepositLogDecoder.java
@@ -0,0 +1,40 @@
+/*
+ * 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.core.encoding;
+
+import org.hyperledger.besu.ethereum.core.DepositContract;
+import org.hyperledger.besu.evm.log.Log;
+
+import org.apache.tuweni.bytes.Bytes;
+import org.web3j.tx.Contract;
+
+public class DepositLogDecoder {
+
+  public static Bytes decodeFromLog(final Log log) {
+    Contract.EventValuesWithLog eventValues = DepositContract.staticExtractDepositEventWithLog(log);
+    final Bytes rawPublicKey =
+        Bytes.wrap((byte[]) eventValues.getNonIndexedValues().get(0).getValue());
+    final Bytes rawWithdrawalCredential =
+        Bytes.wrap((byte[]) eventValues.getNonIndexedValues().get(1).getValue());
+    final Bytes rawAmount =
+        Bytes.wrap((byte[]) eventValues.getNonIndexedValues().get(2).getValue());
+    final Bytes rawSignature =
+        Bytes.wrap((byte[]) eventValues.getNonIndexedValues().get(3).getValue());
+    final Bytes rawIndex = Bytes.wrap((byte[]) eventValues.getNonIndexedValues().get(4).getValue());
+
+    return Bytes.concatenate(
+        rawPublicKey, rawWithdrawalCredential, rawAmount, rawSignature, rawIndex);
+  }
+}
diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/DepositRequestDecoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/DepositRequestDecoder.java
deleted file mode 100644
index 85b56e1a57..0000000000
--- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/DepositRequestDecoder.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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.core.encoding;
-
-import org.hyperledger.besu.datatypes.BLSPublicKey;
-import org.hyperledger.besu.datatypes.BLSSignature;
-import org.hyperledger.besu.datatypes.GWei;
-import org.hyperledger.besu.ethereum.core.DepositContract;
-import org.hyperledger.besu.ethereum.core.DepositRequest;
-import org.hyperledger.besu.ethereum.rlp.RLP;
-import org.hyperledger.besu.ethereum.rlp.RLPInput;
-import org.hyperledger.besu.evm.log.Log;
-
-import java.nio.ByteOrder;
-
-import org.apache.tuweni.bytes.Bytes;
-import org.apache.tuweni.bytes.Bytes32;
-import org.apache.tuweni.units.bigints.UInt64;
-import org.web3j.tx.Contract;
-
-public class DepositRequestDecoder {
-
-  public static DepositRequest decode(final RLPInput rlpInput) {
-    rlpInput.enterList();
-    final BLSPublicKey publicKey = BLSPublicKey.readFrom(rlpInput);
-    final Bytes32 depositWithdrawalCredential = Bytes32.wrap(rlpInput.readBytes());
-    final GWei amount = GWei.of(rlpInput.readUInt64Scalar());
-    final BLSSignature signature = BLSSignature.readFrom(rlpInput);
-    final UInt64 index = UInt64.valueOf(rlpInput.readBigIntegerScalar());
-    rlpInput.leaveList();
-
-    return new DepositRequest(publicKey, depositWithdrawalCredential, amount, signature, index);
-  }
-
-  public static DepositRequest decodeFromLog(final Log log) {
-    Contract.EventValuesWithLog eventValues = DepositContract.staticExtractDepositEventWithLog(log);
-    final byte[] rawPublicKey = (byte[]) eventValues.getNonIndexedValues().get(0).getValue();
-    final byte[] rawWithdrawalCredential =
-        (byte[]) eventValues.getNonIndexedValues().get(1).getValue();
-    final byte[] rawAmount = (byte[]) eventValues.getNonIndexedValues().get(2).getValue();
-    final byte[] rawSignature = (byte[]) eventValues.getNonIndexedValues().get(3).getValue();
-    final byte[] rawIndex = (byte[]) eventValues.getNonIndexedValues().get(4).getValue();
-
-    return new DepositRequest(
-        BLSPublicKey.wrap(Bytes.wrap(rawPublicKey)),
-        Bytes32.wrap(Bytes.wrap(rawWithdrawalCredential)),
-        GWei.of(
-            Bytes.wrap(rawAmount)
-                .toLong(
-                    ByteOrder.LITTLE_ENDIAN)), // Amount is little endian as per Deposit Contract
-        BLSSignature.wrap(Bytes.wrap(rawSignature)),
-        UInt64.valueOf(Bytes.wrap(rawIndex).reverse().toLong()));
-  }
-
-  public static DepositRequest decodeOpaqueBytes(final Bytes input) {
-    return decode(RLP.input(input));
-  }
-}
diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/DepositRequestEncoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/DepositRequestEncoder.java
deleted file mode 100644
index a99b0b761c..0000000000
--- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/DepositRequestEncoder.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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.core.encoding;
-
-import org.hyperledger.besu.ethereum.core.DepositRequest;
-import org.hyperledger.besu.ethereum.core.Request;
-import org.hyperledger.besu.ethereum.rlp.RLP;
-import org.hyperledger.besu.ethereum.rlp.RLPOutput;
-
-import org.apache.tuweni.bytes.Bytes;
-
-public class DepositRequestEncoder {
-
-  public static void encode(final Request request, final RLPOutput rlpOutput) {
-    if (!(request instanceof DepositRequest depositRequest)) {
-      throw new IllegalArgumentException("The provided request is not of type deposit.");
-    }
-    rlpOutput.startList();
-    rlpOutput.writeBytes(depositRequest.getPubkey());
-    rlpOutput.writeBytes(depositRequest.getWithdrawalCredentials());
-    rlpOutput.writeUInt64Scalar(depositRequest.getAmount());
-    rlpOutput.writeBytes(depositRequest.getSignature());
-    rlpOutput.writeUInt64Scalar(depositRequest.getIndex());
-    rlpOutput.endList();
-  }
-
-  public static Bytes encodeOpaqueBytes(final Request deposit) {
-    return RLP.encode(rlpOutput -> encode(deposit, rlpOutput));
-  }
-}
diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/RequestDecoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/RequestDecoder.java
deleted file mode 100644
index 64191e104b..0000000000
--- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/RequestDecoder.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * 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.core.encoding;
-
-import org.hyperledger.besu.datatypes.RequestType;
-import org.hyperledger.besu.ethereum.core.Request;
-import org.hyperledger.besu.ethereum.rlp.RLP;
-import org.hyperledger.besu.ethereum.rlp.RLPInput;
-
-import java.util.Optional;
-
-import com.google.common.collect.ImmutableMap;
-import org.apache.tuweni.bytes.Bytes;
-
-/**
- * Decodes a request from its RLP encoded form.
- *
- * 

This class provides functionality to decode requests based on their type. - */ -public class RequestDecoder { - - @FunctionalInterface - interface Decoder { - Request decode(RLPInput input); - } - - private static final ImmutableMap DECODERS = - ImmutableMap.of( - RequestType.WITHDRAWAL, - WithdrawalRequestDecoder::decode, - RequestType.DEPOSIT, - DepositRequestDecoder::decode, - RequestType.CONSOLIDATION, - ConsolidationRequestDecoder::decode); - - /** - * Decodes a request from its RLP encoded bytes. - * - *

This method first determines the type of the request and then decodes the request data - * according to the request type. - * - * @param rlpInput The RLP encoded request. - * @return The decoded Request object. - * @throws IllegalArgumentException if the request type is unsupported or invalid. - */ - public static Request decode(final RLPInput rlpInput) { - final Bytes requestBytes = rlpInput.readBytes(); - return getRequestType(requestBytes) - .map(type -> decodeRequest(requestBytes, type)) - .orElseThrow(() -> new IllegalArgumentException("Unsupported or invalid request type")); - } - - /** - * Decodes the request data according to the request type. - * - * @param requestBytes The bytes representing the request, including the request type byte. - * @param requestType The type of the request to decode. - * @return The decoded Request. - * @throws IllegalStateException if no decoder is found for the specified request type. - */ - private static Request decodeRequest(final Bytes requestBytes, final RequestType requestType) { - // Skip the first byte which is the request type - RLPInput requestInput = RLP.input(requestBytes.slice(1)); - Decoder decoder = - Optional.ofNullable(DECODERS.get(requestType)) - .orElseThrow( - () -> - new IllegalStateException( - "Decoder not found for request type: " + requestType)); - return decoder.decode(requestInput); - } - - /** - * Extracts the request type from the given bytes. - * - * @param bytes The bytes from which to extract the request type. - * @return An Optional containing the RequestType if it could be determined, or an empty Optional - * otherwise. - */ - private static Optional getRequestType(final Bytes bytes) { - try { - byte typeByte = bytes.get(0); - return Optional.of(RequestType.of(typeByte)); - } catch (IllegalArgumentException ex) { - return Optional.empty(); - } - } - - public static Request decodeOpaqueBytes(final Bytes input) { - - RequestType type = getRequestType(input).orElseThrow(); - return decodeRequest(input.slice(1), type); - } -} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/RequestEncoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/RequestEncoder.java deleted file mode 100644 index 3c61a77ac0..0000000000 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/RequestEncoder.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * 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.core.encoding; - -import static com.google.common.base.Preconditions.checkNotNull; - -import org.hyperledger.besu.datatypes.RequestType; -import org.hyperledger.besu.ethereum.core.Request; -import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; -import org.hyperledger.besu.ethereum.rlp.RLP; -import org.hyperledger.besu.ethereum.rlp.RLPOutput; - -import com.google.common.collect.ImmutableMap; -import org.apache.tuweni.bytes.Bytes; - -/** Encodes Request objects into RLP format. */ -public class RequestEncoder { - - @FunctionalInterface - interface Encoder { - void encode(Request request, RLPOutput output); - } - - private static final ImmutableMap ENCODERS = - ImmutableMap.of( - RequestType.WITHDRAWAL, - WithdrawalRequestEncoder::encode, - RequestType.DEPOSIT, - DepositRequestEncoder::encode, - RequestType.CONSOLIDATION, - ConsolidationRequestEncoder::encode); - - /** - * Encodes a Request into the provided RLPOutput. - * - * @param request The Request to encode. - * @param rlpOutput The RLPOutput to write the encoded data to. - */ - public static void encode(final Request request, final RLPOutput rlpOutput) { - final RequestEncoder.Encoder encoder = getEncoder(request.getType()); - Bytes requestBytes = RLP.encode(out -> encoder.encode(request, out)); - rlpOutput.writeBytes( - Bytes.concatenate(Bytes.of(request.getType().getSerializedType()), requestBytes)); - } - - /** - * Encodes a Request into a Bytes object representing the RLP-encoded data. - * - * @param request The Request to encode. - * @return The RLP-encoded data as a Bytes object. - */ - public static Bytes encodeOpaqueBytes(final Request request) { - final RequestEncoder.Encoder encoder = getEncoder(request.getType()); - final BytesValueRLPOutput out = new BytesValueRLPOutput(); - out.writeByte(request.getType().getSerializedType()); - encoder.encode(request, out); - return out.encoded(); - } - - /** - * Retrieves the encoder for the specified RequestType. - * - * @param requestType The type of the request. - * @return The encoder for the specified type. - * @throws NullPointerException if no encoder is found for the specified type. - */ - private static RequestEncoder.Encoder getEncoder(final RequestType requestType) { - return checkNotNull( - ENCODERS.get(requestType), "Encoder not found for request type: %s", requestType); - } -} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalRequestDecoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalRequestDecoder.java deleted file mode 100644 index 031209284e..0000000000 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalRequestDecoder.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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.core.encoding; - -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.BLSPublicKey; -import org.hyperledger.besu.datatypes.GWei; -import org.hyperledger.besu.ethereum.core.WithdrawalRequest; -import org.hyperledger.besu.ethereum.rlp.RLP; -import org.hyperledger.besu.ethereum.rlp.RLPInput; - -import org.apache.tuweni.bytes.Bytes; - -public class WithdrawalRequestDecoder { - - public static WithdrawalRequest decode(final RLPInput rlpInput) { - rlpInput.enterList(); - final Address sourceAddress = Address.readFrom(rlpInput); - final BLSPublicKey validatorPubkey = BLSPublicKey.readFrom(rlpInput); - final GWei amount = GWei.of(rlpInput.readUInt64Scalar()); - rlpInput.leaveList(); - - return new WithdrawalRequest(sourceAddress, validatorPubkey, amount); - } - - public static WithdrawalRequest decodeOpaqueBytes(final Bytes input) { - return decode(RLP.input(input)); - } -} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalRequestEncoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalRequestEncoder.java deleted file mode 100644 index c9fdb37fce..0000000000 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalRequestEncoder.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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.core.encoding; - -import org.hyperledger.besu.datatypes.RequestType; -import org.hyperledger.besu.ethereum.core.Request; -import org.hyperledger.besu.ethereum.core.WithdrawalRequest; -import org.hyperledger.besu.ethereum.rlp.RLP; -import org.hyperledger.besu.ethereum.rlp.RLPOutput; - -import org.apache.tuweni.bytes.Bytes; - -public class WithdrawalRequestEncoder { - - /** - * Encodes a Request into RLP format if it is a WithdrawalRequest. - * - * @param request The Request to encode, which must be a WithdrawalRequest. - * @param rlpOutput The RLPOutput to write the encoded data to. - * @throws IllegalArgumentException if the provided request is not a WithdrawalRequest. - */ - public static void encode(final Request request, final RLPOutput rlpOutput) { - if (!request.getType().equals(RequestType.WITHDRAWAL)) { - throw new IllegalArgumentException("The provided request is not of type WithdrawalRequest."); - } - encodeWithdrawalRequest((WithdrawalRequest) request, rlpOutput); - } - - /** - * Encodes the details of a WithdrawalRequest into RLP format. - * - * @param withdrawalRequest The WithdrawalRequest to encode. - * @param rlpOutput The RLPOutput to write the encoded data to. - */ - private static void encodeWithdrawalRequest( - final WithdrawalRequest withdrawalRequest, final RLPOutput rlpOutput) { - rlpOutput.startList(); - rlpOutput.writeBytes(withdrawalRequest.getSourceAddress()); - rlpOutput.writeBytes(withdrawalRequest.getValidatorPubkey()); - rlpOutput.writeUInt64Scalar(withdrawalRequest.getAmount()); - rlpOutput.endList(); - } - - public static Bytes encodeOpaqueBytes(final Request withdrawalRequest) { - return RLP.encode(rlpOutput -> encode(withdrawalRequest, rlpOutput)); - } -} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/json/ChainIdDeserializer.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/json/ChainIdDeserializer.java new file mode 100644 index 0000000000..04be922ecd --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/json/ChainIdDeserializer.java @@ -0,0 +1,46 @@ +/* + * 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.core.json; + +import java.io.IOException; +import java.math.BigInteger; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import org.apache.tuweni.units.bigints.UInt256; + +public class ChainIdDeserializer extends StdDeserializer { + + public ChainIdDeserializer() { + this(null); + } + + public ChainIdDeserializer(final Class vc) { + super(vc); + } + + @Override + public BigInteger deserialize(final JsonParser jsonparser, final DeserializationContext context) + throws IOException { + final var chainId = + UInt256.fromHexString(jsonparser.getCodec().readValue(jsonparser, String.class)) + .toBigInteger(); + if (chainId.signum() <= 0) { + throw new IllegalArgumentException("Non positive chain id: " + chainId); + } + return chainId; + } +} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/AbstractBlockProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/AbstractBlockProcessor.java index 4c5c59f176..a4772bc94d 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/AbstractBlockProcessor.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/AbstractBlockProcessor.java @@ -218,7 +218,7 @@ public abstract class AbstractBlockProcessor implements BlockProcessor { blockHashLookup, OperationTracer.NO_TRACING); - maybeRequests = requestProcessor.get().process(context); + maybeRequests = Optional.of(requestProcessor.get().process(context)); } if (!rewardCoinbase(worldState, blockHeader, ommers, skipZeroBlockRewards)) { diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/BaseFeeBlockBodyValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/BaseFeeBlockBodyValidator.java index aabc4ee5d0..0d43a47022 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/BaseFeeBlockBodyValidator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/BaseFeeBlockBodyValidator.java @@ -18,7 +18,6 @@ import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.core.Block; import org.hyperledger.besu.ethereum.core.BlockBody; -import org.hyperledger.besu.ethereum.core.Request; import org.hyperledger.besu.ethereum.core.Transaction; import org.hyperledger.besu.ethereum.core.TransactionReceipt; import org.hyperledger.besu.ethereum.core.feemarket.TransactionPriceCalculator; @@ -42,12 +41,11 @@ public class BaseFeeBlockBodyValidator extends MainnetBlockBodyValidator { final ProtocolContext context, final Block block, final List receipts, - final Optional> requests, final HeaderValidationMode ommerValidationMode, final BodyValidationMode bodyValidationMode) { return super.validateBodyLight( - context, block, receipts, requests, ommerValidationMode, bodyValidationMode) + context, block, receipts, ommerValidationMode, bodyValidationMode) && validateTransactionGasPrice(block); } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/BlockBodyValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/BlockBodyValidator.java index c84be3771b..32000d12b9 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/BlockBodyValidator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/BlockBodyValidator.java @@ -17,11 +17,9 @@ package org.hyperledger.besu.ethereum.mainnet; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.core.Block; -import org.hyperledger.besu.ethereum.core.Request; import org.hyperledger.besu.ethereum.core.TransactionReceipt; import java.util.List; -import java.util.Optional; /** Validates block bodies. */ public interface BlockBodyValidator { @@ -41,7 +39,6 @@ public interface BlockBodyValidator { ProtocolContext context, Block block, List receipts, - Optional> requests, Hash worldStateRootHash, final HeaderValidationMode ommerValidationMode); @@ -58,7 +55,6 @@ public interface BlockBodyValidator { ProtocolContext context, Block block, List receipts, - final Optional> requests, final HeaderValidationMode ommerValidationMode, final BodyValidationMode bodyValidationMode); } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/BodyValidation.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/BodyValidation.java index 15e8c3c804..f9835c2de5 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/BodyValidation.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/BodyValidation.java @@ -15,6 +15,7 @@ package org.hyperledger.besu.ethereum.mainnet; import static org.hyperledger.besu.crypto.Hash.keccak256; +import static org.hyperledger.besu.crypto.Hash.sha256; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.core.BlockHeader; @@ -23,7 +24,6 @@ import org.hyperledger.besu.ethereum.core.Transaction; import org.hyperledger.besu.ethereum.core.TransactionReceipt; import org.hyperledger.besu.ethereum.core.Withdrawal; import org.hyperledger.besu.ethereum.core.encoding.EncodingContext; -import org.hyperledger.besu.ethereum.core.encoding.RequestEncoder; import org.hyperledger.besu.ethereum.core.encoding.TransactionEncoder; import org.hyperledger.besu.ethereum.core.encoding.WithdrawalEncoder; import org.hyperledger.besu.ethereum.rlp.RLP; @@ -31,6 +31,7 @@ import org.hyperledger.besu.ethereum.trie.MerkleTrie; import org.hyperledger.besu.ethereum.trie.patricia.SimpleMerklePatriciaTrie; import org.hyperledger.besu.evm.log.LogsBloomFilter; +import java.util.ArrayList; import java.util.List; import java.util.stream.IntStream; @@ -89,16 +90,24 @@ public final class BodyValidation { } /** - * Generates the requests root for a list of requests + * Generates the requests hash for a list of requests * * @param requests list of request - * @return the requests root + * @return the requests hash */ - public static Hash requestsRoot(final List requests) { - final MerkleTrie trie = trie(); + public static Hash requestsHash(final List requests) { + List requestHashes = new ArrayList<>(); IntStream.range(0, requests.size()) - .forEach(i -> trie.put(indexKey(i), RequestEncoder.encodeOpaqueBytes(requests.get(i)))); - return Hash.wrap(trie.getRootHash()); + .forEach( + i -> { + final Request request = requests.get(i); + final Bytes requestBytes = + Bytes.concatenate( + Bytes.of(request.getType().getSerializedType()), request.getData()); + requestHashes.add(sha256(requestBytes)); + }); + + return Hash.wrap(sha256(Bytes.wrap(requestHashes))); } /** diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockBodyValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockBodyValidator.java index 68951f9f2a..1423183e94 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockBodyValidator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockBodyValidator.java @@ -19,14 +19,11 @@ import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.core.Block; import org.hyperledger.besu.ethereum.core.BlockBody; import org.hyperledger.besu.ethereum.core.BlockHeader; -import org.hyperledger.besu.ethereum.core.Request; import org.hyperledger.besu.ethereum.core.TransactionReceipt; -import org.hyperledger.besu.ethereum.mainnet.requests.RequestsValidatorCoordinator; import org.hyperledger.besu.evm.log.LogsBloomFilter; import java.util.HashSet; import java.util.List; -import java.util.Optional; import java.util.Set; import com.google.common.annotations.VisibleForTesting; @@ -52,12 +49,11 @@ public class MainnetBlockBodyValidator implements BlockBodyValidator { final ProtocolContext context, final Block block, final List receipts, - final Optional> requests, final Hash worldStateRootHash, final HeaderValidationMode ommerValidationMode) { if (!validateBodyLight( - context, block, receipts, requests, ommerValidationMode, BodyValidationMode.FULL)) { + context, block, receipts, ommerValidationMode, BodyValidationMode.FULL)) { return false; } @@ -78,7 +74,6 @@ public class MainnetBlockBodyValidator implements BlockBodyValidator { final ProtocolContext context, final Block block, final List receipts, - final Optional> requests, final HeaderValidationMode ommerValidationMode, final BodyValidationMode bodyValidationMode) { if (bodyValidationMode == BodyValidationMode.NONE) { @@ -119,9 +114,6 @@ public class MainnetBlockBodyValidator implements BlockBodyValidator { return false; } - if (!validateRequests(block, requests, receipts)) { - return false; - } return true; } @@ -324,13 +316,4 @@ public class MainnetBlockBodyValidator implements BlockBodyValidator { return true; } - - private boolean validateRequests( - final Block block, - final Optional> requests, - final List receipts) { - final RequestsValidatorCoordinator requestValidator = - protocolSchedule.getByBlockHeader(block.getHeader()).getRequestsValidatorCoordinator(); - return requestValidator.validate(block, requests, receipts); - } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockHeaderValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockHeaderValidator.java index 5f1fdff0f4..0598c817bd 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockHeaderValidator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockHeaderValidator.java @@ -14,7 +14,7 @@ */ package org.hyperledger.besu.ethereum.mainnet; -import org.hyperledger.besu.config.MergeConfigOptions; +import org.hyperledger.besu.config.MergeConfiguration; import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.mainnet.feemarket.BaseFeeMarket; import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; @@ -130,7 +130,7 @@ public final class MainnetBlockHeaderValidator { public static BlockHeaderValidator.Builder createBaseFeeMarketValidator( final BaseFeeMarket baseFeeMarket) { - return createBaseFeeMarketValidator(baseFeeMarket, MergeConfigOptions.isMergeEnabled()); + return createBaseFeeMarketValidator(baseFeeMarket, MergeConfiguration.isMergeEnabled()); } @VisibleForTesting diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockImporter.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockImporter.java index 8646467a28..7d655ea4c3 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockImporter.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockImporter.java @@ -66,13 +66,7 @@ public class MainnetBlockImporter implements BlockImporter { final BodyValidationMode bodyValidationMode) { if (blockValidator.validateBlockForSyncing( - context, - block, - receipts, - block.getBody().getRequests(), - headerValidationMode, - ommerValidationMode, - bodyValidationMode)) { + context, block, receipts, headerValidationMode, ommerValidationMode, bodyValidationMode)) { context.getBlockchain().appendBlock(block, receipts); return new BlockImportResult(true); } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecFactory.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecFactory.java index b89e6f743c..a57b13ac53 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecFactory.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecFactory.java @@ -233,8 +233,8 @@ public class MainnetProtocolSpecFactory { // metricsSystem); } - public ProtocolSpecBuilder pragueEOFDefinition(final GenesisConfigOptions genesisConfigOptions) { - return MainnetProtocolSpecs.pragueEOFDefinition( + public ProtocolSpecBuilder osakaDefinition(final GenesisConfigOptions genesisConfigOptions) { + return MainnetProtocolSpecs.osakaDefinition( chainId, isRevertReasonEnabled, genesisConfigOptions, diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecs.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecs.java index 47ae4d71bd..d6ab3b79b8 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecs.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecs.java @@ -14,8 +14,7 @@ */ package org.hyperledger.besu.ethereum.mainnet; -import static org.hyperledger.besu.ethereum.mainnet.requests.MainnetRequestsValidator.pragueRequestsProcessors; -import static org.hyperledger.besu.ethereum.mainnet.requests.MainnetRequestsValidator.pragueRequestsValidator; +import static org.hyperledger.besu.ethereum.mainnet.requests.MainnetRequestsProcessor.pragueRequestsProcessors; import org.hyperledger.besu.config.GenesisConfigOptions; import org.hyperledger.besu.config.PowAlgorithm; @@ -41,6 +40,7 @@ import org.hyperledger.besu.ethereum.mainnet.blockhash.PragueBlockHashProcessor; import org.hyperledger.besu.ethereum.mainnet.feemarket.BaseFeeMarket; import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; import org.hyperledger.besu.ethereum.mainnet.parallelization.MainnetParallelBlockProcessor; +import org.hyperledger.besu.ethereum.mainnet.requests.MainnetRequestsValidator; import org.hyperledger.besu.ethereum.mainnet.requests.RequestContractAddresses; import org.hyperledger.besu.ethereum.privacy.PrivateTransactionProcessor; import org.hyperledger.besu.ethereum.privacy.PrivateTransactionValidator; @@ -60,8 +60,8 @@ import org.hyperledger.besu.evm.gascalculator.FrontierGasCalculator; import org.hyperledger.besu.evm.gascalculator.HomesteadGasCalculator; import org.hyperledger.besu.evm.gascalculator.IstanbulGasCalculator; import org.hyperledger.besu.evm.gascalculator.LondonGasCalculator; +import org.hyperledger.besu.evm.gascalculator.OsakaGasCalculator; import org.hyperledger.besu.evm.gascalculator.PetersburgGasCalculator; -import org.hyperledger.besu.evm.gascalculator.PragueEOFGasCalculator; import org.hyperledger.besu.evm.gascalculator.PragueGasCalculator; import org.hyperledger.besu.evm.gascalculator.ShanghaiGasCalculator; import org.hyperledger.besu.evm.gascalculator.SpuriousDragonGasCalculator; @@ -795,7 +795,7 @@ public abstract class MainnetProtocolSpecs { .precompileContractRegistryBuilder(MainnetPrecompiledContractRegistries::prague) // EIP-7002 Withdrawals / EIP-6610 Deposits / EIP-7685 Requests - .requestsValidator(pragueRequestsValidator(requestContractAddresses)) + .requestsValidator(new MainnetRequestsValidator()) // EIP-7002 Withdrawals / EIP-6610 Deposits / EIP-7685 Requests .requestProcessorCoordinator(pragueRequestsProcessors(requestContractAddresses)) @@ -821,7 +821,7 @@ public abstract class MainnetProtocolSpecs { .name("Prague"); } - static ProtocolSpecBuilder pragueEOFDefinition( + static ProtocolSpecBuilder osakaDefinition( final Optional chainId, final boolean enableRevertReason, final GenesisConfigOptions genesisConfigOptions, @@ -839,7 +839,7 @@ public abstract class MainnetProtocolSpecs { miningParameters, isParallelTxProcessingEnabled, metricsSystem); - return addEOF(chainId, evmConfiguration, protocolSpecBuilder).name("PragueEOF"); + return addEOF(chainId, evmConfiguration, protocolSpecBuilder).name("Osaka"); } private static ProtocolSpecBuilder addEOF( @@ -848,12 +848,11 @@ public abstract class MainnetProtocolSpecs { final ProtocolSpecBuilder protocolSpecBuilder) { return protocolSpecBuilder // EIP-7692 EOF v1 Gas calculator - .gasCalculator(PragueEOFGasCalculator::new) + .gasCalculator(OsakaGasCalculator::new) // EIP-7692 EOF v1 EVM and opcodes .evmBuilder( (gasCalculator, jdCacheConfig) -> - MainnetEVMs.pragueEOF( - gasCalculator, chainId.orElse(BigInteger.ZERO), evmConfiguration)) + MainnetEVMs.osaka(gasCalculator, chainId.orElse(BigInteger.ZERO), evmConfiguration)) // EIP-7698 EOF v1 creation transaction .contractCreationProcessorBuilder( evm -> @@ -919,7 +918,7 @@ public abstract class MainnetProtocolSpecs { final MiningParameters miningParameters, final boolean isParallelTxProcessingEnabled, final MetricsSystem metricsSystem) { - return pragueEOFDefinition( + return osakaDefinition( chainId, enableRevertReason, genesisConfigOptions, diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolScheduleBuilder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolScheduleBuilder.java index beac906be5..52003bc96c 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolScheduleBuilder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolScheduleBuilder.java @@ -16,6 +16,7 @@ package org.hyperledger.besu.ethereum.mainnet; import org.hyperledger.besu.config.GenesisConfigOptions; import org.hyperledger.besu.datatypes.HardforkId; +import org.hyperledger.besu.datatypes.HardforkId.MainnetHardforkId; import org.hyperledger.besu.ethereum.chain.BadBlockManager; import org.hyperledger.besu.ethereum.core.MiningParameters; import org.hyperledger.besu.ethereum.core.PrivacyParameters; @@ -277,7 +278,7 @@ public class ProtocolScheduleBuilder { lastForkBlock = validateForkOrder("Cancun", config.getCancunTime(), lastForkBlock); lastForkBlock = validateForkOrder("CancunEOF", config.getCancunEOFTime(), lastForkBlock); lastForkBlock = validateForkOrder("Prague", config.getPragueTime(), lastForkBlock); - lastForkBlock = validateForkOrder("PragueEOF", config.getPragueEOFTime(), lastForkBlock); + lastForkBlock = validateForkOrder("Osaka", config.getOsakaTime(), lastForkBlock); lastForkBlock = validateForkOrder("FutureEips", config.getFutureEipsTime(), lastForkBlock); lastForkBlock = validateForkOrder("ExperimentalEips", config.getExperimentalEipsTime(), lastForkBlock); @@ -413,9 +414,9 @@ public class ProtocolScheduleBuilder { config.getPragueTime(), specFactory.pragueDefinition(config)), timestampMilestone( - HardforkId.MainnetHardforkId.PRAGUE_EOF, - config.getPragueEOFTime(), - specFactory.pragueEOFDefinition(config)), + MainnetHardforkId.OSAKA, + config.getOsakaTime(), + specFactory.osakaDefinition(config)), timestampMilestone( HardforkId.MainnetHardforkId.FUTURE_EIPS, config.getFutureEipsTime(), diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolSpec.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolSpec.java index 8852fa8171..b6c12da713 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolSpec.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolSpec.java @@ -22,7 +22,7 @@ import org.hyperledger.besu.ethereum.core.BlockImporter; import org.hyperledger.besu.ethereum.mainnet.blockhash.BlockHashProcessor; import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; import org.hyperledger.besu.ethereum.mainnet.requests.RequestProcessorCoordinator; -import org.hyperledger.besu.ethereum.mainnet.requests.RequestsValidatorCoordinator; +import org.hyperledger.besu.ethereum.mainnet.requests.RequestsValidator; import org.hyperledger.besu.ethereum.privacy.PrivateTransactionProcessor; import org.hyperledger.besu.evm.EVM; import org.hyperledger.besu.evm.gascalculator.GasCalculator; @@ -78,7 +78,7 @@ public class ProtocolSpec { private final WithdrawalsValidator withdrawalsValidator; private final Optional withdrawalsProcessor; - private final RequestsValidatorCoordinator requestsValidatorCoordinator; + private final RequestsValidator requestsValidator; private final Optional requestProcessorCoordinator; private final BlockHashProcessor blockHashProcessor; @@ -113,7 +113,7 @@ public class ProtocolSpec { * @param feeMarket an {@link Optional} wrapping {@link FeeMarket} class if appropriate. * @param powHasher the proof-of-work hasher * @param withdrawalsProcessor the Withdrawals processor to use - * @param requestsValidatorCoordinator the request validator to use + * @param requestsValidator the request validator to use * @param requestProcessorCoordinator the request processor to use * @param blockHashProcessor the blockHash processor to use * @param isPoS indicates whether the current spec is PoS @@ -146,7 +146,7 @@ public class ProtocolSpec { final Optional powHasher, final WithdrawalsValidator withdrawalsValidator, final Optional withdrawalsProcessor, - final RequestsValidatorCoordinator requestsValidatorCoordinator, + final RequestsValidator requestsValidator, final Optional requestProcessorCoordinator, final BlockHashProcessor blockHashProcessor, final boolean isPoS, @@ -176,7 +176,7 @@ public class ProtocolSpec { this.powHasher = powHasher; this.withdrawalsValidator = withdrawalsValidator; this.withdrawalsProcessor = withdrawalsProcessor; - this.requestsValidatorCoordinator = requestsValidatorCoordinator; + this.requestsValidator = requestsValidator; this.requestProcessorCoordinator = requestProcessorCoordinator; this.blockHashProcessor = blockHashProcessor; this.isPoS = isPoS; @@ -381,8 +381,8 @@ public class ProtocolSpec { return withdrawalsProcessor; } - public RequestsValidatorCoordinator getRequestsValidatorCoordinator() { - return requestsValidatorCoordinator; + public RequestsValidator getRequestsValidator() { + return requestsValidator; } public Optional getRequestProcessorCoordinator() { diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolSpecBuilder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolSpecBuilder.java index 61b28c9584..02454ccd07 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolSpecBuilder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolSpecBuilder.java @@ -31,8 +31,9 @@ import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; import org.hyperledger.besu.ethereum.mainnet.precompiles.privacy.FlexiblePrivacyPrecompiledContract; import org.hyperledger.besu.ethereum.mainnet.precompiles.privacy.PrivacyPluginPrecompiledContract; import org.hyperledger.besu.ethereum.mainnet.precompiles.privacy.PrivacyPrecompiledContract; +import org.hyperledger.besu.ethereum.mainnet.requests.ProhibitedRequestValidator; import org.hyperledger.besu.ethereum.mainnet.requests.RequestProcessorCoordinator; -import org.hyperledger.besu.ethereum.mainnet.requests.RequestsValidatorCoordinator; +import org.hyperledger.besu.ethereum.mainnet.requests.RequestsValidator; import org.hyperledger.besu.ethereum.privacy.PrivateTransactionProcessor; import org.hyperledger.besu.ethereum.privacy.PrivateTransactionValidator; import org.hyperledger.besu.evm.EVM; @@ -80,9 +81,7 @@ public class ProtocolSpecBuilder { private WithdrawalsValidator withdrawalsValidator = new WithdrawalsValidator.ProhibitedWithdrawals(); private WithdrawalsProcessor withdrawalsProcessor; - - private RequestsValidatorCoordinator requestsValidatorCoordinator = - RequestsValidatorCoordinator.empty(); + private RequestsValidator requestsValidator = new ProhibitedRequestValidator(); private RequestProcessorCoordinator requestProcessorCoordinator; protected BlockHashProcessor blockHashProcessor; @@ -273,8 +272,8 @@ public class ProtocolSpecBuilder { } public ProtocolSpecBuilder requestsValidator( - final RequestsValidatorCoordinator requestsValidatorCoordinator) { - this.requestsValidatorCoordinator = requestsValidatorCoordinator; + final RequestsValidator requestsValidatorCoordinator) { + this.requestsValidator = requestsValidatorCoordinator; return this; } @@ -413,7 +412,7 @@ public class ProtocolSpecBuilder { Optional.ofNullable(powHasher), withdrawalsValidator, Optional.ofNullable(withdrawalsProcessor), - requestsValidatorCoordinator, + requestsValidator, Optional.ofNullable(requestProcessorCoordinator), blockHashProcessor, isPoS, diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/SystemCallProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/SystemCallProcessor.java index f74de79442..06aa3efd8e 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/SystemCallProcessor.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/SystemCallProcessor.java @@ -56,7 +56,8 @@ public class SystemCallProcessor { * @param blockHeader the current block header. * @param operationTracer the operation tracer for tracing EVM operations. * @param blockHashLookup the block hash lookup function. - * @return the output data from the call + * @return the output data from the call. If no code exists at the callAddress then an empty Bytes + * is returned. */ public Bytes process( final Address callAddress, @@ -69,7 +70,7 @@ public class SystemCallProcessor { final Account maybeContract = worldState.get(callAddress); if (maybeContract == null) { LOG.trace("System call address not found {}", callAddress); - return null; + return Bytes.EMPTY; } final AbstractMessageProcessor messageProcessor = diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/AbstractSystemCallRequestProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/AbstractSystemCallRequestProcessor.java deleted file mode 100644 index a7d959f4b9..0000000000 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/AbstractSystemCallRequestProcessor.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * 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.requests; - -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.ethereum.core.Request; -import org.hyperledger.besu.ethereum.mainnet.SystemCallProcessor; - -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; - -import org.apache.tuweni.bytes.Bytes; - -/** - * Abstract base class for processing system call requests. - * - * @param The type of request to be processed. - */ -public abstract class AbstractSystemCallRequestProcessor - implements RequestProcessor { - - /** - * Processes a system call and converts the result into requests of type T. - * - * @param context The request context being processed. - * @return An {@link Optional} containing a list of {@link T} objects if any are found - */ - @Override - public Optional> process(final ProcessRequestContext context) { - - SystemCallProcessor systemCallProcessor = - new SystemCallProcessor(context.protocolSpec().getTransactionProcessor()); - - Bytes systemCallOutput = - systemCallProcessor.process( - getCallAddress(), - context.mutableWorldState().updater(), - context.blockHeader(), - context.operationTracer(), - context.blockHashLookup()); - - List requests = parseRequests(systemCallOutput); - return Optional.ofNullable(requests); - } - - /** - * Parses the provided bytes into a list of {@link T} objects. - * - * @param bytes The bytes representing requests. - * @return A list of parsed {@link T} objects. - */ - protected List parseRequests(final Bytes bytes) { - if (bytes == null) { - return null; - } - final List requests = new ArrayList<>(); - if (bytes.isEmpty()) { - return requests; - } - int count = bytes.size() / getRequestBytesSize(); - for (int i = 0; i < count; i++) { - Bytes requestBytes = bytes.slice(i * getRequestBytesSize(), getRequestBytesSize()); - requests.add(parseRequest(requestBytes)); - } - return requests; - } - - /** - * Parses a single request from the provided bytes. - * - * @param requestBytes The bytes representing a single request. - * @return A parsed {@link T} object. - */ - protected abstract T parseRequest(final Bytes requestBytes); - - /** - * Gets the call address for the specific request type. - * - * @return The call address. - */ - protected abstract Address getCallAddress(); - - /** - * Gets the size of the bytes representing a single request. - * - * @return The size of the bytes representing a single request. - */ - protected abstract int getRequestBytesSize(); -} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/ConsolidationRequestProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/ConsolidationRequestProcessor.java deleted file mode 100644 index 641720670f..0000000000 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/ConsolidationRequestProcessor.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 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.requests; - -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.BLSPublicKey; -import org.hyperledger.besu.ethereum.core.ConsolidationRequest; - -import org.apache.tuweni.bytes.Bytes; - -public class ConsolidationRequestProcessor - extends AbstractSystemCallRequestProcessor { - public static final Address CONSOLIDATION_REQUEST_CONTRACT_ADDRESS = - Address.fromHexString("0x00b42dbF2194e931E80326D950320f7d9Dbeac02"); - - private static final int ADDRESS_BYTES = 20; - private static final int PUBLIC_KEY_BYTES = 48; - private static final int CONSOLIDATION_REQUEST_BYTES_SIZE = - ADDRESS_BYTES + PUBLIC_KEY_BYTES + PUBLIC_KEY_BYTES; - private final Address consolidationRequestContractAddress; - - public ConsolidationRequestProcessor(final Address consolidationRequestContractAddress) { - this.consolidationRequestContractAddress = consolidationRequestContractAddress; - } - - /** - * Gets the call address for consolidation requests. - * - * @return The call address. - */ - @Override - protected Address getCallAddress() { - return consolidationRequestContractAddress; - } - - /** - * Gets the size of the bytes representing a single consolidation request. - * - * @return The size of the bytes representing a single consolidation request. - */ - @Override - protected int getRequestBytesSize() { - return CONSOLIDATION_REQUEST_BYTES_SIZE; - } - - /** - * Parses a single consolidation request from the provided bytes. - * - * @param requestBytes The bytes representing a single consolidation request. - * @return A parsed {@link ConsolidationRequest} object. - */ - @Override - protected ConsolidationRequest parseRequest(final Bytes requestBytes) { - final Address sourceAddress = Address.wrap(requestBytes.slice(0, ADDRESS_BYTES)); - final BLSPublicKey sourcePublicKey = - BLSPublicKey.wrap(requestBytes.slice(ADDRESS_BYTES, PUBLIC_KEY_BYTES)); - final BLSPublicKey targetPublicKey = - BLSPublicKey.wrap(requestBytes.slice(ADDRESS_BYTES + PUBLIC_KEY_BYTES, PUBLIC_KEY_BYTES)); - return new ConsolidationRequest(sourceAddress, sourcePublicKey, targetPublicKey); - } -} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/ConsolidationRequestValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/ConsolidationRequestValidator.java deleted file mode 100644 index f03de5e6b5..0000000000 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/ConsolidationRequestValidator.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * 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.requests; - -import static org.hyperledger.besu.ethereum.mainnet.requests.RequestUtil.getConsolidationRequests; - -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.ethereum.core.Block; -import org.hyperledger.besu.ethereum.core.ConsolidationRequest; -import org.hyperledger.besu.ethereum.core.Request; -import org.hyperledger.besu.ethereum.core.TransactionReceipt; - -import java.util.Collections; -import java.util.List; -import java.util.Optional; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class ConsolidationRequestValidator implements RequestValidator { - - private static final Logger LOG = LoggerFactory.getLogger(ConsolidationRequestValidator.class); - - public static final int MAX_CONSOLIDATION_REQUESTS_PER_BLOCK = 1; - - private boolean validateConsolidationRequestParameter( - final Optional> consolidationRequests) { - return consolidationRequests.isPresent(); - } - - private boolean validateConsolidationRequestsInBlock( - final Block block, final List consolidationRequests) { - final Hash blockHash = block.getHash(); - - final List consolidationRequestsInBlock = - block - .getBody() - .getRequests() - .flatMap(requests -> getConsolidationRequests(Optional.of(requests))) - .orElse(Collections.emptyList()); - - if (consolidationRequestsInBlock.size() > MAX_CONSOLIDATION_REQUESTS_PER_BLOCK) { - LOG.warn( - "Block {} has more than the allowed maximum number of consolidation requests", blockHash); - return false; - } - - // Validate ConsolidationRequests - final boolean expectedConsolidationRequestMatch = - consolidationRequests.equals(consolidationRequestsInBlock); - if (!expectedConsolidationRequestMatch) { - LOG.warn( - "Block {} has a mismatch between block consolidations and RPC consolidation requests (in_block = {}, " - + "expected = {})", - blockHash, - consolidationRequestsInBlock, - consolidationRequests); - return false; - } - return true; - } - - @Override - public boolean validate( - final Block block, final List requests, final List receipts) { - var consolidationRequests = - getConsolidationRequests(Optional.of(requests)).orElse(Collections.emptyList()); - return validateConsolidationRequestsInBlock(block, consolidationRequests); - } - - @Override - public boolean validateParameter(final Optional> request) { - if (request.isEmpty()) { - return true; - } - var consolidationRequests = - RequestUtil.filterRequestsOfType(request.get(), ConsolidationRequest.class); - return validateConsolidationRequestParameter(Optional.of(consolidationRequests)); - } -} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/DepositRequestProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/DepositRequestProcessor.java index 8902ecc510..37e266f015 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/DepositRequestProcessor.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/DepositRequestProcessor.java @@ -15,22 +15,19 @@ package org.hyperledger.besu.ethereum.mainnet.requests; import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.ethereum.core.DepositRequest; +import org.hyperledger.besu.datatypes.RequestType; import org.hyperledger.besu.ethereum.core.Request; import org.hyperledger.besu.ethereum.core.TransactionReceipt; -import org.hyperledger.besu.ethereum.core.encoding.DepositRequestDecoder; +import org.hyperledger.besu.ethereum.core.encoding.DepositLogDecoder; -import java.util.Collections; import java.util.List; import java.util.Optional; import com.google.common.annotations.VisibleForTesting; +import org.apache.tuweni.bytes.Bytes; public class DepositRequestProcessor implements RequestProcessor { - public static final Address DEFAULT_DEPOSIT_CONTRACT_ADDRESS = - Address.fromHexString("0x00000000219ab540356cbb839cbe05303d7705fa"); - private final Optional

depositContractAddress; public DepositRequestProcessor(final Address depositContractAddress) { @@ -38,26 +35,22 @@ public class DepositRequestProcessor implements RequestProcessor { } @Override - public Optional> process(final ProcessRequestContext context) { + public Request process(final ProcessRequestContext context) { if (depositContractAddress.isEmpty()) { - return Optional.empty(); + return new Request(RequestType.DEPOSIT, Bytes.EMPTY); } - List depositRequests = - findDepositRequestsFromReceipts(context.transactionReceipts()); - return Optional.of(depositRequests); + Optional depositRequests = getDepositRequestData(context.transactionReceipts()); + return new Request(RequestType.DEPOSIT, depositRequests.orElse(Bytes.EMPTY)); } @VisibleForTesting - List findDepositRequestsFromReceipts( - final List transactionReceipts) { - return depositContractAddress - .map( - address -> - transactionReceipts.stream() - .flatMap(receipt -> receipt.getLogsList().stream()) - .filter(log -> address.equals(log.getLogger())) - .map(DepositRequestDecoder::decodeFromLog) - .toList()) - .orElse(Collections.emptyList()); + Optional getDepositRequestData(final List transactionReceipts) { + return depositContractAddress.flatMap( + address -> + transactionReceipts.stream() + .flatMap(receipt -> receipt.getLogsList().stream()) + .filter(log -> address.equals(log.getLogger())) + .map(DepositLogDecoder::decodeFromLog) + .reduce(Bytes::concatenate)); } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/DepositRequestValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/DepositRequestValidator.java deleted file mode 100644 index 6c9eedf305..0000000000 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/DepositRequestValidator.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * 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.requests; - -import static org.hyperledger.besu.ethereum.mainnet.requests.RequestUtil.getDepositRequests; - -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.ethereum.core.Block; -import org.hyperledger.besu.ethereum.core.DepositRequest; -import org.hyperledger.besu.ethereum.core.Request; -import org.hyperledger.besu.ethereum.core.TransactionReceipt; -import org.hyperledger.besu.ethereum.core.encoding.DepositRequestDecoder; -import org.hyperledger.besu.evm.log.Log; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Optional; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class DepositRequestValidator implements RequestValidator { - - private static final Logger LOG = LoggerFactory.getLogger(DepositRequestValidator.class); - private final Address depositContractAddress; - - public DepositRequestValidator(final Address depositContractAddress) { - this.depositContractAddress = depositContractAddress; - } - - @Override - public boolean validateParameter(final Optional> depositRequests) { - return depositRequests.isPresent(); - } - - public boolean validateDepositRequests( - final Block block, - final List actualDepositRequests, - final List receipts) { - - List expectedDepositRequests = new ArrayList<>(); - - for (TransactionReceipt receipt : receipts) { - for (Log log : receipt.getLogsList()) { - if (depositContractAddress.equals(log.getLogger())) { - DepositRequest depositRequest = DepositRequestDecoder.decodeFromLog(log); - expectedDepositRequests.add(depositRequest); - } - } - } - - boolean isValid = actualDepositRequests.equals(expectedDepositRequests); - - if (!isValid) { - LOG.warn( - "Deposits validation failed. Deposits from block body do not match deposits from logs. Block hash: {}", - block.getHash()); - LOG.debug( - "Deposits from logs: {}, deposits from block body: {}", - expectedDepositRequests, - actualDepositRequests); - } - - return isValid; - } - - @Override - public boolean validate( - final Block block, final List requests, final List receipts) { - var depositRequests = getDepositRequests(Optional.of(requests)).orElse(Collections.emptyList()); - return validateDepositRequests(block, depositRequests, receipts); - } -} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/MainnetRequestsProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/MainnetRequestsProcessor.java new file mode 100644 index 0000000000..d1c290c407 --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/MainnetRequestsProcessor.java @@ -0,0 +1,39 @@ +/* + * 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.requests; + +import org.hyperledger.besu.datatypes.RequestType; + +public class MainnetRequestsProcessor { + + public static RequestProcessorCoordinator pragueRequestsProcessors( + final RequestContractAddresses requestContractAddresses) { + return new RequestProcessorCoordinator.Builder() + .addProcessor( + RequestType.WITHDRAWAL, + new SystemCallRequestProcessor( + requestContractAddresses.getWithdrawalRequestContractAddress(), + RequestType.WITHDRAWAL)) + .addProcessor( + RequestType.CONSOLIDATION, + new SystemCallRequestProcessor( + requestContractAddresses.getConsolidationRequestContractAddress(), + RequestType.CONSOLIDATION)) + .addProcessor( + RequestType.DEPOSIT, + new DepositRequestProcessor(requestContractAddresses.getDepositContractAddress())) + .build(); + } +} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/MainnetRequestsValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/MainnetRequestsValidator.java index 9c86d18f7a..fb49ba71fc 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/MainnetRequestsValidator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/MainnetRequestsValidator.java @@ -14,34 +14,47 @@ */ package org.hyperledger.besu.ethereum.mainnet.requests; -import org.hyperledger.besu.datatypes.RequestType; - -public class MainnetRequestsValidator { - public static RequestsValidatorCoordinator pragueRequestsValidator( - final RequestContractAddresses requestContractAddresses) { - return new RequestsValidatorCoordinator.Builder() - .addValidator(RequestType.WITHDRAWAL, new WithdrawalRequestValidator()) - .addValidator(RequestType.CONSOLIDATION, new ConsolidationRequestValidator()) - .addValidator( - RequestType.DEPOSIT, - new DepositRequestValidator(requestContractAddresses.getDepositContractAddress())) - .build(); +import org.hyperledger.besu.ethereum.core.Request; + +import java.util.List; +import java.util.Optional; + +import com.google.common.collect.Ordering; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Validates requests within a block against a set of predefined validators. This class delegates + * the validation of requests of specific types to corresponding validators. It ensures that + * requests are properly ordered, have a valid hash, and meet the criteria defined by their + * validators. + */ +public class MainnetRequestsValidator implements RequestsValidator { + private static final Logger LOG = LoggerFactory.getLogger(MainnetRequestsValidator.class); + + /** + * Validates a block's requests by ensuring they are correctly ordered, have a valid hash, and + * pass their respective type-specific validations. + * + * @param maybeRequests The list of requests to be validated. + * @return true if all validations pass; false otherwise. + */ + @Override + public boolean validate(final Optional> maybeRequests) { + if (maybeRequests.isEmpty()) { + LOG.warn("Must contain requests (even if empty list)"); + return false; + } + + if (!isRequestOrderValid(maybeRequests.get())) { + LOG.warn("Ordering across requests must be ascending by type"); + return false; + } + + return true; } - public static RequestProcessorCoordinator pragueRequestsProcessors( - final RequestContractAddresses requestContractAddresses) { - return new RequestProcessorCoordinator.Builder() - .addProcessor( - RequestType.WITHDRAWAL, - new WithdrawalRequestProcessor( - requestContractAddresses.getWithdrawalRequestContractAddress())) - .addProcessor( - RequestType.CONSOLIDATION, - new ConsolidationRequestProcessor( - requestContractAddresses.getConsolidationRequestContractAddress())) - .addProcessor( - RequestType.DEPOSIT, - new DepositRequestProcessor(requestContractAddresses.getDepositContractAddress())) - .build(); + private static boolean isRequestOrderValid(final List requests) { + return Ordering.natural().onResultOf(Request::getType).isOrdered(requests); } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/ProhibitedRequestValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/ProhibitedRequestValidator.java new file mode 100644 index 0000000000..4545ff3530 --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/ProhibitedRequestValidator.java @@ -0,0 +1,38 @@ +/* + * Copyright contributors to 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.requests; + +import org.hyperledger.besu.ethereum.core.Request; + +import java.util.List; +import java.util.Optional; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ProhibitedRequestValidator implements RequestsValidator { + private static final Logger LOG = LoggerFactory.getLogger(MainnetRequestsValidator.class); + + @Override + public boolean validate(final Optional> maybeRequests) { + boolean hasRequests = maybeRequests.isPresent(); + + if (hasRequests) { + LOG.warn("There are requests but requests are prohibited"); + } + + return !hasRequests; + } +} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/ProhibitedRequestsValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/ProhibitedRequestsValidator.java deleted file mode 100644 index 362da52728..0000000000 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/ProhibitedRequestsValidator.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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.requests; - -import org.hyperledger.besu.ethereum.core.Block; -import org.hyperledger.besu.ethereum.core.Request; -import org.hyperledger.besu.ethereum.core.TransactionReceipt; - -import java.util.List; -import java.util.Optional; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** Validates that a block does not contain any prohibited requests. */ -public class ProhibitedRequestsValidator implements RequestValidator { - private static final Logger LOG = LoggerFactory.getLogger(ProhibitedRequestsValidator.class); - - @Override - public boolean validate( - final Block block, final List request, final List receipts) { - boolean hasRequests = block.getBody().getRequests().isPresent(); - boolean hasRequestsRoot = block.getHeader().getRequestsRoot().isPresent(); - - if (hasRequests) { - LOG.warn("Block {} contains requests but requests are prohibited", block.getHash()); - } - - if (hasRequestsRoot) { - LOG.warn( - "Block {} header contains requests_root but requests are prohibited", block.getHash()); - } - - return !(hasRequests || hasRequestsRoot); - } - - @Override - public boolean validateParameter(final Optional> request) { - return request.isEmpty(); - } -} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/RequestContractAddresses.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/RequestContractAddresses.java index b75677dda7..d16d1bddbc 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/RequestContractAddresses.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/RequestContractAddresses.java @@ -14,10 +14,6 @@ */ package org.hyperledger.besu.ethereum.mainnet.requests; -import static org.hyperledger.besu.ethereum.mainnet.requests.ConsolidationRequestProcessor.CONSOLIDATION_REQUEST_CONTRACT_ADDRESS; -import static org.hyperledger.besu.ethereum.mainnet.requests.DepositRequestProcessor.DEFAULT_DEPOSIT_CONTRACT_ADDRESS; -import static org.hyperledger.besu.ethereum.mainnet.requests.WithdrawalRequestProcessor.DEFAULT_WITHDRAWAL_REQUEST_CONTRACT_ADDRESS; - import org.hyperledger.besu.config.GenesisConfigOptions; import org.hyperledger.besu.datatypes.Address; @@ -26,6 +22,13 @@ public class RequestContractAddresses { private final Address depositContractAddress; private final Address consolidationRequestContractAddress; + public static final Address DEFAULT_WITHDRAWAL_REQUEST_CONTRACT_ADDRESS = + Address.fromHexString("0x09FC772D0857550724B07B850A4323F39112AAAA"); + public static final Address DEFAULT_CONSOLIDATION_REQUEST_CONTRACT_ADDRESS = + Address.fromHexString("0x01ABEA29659E5E97C95107F20BB753CD3E09BBBB"); + public static final Address DEFAULT_DEPOSIT_CONTRACT_ADDRESS = + Address.fromHexString("0x00000000219ab540356cbb839cbe05303d7705fa"); + public RequestContractAddresses( final Address withdrawalRequestContractAddress, final Address depositContractAddress, @@ -44,7 +47,7 @@ public class RequestContractAddresses { genesisConfigOptions.getDepositContractAddress().orElse(DEFAULT_DEPOSIT_CONTRACT_ADDRESS), genesisConfigOptions .getConsolidationRequestContractAddress() - .orElse(CONSOLIDATION_REQUEST_CONTRACT_ADDRESS)); + .orElse(DEFAULT_CONSOLIDATION_REQUEST_CONTRACT_ADDRESS)); } public Address getWithdrawalRequestContractAddress() { diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/RequestProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/RequestProcessor.java index 55f3cd4178..dd471aec1e 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/RequestProcessor.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/RequestProcessor.java @@ -16,9 +16,6 @@ package org.hyperledger.besu.ethereum.mainnet.requests; import org.hyperledger.besu.ethereum.core.Request; -import java.util.List; -import java.util.Optional; - public interface RequestProcessor { - Optional> process(final ProcessRequestContext context); + Request process(final ProcessRequestContext context); } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/RequestProcessorCoordinator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/RequestProcessorCoordinator.java index b98274729d..7dd3b5c6dd 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/RequestProcessorCoordinator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/RequestProcessorCoordinator.java @@ -17,9 +17,7 @@ package org.hyperledger.besu.ethereum.mainnet.requests; import org.hyperledger.besu.datatypes.RequestType; import org.hyperledger.besu.ethereum.core.Request; -import java.util.ArrayList; import java.util.List; -import java.util.Optional; import com.google.common.collect.ImmutableSortedMap; @@ -37,18 +35,10 @@ public class RequestProcessorCoordinator { this.processors = processors; } - public Optional> process(final ProcessRequestContext context) { - List requests = null; - for (RequestProcessor requestProcessor : processors.values()) { - var r = requestProcessor.process(context); - if (r.isPresent()) { - if (requests == null) { - requests = new ArrayList<>(); - } - requests.addAll(r.get()); - } - } - return Optional.ofNullable(requests); + public List process(final ProcessRequestContext context) { + return processors.values().stream() + .map(requestProcessor -> requestProcessor.process(context)) + .toList(); } public static class Builder { @@ -62,7 +52,12 @@ public class RequestProcessorCoordinator { } public RequestProcessorCoordinator build() { - return new RequestProcessorCoordinator(requestProcessorBuilder.build()); + final ImmutableSortedMap processors = + requestProcessorBuilder.build(); + if (processors.isEmpty()) { + throw new IllegalStateException("No processors added to RequestProcessorCoordinator"); + } + return new RequestProcessorCoordinator(processors); } } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/RequestUtil.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/RequestUtil.java deleted file mode 100644 index f3a10161a4..0000000000 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/RequestUtil.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * 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.requests; - -import org.hyperledger.besu.ethereum.core.ConsolidationRequest; -import org.hyperledger.besu.ethereum.core.DepositRequest; -import org.hyperledger.besu.ethereum.core.Request; -import org.hyperledger.besu.ethereum.core.WithdrawalRequest; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Optional; - -public class RequestUtil { - - /** - * Filters and returns a list of requests of a specific type from a given list of requests. - * - * @param The type of the request to filter by, extending Request. - * @param requests The list of requests to filter. - * @param requestType The class of the request type to filter for. - * @return A List containing only requests of the specified type, or an empty list if the input - * list is null or contains no requests of the specified type. - */ - public static List filterRequestsOfType( - final List requests, final Class requestType) { - if (requests == null) { - return Collections.emptyList(); - } - return requests.stream().filter(requestType::isInstance).map(requestType::cast).toList(); - } - - public static Optional> getDepositRequests( - final Optional> requests) { - return requests.map(r -> filterRequestsOfType(r, DepositRequest.class)); - } - - public static Optional> getWithdrawalRequests( - final Optional> requests) { - return requests.map(r -> filterRequestsOfType(r, WithdrawalRequest.class)); - } - - public static Optional> getConsolidationRequests( - final Optional> requests) { - return requests.map(r -> filterRequestsOfType(r, ConsolidationRequest.class)); - } - - /** - * Combines multiple optional lists of requests into a single optional list. - * - * @param maybeDepositRequests Optional list of deposit requests. - * @param maybeWithdrawalRequest Optional list of withdrawal requests. - * @param maybeConsolidationRequest Optional list of withdrawal requests. - * @return An Optional containing the combined list of requests, or an empty Optional if all input - * lists are empty. - */ - public static Optional> combine( - final Optional> maybeDepositRequests, - final Optional> maybeWithdrawalRequest, - final Optional> maybeConsolidationRequest) { - if (maybeDepositRequests.isEmpty() - && maybeWithdrawalRequest.isEmpty() - && maybeConsolidationRequest.isEmpty()) { - return Optional.empty(); - } - List requests = new ArrayList<>(); - maybeDepositRequests.ifPresent(requests::addAll); - maybeWithdrawalRequest.ifPresent(requests::addAll); - maybeConsolidationRequest.ifPresent(requests::addAll); - return Optional.of(requests); - } -} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/RequestValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/RequestsValidator.java similarity index 63% rename from ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/RequestValidator.java rename to ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/RequestsValidator.java index 74fd8cd7eb..a05afa8128 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/RequestValidator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/RequestsValidator.java @@ -1,5 +1,5 @@ /* - * Copyright contributors to Hyperledger Besu. + * Copyright contributors to 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 @@ -14,17 +14,11 @@ */ package org.hyperledger.besu.ethereum.mainnet.requests; -import org.hyperledger.besu.ethereum.core.Block; import org.hyperledger.besu.ethereum.core.Request; -import org.hyperledger.besu.ethereum.core.TransactionReceipt; import java.util.List; import java.util.Optional; -/** Interface for request validation logic. */ -public interface RequestValidator { - boolean validate( - final Block block, final List request, final List receipts); - - boolean validateParameter(final Optional> request); +public interface RequestsValidator { + boolean validate(Optional> maybeRequests); } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/RequestsValidatorCoordinator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/RequestsValidatorCoordinator.java deleted file mode 100644 index 7b8f5cf497..0000000000 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/RequestsValidatorCoordinator.java +++ /dev/null @@ -1,202 +0,0 @@ -/* - * 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.requests; - -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.datatypes.RequestType; -import org.hyperledger.besu.ethereum.core.Block; -import org.hyperledger.besu.ethereum.core.Request; -import org.hyperledger.besu.ethereum.core.TransactionReceipt; -import org.hyperledger.besu.ethereum.mainnet.BodyValidation; - -import java.util.List; -import java.util.Optional; -import java.util.Set; -import java.util.stream.Collectors; -import java.util.stream.IntStream; - -import com.google.common.collect.ImmutableSortedMap; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Validates requests within a block against a set of predefined validators. This class delegates - * the validation of requests of specific types to corresponding validators. It ensures that - * requests are properly ordered, have a valid root, and meet the criteria defined by their - * validators. - */ -public class RequestsValidatorCoordinator { - private static final Logger LOG = LoggerFactory.getLogger(RequestsValidatorCoordinator.class); - private final ImmutableSortedMap validators; - - public static RequestsValidatorCoordinator empty() { - return new Builder().build(); - } - - /** - * Constructs a new RequestsDelegateValidator with a mapping of request types to their respective - * validators. - * - * @param validators An immutable map of request types to their corresponding validators. - */ - private RequestsValidatorCoordinator( - final ImmutableSortedMap validators) { - this.validators = validators; - } - - /** - * Validates a block's requests by ensuring they are correctly ordered, have a valid root, and - * pass their respective type-specific validations. - * - * @param block The block containing the requests to be validated. - * @param maybeRequests The list of requests contained within the block. - * @param receipts The list of transaction receipts corresponding to the requests. - * @return true if all validations pass; false otherwise. - */ - public boolean validate( - final Block block, - final Optional> maybeRequests, - final List receipts) { - - if (validators.isEmpty()) { - return isRequestsEmpty(block, maybeRequests); - } - - if (!isRequestsRootValid(block, maybeRequests)) { - return false; - } - - if (!isRequestOrderValid(maybeRequests.get())) { - final Hash blockHash = block.getHash(); - LOG.warn("Block {} the ordering across requests must be ascending by type", blockHash); - return false; - } - return validateRequests(block, maybeRequests.get(), receipts); - } - - /** - * Validates the requests contained within a block against their respective type-specific - * validators. - * - * @param block The block containing the requests. - * @param requests The list of requests to be validated. - * @param receipts The list of transaction receipts corresponding to the requests. - * @return true if all requests pass their type-specific validations; false otherwise. - */ - private boolean validateRequests( - final Block block, final List requests, final List receipts) { - return requestTypes(requests).stream() - .allMatch(type -> validateRequestOfType(type, block, requests, receipts)); - } - - private boolean isRequestsRootValid(final Block block, final Optional> requests) { - final Hash blockHash = block.getHash(); - final Optional maybeRequestsRoot = block.getHeader().getRequestsRoot(); - - if (maybeRequestsRoot.isEmpty()) { - LOG.warn("Block {} must contain requests root", blockHash); - return false; - } - - if (block.getBody().getRequests().isEmpty()) { - LOG.warn("Block body {} must contain requests (even if empty list)", blockHash); - return false; - } - - if (requests.isEmpty()) { - LOG.warn("Block {} must contain requests (even if empty list)", blockHash); - return false; - } - - final Hash expectedRequestsRoot = BodyValidation.requestsRoot(requests.get()); - if (!expectedRequestsRoot.equals(maybeRequestsRoot.get())) { - LOG.warn( - "Block {} requests root does not match expected hash root for requests in block", - blockHash); - return false; - } - return true; - } - - private boolean isRequestsEmpty(final Block block, final Optional> requests) { - final Hash blockHash = block.getHash(); - final Optional maybeRequestsRoot = block.getHeader().getRequestsRoot(); - - if (maybeRequestsRoot.isPresent()) { - LOG.warn("Block {} must not contain requests root", blockHash); - return false; - } - - if (block.getBody().getRequests().isPresent()) { - LOG.warn("Block body {} must not contain requests", blockHash); - return false; - } - - if (requests.isPresent()) { - LOG.warn("Block {} must not contain requests", blockHash); - return false; - } - return true; - } - - private boolean validateRequestOfType( - final RequestType type, - final Block block, - final List requests, - final List receipts) { - - Optional requestValidator = getRequestValidator(type); - if (requestValidator.isEmpty()) { - LOG.warn("Block {} contains prohibited requests of type: {}", block.getHash(), type); - return false; - } - List typedRequests = filterRequestsOfType(requests, type); - return requestValidator.get().validate(block, typedRequests, receipts); - } - - public Optional getRequestValidator(final RequestType requestType) { - return Optional.ofNullable(validators.get(requestType)); - } - - private static Set requestTypes(final List requests) { - return requests.stream().map(Request::getType).collect(Collectors.toSet()); - } - - private static boolean isRequestOrderValid(final List requests) { - return IntStream.range(0, requests.size() - 1) - .allMatch(i -> requests.get(i).getType().compareTo(requests.get(i + 1).getType()) <= 0); - } - - private static List filterRequestsOfType( - final List requests, final RequestType type) { - return requests.stream() - .filter(request -> request.getType() == type) - .collect(Collectors.toList()); - } - - public static class Builder { - private final ImmutableSortedMap.Builder validatorsBuilder = - ImmutableSortedMap.naturalOrder(); - - public Builder addValidator(final RequestType type, final RequestValidator validator) { - this.validatorsBuilder.put(type, validator); - return this; - } - - public RequestsValidatorCoordinator build() { - return new RequestsValidatorCoordinator(validatorsBuilder.build()); - } - } -} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/SystemCallRequestProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/SystemCallRequestProcessor.java new file mode 100644 index 0000000000..3bcfe02c2a --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/SystemCallRequestProcessor.java @@ -0,0 +1,57 @@ +/* + * 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.requests; + +import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.datatypes.RequestType; +import org.hyperledger.besu.ethereum.core.Request; +import org.hyperledger.besu.ethereum.mainnet.SystemCallProcessor; + +import org.apache.tuweni.bytes.Bytes; + +/** Processes system call requests. */ +public class SystemCallRequestProcessor implements RequestProcessor { + + private final Address callAddress; + private final RequestType requestType; + + public SystemCallRequestProcessor(final Address callAddress, final RequestType requestType) { + this.callAddress = callAddress; + this.requestType = requestType; + } + + /** + * Processes a system call and converts the result as a Request. + * + * @param context The request context being processed. + * @return A {@link Request} request + */ + @Override + public Request process(final ProcessRequestContext context) { + + SystemCallProcessor systemCallProcessor = + new SystemCallProcessor(context.protocolSpec().getTransactionProcessor()); + + Bytes systemCallOutput = + systemCallProcessor.process( + callAddress, + context.mutableWorldState().updater(), + context.blockHeader(), + context.operationTracer(), + context.blockHashLookup()); + + return new Request(requestType, systemCallOutput); + } +} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/WithdrawalRequestProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/WithdrawalRequestProcessor.java deleted file mode 100644 index d4021c9a10..0000000000 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/WithdrawalRequestProcessor.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * 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.requests; - -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.BLSPublicKey; -import org.hyperledger.besu.datatypes.GWei; -import org.hyperledger.besu.ethereum.core.WithdrawalRequest; - -import org.apache.tuweni.bytes.Bytes; -import org.apache.tuweni.units.bigints.UInt64; - -/** Processor for handling withdrawal requests. */ -public class WithdrawalRequestProcessor - extends AbstractSystemCallRequestProcessor { - - public static final Address DEFAULT_WITHDRAWAL_REQUEST_CONTRACT_ADDRESS = - Address.fromHexString("0x00A3ca265EBcb825B45F985A16CEFB49958cE017"); - - private static final int ADDRESS_BYTES = 20; - private static final int PUBLIC_KEY_BYTES = 48; - private static final int AMOUNT_BYTES = 8; - private static final int WITHDRAWAL_REQUEST_BYTES_SIZE = - ADDRESS_BYTES + PUBLIC_KEY_BYTES + AMOUNT_BYTES; - - private final Address withdrawalRequestContractAddress; - - public WithdrawalRequestProcessor(final Address withdrawalRequestContractAddress) { - this.withdrawalRequestContractAddress = withdrawalRequestContractAddress; - } - - /** - * Gets the call address for withdrawal requests. - * - * @return The call address. - */ - @Override - protected Address getCallAddress() { - return withdrawalRequestContractAddress; - } - - /** - * Gets the size of the bytes representing a single withdrawal request. - * - * @return The size of the bytes representing a single withdrawal request. - */ - @Override - protected int getRequestBytesSize() { - return WITHDRAWAL_REQUEST_BYTES_SIZE; - } - - /** - * Parses a single withdrawal request from the provided bytes. - * - * @param requestBytes The bytes representing a single withdrawal request. - * @return A parsed {@link WithdrawalRequest} object. - */ - @Override - protected WithdrawalRequest parseRequest(final Bytes requestBytes) { - final Address sourceAddress = Address.wrap(requestBytes.slice(0, ADDRESS_BYTES)); - final BLSPublicKey validatorPublicKey = - BLSPublicKey.wrap(requestBytes.slice(ADDRESS_BYTES, PUBLIC_KEY_BYTES)); - final UInt64 amount = - UInt64.fromBytes(requestBytes.slice(ADDRESS_BYTES + PUBLIC_KEY_BYTES, AMOUNT_BYTES)); - return new WithdrawalRequest(sourceAddress, validatorPublicKey, GWei.of(amount)); - } -} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/WithdrawalRequestValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/WithdrawalRequestValidator.java deleted file mode 100644 index fc108b798f..0000000000 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/WithdrawalRequestValidator.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * 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.requests; - -import static org.hyperledger.besu.ethereum.mainnet.requests.RequestUtil.getWithdrawalRequests; - -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.ethereum.core.Block; -import org.hyperledger.besu.ethereum.core.Request; -import org.hyperledger.besu.ethereum.core.TransactionReceipt; -import org.hyperledger.besu.ethereum.core.WithdrawalRequest; - -import java.util.Collections; -import java.util.List; -import java.util.Optional; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class WithdrawalRequestValidator implements RequestValidator { - - public static final int MAX_WITHDRAWAL_REQUESTS_PER_BLOCK = 16; - - private static final Logger LOG = LoggerFactory.getLogger(WithdrawalRequestValidator.class); - - private boolean validateWithdrawalRequestParameter( - final Optional> withdrawalRequests) { - return withdrawalRequests.isPresent(); - } - - private boolean validateWithdrawalRequestsInBlock( - final Block block, final List withdrawalRequests) { - final Hash blockHash = block.getHash(); - - final List withdrawalRequestsInBlock = - block - .getBody() - .getRequests() - .flatMap(requests -> getWithdrawalRequests(Optional.of(requests))) - .orElse(Collections.emptyList()); - - // TODO Do we need to allow for customization? (e.g. if the value changes in the next fork) - if (withdrawalRequestsInBlock.size() > MAX_WITHDRAWAL_REQUESTS_PER_BLOCK) { - LOG.warn( - "Block {} has more than the allowed maximum number of withdrawal requests", blockHash); - return false; - } - - // Validate WithdrawalRequests - final boolean expectedWithdrawalRequestMatch = - withdrawalRequests.equals(withdrawalRequestsInBlock); - if (!expectedWithdrawalRequestMatch) { - LOG.warn( - "Block {} has a mismatch between its withdrawal requests and expected withdrawal requests (in_block = {}, " - + "expected = {})", - blockHash, - withdrawalRequestsInBlock, - withdrawalRequests); - return false; - } - return true; - } - - @Override - public boolean validate( - final Block block, final List requests, final List receipts) { - var withdrawalRequests = - getWithdrawalRequests(Optional.of(requests)).orElse(Collections.emptyList()); - return validateWithdrawalRequestsInBlock(block, withdrawalRequests); - } - - @Override - public boolean validateParameter(final Optional> request) { - if (request.isEmpty()) { - return false; - } - var withdrawalRequests = - RequestUtil.filterRequestsOfType(request.get(), WithdrawalRequest.class); - return validateWithdrawalRequestParameter(Optional.of(withdrawalRequests)); - } -} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/CallParameter.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/CallParameter.java index 292c65cac6..ce2e63a71a 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/CallParameter.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/CallParameter.java @@ -20,6 +20,7 @@ import org.hyperledger.besu.datatypes.VersionedHash; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.core.Transaction; +import java.math.BigInteger; import java.util.List; import java.util.Objects; import java.util.Optional; @@ -28,6 +29,7 @@ import org.apache.tuweni.bytes.Bytes; // Represents parameters for eth_call and eth_estimateGas JSON-RPC methods. public class CallParameter { + private final Optional chainId; private final Address from; @@ -56,6 +58,7 @@ public class CallParameter { final Wei gasPrice, final Wei value, final Bytes payload) { + this.chainId = Optional.empty(); this.from = from; this.to = to; this.gasLimit = gasLimit; @@ -79,6 +82,7 @@ public class CallParameter { final Wei value, final Bytes payload, final Optional> accessList) { + this.chainId = Optional.empty(); this.from = from; this.to = to; this.gasLimit = gasLimit; @@ -93,6 +97,7 @@ public class CallParameter { } public CallParameter( + final Optional chainId, final Address from, final Address to, final long gasLimit, @@ -104,6 +109,7 @@ public class CallParameter { final Optional> accessList, final Optional maxFeePerBlobGas, final Optional> blobVersionedHashes) { + this.chainId = chainId; this.from = from; this.to = to; this.gasLimit = gasLimit; @@ -117,6 +123,10 @@ public class CallParameter { this.blobVersionedHashes = blobVersionedHashes; } + public Optional getChainId() { + return chainId; + } + public Address getFrom() { return from; } @@ -171,6 +181,7 @@ public class CallParameter { } final CallParameter that = (CallParameter) o; return gasLimit == that.gasLimit + && chainId.equals(that.chainId) && Objects.equals(from, that.from) && Objects.equals(to, that.to) && Objects.equals(gasPrice, that.gasPrice) @@ -186,6 +197,7 @@ public class CallParameter { @Override public int hashCode() { return Objects.hash( + chainId, from, to, gasLimit, @@ -202,7 +214,9 @@ public class CallParameter { @Override public String toString() { return "CallParameter{" - + "from=" + + "chainId=" + + chainId + + ", from=" + from + ", to=" + to @@ -229,6 +243,7 @@ public class CallParameter { public static CallParameter fromTransaction(final Transaction tx) { return new CallParameter( + tx.getChainId(), tx.getSender(), tx.getTo().orElse(null), tx.getGasLimit(), @@ -244,6 +259,7 @@ public class CallParameter { public static CallParameter fromTransaction(final org.hyperledger.besu.datatypes.Transaction tx) { return new CallParameter( + tx.getChainId(), tx.getSender(), tx.getTo().orElse(null), tx.getGasLimit(), diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/TransactionSimulator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/TransactionSimulator.java index 5e78256a78..321dc965ec 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/TransactionSimulator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/TransactionSimulator.java @@ -369,10 +369,13 @@ public class TransactionSimulator { transactionBuilder.maxFeePerBlobGas(maxFeePerBlobGas); } if (transactionBuilder.getTransactionType().requiresChainId()) { - transactionBuilder.chainId( - protocolSchedule - .getChainId() - .orElse(BigInteger.ONE)); // needed to make some transactions valid + callParams + .getChainId() + .ifPresentOrElse( + transactionBuilder::chainId, + () -> + // needed to make some transactions valid + transactionBuilder.chainId(protocolSchedule.getChainId().orElse(BigInteger.ONE))); } final Transaction transaction = transactionBuilder.build(); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/BonsaiWorldStateKeyValueStorage.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/BonsaiWorldStateKeyValueStorage.java index 9f40d2bd35..07ded9ddf6 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/BonsaiWorldStateKeyValueStorage.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/BonsaiWorldStateKeyValueStorage.java @@ -24,9 +24,10 @@ import org.hyperledger.besu.datatypes.StorageSlotKey; import org.hyperledger.besu.ethereum.storage.StorageProvider; import org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier; import org.hyperledger.besu.ethereum.trie.MerkleTrie; +import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.flat.BonsaiFlatDbStrategy; +import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.flat.BonsaiFlatDbStrategyProvider; import org.hyperledger.besu.ethereum.trie.diffbased.common.storage.DiffBasedWorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.trie.diffbased.common.storage.flat.FlatDbStrategy; -import org.hyperledger.besu.ethereum.trie.diffbased.common.storage.flat.FlatDbStrategyProvider; import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; import org.hyperledger.besu.ethereum.worldstate.FlatDbMode; import org.hyperledger.besu.ethereum.worldstate.StateTrieAccountValue; @@ -49,7 +50,7 @@ import org.apache.tuweni.bytes.Bytes32; public class BonsaiWorldStateKeyValueStorage extends DiffBasedWorldStateKeyValueStorage implements WorldStateKeyValueStorage { - protected final FlatDbStrategyProvider flatDbStrategyProvider; + protected final BonsaiFlatDbStrategyProvider flatDbStrategyProvider; public BonsaiWorldStateKeyValueStorage( final StorageProvider provider, @@ -61,12 +62,12 @@ public class BonsaiWorldStateKeyValueStorage extends DiffBasedWorldStateKeyValue ACCOUNT_INFO_STATE, CODE_STORAGE, ACCOUNT_STORAGE_STORAGE, TRIE_BRANCH_STORAGE)), provider.getStorageBySegmentIdentifier(KeyValueSegmentIdentifier.TRIE_LOG_STORAGE)); this.flatDbStrategyProvider = - new FlatDbStrategyProvider(metricsSystem, dataStorageConfiguration); + new BonsaiFlatDbStrategyProvider(metricsSystem, dataStorageConfiguration); flatDbStrategyProvider.loadFlatDbStrategy(composedWorldStateStorage); } public BonsaiWorldStateKeyValueStorage( - final FlatDbStrategyProvider flatDbStrategyProvider, + final BonsaiFlatDbStrategyProvider flatDbStrategyProvider, final SegmentedKeyValueStorage composedWorldStateStorage, final KeyValueStorage trieLogStorage) { super(composedWorldStateStorage, trieLogStorage); @@ -87,15 +88,12 @@ public class BonsaiWorldStateKeyValueStorage extends DiffBasedWorldStateKeyValue if (codeHash.equals(Hash.EMPTY)) { return Optional.of(Bytes.EMPTY); } else { - return flatDbStrategyProvider - .getFlatDbStrategy(composedWorldStateStorage) - .getFlatCode(codeHash, accountHash, composedWorldStateStorage); + return getFlatDbStrategy().getFlatCode(codeHash, accountHash, composedWorldStateStorage); } } public Optional getAccount(final Hash accountHash) { - return flatDbStrategyProvider - .getFlatDbStrategy(composedWorldStateStorage) + return getFlatDbStrategy() .getFlatAccount( this::getWorldStateRootHash, this::getAccountStateTrieNode, @@ -148,8 +146,7 @@ public class BonsaiWorldStateKeyValueStorage extends DiffBasedWorldStateKeyValue final Supplier> storageRootSupplier, final Hash accountHash, final StorageSlotKey storageSlotKey) { - return flatDbStrategyProvider - .getFlatDbStrategy(composedWorldStateStorage) + return getFlatDbStrategy() .getFlatStorageValueByStorageSlotKey( this::getWorldStateRootHash, storageRootSupplier, @@ -180,8 +177,9 @@ public class BonsaiWorldStateKeyValueStorage extends DiffBasedWorldStateKeyValue } @Override - public FlatDbStrategy getFlatDbStrategy() { - return flatDbStrategyProvider.getFlatDbStrategy(composedWorldStateStorage); + public BonsaiFlatDbStrategy getFlatDbStrategy() { + return (BonsaiFlatDbStrategy) + flatDbStrategyProvider.getFlatDbStrategy(composedWorldStateStorage); } @Override @@ -189,7 +187,7 @@ public class BonsaiWorldStateKeyValueStorage extends DiffBasedWorldStateKeyValue return new Updater( composedWorldStateStorage.startTransaction(), trieLogStorage.startTransaction(), - flatDbStrategyProvider.getFlatDbStrategy(composedWorldStateStorage)); + getFlatDbStrategy()); } public static class Updater implements DiffBasedWorldStateKeyValueStorage.Updater { diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/flat/BonsaiFlatDbStrategy.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/flat/BonsaiFlatDbStrategy.java new file mode 100644 index 0000000000..d0330ed244 --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/flat/BonsaiFlatDbStrategy.java @@ -0,0 +1,173 @@ +/* + * 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.storage.flat; + +import static org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier.ACCOUNT_INFO_STATE; +import static org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier.ACCOUNT_STORAGE_STORAGE; +import static org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier.CODE_STORAGE; + +import org.hyperledger.besu.datatypes.Hash; +import org.hyperledger.besu.datatypes.StorageSlotKey; +import org.hyperledger.besu.ethereum.trie.NodeLoader; +import org.hyperledger.besu.ethereum.trie.diffbased.common.storage.flat.CodeStorageStrategy; +import org.hyperledger.besu.ethereum.trie.diffbased.common.storage.flat.FlatDbStrategy; +import org.hyperledger.besu.plugin.services.MetricsSystem; +import org.hyperledger.besu.plugin.services.storage.SegmentedKeyValueStorage; +import org.hyperledger.besu.plugin.services.storage.SegmentedKeyValueStorageTransaction; + +import java.util.Optional; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.stream.Stream; + +import kotlin.Pair; +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; + +/** + * This class represents a FlatDbReaderStrategy, which is responsible for reading and writing data + * from flat databases. It implements various methods for storing and retrieving account data, code + * data, and storage data from the corresponding KeyValueStorage. + */ +public abstract class BonsaiFlatDbStrategy extends FlatDbStrategy { + + public BonsaiFlatDbStrategy( + final MetricsSystem metricsSystem, final CodeStorageStrategy codeStorageStrategy) { + super(metricsSystem, codeStorageStrategy); + } + + /* + * Retrieves the account data for the given account hash, using the world state root hash supplier and node loader. + */ + public abstract Optional getFlatAccount( + Supplier> worldStateRootHashSupplier, + NodeLoader nodeLoader, + Hash accountHash, + SegmentedKeyValueStorage storage); + + /* + * Retrieves the storage value for the given account hash and storage slot key, using the world state root hash supplier, storage root supplier, and node loader. + */ + + public abstract Optional getFlatStorageValueByStorageSlotKey( + Supplier> worldStateRootHashSupplier, + Supplier> storageRootSupplier, + NodeLoader nodeLoader, + Hash accountHash, + StorageSlotKey storageSlotKey, + SegmentedKeyValueStorage storageStorage); + + @Override + public void putFlatAccount( + final SegmentedKeyValueStorageTransaction transaction, + final Hash accountHash, + final Bytes accountValue) { + transaction.put(ACCOUNT_INFO_STATE, accountHash.toArrayUnsafe(), accountValue.toArrayUnsafe()); + } + + @Override + public void removeFlatAccount( + final SegmentedKeyValueStorageTransaction transaction, final Hash accountHash) { + transaction.remove(ACCOUNT_INFO_STATE, accountHash.toArrayUnsafe()); + } + + @Override + public void putFlatAccountStorageValueByStorageSlotHash( + final SegmentedKeyValueStorageTransaction transaction, + final Hash accountHash, + final Hash slotHash, + final Bytes storage) { + transaction.put( + ACCOUNT_STORAGE_STORAGE, + Bytes.concatenate(accountHash, slotHash).toArrayUnsafe(), + storage.toArrayUnsafe()); + } + + @Override + public void removeFlatAccountStorageValueByStorageSlotHash( + final SegmentedKeyValueStorageTransaction transaction, + final Hash accountHash, + final Hash slotHash) { + transaction.remove( + ACCOUNT_STORAGE_STORAGE, Bytes.concatenate(accountHash, slotHash).toArrayUnsafe()); + } + + @Override + public void clearAll(final SegmentedKeyValueStorage storage) { + storage.clear(ACCOUNT_INFO_STATE); + storage.clear(ACCOUNT_STORAGE_STORAGE); + storage.clear(CODE_STORAGE); + } + + @Override + public void resetOnResync(final SegmentedKeyValueStorage storage) { + storage.clear(ACCOUNT_INFO_STATE); + storage.clear(ACCOUNT_STORAGE_STORAGE); + } + + @Override + protected Stream> storageToPairStream( + final SegmentedKeyValueStorage storage, + final Hash accountHash, + final Bytes startKeyHash, + final Function valueMapper) { + + return storage + .streamFromKey( + ACCOUNT_STORAGE_STORAGE, Bytes.concatenate(accountHash, startKeyHash).toArrayUnsafe()) + .takeWhile(pair -> Bytes.wrap(pair.getKey()).slice(0, Hash.SIZE).equals(accountHash)) + .map( + pair -> + new Pair<>( + Bytes32.wrap(Bytes.wrap(pair.getKey()).slice(Hash.SIZE)), + valueMapper.apply(Bytes.wrap(pair.getValue()).trimLeadingZeros()))); + } + + @Override + protected Stream> storageToPairStream( + final SegmentedKeyValueStorage storage, + final Hash accountHash, + final Bytes startKeyHash, + final Bytes32 endKeyHash, + final Function valueMapper) { + + return storage + .streamFromKey( + ACCOUNT_STORAGE_STORAGE, + Bytes.concatenate(accountHash, startKeyHash).toArrayUnsafe(), + Bytes.concatenate(accountHash, endKeyHash).toArrayUnsafe()) + .map( + pair -> + new Pair<>( + Bytes32.wrap(Bytes.wrap(pair.getKey()).slice(Hash.SIZE)), + valueMapper.apply(Bytes.wrap(pair.getValue()).trimLeadingZeros()))); + } + + @Override + protected Stream> accountsToPairStream( + final SegmentedKeyValueStorage storage, final Bytes startKeyHash, final Bytes32 endKeyHash) { + return storage + .streamFromKey(ACCOUNT_INFO_STATE, startKeyHash.toArrayUnsafe(), endKeyHash.toArrayUnsafe()) + .map(pair -> new Pair<>(Bytes32.wrap(pair.getKey()), Bytes.wrap(pair.getValue()))); + } + + @Override + protected Stream> accountsToPairStream( + final SegmentedKeyValueStorage storage, final Bytes startKeyHash) { + return storage + .streamFromKey(ACCOUNT_INFO_STATE, startKeyHash.toArrayUnsafe()) + .map(pair -> new Pair<>(Bytes32.wrap(pair.getKey()), Bytes.wrap(pair.getValue()))); + } +} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/flat/BonsaiFlatDbStrategyProvider.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/flat/BonsaiFlatDbStrategyProvider.java new file mode 100644 index 0000000000..f6157ca2fe --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/flat/BonsaiFlatDbStrategyProvider.java @@ -0,0 +1,88 @@ +/* + * 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.storage.flat; + +import static org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier.TRIE_BRANCH_STORAGE; + +import org.hyperledger.besu.ethereum.trie.diffbased.common.storage.flat.CodeStorageStrategy; +import org.hyperledger.besu.ethereum.trie.diffbased.common.storage.flat.FlatDbStrategy; +import org.hyperledger.besu.ethereum.trie.diffbased.common.storage.flat.FlatDbStrategyProvider; +import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; +import org.hyperledger.besu.ethereum.worldstate.FlatDbMode; +import org.hyperledger.besu.plugin.services.MetricsSystem; +import org.hyperledger.besu.plugin.services.storage.SegmentedKeyValueStorage; +import org.hyperledger.besu.plugin.services.storage.SegmentedKeyValueStorageTransaction; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class BonsaiFlatDbStrategyProvider extends FlatDbStrategyProvider { + + private static final Logger LOG = LoggerFactory.getLogger(BonsaiFlatDbStrategyProvider.class); + + public BonsaiFlatDbStrategyProvider( + final MetricsSystem metricsSystem, final DataStorageConfiguration dataStorageConfiguration) { + super(metricsSystem, dataStorageConfiguration); + } + + @Override + protected FlatDbMode getRequestedFlatDbMode( + final DataStorageConfiguration dataStorageConfiguration) { + return dataStorageConfiguration + .getDiffBasedSubStorageConfiguration() + .getUnstable() + .getFullFlatDbEnabled() + ? FlatDbMode.FULL + : FlatDbMode.PARTIAL; + } + + @Override + protected FlatDbMode alternativeFlatDbModeForExistingDatabase() { + return FlatDbMode.PARTIAL; + } + + public void upgradeToFullFlatDbMode(final SegmentedKeyValueStorage composedWorldStateStorage) { + final SegmentedKeyValueStorageTransaction transaction = + composedWorldStateStorage.startTransaction(); + LOG.info("setting FlatDbStrategy to FULL"); + transaction.put( + TRIE_BRANCH_STORAGE, FLAT_DB_MODE, FlatDbMode.FULL.getVersion().toArrayUnsafe()); + transaction.commit(); + loadFlatDbStrategy(composedWorldStateStorage); // force reload of flat db reader strategy + } + + public void downgradeToPartialFlatDbMode( + final SegmentedKeyValueStorage composedWorldStateStorage) { + final SegmentedKeyValueStorageTransaction transaction = + composedWorldStateStorage.startTransaction(); + LOG.info("setting FlatDbStrategy to PARTIAL"); + transaction.put( + TRIE_BRANCH_STORAGE, FLAT_DB_MODE, FlatDbMode.PARTIAL.getVersion().toArrayUnsafe()); + transaction.commit(); + loadFlatDbStrategy(composedWorldStateStorage); // force reload of flat db reader strategy + } + + @Override + protected FlatDbStrategy createFlatDbStrategy( + final FlatDbMode flatDbMode, + final MetricsSystem metricsSystem, + final CodeStorageStrategy codeStorageStrategy) { + if (flatDbMode == FlatDbMode.FULL) { + return new BonsaiFullFlatDbStrategy(metricsSystem, codeStorageStrategy); + } else { + return new BonsaiPartialFlatDbStrategy(metricsSystem, codeStorageStrategy); + } + } +} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/flat/FullFlatDbStrategy.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/flat/BonsaiFullFlatDbStrategy.java similarity index 95% rename from ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/flat/FullFlatDbStrategy.java rename to ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/flat/BonsaiFullFlatDbStrategy.java index dd4dac5563..7a251a03ae 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/flat/FullFlatDbStrategy.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/flat/BonsaiFullFlatDbStrategy.java @@ -21,7 +21,6 @@ import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.StorageSlotKey; import org.hyperledger.besu.ethereum.trie.NodeLoader; import org.hyperledger.besu.ethereum.trie.diffbased.common.storage.flat.CodeStorageStrategy; -import org.hyperledger.besu.ethereum.trie.diffbased.common.storage.flat.FlatDbStrategy; import org.hyperledger.besu.metrics.BesuMetricCategory; import org.hyperledger.besu.plugin.services.MetricsSystem; import org.hyperledger.besu.plugin.services.metrics.Counter; @@ -32,13 +31,13 @@ import java.util.function.Supplier; import org.apache.tuweni.bytes.Bytes; -public class FullFlatDbStrategy extends FlatDbStrategy { +public class BonsaiFullFlatDbStrategy extends BonsaiFlatDbStrategy { protected final Counter getAccountNotFoundInFlatDatabaseCounter; protected final Counter getStorageValueNotFoundInFlatDatabaseCounter; - public FullFlatDbStrategy( + public BonsaiFullFlatDbStrategy( final MetricsSystem metricsSystem, final CodeStorageStrategy codeStorageStrategy) { super(metricsSystem, codeStorageStrategy); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/flat/PartialFlatDbStrategy.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/flat/BonsaiPartialFlatDbStrategy.java similarity index 97% rename from ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/flat/PartialFlatDbStrategy.java rename to ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/flat/BonsaiPartialFlatDbStrategy.java index 250dc7505c..301536bcc5 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/flat/PartialFlatDbStrategy.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/flat/BonsaiPartialFlatDbStrategy.java @@ -21,7 +21,6 @@ import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.StorageSlotKey; import org.hyperledger.besu.ethereum.trie.NodeLoader; import org.hyperledger.besu.ethereum.trie.diffbased.common.storage.flat.CodeStorageStrategy; -import org.hyperledger.besu.ethereum.trie.diffbased.common.storage.flat.FlatDbStrategy; import org.hyperledger.besu.ethereum.trie.patricia.StoredMerklePatriciaTrie; import org.hyperledger.besu.ethereum.trie.patricia.StoredNodeFactory; import org.hyperledger.besu.metrics.BesuMetricCategory; @@ -45,7 +44,7 @@ import org.apache.tuweni.rlp.RLP; * methods, which checks if the data is present in the flat database, and if not, queries the merkle * trie */ -public class PartialFlatDbStrategy extends FlatDbStrategy { +public class BonsaiPartialFlatDbStrategy extends BonsaiFlatDbStrategy { protected final Counter getAccountMerkleTrieCounter; protected final Counter getAccountMissingMerkleTrieCounter; @@ -53,7 +52,7 @@ public class PartialFlatDbStrategy extends FlatDbStrategy { protected final Counter getStorageValueMerkleTrieCounter; protected final Counter getStorageValueMissingMerkleTrieCounter; - public PartialFlatDbStrategy( + public BonsaiPartialFlatDbStrategy( final MetricsSystem metricsSystem, final CodeStorageStrategy codeStorageStrategy) { super(metricsSystem, codeStorageStrategy); getAccountMerkleTrieCounter = diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/storage/flat/FlatDbStrategy.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/storage/flat/FlatDbStrategy.java index ad631b8da9..046aaa5cc6 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/storage/flat/FlatDbStrategy.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/storage/flat/FlatDbStrategy.java @@ -14,13 +14,7 @@ */ package org.hyperledger.besu.ethereum.trie.diffbased.common.storage.flat; -import static org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier.ACCOUNT_INFO_STATE; -import static org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier.ACCOUNT_STORAGE_STORAGE; -import static org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier.CODE_STORAGE; - import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.datatypes.StorageSlotKey; -import org.hyperledger.besu.ethereum.trie.NodeLoader; import org.hyperledger.besu.metrics.BesuMetricCategory; import org.hyperledger.besu.plugin.services.MetricsSystem; import org.hyperledger.besu.plugin.services.metrics.Counter; @@ -33,7 +27,6 @@ import java.util.Optional; import java.util.TreeMap; import java.util.function.Function; import java.util.function.Predicate; -import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -86,27 +79,6 @@ public abstract class FlatDbStrategy { "Number of storage slots found in the flat database"); } - /* - * Retrieves the account data for the given account hash, using the world state root hash supplier and node loader. - */ - public abstract Optional getFlatAccount( - Supplier> worldStateRootHashSupplier, - NodeLoader nodeLoader, - Hash accountHash, - SegmentedKeyValueStorage storage); - - /* - * Retrieves the storage value for the given account hash and storage slot key, using the world state root hash supplier, storage root supplier, and node loader. - */ - - public abstract Optional getFlatStorageValueByStorageSlotKey( - Supplier> worldStateRootHashSupplier, - Supplier> storageRootSupplier, - NodeLoader nodeLoader, - Hash accountHash, - StorageSlotKey storageSlotKey, - SegmentedKeyValueStorage storageStorage); - public boolean isCodeByCodeHash() { return codeStorageStrategy instanceof CodeHashCodeStorageStrategy; } @@ -124,76 +96,57 @@ public abstract class FlatDbStrategy { } /* - * Puts the account data for the given account hash, using the world state root hash supplier and node loader. + * Removes code for the given account hash. */ - public void putFlatAccount( + public void removeFlatCode( final SegmentedKeyValueStorageTransaction transaction, final Hash accountHash, - final Bytes accountValue) { - transaction.put(ACCOUNT_INFO_STATE, accountHash.toArrayUnsafe(), accountValue.toArrayUnsafe()); - } - - public void removeFlatAccount( - final SegmentedKeyValueStorageTransaction transaction, final Hash accountHash) { - transaction.remove(ACCOUNT_INFO_STATE, accountHash.toArrayUnsafe()); + final Hash codeHash) { + codeStorageStrategy.removeFlatCode(transaction, accountHash, codeHash); } /* - * Puts the storage value for the given account hash and storage slot key, using the world state root hash supplier, storage root supplier, and node loader. + * Puts the code data for the given code hash and account hash. */ - public void putFlatAccountStorageValueByStorageSlotHash( + public void putFlatCode( final SegmentedKeyValueStorageTransaction transaction, final Hash accountHash, - final Hash slotHash, - final Bytes storage) { - transaction.put( - ACCOUNT_STORAGE_STORAGE, - Bytes.concatenate(accountHash, slotHash).toArrayUnsafe(), - storage.toArrayUnsafe()); + final Hash codeHash, + final Bytes code) { + codeStorageStrategy.putFlatCode(transaction, accountHash, codeHash, code); } /* - * Removes the storage value for the given account hash and storage slot key, using the world state root hash supplier, storage root supplier, and node loader. + * Puts the account data for the given account hash, using the world state root hash supplier and node loader. */ - public void removeFlatAccountStorageValueByStorageSlotHash( + public abstract void putFlatAccount( final SegmentedKeyValueStorageTransaction transaction, final Hash accountHash, - final Hash slotHash) { - transaction.remove( - ACCOUNT_STORAGE_STORAGE, Bytes.concatenate(accountHash, slotHash).toArrayUnsafe()); - } + final Bytes accountValue); + + public abstract void removeFlatAccount( + final SegmentedKeyValueStorageTransaction transaction, final Hash accountHash); /* - * Removes code for the given account hash. + * Puts the storage value for the given account hash and storage slot key, using the world state root hash supplier, storage root supplier, and node loader. */ - public void removeFlatCode( + public abstract void putFlatAccountStorageValueByStorageSlotHash( final SegmentedKeyValueStorageTransaction transaction, final Hash accountHash, - final Hash codeHash) { - codeStorageStrategy.removeFlatCode(transaction, accountHash, codeHash); - } + final Hash slotHash, + final Bytes storage); /* - * Puts the code data for the given code hash and account hash. + * Removes the storage value for the given account hash and storage slot key, using the world state root hash supplier, storage root supplier, and node loader. */ - public void putFlatCode( + public abstract void removeFlatAccountStorageValueByStorageSlotHash( final SegmentedKeyValueStorageTransaction transaction, final Hash accountHash, - final Hash codeHash, - final Bytes code) { - codeStorageStrategy.putFlatCode(transaction, accountHash, codeHash, code); - } + final Hash slotHash); - public void clearAll(final SegmentedKeyValueStorage storage) { - storage.clear(ACCOUNT_INFO_STATE); - storage.clear(ACCOUNT_STORAGE_STORAGE); - storage.clear(CODE_STORAGE); - } + public abstract void clearAll(final SegmentedKeyValueStorage storage); - public void resetOnResync(final SegmentedKeyValueStorage storage) { - storage.clear(ACCOUNT_INFO_STATE); - storage.clear(ACCOUNT_STORAGE_STORAGE); - } + public abstract void resetOnResync(final SegmentedKeyValueStorage storage); public NavigableMap streamAccountFlatDatabase( final SegmentedKeyValueStorage storage, @@ -249,57 +202,26 @@ public abstract class FlatDbStrategy { .takeWhile(takeWhile)); } - private static Stream> storageToPairStream( + protected abstract Stream> storageToPairStream( final SegmentedKeyValueStorage storage, final Hash accountHash, final Bytes startKeyHash, - final Function valueMapper) { - - return storage - .streamFromKey( - ACCOUNT_STORAGE_STORAGE, Bytes.concatenate(accountHash, startKeyHash).toArrayUnsafe()) - .takeWhile(pair -> Bytes.wrap(pair.getKey()).slice(0, Hash.SIZE).equals(accountHash)) - .map( - pair -> - new Pair<>( - Bytes32.wrap(Bytes.wrap(pair.getKey()).slice(Hash.SIZE)), - valueMapper.apply(Bytes.wrap(pair.getValue()).trimLeadingZeros()))); - } + final Function valueMapper); - private static Stream> storageToPairStream( + protected abstract Stream> storageToPairStream( final SegmentedKeyValueStorage storage, final Hash accountHash, final Bytes startKeyHash, final Bytes32 endKeyHash, - final Function valueMapper) { - - return storage - .streamFromKey( - ACCOUNT_STORAGE_STORAGE, - Bytes.concatenate(accountHash, startKeyHash).toArrayUnsafe(), - Bytes.concatenate(accountHash, endKeyHash).toArrayUnsafe()) - .map( - pair -> - new Pair<>( - Bytes32.wrap(Bytes.wrap(pair.getKey()).slice(Hash.SIZE)), - valueMapper.apply(Bytes.wrap(pair.getValue()).trimLeadingZeros()))); - } + final Function valueMapper); - private static Stream> accountsToPairStream( - final SegmentedKeyValueStorage storage, final Bytes startKeyHash, final Bytes32 endKeyHash) { - return storage - .streamFromKey(ACCOUNT_INFO_STATE, startKeyHash.toArrayUnsafe(), endKeyHash.toArrayUnsafe()) - .map(pair -> new Pair<>(Bytes32.wrap(pair.getKey()), Bytes.wrap(pair.getValue()))); - } + protected abstract Stream> accountsToPairStream( + final SegmentedKeyValueStorage storage, final Bytes startKeyHash, final Bytes32 endKeyHash); - private static Stream> accountsToPairStream( - final SegmentedKeyValueStorage storage, final Bytes startKeyHash) { - return storage - .streamFromKey(ACCOUNT_INFO_STATE, startKeyHash.toArrayUnsafe()) - .map(pair -> new Pair<>(Bytes32.wrap(pair.getKey()), Bytes.wrap(pair.getValue()))); - } + protected abstract Stream> accountsToPairStream( + final SegmentedKeyValueStorage storage, final Bytes startKeyHash); - private static NavigableMap toNavigableMap( + private NavigableMap toNavigableMap( final Stream> pairStream) { final TreeMap collected = pairStream.collect( diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/storage/flat/FlatDbStrategyProvider.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/storage/flat/FlatDbStrategyProvider.java index 3ce51e793a..31e8598b28 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/storage/flat/FlatDbStrategyProvider.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/storage/flat/FlatDbStrategyProvider.java @@ -18,13 +18,10 @@ import static org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIden import static org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier.TRIE_BRANCH_STORAGE; import static org.hyperledger.besu.ethereum.trie.diffbased.common.storage.DiffBasedWorldStateKeyValueStorage.WORLD_ROOT_HASH_KEY; -import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.flat.FullFlatDbStrategy; -import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.flat.PartialFlatDbStrategy; import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; import org.hyperledger.besu.ethereum.worldstate.FlatDbMode; import org.hyperledger.besu.plugin.services.MetricsSystem; import org.hyperledger.besu.plugin.services.storage.SegmentedKeyValueStorage; -import org.hyperledger.besu.plugin.services.storage.SegmentedKeyValueStorageTransaction; import java.nio.charset.StandardCharsets; import java.util.Optional; @@ -34,7 +31,7 @@ import org.apache.tuweni.bytes.Bytes; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class FlatDbStrategyProvider { +public abstract class FlatDbStrategyProvider { private static final Logger LOG = LoggerFactory.getLogger(FlatDbStrategyProvider.class); // 0x666C61744462537461747573 @@ -61,20 +58,48 @@ public class FlatDbStrategyProvider { deriveUseCodeStorageByHash(composedWorldStateStorage) ? new CodeHashCodeStorageStrategy() : new AccountHashCodeStorageStrategy(); - if (flatDbMode == FlatDbMode.FULL) { - this.flatDbStrategy = new FullFlatDbStrategy(metricsSystem, codeStorageStrategy); - } else { - this.flatDbStrategy = new PartialFlatDbStrategy(metricsSystem, codeStorageStrategy); - } + this.flatDbStrategy = createFlatDbStrategy(flatDbMode, metricsSystem, codeStorageStrategy); } } + protected boolean deriveUseCodeStorageByHash( + final SegmentedKeyValueStorage composedWorldStateStorage) { + final boolean configCodeUsingHash = + dataStorageConfiguration + .getDiffBasedSubStorageConfiguration() + .getUnstable() + .getCodeStoredByCodeHashEnabled(); + boolean codeUsingCodeByHash = + detectCodeStorageByHash(composedWorldStateStorage) + .map( + dbCodeUsingHash -> { + if (dbCodeUsingHash != configCodeUsingHash) { + LOG.warn( + "Bonsai db is using code storage mode {} but config specifies mode {}. Using mode from database", + dbCodeUsingHash, + configCodeUsingHash); + } + return dbCodeUsingHash; + }) + .orElse(configCodeUsingHash); + LOG.info("DB mode with code stored using code hash enabled = {}", codeUsingCodeByHash); + return codeUsingCodeByHash; + } + + private Optional detectCodeStorageByHash( + final SegmentedKeyValueStorage composedWorldStateStorage) { + return composedWorldStateStorage.stream(CODE_STORAGE) + .limit(1) + .findFirst() + .map( + keypair -> + CodeHashCodeStorageStrategy.isCodeHashValue(keypair.getKey(), keypair.getValue())); + } + @VisibleForTesting - FlatDbMode deriveFlatDbStrategy(final SegmentedKeyValueStorage composedWorldStateStorage) { - final FlatDbMode requestedFlatDbMode = - dataStorageConfiguration.getUnstable().getBonsaiFullFlatDbEnabled() - ? FlatDbMode.FULL - : FlatDbMode.PARTIAL; + private FlatDbMode deriveFlatDbStrategy( + final SegmentedKeyValueStorage composedWorldStateStorage) { + final FlatDbMode requestedFlatDbMode = getRequestedFlatDbMode(dataStorageConfiguration); final var existingTrieData = composedWorldStateStorage.get(TRIE_BRANCH_STORAGE, WORLD_ROOT_HASH_KEY).isPresent(); @@ -91,7 +116,7 @@ public class FlatDbStrategyProvider { // and default to the storage config otherwise var flatDbModeVal = existingTrieData - ? FlatDbMode.PARTIAL.getVersion() + ? alternativeFlatDbModeForExistingDatabase().getVersion() : requestedFlatDbMode.getVersion(); // persist this config in the db var setDbModeTx = composedWorldStateStorage.startTransaction(); @@ -101,42 +126,11 @@ public class FlatDbStrategyProvider { return flatDbModeVal; })); - LOG.info("Bonsai flat db mode found {}", flatDbMode); + LOG.info("Flat db mode found {}", flatDbMode); return flatDbMode; } - protected boolean deriveUseCodeStorageByHash( - final SegmentedKeyValueStorage composedWorldStateStorage) { - final boolean configCodeUsingHash = - dataStorageConfiguration.getUnstable().getBonsaiCodeStoredByCodeHashEnabled(); - boolean codeUsingCodeByHash = - detectCodeStorageByHash(composedWorldStateStorage) - .map( - dbCodeUsingHash -> { - if (dbCodeUsingHash != configCodeUsingHash) { - LOG.warn( - "Bonsai db is using code storage mode {} but config specifies mode {}. Using mode from database", - dbCodeUsingHash, - configCodeUsingHash); - } - return dbCodeUsingHash; - }) - .orElse(configCodeUsingHash); - LOG.info("Bonsai db mode with code stored using code hash enabled = {}", codeUsingCodeByHash); - return codeUsingCodeByHash; - } - - private Optional detectCodeStorageByHash( - final SegmentedKeyValueStorage composedWorldStateStorage) { - return composedWorldStateStorage.stream(CODE_STORAGE) - .limit(1) - .findFirst() - .map( - keypair -> - CodeHashCodeStorageStrategy.isCodeHashValue(keypair.getKey(), keypair.getValue())); - } - public FlatDbStrategy getFlatDbStrategy( final SegmentedKeyValueStorage composedWorldStateStorage) { if (flatDbStrategy == null) { @@ -145,28 +139,17 @@ public class FlatDbStrategyProvider { return flatDbStrategy; } - public void upgradeToFullFlatDbMode(final SegmentedKeyValueStorage composedWorldStateStorage) { - final SegmentedKeyValueStorageTransaction transaction = - composedWorldStateStorage.startTransaction(); - LOG.info("setting FlatDbStrategy to FULL"); - transaction.put( - TRIE_BRANCH_STORAGE, FLAT_DB_MODE, FlatDbMode.FULL.getVersion().toArrayUnsafe()); - transaction.commit(); - loadFlatDbStrategy(composedWorldStateStorage); // force reload of flat db reader strategy - } - - public void downgradeToPartialFlatDbMode( - final SegmentedKeyValueStorage composedWorldStateStorage) { - final SegmentedKeyValueStorageTransaction transaction = - composedWorldStateStorage.startTransaction(); - LOG.info("setting FlatDbStrategy to PARTIAL"); - transaction.put( - TRIE_BRANCH_STORAGE, FLAT_DB_MODE, FlatDbMode.PARTIAL.getVersion().toArrayUnsafe()); - transaction.commit(); - loadFlatDbStrategy(composedWorldStateStorage); // force reload of flat db reader strategy - } - public FlatDbMode getFlatDbMode() { return flatDbMode; } + + protected abstract FlatDbMode getRequestedFlatDbMode( + final DataStorageConfiguration dataStorageConfiguration); + + protected abstract FlatDbMode alternativeFlatDbModeForExistingDatabase(); + + protected abstract FlatDbStrategy createFlatDbStrategy( + final FlatDbMode flatDbMode, + final MetricsSystem metricsSystem, + final CodeStorageStrategy codeStorageStrategy); } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/verkle/storage/VerkleWorldStateKeyValueStorage.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/verkle/storage/VerkleWorldStateKeyValueStorage.java index 46088e1a0f..8cc40c4d8b 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/verkle/storage/VerkleWorldStateKeyValueStorage.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/verkle/storage/VerkleWorldStateKeyValueStorage.java @@ -23,7 +23,8 @@ import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.StorageSlotKey; import org.hyperledger.besu.ethereum.storage.StorageProvider; import org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier; -import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.flat.FullFlatDbStrategy; +import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.flat.BonsaiFlatDbStrategy; +import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.flat.BonsaiFullFlatDbStrategy; import org.hyperledger.besu.ethereum.trie.diffbased.common.storage.DiffBasedWorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.trie.diffbased.common.storage.flat.CodeHashCodeStorageStrategy; import org.hyperledger.besu.ethereum.trie.diffbased.common.storage.flat.FlatDbStrategy; @@ -45,7 +46,7 @@ import org.apache.tuweni.bytes.Bytes32; public class VerkleWorldStateKeyValueStorage extends DiffBasedWorldStateKeyValueStorage implements WorldStateKeyValueStorage { - protected FullFlatDbStrategy flatDbStrategy; + protected BonsaiFullFlatDbStrategy flatDbStrategy; public VerkleWorldStateKeyValueStorage( final StorageProvider provider, final MetricsSystem metricsSystem) { @@ -54,11 +55,11 @@ public class VerkleWorldStateKeyValueStorage extends DiffBasedWorldStateKeyValue List.of( ACCOUNT_INFO_STATE, CODE_STORAGE, ACCOUNT_STORAGE_STORAGE, TRIE_BRANCH_STORAGE)), provider.getStorageBySegmentIdentifier(KeyValueSegmentIdentifier.TRIE_LOG_STORAGE)); - this.flatDbStrategy = new FullFlatDbStrategy(metricsSystem, new CodeHashCodeStorageStrategy()); + this.flatDbStrategy = new BonsaiFullFlatDbStrategy(metricsSystem, new CodeHashCodeStorageStrategy()); } public VerkleWorldStateKeyValueStorage( - final FullFlatDbStrategy flatDbStrategy, + final BonsaiFullFlatDbStrategy flatDbStrategy, final SegmentedKeyValueStorage composedWorldStateStorage, final KeyValueStorage trieLogStorage) { super(composedWorldStateStorage, trieLogStorage); @@ -66,7 +67,7 @@ public class VerkleWorldStateKeyValueStorage extends DiffBasedWorldStateKeyValue } @Override - public FlatDbStrategy getFlatDbStrategy() { + public BonsaiFlatDbStrategy getFlatDbStrategy() { return flatDbStrategy; } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/worldstate/DataStorageConfiguration.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/worldstate/DataStorageConfiguration.java index 320e38733d..9ce059e94c 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/worldstate/DataStorageConfiguration.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/worldstate/DataStorageConfiguration.java @@ -14,6 +14,7 @@ */ package org.hyperledger.besu.ethereum.worldstate; +import org.hyperledger.besu.ethereum.worldstate.DiffBasedSubStorageConfiguration.DiffBasedUnstable; import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; import org.immutables.value.Value; @@ -22,90 +23,40 @@ import org.immutables.value.Value; @Value.Enclosing public interface DataStorageConfiguration { - long DEFAULT_BONSAI_MAX_LAYERS_TO_LOAD = 512; - boolean DEFAULT_BONSAI_LIMIT_TRIE_LOGS_ENABLED = true; - long MINIMUM_BONSAI_TRIE_LOG_RETENTION_LIMIT = DEFAULT_BONSAI_MAX_LAYERS_TO_LOAD; - int DEFAULT_BONSAI_TRIE_LOG_PRUNING_WINDOW_SIZE = 5_000; boolean DEFAULT_RECEIPT_COMPACTION_ENABLED = true; DataStorageConfiguration DEFAULT_CONFIG = ImmutableDataStorageConfiguration.builder() .dataStorageFormat(DataStorageFormat.BONSAI) - .bonsaiMaxLayersToLoad(DEFAULT_BONSAI_MAX_LAYERS_TO_LOAD) - .unstable(Unstable.DEFAULT) + .diffBasedSubStorageConfiguration(DiffBasedSubStorageConfiguration.DEFAULT) .build(); - DataStorageConfiguration DEFAULT_BONSAI_CONFIG = - ImmutableDataStorageConfiguration.builder() - .dataStorageFormat(DataStorageFormat.BONSAI) - .bonsaiMaxLayersToLoad(DEFAULT_BONSAI_MAX_LAYERS_TO_LOAD) - .build(); + DataStorageConfiguration DEFAULT_BONSAI_CONFIG = DEFAULT_CONFIG; DataStorageConfiguration DEFAULT_BONSAI_PARTIAL_DB_CONFIG = ImmutableDataStorageConfiguration.builder() .dataStorageFormat(DataStorageFormat.BONSAI) - .bonsaiMaxLayersToLoad(DEFAULT_BONSAI_MAX_LAYERS_TO_LOAD) - .unstable(Unstable.DEFAULT_PARTIAL) + .diffBasedSubStorageConfiguration( + ImmutableDiffBasedSubStorageConfiguration.builder() + .unstable(DiffBasedUnstable.PARTIAL_MODE) + .build()) .build(); DataStorageConfiguration DEFAULT_FOREST_CONFIG = ImmutableDataStorageConfiguration.builder() .dataStorageFormat(DataStorageFormat.FOREST) - .bonsaiMaxLayersToLoad(DEFAULT_BONSAI_MAX_LAYERS_TO_LOAD) - .unstable(Unstable.DEFAULT) + .diffBasedSubStorageConfiguration(DiffBasedSubStorageConfiguration.DISABLED) .build(); DataStorageFormat getDataStorageFormat(); - Long getBonsaiMaxLayersToLoad(); - - @Value.Default - default boolean getBonsaiLimitTrieLogsEnabled() { - return DEFAULT_BONSAI_LIMIT_TRIE_LOGS_ENABLED; - } - @Value.Default - default int getBonsaiTrieLogPruningWindowSize() { - return DEFAULT_BONSAI_TRIE_LOG_PRUNING_WINDOW_SIZE; + default DiffBasedSubStorageConfiguration getDiffBasedSubStorageConfiguration() { + return DiffBasedSubStorageConfiguration.DEFAULT; } @Value.Default default boolean getReceiptCompactionEnabled() { return DEFAULT_RECEIPT_COMPACTION_ENABLED; } - - @Value.Default - default Unstable getUnstable() { - return Unstable.DEFAULT; - } - - @Value.Immutable - interface Unstable { - - boolean DEFAULT_BONSAI_FULL_FLAT_DB_ENABLED = true; - boolean DEFAULT_BONSAI_CODE_USING_CODE_HASH_ENABLED = true; - - boolean DEFAULT_PARALLEL_TRX_ENABLED = false; - - DataStorageConfiguration.Unstable DEFAULT = - ImmutableDataStorageConfiguration.Unstable.builder().build(); - - DataStorageConfiguration.Unstable DEFAULT_PARTIAL = - ImmutableDataStorageConfiguration.Unstable.builder().bonsaiFullFlatDbEnabled(false).build(); - - @Value.Default - default boolean getBonsaiFullFlatDbEnabled() { - return DEFAULT_BONSAI_FULL_FLAT_DB_ENABLED; - } - - @Value.Default - default boolean getBonsaiCodeStoredByCodeHashEnabled() { - return DEFAULT_BONSAI_CODE_USING_CODE_HASH_ENABLED; - } - - @Value.Default - default boolean isParallelTxProcessingEnabled() { - return DEFAULT_PARALLEL_TRX_ENABLED; - } - } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/worldstate/DiffBasedSubStorageConfiguration.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/worldstate/DiffBasedSubStorageConfiguration.java new file mode 100644 index 0000000000..fc0f98e21d --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/worldstate/DiffBasedSubStorageConfiguration.java @@ -0,0 +1,95 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.worldstate; + +import org.immutables.value.Value; + +@Value.Immutable +@Value.Enclosing +public interface DiffBasedSubStorageConfiguration { + + DiffBasedSubStorageConfiguration DEFAULT = + ImmutableDiffBasedSubStorageConfiguration.builder().build(); + + DiffBasedSubStorageConfiguration DISABLED = + ImmutableDiffBasedSubStorageConfiguration.builder() + .limitTrieLogsEnabled(false) + .unstable(DiffBasedUnstable.DISABLED) + .build(); + + long DEFAULT_MAX_LAYERS_TO_LOAD = 512; + boolean DEFAULT_LIMIT_TRIE_LOGS_ENABLED = true; + long MINIMUM_TRIE_LOG_RETENTION_LIMIT = DEFAULT_MAX_LAYERS_TO_LOAD; + int DEFAULT_TRIE_LOG_PRUNING_WINDOW_SIZE = 5_000; + + @Value.Default + default Long getMaxLayersToLoad() { + return DEFAULT_MAX_LAYERS_TO_LOAD; + } + + @Value.Default + default boolean getLimitTrieLogsEnabled() { + return DEFAULT_LIMIT_TRIE_LOGS_ENABLED; + } + + @Value.Default + default int getTrieLogPruningWindowSize() { + return DEFAULT_TRIE_LOG_PRUNING_WINDOW_SIZE; + } + + @Value.Default + default DiffBasedUnstable getUnstable() { + return DiffBasedUnstable.DEFAULT; + } + + @Value.Immutable + interface DiffBasedUnstable { + + DiffBasedSubStorageConfiguration.DiffBasedUnstable DEFAULT = + ImmutableDiffBasedSubStorageConfiguration.DiffBasedUnstable.builder().build(); + + DiffBasedSubStorageConfiguration.DiffBasedUnstable PARTIAL_MODE = + ImmutableDiffBasedSubStorageConfiguration.DiffBasedUnstable.builder() + .fullFlatDbEnabled(false) + .build(); + + DiffBasedSubStorageConfiguration.DiffBasedUnstable DISABLED = + ImmutableDiffBasedSubStorageConfiguration.DiffBasedUnstable.builder() + .fullFlatDbEnabled(false) + .codeStoredByCodeHashEnabled(false) + .isParallelTxProcessingEnabled(false) + .build(); + + boolean DEFAULT_FULL_FLAT_DB_ENABLED = true; + boolean DEFAULT_CODE_USING_CODE_HASH_ENABLED = true; + + boolean DEFAULT_PARALLEL_TRX_ENABLED = false; + + @Value.Default + default boolean getFullFlatDbEnabled() { + return DEFAULT_FULL_FLAT_DB_ENABLED; + } + + @Value.Default + default boolean getCodeStoredByCodeHashEnabled() { + return DEFAULT_CODE_USING_CODE_HASH_ENABLED; + } + + @Value.Default + default boolean isParallelTxProcessingEnabled() { + return DEFAULT_PARALLEL_TRX_ENABLED; + } + } +} diff --git a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlobTestFixture.java b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlobTestFixture.java index 21e8630c84..9c3f62126f 100644 --- a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlobTestFixture.java +++ b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlobTestFixture.java @@ -23,8 +23,6 @@ import org.hyperledger.besu.datatypes.KZGProof; import org.hyperledger.besu.datatypes.VersionedHash; import org.hyperledger.besu.evm.precompile.KZGPointEvalPrecompiledContract; -import java.io.IOException; -import java.io.InputStream; import java.util.ArrayList; import java.util.List; @@ -36,6 +34,8 @@ import org.bouncycastle.crypto.digests.SHA256Digest; public class BlobTestFixture { + private byte byteValue = 0x00; + public BlobTestFixture() { try { // optimistically tear down a potential previous loaded trusted setup @@ -58,14 +58,8 @@ public class BlobTestFixture { ; public BlobTriplet createBlobTriplet() { - byte[] rawMaterial = {}; - try (InputStream readme = - BlobTestFixture.class.getResourceAsStream( - "/org/hyperledger/besu/ethereum/core/encoding/BlobDataFixture.bin")) { - rawMaterial = readme.readAllBytes(); - } catch (IOException e) { - fail("Failed to read blob file", e); - } + byte[] rawMaterial = new byte[131072]; + rawMaterial[0] = byteValue++; Bytes48 commitment = Bytes48.wrap(CKZG4844JNI.blobToKzgCommitment(rawMaterial)); diff --git a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlockDataGenerator.java b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlockDataGenerator.java index ea62d7f1fa..acbd8679f4 100644 --- a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlockDataGenerator.java +++ b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlockDataGenerator.java @@ -303,7 +303,7 @@ public class BlockDataGenerator { .mixHash(hash()) .nonce(blockNonce) .withdrawalsRoot(options.getWithdrawalsRoot(null)) - .requestsRoot(options.getRequestsRoot(null)) + .requestsHash(options.getRequestsHash(null)) .blockHeaderFunctions( options.getBlockHeaderFunctions(new MainnetBlockHeaderFunctions())); options.getBaseFee(Optional.of(Wei.of(uint256(2)))).ifPresent(blockHeaderBuilder::baseFee); @@ -329,10 +329,7 @@ public class BlockDataGenerator { } return new BlockBody( - options.getTransactions(defaultTxs), - ommers, - options.getWithdrawals(Optional.empty()), - options.getRequests(Optional.empty())); + options.getTransactions(defaultTxs), ommers, options.getWithdrawals(Optional.empty())); } private BlockHeader ommer() { @@ -655,7 +652,7 @@ public class BlockDataGenerator { private Optional> maybeBaseFee = Optional.empty(); private Optional withdrawalsRoot = Optional.empty(); - private Optional requestsRoot = Optional.empty(); + private Optional requestsHash = Optional.empty(); private Optional> maybeMaxFeePerBlobGas = Optional.empty(); @@ -724,8 +721,8 @@ public class BlockDataGenerator { return withdrawals.orElse(defaultValue); } - public Hash getRequestsRoot(final Hash defaultValue) { - return requestsRoot.orElse(defaultValue); + public Hash getRequestsHash(final Hash defaultValue) { + return requestsHash.orElse(defaultValue); } public Optional> getRequests(final Optional> defaultValue) { @@ -852,8 +849,8 @@ public class BlockDataGenerator { return this; } - public BlockOptions setRequestsRoot(final Hash requestsRoot) { - this.requestsRoot = Optional.of(requestsRoot); + public BlockOptions setRequestsHash(final Hash requestsHash) { + this.requestsHash = Optional.of(requestsHash); return this; } diff --git a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlockHeaderTestFixture.java b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlockHeaderTestFixture.java index 44a4ffd060..b0b9aa6497 100644 --- a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlockHeaderTestFixture.java +++ b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlockHeaderTestFixture.java @@ -25,6 +25,7 @@ import java.util.Optional; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; +import org.apache.tuweni.units.bigints.UInt64; public class BlockHeaderTestFixture { @@ -50,11 +51,12 @@ public class BlockHeaderTestFixture { private Hash mixHash = Hash.EMPTY; private long nonce = 0; private Optional withdrawalsRoot = Optional.empty(); - private Optional requestsRoot = Optional.empty(); + private Optional requestsHash = Optional.empty(); private BlockHeaderFunctions blockHeaderFunctions = new MainnetBlockHeaderFunctions(); private Optional excessBlobGas = Optional.empty(); private Optional blobGasUsed = Optional.empty(); private Optional parentBeaconBlockRoot = Optional.empty(); + private Optional targetBlobCount = Optional.empty(); public BlockHeader buildHeader() { final BlockHeaderBuilder builder = BlockHeaderBuilder.create(); @@ -78,8 +80,9 @@ public class BlockHeaderTestFixture { withdrawalsRoot.ifPresent(builder::withdrawalsRoot); excessBlobGas.ifPresent(builder::excessBlobGas); blobGasUsed.ifPresent(builder::blobGasUsed); - requestsRoot.ifPresent(builder::requestsRoot); + requestsHash.ifPresent(builder::requestsHash); parentBeaconBlockRoot.ifPresent(builder::parentBeaconBlockRoot); + targetBlobCount.ifPresent(builder::targetBlobCount); builder.blockHeaderFunctions(blockHeaderFunctions); return builder.buildBlockHeader(); @@ -175,8 +178,8 @@ public class BlockHeaderTestFixture { return this; } - public BlockHeaderTestFixture requestsRoot(final Hash requestsRoot) { - this.requestsRoot = Optional.ofNullable(requestsRoot); + public BlockHeaderTestFixture requestsHash(final Hash requestsHash) { + this.requestsHash = Optional.ofNullable(requestsHash); return this; } @@ -201,4 +204,9 @@ public class BlockHeaderTestFixture { this.parentBeaconBlockRoot = parentBeaconBlockRoot; return this; } + + public BlockHeaderTestFixture targetBlobCount(final UInt64 targetBlobCount) { + this.targetBlobCount = Optional.of(targetBlobCount); + return this; + } } diff --git a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlockchainSetupUtil.java b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlockchainSetupUtil.java index 62d670c07a..7be6ad12c4 100644 --- a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlockchainSetupUtil.java +++ b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlockchainSetupUtil.java @@ -194,6 +194,7 @@ public class BlockchainSetupUtil { genesisState.writeStateTo(worldArchive.getMutable()); final ProtocolContext protocolContext = protocolContextProvider.get(blockchain, worldArchive); + protocolContext.setSynchronizer(new DummySynchronizer()); final Path blocksPath = Path.of(chainResources.getBlocksURL().toURI()); final List blocks = new ArrayList<>(); diff --git a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/DummySynchronizer.java b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/DummySynchronizer.java similarity index 89% rename from ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/DummySynchronizer.java rename to ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/DummySynchronizer.java index b8d90e9974..0de02d6d52 100644 --- a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/DummySynchronizer.java +++ b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/DummySynchronizer.java @@ -12,10 +12,9 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.ethereum.retesteth; +package org.hyperledger.besu.ethereum.core; import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.ethereum.core.Synchronizer; import org.hyperledger.besu.plugin.data.SyncStatus; import org.hyperledger.besu.plugin.services.BesuEvents; @@ -81,4 +80,14 @@ public class DummySynchronizer implements Synchronizer { public boolean unsubscribeInSync(final long listenerId) { return false; } + + @Override + public long subscribeInitialSync(final BesuEvents.InitialSyncCompletionListener listener) { + return 0; + } + + @Override + public boolean unsubscribeInitialSync(final long listenerId) { + return false; + } } diff --git a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/InMemoryKeyValueStorageProvider.java b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/InMemoryKeyValueStorageProvider.java index 7e7858f215..29e399effb 100644 --- a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/InMemoryKeyValueStorageProvider.java +++ b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/InMemoryKeyValueStorageProvider.java @@ -14,8 +14,6 @@ */ package org.hyperledger.besu.ethereum.core; -import static org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration.DEFAULT_BONSAI_MAX_LAYERS_TO_LOAD; - import org.hyperledger.besu.ethereum.chain.Blockchain; import org.hyperledger.besu.ethereum.chain.DefaultBlockchain; import org.hyperledger.besu.ethereum.chain.MutableBlockchain; @@ -36,6 +34,7 @@ import org.hyperledger.besu.ethereum.trie.forest.ForestWorldStateArchive; import org.hyperledger.besu.ethereum.trie.forest.storage.ForestWorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.trie.forest.worldview.ForestMutableWorldState; import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; +import org.hyperledger.besu.ethereum.worldstate.DiffBasedSubStorageConfiguration; import org.hyperledger.besu.ethereum.worldstate.ImmutableDataStorageConfiguration; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; import org.hyperledger.besu.evm.internal.EvmConfiguration; @@ -126,8 +125,7 @@ public class InMemoryKeyValueStorageProvider extends KeyValueStorageProvider { final DataStorageConfiguration verkleDataStorageConfig = ImmutableDataStorageConfiguration.builder() .dataStorageFormat(DataStorageFormat.VERKLE) - .bonsaiMaxLayersToLoad(DEFAULT_BONSAI_MAX_LAYERS_TO_LOAD) - .unstable(DataStorageConfiguration.Unstable.DEFAULT) + .diffBasedSubStorageConfiguration(DiffBasedSubStorageConfiguration.DEFAULT) .build(); return new VerkleWorldStateProvider( (VerkleWorldStateKeyValueStorage) diff --git a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/NonBesuBlockHeader.java b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/NonBesuBlockHeader.java index 14acd8f9ca..f0f92cac43 100644 --- a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/NonBesuBlockHeader.java +++ b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/NonBesuBlockHeader.java @@ -115,7 +115,7 @@ public class NonBesuBlockHeader implements BlockHeader { } @Override - public Optional getRequestsRoot() { + public Optional getRequestsHash() { return Optional.empty(); } diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/BlockImportExceptionHandlingTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/BlockImportExceptionHandlingTest.java index d3a261803f..f9a325f3d7 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/BlockImportExceptionHandlingTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/BlockImportExceptionHandlingTest.java @@ -42,7 +42,6 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; 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.storage.StorageProvider; import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.BonsaiWorldStateProvider; import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.BonsaiWorldStateKeyValueStorage; @@ -117,8 +116,6 @@ class BlockImportExceptionHandlingTest { when(protocolContext.getBlockchain()).thenReturn(blockchain); when(protocolContext.getWorldStateArchive()).thenReturn(worldStateArchive); when(protocolSchedule.getByBlockHeader(any())).thenReturn(protocolSpec); - when(protocolSpec.getRequestsValidatorCoordinator()) - .thenReturn(RequestsValidatorCoordinator.empty()); when(protocolSpec.getBlockHashProcessor()).thenReturn(new FrontierBlockHashProcessor()); when(protocolSpec.getGasCalculator()).thenReturn(gasCalculator); when(protocolSpec.getFeeMarket()).thenReturn(feeMarket); @@ -156,7 +153,6 @@ class BlockImportExceptionHandlingTest { eq(goodBlock), any(), any(), - any(), eq(HeaderValidationMode.DETACHED_ONLY))) .thenReturn(true); assertThat(badBlockManager.getBadBlocks()).isEmpty(); @@ -193,7 +189,6 @@ class BlockImportExceptionHandlingTest { eq(goodBlock), any(), any(), - any(), eq(HeaderValidationMode.DETACHED_ONLY))) .thenReturn(true); assertThat(badBlockManager.getBadBlocks()).isEmpty(); @@ -262,7 +257,6 @@ class BlockImportExceptionHandlingTest { eq(goodBlock), any(), any(), - any(), eq(HeaderValidationMode.DETACHED_ONLY))) .thenThrow(new StorageException("database problem")); assertThat(badBlockManager.getBadBlocks()).isEmpty(); diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/MainnetBlockValidatorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/MainnetBlockValidatorTest.java index 40573ee8d6..013adae51e 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/MainnetBlockValidatorTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/MainnetBlockValidatorTest.java @@ -31,6 +31,7 @@ import org.hyperledger.besu.ethereum.core.Block; import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.BlockchainSetupUtil; import org.hyperledger.besu.ethereum.core.MutableWorldState; +import org.hyperledger.besu.ethereum.core.Synchronizer; import org.hyperledger.besu.ethereum.mainnet.BlockBodyValidator; import org.hyperledger.besu.ethereum.mainnet.BlockHeaderValidator; import org.hyperledger.besu.ethereum.mainnet.BlockProcessor; @@ -90,6 +91,7 @@ public class MainnetBlockValidatorTest { when(protocolContext.getBlockchain()).thenReturn(blockchain); when(protocolContext.getWorldStateArchive()).thenReturn(worldStateArchive); + when(protocolContext.getSynchronizer()).thenReturn(mock(Synchronizer.class)); when(worldStateArchive.getMutable(any(BlockHeader.class), anyBoolean())) .thenReturn(Optional.of(worldState)); when(worldStateArchive.getMutable(any(Hash.class), any(Hash.class))) @@ -97,10 +99,8 @@ public class MainnetBlockValidatorTest { when(worldStateArchive.getMutable()).thenReturn(worldState); when(blockHeaderValidator.validateHeader(any(), any(), any())).thenReturn(true); when(blockHeaderValidator.validateHeader(any(), any(), any(), any())).thenReturn(true); - when(blockBodyValidator.validateBody(any(), any(), any(), any(), any(), any())) - .thenReturn(true); - when(blockBodyValidator.validateBodyLight(any(), any(), any(), any(), any(), any())) - .thenReturn(true); + when(blockBodyValidator.validateBody(any(), any(), any(), any(), any())).thenReturn(true); + when(blockBodyValidator.validateBodyLight(any(), any(), any(), any(), any())).thenReturn(true); when(blockProcessor.processBlock(any(), any(), any())).thenReturn(successfulProcessingResult); when(blockProcessor.processBlock(any(), any(), any(), any())) .thenReturn(successfulProcessingResult); @@ -165,8 +165,7 @@ public class MainnetBlockValidatorTest { @Test public void validateAndProcessBlock_whenBlockBodyInvalid() { - when(blockBodyValidator.validateBody(any(), eq(block), any(), any(), any(), any())) - .thenReturn(false); + when(blockBodyValidator.validateBody(any(), eq(block), any(), any(), any())).thenReturn(false); BlockProcessingResult result = mainnetBlockValidator.validateAndProcessBlock( @@ -351,7 +350,6 @@ public class MainnetBlockValidatorTest { protocolContext, block, Collections.emptyList(), - block.getBody().getRequests(), HeaderValidationMode.FULL, HeaderValidationMode.FULL, BodyValidationMode.FULL); @@ -373,7 +371,6 @@ public class MainnetBlockValidatorTest { protocolContext, block, Collections.emptyList(), - block.getBody().getRequests(), headerValidationMode, headerValidationMode, bodyValidationMode); @@ -390,7 +387,6 @@ public class MainnetBlockValidatorTest { eq(protocolContext), eq(block), any(), - any(), eq(headerValidationMode), eq(bodyValidationMode))) .thenReturn(false); @@ -400,7 +396,6 @@ public class MainnetBlockValidatorTest { protocolContext, block, Collections.emptyList(), - block.getBody().getRequests(), headerValidationMode, headerValidationMode, bodyValidationMode); diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/chain/GenesisStateTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/chain/GenesisStateTest.java index 70c1e64bd1..83c0f1a4c4 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/chain/GenesisStateTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/chain/GenesisStateTest.java @@ -31,6 +31,7 @@ import java.util.stream.Stream; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.units.bigints.UInt256; +import org.apache.tuweni.units.bigints.UInt64; import org.bouncycastle.util.encoders.Hex; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtensionContext; @@ -275,7 +276,7 @@ final class GenesisStateTest { assertThat(last).isNotNull(); Wei lastBalance = last.getBalance(); assertThat(lastBalance).isEqualTo(Wei.fromHexString("0x123450000000000000000")); - assertThat(header.getRequestsRoot().isPresent()).isFalse(); + assertThat(header.getRequestsHash().isPresent()).isFalse(); } @ParameterizedTest @@ -287,10 +288,6 @@ final class GenesisStateTest { GenesisStateTest.class.getResource("genesis_prague.json"), ProtocolScheduleFixture.MAINNET); final BlockHeader header = genesisState.getBlock().getHeader(); - assertThat(header.getHash()) - .isEqualTo( - Hash.fromHexString( - "0xaad700fd347070b47165c299dd5b843d0a47d4eaee12d3414a5cb58c5c8a8fe4")); assertThat(header.getGasLimit()).isEqualTo(0x2fefd8); assertThat(header.getGasUsed()).isZero(); assertThat(header.getNumber()).isZero(); @@ -326,11 +323,18 @@ final class GenesisStateTest { Wei lastBalance = last.getBalance(); assertThat(lastBalance).isEqualTo(Wei.fromHexString("0x123450000000000000000")); - assertThat(header.getRequestsRoot().isPresent()).isTrue(); - assertThat(header.getRequestsRoot().get()) + assertThat(header.getRequestsHash().isPresent()).isTrue(); + assertThat(header.getRequestsHash().get()) .isEqualTo( Hash.fromHexString( - "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")); + "0x6036c41849da9c076ed79654d434017387a88fb833c2856b32e18218b3341c5f")); + assertThat(header.getTargetBlobCount().isPresent()).isTrue(); + assertThat(header.getTargetBlobCount().get()).isEqualTo(UInt64.ONE); + + assertThat(header.getHash()) + .isEqualTo( + Hash.fromHexString( + "0xdbc64edecb3a432e48cbd270b4a248ffc611b5f3dd666c8a10d546672cae17bd")); } @Test diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/ConsolidationRequestDecoderTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/ConsolidationRequestDecoderTest.java deleted file mode 100644 index bb264dfa23..0000000000 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/ConsolidationRequestDecoderTest.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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.core.encoding; - -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.BLSPublicKey; -import org.hyperledger.besu.ethereum.core.ConsolidationRequest; -import org.hyperledger.besu.ethereum.core.Request; -import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; -import org.hyperledger.besu.ethereum.rlp.RLP; - -import org.assertj.core.api.Assertions; -import org.junit.jupiter.api.Test; - -class ConsolidationRequestDecoderTest { - - @Test - public void shouldDecodeWithdrawalRequest() { - final ConsolidationRequest expectedConsolidationRequest = - new ConsolidationRequest( - Address.fromHexString("0x814FaE9f487206471B6B0D713cD51a2D35980000"), - BLSPublicKey.fromHexString( - "0xb10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e"), - BLSPublicKey.fromHexString( - "0xa09a4a15bf67b328c9b101d09e5c6ee6672978f7ad9ef0d9e2c457aee99223555d8601f0cb3bcc4ce1af9864779a416e")); - - final BytesValueRLPOutput out = new BytesValueRLPOutput(); - expectedConsolidationRequest.writeTo(out); - - final Request decodedWithdrawalRequest = RequestDecoder.decode(RLP.input(out.encoded())); - - Assertions.assertThat(decodedWithdrawalRequest).isEqualTo(expectedConsolidationRequest); - } -} diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/ConsolidationRequestEncoderTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/ConsolidationRequestEncoderTest.java deleted file mode 100644 index 10a53379b8..0000000000 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/ConsolidationRequestEncoderTest.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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.core.encoding; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.BLSPublicKey; -import org.hyperledger.besu.ethereum.core.ConsolidationRequest; - -import org.apache.tuweni.bytes.Bytes; -import org.junit.jupiter.api.Test; - -class ConsolidationRequestEncoderTest { - - private final String expectedEncodedBytes = - "f87794763c396673f9c391dce3361a9a71c8e161388000b0b10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416eb0a09a4a15bf67b328c9b101d09e5c6ee6672978f7ad9ef0d9e2c457aee99223555d8601f0cb3bcc4ce1af9864779a416e"; - - final ConsolidationRequest consolidationRequest = - new ConsolidationRequest( - Address.fromHexString("0x763c396673F9c391DCe3361A9A71C8E161388000"), - BLSPublicKey.fromHexString( - "0xb10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e"), - BLSPublicKey.fromHexString( - "0xa09a4a15bf67b328c9b101d09e5c6ee6672978f7ad9ef0d9e2c457aee99223555d8601f0cb3bcc4ce1af9864779a416e")); - - @Test - void shouldEncodeConsolidationRequest() { - final Bytes encoded = ConsolidationRequestEncoder.encodeOpaqueBytes(consolidationRequest); - assertThat(encoded).isEqualTo(Bytes.fromHexString(expectedEncodedBytes)); - } - - @Test - void shouldEncodeRequest() { - final Bytes encoded = RequestEncoder.encodeOpaqueBytes(consolidationRequest); - assertThat(encoded) - .isEqualTo( - Bytes.fromHexString( - String.format( - "0x%02X%s", - consolidationRequest.getType().getSerializedType(), expectedEncodedBytes))); - } -} diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/DepositRequestDecoderTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/DepositLogDecoderTest.java similarity index 51% rename from ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/DepositRequestDecoderTest.java rename to ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/DepositLogDecoderTest.java index 622bd89754..14166553e6 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/DepositRequestDecoderTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/DepositLogDecoderTest.java @@ -17,41 +17,15 @@ package org.hyperledger.besu.ethereum.core.encoding; import static org.assertj.core.api.Assertions.assertThat; import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.BLSPublicKey; -import org.hyperledger.besu.datatypes.BLSSignature; -import org.hyperledger.besu.datatypes.GWei; -import org.hyperledger.besu.ethereum.core.DepositRequest; import org.hyperledger.besu.evm.log.Log; import org.hyperledger.besu.evm.log.LogTopic; import java.util.List; import org.apache.tuweni.bytes.Bytes; -import org.apache.tuweni.bytes.Bytes32; -import org.apache.tuweni.units.bigints.UInt64; import org.junit.jupiter.api.Test; -class DepositRequestDecoderTest { - @Test - void shouldDecodeDeposit() { - final DepositRequest expectedDepositRequest = - new DepositRequest( - BLSPublicKey.fromHexString( - "0xb10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e"), - Bytes32.fromHexString( - "0x0017a7fcf06faf493d30bbe2632ea7c2383cd86825e12797165de7aa35589483"), - GWei.of(32000000000L), - BLSSignature.fromHexString( - "0xa889db8300194050a2636c92a95bc7160515867614b7971a9500cdb62f9c0890217d2901c3241f86fac029428fc106930606154bd9e406d7588934a5f15b837180b17194d6e44bd6de23e43b163dfe12e369dcc75a3852cd997963f158217eb5"), - UInt64.ONE); - - final DepositRequest depositRequest = - DepositRequestDecoder.decodeOpaqueBytes( - Bytes.fromHexString( - "0xf8bbb0b10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416ea00017a7fcf06faf493d30bbe2632ea7c2383cd86825e12797165de7aa35589483850773594000b860a889db8300194050a2636c92a95bc7160515867614b7971a9500cdb62f9c0890217d2901c3241f86fac029428fc106930606154bd9e406d7588934a5f15b837180b17194d6e44bd6de23e43b163dfe12e369dcc75a3852cd997963f158217eb501")); - - assertThat(depositRequest).isEqualTo(expectedDepositRequest); - } +class DepositLogDecoderTest { @Test void shouldDecodeDepositFromLog() { @@ -65,19 +39,12 @@ class DepositRequestDecoderTest { "0x00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000030b10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200017a7fcf06faf493d30bbe2632ea7c2383cd86825e12797165de7aa35589483000000000000000000000000000000000000000000000000000000000000000800405973070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060a889db8300194050a2636c92a95bc7160515867614b7971a9500cdb62f9c0890217d2901c3241f86fac029428fc106930606154bd9e406d7588934a5f15b837180b17194d6e44bd6de23e43b163dfe12e369dcc75a3852cd997963f158217eb500000000000000000000000000000000000000000000000000000000000000083f3d080000000000000000000000000000000000000000000000000000000000"); final Log log = new Log(address, data, topics); - final DepositRequest depositRequest = DepositRequestDecoder.decodeFromLog(log); + final Bytes requestData = DepositLogDecoder.decodeFromLog(log); - final DepositRequest expectedDepositRequest = - new DepositRequest( - BLSPublicKey.fromHexString( - "0xb10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e"), - Bytes32.fromHexString( - "0x0017a7fcf06faf493d30bbe2632ea7c2383cd86825e12797165de7aa35589483"), - GWei.of(32000000000L), - BLSSignature.fromHexString( - "0xa889db8300194050a2636c92a95bc7160515867614b7971a9500cdb62f9c0890217d2901c3241f86fac029428fc106930606154bd9e406d7588934a5f15b837180b17194d6e44bd6de23e43b163dfe12e369dcc75a3852cd997963f158217eb5"), - UInt64.valueOf(539967)); + final Bytes expectedDepositRequestData = + Bytes.fromHexString( + "0xb10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e0017a7fcf06faf493d30bbe2632ea7c2383cd86825e12797165de7aa355894830040597307000000a889db8300194050a2636c92a95bc7160515867614b7971a9500cdb62f9c0890217d2901c3241f86fac029428fc106930606154bd9e406d7588934a5f15b837180b17194d6e44bd6de23e43b163dfe12e369dcc75a3852cd997963f158217eb53f3d080000000000"); - assertThat(depositRequest).isEqualTo(expectedDepositRequest); + assertThat(requestData).isEqualTo(expectedDepositRequestData); } } diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/DepositRequestEncoderTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/DepositRequestEncoderTest.java deleted file mode 100644 index 1e6dde6aa8..0000000000 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/DepositRequestEncoderTest.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * 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.core.encoding; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.hyperledger.besu.datatypes.BLSPublicKey; -import org.hyperledger.besu.datatypes.BLSSignature; -import org.hyperledger.besu.datatypes.GWei; -import org.hyperledger.besu.ethereum.core.DepositRequest; - -import org.apache.tuweni.bytes.Bytes; -import org.apache.tuweni.bytes.Bytes32; -import org.apache.tuweni.units.bigints.UInt64; -import org.junit.jupiter.api.Test; - -class DepositRequestEncoderTest { - private final String expectedDepositEncodedBytes = - "f8bbb0b10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416ea00017a7fcf06faf493d30bbe2632ea7c2383cd86825e12797165de7aa35589483850773594000b860a889db8300194050a2636c92a95bc7160515867614b7971a9500cdb62f9c0890217d2901c3241f86fac029428fc106930606154bd9e406d7588934a5f15b837180b17194d6e44bd6de23e43b163dfe12e369dcc75a3852cd997963f158217eb501"; - - final DepositRequest depositRequest = - new DepositRequest( - BLSPublicKey.fromHexString( - "0xb10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e"), - Bytes32.fromHexString( - "0x0017a7fcf06faf493d30bbe2632ea7c2383cd86825e12797165de7aa35589483"), - GWei.of(32000000000L), - BLSSignature.fromHexString( - "0xa889db8300194050a2636c92a95bc7160515867614b7971a9500cdb62f9c0890217d2901c3241f86fac029428fc106930606154bd9e406d7588934a5f15b837180b17194d6e44bd6de23e43b163dfe12e369dcc75a3852cd997963f158217eb5"), - UInt64.ONE); - - @Test - void shouldEncodeDeposit() { - final Bytes encoded = DepositRequestEncoder.encodeOpaqueBytes(depositRequest); - assertThat(encoded).isEqualTo(Bytes.fromHexString(expectedDepositEncodedBytes)); - } - - @Test - void shouldEncodeDepositRequest() { - final Bytes encoded = RequestEncoder.encodeOpaqueBytes(depositRequest); - // Request encoding is Request = RequestType ++ RequestData - assertThat(encoded) - .isEqualTo( - Bytes.fromHexString( - String.format( - "0x%02X%s", - depositRequest.getType().getSerializedType(), expectedDepositEncodedBytes))); - } -} diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalRequestDecoderTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalRequestDecoderTest.java deleted file mode 100644 index ad6da667c1..0000000000 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalRequestDecoderTest.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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.core.encoding; - -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.BLSPublicKey; -import org.hyperledger.besu.datatypes.GWei; -import org.hyperledger.besu.ethereum.core.Request; -import org.hyperledger.besu.ethereum.core.WithdrawalRequest; -import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; -import org.hyperledger.besu.ethereum.rlp.RLP; - -import org.assertj.core.api.Assertions; -import org.junit.jupiter.api.Test; - -class WithdrawalRequestDecoderTest { - - @Test - public void shouldDecodeWithdrawalRequest() { - final WithdrawalRequest expectedWithdrawalRequest = - new WithdrawalRequest( - Address.fromHexString("0x814FaE9f487206471B6B0D713cD51a2D35980000"), - BLSPublicKey.fromHexString( - "0xb10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e"), - GWei.of(5)); - - final BytesValueRLPOutput out = new BytesValueRLPOutput(); - expectedWithdrawalRequest.writeTo(out); - - final Request decodedWithdrawalRequest = RequestDecoder.decode(RLP.input(out.encoded())); - - Assertions.assertThat(decodedWithdrawalRequest).isEqualTo(expectedWithdrawalRequest); - } -} diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalRequestEncoderTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalRequestEncoderTest.java deleted file mode 100644 index 14c9cfacef..0000000000 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalRequestEncoderTest.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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.core.encoding; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.BLSPublicKey; -import org.hyperledger.besu.datatypes.GWei; -import org.hyperledger.besu.ethereum.core.WithdrawalRequest; - -import org.apache.tuweni.bytes.Bytes; -import org.junit.jupiter.api.Test; - -class WithdrawalRequestEncoderTest { - - private final String expectedEncodedBytes = - "f84794763c396673f9c391dce3361a9a71c8e161388000b0b10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e05"; - - final WithdrawalRequest withdrawalRequest = - new WithdrawalRequest( - Address.fromHexString("0x763c396673F9c391DCe3361A9A71C8E161388000"), - BLSPublicKey.fromHexString( - "0xb10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e"), - GWei.of(5)); - - @Test - void shouldEncodeWithdrawalRequest() { - final Bytes encoded = WithdrawalRequestEncoder.encodeOpaqueBytes(withdrawalRequest); - assertThat(encoded).isEqualTo(Bytes.fromHexString(expectedEncodedBytes)); - } - - @Test - void shouldEncodeRequest() { - final Bytes encoded = RequestEncoder.encodeOpaqueBytes(withdrawalRequest); - assertThat(encoded) - .isEqualTo( - Bytes.fromHexString( - String.format( - "0x%02X%s", - withdrawalRequest.getType().getSerializedType(), expectedEncodedBytes))); - } -} diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/AbstractBlockProcessorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/AbstractBlockProcessorTest.java index 2a66c6e115..33347929cf 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/AbstractBlockProcessorTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/AbstractBlockProcessorTest.java @@ -33,7 +33,6 @@ import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture; import org.hyperledger.besu.ethereum.core.MutableWorldState; import org.hyperledger.besu.ethereum.core.Withdrawal; import org.hyperledger.besu.ethereum.mainnet.blockhash.FrontierBlockHashProcessor; -import org.hyperledger.besu.ethereum.mainnet.requests.RequestsValidatorCoordinator; import org.hyperledger.besu.ethereum.referencetests.ReferenceTestBlockchain; import org.hyperledger.besu.ethereum.referencetests.ReferenceTestWorldState; @@ -68,9 +67,6 @@ abstract class AbstractBlockProcessorTest { @BeforeEach void baseSetup() { lenient().when(protocolSchedule.getByBlockHeader(any())).thenReturn(protocolSpec); - lenient() - .when(protocolSpec.getRequestsValidatorCoordinator()) - .thenReturn(RequestsValidatorCoordinator.empty()); lenient() .when(protocolSpec.getBlockHashProcessor()) .thenReturn(new FrontierBlockHashProcessor()); diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/BodyValidationTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/BodyValidationTest.java index fd5c4387cc..45ce54f252 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/BodyValidationTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/BodyValidationTest.java @@ -15,12 +15,16 @@ package org.hyperledger.besu.ethereum.mainnet; import org.hyperledger.besu.datatypes.Hash; +import org.hyperledger.besu.datatypes.RequestType; import org.hyperledger.besu.ethereum.core.BlockBody; import org.hyperledger.besu.ethereum.core.BlockHeader; +import org.hyperledger.besu.ethereum.core.Request; import java.io.IOException; import java.util.Arrays; +import java.util.List; +import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; @@ -57,4 +61,28 @@ public final class BodyValidationTest { Assertions.assertThat(header.getWithdrawalsRoot()).hasValue(Hash.wrap(withdrawalsRoot)); } } + + @Test + public void calculateRequestsHash() { + List requests = + List.of( + new Request( + RequestType.DEPOSIT, + Bytes.fromHexString( + "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100405973070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000")), + new Request( + RequestType.WITHDRAWAL, + Bytes.fromHexString( + "0x6389e7f33ce3b1e94e4325ef02829cd12297ef710000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000")), + new Request( + RequestType.CONSOLIDATION, + Bytes.fromHexString( + "0x8a0a19589531694250d570040a0c4b74576919b8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001"))); + + Bytes32 requestHash = BodyValidation.requestsHash(requests); + Assertions.assertThat(requestHash) + .isEqualTo( + Bytes32.fromHexString( + "0x0e53a6857da18cf29c6ae28be10a333fc0eaafbd3f425f09e5e81f29e4d3d766")); + } } diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/ConsolidationRequestValidatorTestFixtures.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/ConsolidationRequestValidatorTestFixtures.java deleted file mode 100644 index fbd304d1cd..0000000000 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/ConsolidationRequestValidatorTestFixtures.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * 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; - -import static org.hyperledger.besu.ethereum.mainnet.requests.ConsolidationRequestValidator.MAX_CONSOLIDATION_REQUESTS_PER_BLOCK; - -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.BLSPublicKey; -import org.hyperledger.besu.ethereum.core.Block; -import org.hyperledger.besu.ethereum.core.BlockDataGenerator; -import org.hyperledger.besu.ethereum.core.ConsolidationRequest; -import org.hyperledger.besu.ethereum.core.Request; - -import java.util.List; -import java.util.Optional; -import java.util.stream.IntStream; - -import org.apache.tuweni.bytes.Bytes32; -import org.apache.tuweni.bytes.Bytes48; - -public class ConsolidationRequestValidatorTestFixtures { - - private static final BlockDataGenerator blockDataGenerator = new BlockDataGenerator(); - - static ConsolidationRequestTestParameter - blockWithConsolidationRequestsAndWithdrawalRequestsRoot() { - final ConsolidationRequest consolidationRequest = createConsolidationRequest(); - final Optional> maybeConsolidationRequests = - Optional.of(List.of(consolidationRequest)); - - final BlockDataGenerator.BlockOptions blockOptions = - BlockDataGenerator.BlockOptions.create() - .setRequestsRoot(BodyValidation.requestsRoot(maybeConsolidationRequests.get())) - .setRequests(maybeConsolidationRequests); - final Block block = blockDataGenerator.block(blockOptions); - - return new ConsolidationRequestTestParameter( - "Block with consolidation requests and withdrawal_requests_root", - block, - Optional.of(List.of(consolidationRequest))); - } - - static ConsolidationRequestTestParameter blockWithConsolidationRequestsMismatch() { - final ConsolidationRequest consolidationRequest = createConsolidationRequest(); - - final Optional> requests = - Optional.of(List.of(consolidationRequest, consolidationRequest)); - - final BlockDataGenerator.BlockOptions blockOptions = - BlockDataGenerator.BlockOptions.create() - .setRequestsRoot(BodyValidation.requestsRoot(requests.get())) - .setRequests(requests); - final Block block = blockDataGenerator.block(blockOptions); - - return new ConsolidationRequestTestParameter( - "Block with consolidation requests mismatch", - block, - Optional.of(List.of(consolidationRequest, consolidationRequest)), - List.of(createConsolidationRequest())); - } - - static ConsolidationRequestTestParameter blockWithMoreThanMaximumConsolidationRequests() { - final List consolidationRequests = - IntStream.range(0, MAX_CONSOLIDATION_REQUESTS_PER_BLOCK + 1) - .mapToObj(__ -> createConsolidationRequest()) - .toList(); - - final Optional> maybeConsolidationRequest = - Optional.of(consolidationRequests); - final Optional> maybeRequests = - Optional.of(consolidationRequests.stream().map(r -> (Request) r).toList()); - - final BlockDataGenerator.BlockOptions blockOptions = - BlockDataGenerator.BlockOptions.create() - .setRequestsRoot(BodyValidation.requestsRoot(maybeRequests.get())) - .setRequests(maybeRequests); - final Block block = blockDataGenerator.block(blockOptions); - - return new ConsolidationRequestTestParameter( - "Block with more than maximum consolidation requests", block, maybeConsolidationRequest); - } - - static ConsolidationRequest createConsolidationRequest() { - return new ConsolidationRequest( - Address.extract(Bytes32.random()), - BLSPublicKey.wrap(Bytes48.random()), - BLSPublicKey.wrap(Bytes48.random())); - } - - static class ConsolidationRequestTestParameter { - - String description; - Block block; - Optional> maybeConsolidationRequest; - List expectedConsolidationRequest; - - public ConsolidationRequestTestParameter( - final String description, - final Block block, - final Optional> maybeConsolidationRequest) { - this( - description, - block, - maybeConsolidationRequest, - maybeConsolidationRequest.orElseGet(List::of)); - } - - public ConsolidationRequestTestParameter( - final String description, - final Block block, - final Optional> maybeConsolidationRequest, - final List expectedConsolidationRequest) { - this.description = description; - this.block = block; - this.maybeConsolidationRequest = maybeConsolidationRequest; - this.expectedConsolidationRequest = expectedConsolidationRequest; - } - - @Override - public String toString() { - return description; - } - } -} diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/DepositRequestValidatorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/DepositRequestValidatorTest.java deleted file mode 100644 index 0360032388..0000000000 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/DepositRequestValidatorTest.java +++ /dev/null @@ -1,234 +0,0 @@ -/* - * 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; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.BLSPublicKey; -import org.hyperledger.besu.datatypes.BLSSignature; -import org.hyperledger.besu.datatypes.GWei; -import org.hyperledger.besu.datatypes.RequestType; -import org.hyperledger.besu.ethereum.core.Block; -import org.hyperledger.besu.ethereum.core.BlockDataGenerator; -import org.hyperledger.besu.ethereum.core.DepositRequest; -import org.hyperledger.besu.ethereum.core.Request; -import org.hyperledger.besu.ethereum.core.TransactionReceipt; -import org.hyperledger.besu.ethereum.mainnet.requests.DepositRequestValidator; -import org.hyperledger.besu.ethereum.mainnet.requests.RequestsValidatorCoordinator; -import org.hyperledger.besu.ethereum.mainnet.requests.WithdrawalRequestValidator; -import org.hyperledger.besu.evm.log.Log; -import org.hyperledger.besu.evm.log.LogTopic; - -import java.util.List; -import java.util.Optional; - -import org.apache.tuweni.bytes.Bytes; -import org.apache.tuweni.bytes.Bytes32; -import org.apache.tuweni.units.bigints.UInt64; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -public class DepositRequestValidatorTest { - private final BlockDataGenerator blockDataGenerator = new BlockDataGenerator(); - private static DepositRequest depositRequest1; - private static DepositRequest depositRequest2; - private static Log LOG_1; - private static Log LOG_2; - private static Address DEPOSIT_CONTRACT_ADDRESS; - private static RequestsValidatorCoordinator requestsValidatorCoordinator; - private static DepositRequestValidator depositRequestValidator; - - @BeforeAll - public static void setup() { - depositRequest1 = - new DepositRequest( - BLSPublicKey.fromHexString( - "0xb10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e"), - Bytes32.fromHexString( - "0x0017a7fcf06faf493d30bbe2632ea7c2383cd86825e12797165de7aa35589483"), - GWei.of(32000000000L), - BLSSignature.fromHexString( - "0xa889db8300194050a2636c92a95bc7160515867614b7971a9500cdb62f9c0890217d2901c3241f86fac029428fc106930606154bd9e406d7588934a5f15b837180b17194d6e44bd6de23e43b163dfe12e369dcc75a3852cd997963f158217eb5"), - UInt64.valueOf(539967)); - - depositRequest2 = - new DepositRequest( - BLSPublicKey.fromHexString( - "0x8706d19a62f28a6a6549f96c5adaebac9124a61d44868ec94f6d2d707c6a2f82c9162071231dfeb40e24bfde4ffdf243"), - Bytes32.fromHexString( - "0x006a8dc800c6d8dd6977ef53264e2d030350f0145a91bcd167b4f1c3ea21b271"), - GWei.of(32000000000L), - BLSSignature.fromHexString( - "0x801b08ca107b623eca32ee9f9111b4e50eb9cfe19e38204b72de7dc04c5a5e00f61bab96f10842576f66020ce851083f1583dd9a6b73301bea6c245cf51f27cf96aeb018852c5f70bf485d16b957cfe49ca008913346b431e7653ae3ddb23b07"), - UInt64.valueOf(559887)); - - LOG_1 = - new Log( - Address.fromHexString("0x00000000219ab540356cbb839cbe05303d7705fa"), - Bytes.fromHexString( - "0x00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000030b10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200017a7fcf06faf493d30bbe2632ea7c2383cd86825e12797165de7aa35589483000000000000000000000000000000000000000000000000000000000000000800405973070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060a889db8300194050a2636c92a95bc7160515867614b7971a9500cdb62f9c0890217d2901c3241f86fac029428fc106930606154bd9e406d7588934a5f15b837180b17194d6e44bd6de23e43b163dfe12e369dcc75a3852cd997963f158217eb500000000000000000000000000000000000000000000000000000000000000083f3d080000000000000000000000000000000000000000000000000000000000"), - List.of( - LogTopic.fromHexString( - "0x649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5"))); - - LOG_2 = - new Log( - Address.fromHexString("0x00000000219ab540356cbb839cbe05303d7705fa"), - Bytes.fromHexString( - "0x00000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000180000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000308706d19a62f28a6a6549f96c5adaebac9124a61d44868ec94f6d2d707c6a2f82c9162071231dfeb40e24bfde4ffdf243000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020006a8dc800c6d8dd6977ef53264e2d030350f0145a91bcd167b4f1c3ea21b271000000000000000000000000000000000000000000000000000000000000000800405973070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060801b08ca107b623eca32ee9f9111b4e50eb9cfe19e38204b72de7dc04c5a5e00f61bab96f10842576f66020ce851083f1583dd9a6b73301bea6c245cf51f27cf96aeb018852c5f70bf485d16b957cfe49ca008913346b431e7653ae3ddb23b0700000000000000000000000000000000000000000000000000000000000000080f8b080000000000000000000000000000000000000000000000000000000000"), - List.of( - LogTopic.fromHexString( - "0x649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5"))); - DEPOSIT_CONTRACT_ADDRESS = Address.fromHexString("0x00000000219ab540356cbb839cbe05303d7705fa"); - requestsValidatorCoordinator = createAllowDepositValidator(); - } - - @Test - public void validateAllowedDepositRequests() { - final List request = List.of(depositRequest1, depositRequest2); - final BlockDataGenerator.BlockOptions blockOptions = - BlockDataGenerator.BlockOptions.create() - .setRequests(Optional.of(request)) - .setRequestsRoot(BodyValidation.requestsRoot(request)); - final Block block = blockDataGenerator.block(blockOptions); - - final TransactionReceipt receipt = - new TransactionReceipt(null, 0L, List.of(LOG_1, LOG_2), Optional.empty()); - - assertThat(requestsValidatorCoordinator.validate(block, Optional.of(request), List.of(receipt))) - .isTrue(); - } - - @Test - public void validateAllowedDepositRequestsSeparateReceipts() { - - final List requests = List.of(depositRequest1, depositRequest2); - - final BlockDataGenerator.BlockOptions blockOptions = - BlockDataGenerator.BlockOptions.create() - .setRequests(Optional.of(requests)) - .setRequestsRoot(BodyValidation.requestsRoot(requests)); - final Block block = blockDataGenerator.block(blockOptions); - - final TransactionReceipt receipt1 = - new TransactionReceipt(null, 0L, List.of(LOG_1), Optional.empty()); - final TransactionReceipt receipt2 = - new TransactionReceipt(null, 0L, List.of(LOG_2), Optional.empty()); - - assertThat( - requestsValidatorCoordinator.validate( - block, Optional.of(requests), List.of(receipt1, receipt2))) - .isTrue(); - } - - @Test - public void invalidateAllowedDepositRequests() { - final BlockDataGenerator.BlockOptions blockOptions = - BlockDataGenerator.BlockOptions.create().setRequests(Optional.of(List.of(depositRequest1))); - final Block block = blockDataGenerator.block(blockOptions); - - final TransactionReceipt receipt1 = - new TransactionReceipt(null, 0L, List.of(LOG_2), Optional.empty()); - - assertThat( - requestsValidatorCoordinator.validate(block, Optional.of(List.of()), List.of(receipt1))) - .isFalse(); - } - - @Test - public void invalidateAllowedDepositRequestsMissingLogInReceipt() { - final BlockDataGenerator.BlockOptions blockOptions = - BlockDataGenerator.BlockOptions.create() - .setRequests(Optional.of(List.of(depositRequest1, depositRequest2))); - final Block block = blockDataGenerator.block(blockOptions); - - final TransactionReceipt receipt1 = - new TransactionReceipt(null, 0L, List.of(LOG_2), Optional.empty()); - - assertThat( - requestsValidatorCoordinator.validate(block, Optional.of(List.of()), List.of(receipt1))) - .isFalse(); - } - - @Test - public void invalidateAllowedDepositRequestsExtraLogInReceipt() { - final BlockDataGenerator.BlockOptions blockOptions = - BlockDataGenerator.BlockOptions.create().setRequests(Optional.of(List.of(depositRequest1))); - final Block block = blockDataGenerator.block(blockOptions); - - final TransactionReceipt receipt1 = - new TransactionReceipt(null, 0L, List.of(LOG_1, LOG_2), Optional.empty()); - - assertThat( - requestsValidatorCoordinator.validate(block, Optional.of(List.of()), List.of(receipt1))) - .isFalse(); - } - - @Test - public void invalidateAllowedDepositRequestsWrongOrder() { - final BlockDataGenerator.BlockOptions blockOptions = - BlockDataGenerator.BlockOptions.create() - .setRequests(Optional.of(List.of(depositRequest1, depositRequest2))); - final Block block = blockDataGenerator.block(blockOptions); - - final TransactionReceipt receipt1 = - new TransactionReceipt(null, 0L, List.of(LOG_2, LOG_1), Optional.empty()); - - assertThat( - requestsValidatorCoordinator.validate(block, Optional.of(List.of()), List.of(receipt1))) - .isFalse(); - } - - @Test - public void invalidateAllowedDepositRequestsMismatchContractAddress() { - - final BlockDataGenerator.BlockOptions blockOptions = - BlockDataGenerator.BlockOptions.create() - .setRequests(Optional.of(List.of(depositRequest1, depositRequest2))); - final Block block = blockDataGenerator.block(blockOptions); - - final TransactionReceipt receipt1 = - new TransactionReceipt(null, 0L, List.of(LOG_1, LOG_2), Optional.empty()); - - assertThat( - requestsValidatorCoordinator.validate(block, Optional.of(List.of()), List.of(receipt1))) - .isFalse(); - } - - @Test - public void validateAllowedDepositParams() { - final Optional> depositRequests = - Optional.of(List.of(depositRequest1, depositRequest2)); - assertThat(depositRequestValidator.validateParameter(depositRequests)).isTrue(); - - final Optional> emptyDepositRequests = Optional.of(List.of()); - assertThat(depositRequestValidator.validateParameter(emptyDepositRequests)).isTrue(); - } - - @Test - public void invalidateAllowedDepositParams() { - final Optional> depositRequests = Optional.empty(); - assertThat(depositRequestValidator.validateParameter(depositRequests)).isFalse(); - } - - static RequestsValidatorCoordinator createAllowDepositValidator() { - depositRequestValidator = new DepositRequestValidator(DEPOSIT_CONTRACT_ADDRESS); - return new RequestsValidatorCoordinator.Builder() - .addValidator(RequestType.WITHDRAWAL, new WithdrawalRequestValidator()) - .addValidator(RequestType.DEPOSIT, depositRequestValidator) - .build(); - } -} diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockBodyValidatorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockBodyValidatorTest.java index c412a30756..8c25d4f58e 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockBodyValidatorTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockBodyValidatorTest.java @@ -36,8 +36,7 @@ import org.hyperledger.besu.ethereum.core.BlockDataGenerator.BlockOptions; import org.hyperledger.besu.ethereum.core.BlockchainSetupUtil; import org.hyperledger.besu.ethereum.core.TransactionReceipt; import org.hyperledger.besu.ethereum.core.Withdrawal; -import org.hyperledger.besu.ethereum.mainnet.requests.DepositRequestValidator; -import org.hyperledger.besu.ethereum.mainnet.requests.RequestsValidatorCoordinator; +import org.hyperledger.besu.ethereum.mainnet.requests.RequestsValidator; import org.hyperledger.besu.evm.log.LogsBloomFilter; import java.util.Collections; @@ -61,8 +60,7 @@ class MainnetBlockBodyValidatorTest { @Mock private ProtocolSchedule protocolSchedule; @Mock private ProtocolSpec protocolSpec; @Mock private WithdrawalsValidator withdrawalsValidator; - @Mock private DepositRequestValidator depositRequestValidator; - @Mock private RequestsValidatorCoordinator requestValidator; + @Mock private RequestsValidator requestValidator; @BeforeEach public void setUp() { @@ -72,12 +70,8 @@ class MainnetBlockBodyValidatorTest { lenient().when(withdrawalsValidator.validateWithdrawals(any())).thenReturn(true); lenient().when(withdrawalsValidator.validateWithdrawalsRoot(any())).thenReturn(true); - lenient() - .when(depositRequestValidator.validateDepositRequests(any(), any(), any())) - .thenReturn(true); - - lenient().when(protocolSpec.getRequestsValidatorCoordinator()).thenReturn(requestValidator); - lenient().when(requestValidator.validate(any(), any(), any())).thenReturn(true); + lenient().when(protocolSpec.getRequestsValidator()).thenReturn(requestValidator); + lenient().when(requestValidator.validate(any())).thenReturn(true); } @Test @@ -104,7 +98,6 @@ class MainnetBlockBodyValidatorTest { blockchainSetupUtil.getProtocolContext(), block, emptyList(), - any(), NONE, BodyValidationMode.FULL)) .isTrue(); @@ -133,7 +126,6 @@ class MainnetBlockBodyValidatorTest { blockchainSetupUtil.getProtocolContext(), block, emptyList(), - any(), NONE, BodyValidationMode.FULL)) .isFalse(); @@ -162,36 +154,6 @@ class MainnetBlockBodyValidatorTest { blockchainSetupUtil.getProtocolContext(), block, emptyList(), - any(), - NONE, - BodyValidationMode.FULL)) - .isFalse(); - } - - @Test - public void validationFailsIfWithdrawalRequestsValidationFails() { - final Block block = - blockDataGenerator.block( - new BlockOptions() - .setBlockNumber(1) - .setGasUsed(0) - .hasTransactions(false) - .hasOmmers(false) - .setReceiptsRoot(BodyValidation.receiptsRoot(emptyList())) - .setLogsBloom(LogsBloomFilter.empty()) - .setParentHash(blockchainSetupUtil.getBlockchain().getChainHeadHash()) - .setRequests(Optional.of(List.of()))); - blockchainSetupUtil.getBlockchain().appendBlock(block, Collections.emptyList()); - - when(requestValidator.validate(any(), any(), any())).thenReturn(false); - - assertThat( - new MainnetBlockBodyValidator(protocolSchedule) - .validateBodyLight( - blockchainSetupUtil.getProtocolContext(), - block, - emptyList(), - any(), NONE, BodyValidationMode.FULL)) .isFalse(); @@ -210,7 +172,6 @@ class MainnetBlockBodyValidatorTest { blockchainSetupUtil.getProtocolContext(), block, receipts, - Optional.empty(), NONE, BodyValidationMode.NONE)) .isTrue(); @@ -241,7 +202,6 @@ class MainnetBlockBodyValidatorTest { blockchainSetupUtil.getProtocolContext(), block, emptyList(), - Optional.empty(), NONE, BodyValidationMode.LIGHT)) .isTrue(); @@ -272,7 +232,6 @@ class MainnetBlockBodyValidatorTest { blockchainSetupUtil.getProtocolContext(), block, emptyList(), - Optional.empty(), NONE, BodyValidationMode.FULL)) .isTrue(); diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockProcessorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockProcessorTest.java index a06aece37b..8baf4d8d03 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockProcessorTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockProcessorTest.java @@ -28,7 +28,6 @@ import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture; import org.hyperledger.besu.ethereum.core.MutableWorldState; import org.hyperledger.besu.ethereum.mainnet.blockhash.FrontierBlockHashProcessor; -import org.hyperledger.besu.ethereum.mainnet.requests.RequestsValidatorCoordinator; import org.hyperledger.besu.ethereum.referencetests.ReferenceTestBlockchain; import org.hyperledger.besu.ethereum.referencetests.ReferenceTestWorldState; @@ -50,8 +49,6 @@ public class MainnetBlockProcessorTest extends AbstractBlockProcessorTest { @BeforeEach public void setup() { when(protocolSchedule.getByBlockHeader(any())).thenReturn(protocolSpec); - when(protocolSpec.getRequestsValidatorCoordinator()) - .thenReturn(RequestsValidatorCoordinator.empty()); when(protocolSpec.getBlockHashProcessor()).thenReturn(new FrontierBlockHashProcessor()); } diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/PragueConsolidationRequestValidatorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/PragueConsolidationRequestValidatorTest.java deleted file mode 100644 index 9d0c9588cc..0000000000 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/PragueConsolidationRequestValidatorTest.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * 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; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.hyperledger.besu.ethereum.mainnet.ConsolidationRequestValidatorTestFixtures.blockWithConsolidationRequestsAndWithdrawalRequestsRoot; -import static org.hyperledger.besu.ethereum.mainnet.ConsolidationRequestValidatorTestFixtures.blockWithConsolidationRequestsMismatch; -import static org.hyperledger.besu.ethereum.mainnet.ConsolidationRequestValidatorTestFixtures.blockWithMoreThanMaximumConsolidationRequests; - -import org.hyperledger.besu.ethereum.core.Request; -import org.hyperledger.besu.ethereum.mainnet.ConsolidationRequestValidatorTestFixtures.ConsolidationRequestTestParameter; -import org.hyperledger.besu.ethereum.mainnet.requests.ConsolidationRequestValidator; - -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.stream.Stream; - -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -class PragueConsolidationRequestValidatorTest { - - @ParameterizedTest(name = "{index}: {0}") - @MethodSource("paramsForValidateConsolidationRequestParameter") - public void validateConsolidationRequestParameter( - final String description, - final Optional> maybeRequests, - final boolean expectedValidity) { - assertThat(new ConsolidationRequestValidator().validateParameter(maybeRequests)) - .isEqualTo(expectedValidity); - } - - private static Stream paramsForValidateConsolidationRequestParameter() { - return Stream.of( - Arguments.of( - "Allowed ConsolidationRequests - validating empty ConsolidationRequests", - Optional.empty(), - true), - Arguments.of( - "Allowed ConsolidationRequests - validating present ConsolidationRequests", - Optional.of(List.of()), - true)); - } - - @ParameterizedTest(name = "{index}: {0}") - @MethodSource("validateConsolidationRequestsInBlockParamsForPrague") - public void validateConsolidationRequestsInBlock_WhenPrague( - final ConsolidationRequestTestParameter param, final boolean expectedValidity) { - assertThat( - new ConsolidationRequestValidator() - .validate( - param.block, new ArrayList<>(param.expectedConsolidationRequest), List.of())) - .isEqualTo(expectedValidity); - } - - private static Stream validateConsolidationRequestsInBlockParamsForPrague() { - return Stream.of( - Arguments.of(blockWithConsolidationRequestsAndWithdrawalRequestsRoot(), true), - Arguments.of(blockWithConsolidationRequestsMismatch(), false), - Arguments.of(blockWithMoreThanMaximumConsolidationRequests(), false)); - } -} diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/PragueRequestsValidatorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/PragueRequestsValidatorTest.java deleted file mode 100644 index 6158ba44c3..0000000000 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/PragueRequestsValidatorTest.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * 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; - -import static java.util.Collections.emptyList; -import static org.assertj.core.api.Assertions.assertThat; -import static org.hyperledger.besu.ethereum.mainnet.HeaderValidationMode.NONE; -import static org.hyperledger.besu.ethereum.mainnet.requests.ConsolidationRequestProcessor.CONSOLIDATION_REQUEST_CONTRACT_ADDRESS; -import static org.hyperledger.besu.ethereum.mainnet.requests.DepositRequestProcessor.DEFAULT_DEPOSIT_CONTRACT_ADDRESS; -import static org.hyperledger.besu.ethereum.mainnet.requests.MainnetRequestsValidator.pragueRequestsValidator; -import static org.hyperledger.besu.ethereum.mainnet.requests.WithdrawalRequestProcessor.DEFAULT_WITHDRAWAL_REQUEST_CONTRACT_ADDRESS; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.lenient; - -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.BLSPublicKey; -import org.hyperledger.besu.datatypes.GWei; -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.ethereum.core.Block; -import org.hyperledger.besu.ethereum.core.BlockDataGenerator; -import org.hyperledger.besu.ethereum.core.BlockchainSetupUtil; -import org.hyperledger.besu.ethereum.core.Request; -import org.hyperledger.besu.ethereum.core.WithdrawalRequest; -import org.hyperledger.besu.ethereum.mainnet.requests.RequestContractAddresses; -import org.hyperledger.besu.ethereum.mainnet.requests.RequestsValidatorCoordinator; -import org.hyperledger.besu.evm.log.LogsBloomFilter; - -import java.util.List; -import java.util.Optional; - -import org.apache.tuweni.bytes.Bytes32; -import org.apache.tuweni.bytes.Bytes48; -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 PragueRequestsValidatorTest { - - private final BlockchainSetupUtil blockchainSetupUtil = BlockchainSetupUtil.forMainnet(); - @Mock private ProtocolSchedule protocolSchedule; - @Mock private ProtocolSpec protocolSpec; - @Mock private WithdrawalsValidator withdrawalsValidator; - private final RequestContractAddresses requestContractAddresses = - new RequestContractAddresses( - DEFAULT_WITHDRAWAL_REQUEST_CONTRACT_ADDRESS, - DEFAULT_DEPOSIT_CONTRACT_ADDRESS, - CONSOLIDATION_REQUEST_CONTRACT_ADDRESS); - - RequestsValidatorCoordinator requestValidator = pragueRequestsValidator(requestContractAddresses); - - @BeforeEach - public void setUp() { - lenient().when(protocolSchedule.getByBlockHeader(any())).thenReturn(protocolSpec); - lenient().when(protocolSpec.getWithdrawalsValidator()).thenReturn(withdrawalsValidator); - lenient().when(withdrawalsValidator.validateWithdrawals(any())).thenReturn(true); - lenient().when(withdrawalsValidator.validateWithdrawalsRoot(any())).thenReturn(true); - lenient().when(protocolSpec.getRequestsValidatorCoordinator()).thenReturn(requestValidator); - } - - private static final BlockDataGenerator blockDataGenerator = new BlockDataGenerator(); - - @Test - void shouldValidateRequestsTest() { - WithdrawalRequest request = - new WithdrawalRequest( - Address.extract(Bytes32.fromHexStringLenient("1")), - BLSPublicKey.wrap(Bytes48.fromHexStringLenient("1")), - GWei.ONE); - - WithdrawalRequest requestTwo = - new WithdrawalRequest( - Address.extract(Bytes32.fromHexStringLenient("1")), - BLSPublicKey.wrap(Bytes48.fromHexStringLenient("1")), - GWei.ZERO); - - Optional> blockRequests = Optional.of(List.of(request)); - Optional> expectedRequests = Optional.of(List.of(requestTwo)); - Hash requestsRoot = BodyValidation.requestsRoot(blockRequests.get()); - - final BlockDataGenerator.BlockOptions blockOptions = - BlockDataGenerator.BlockOptions.create() - .setRequestsRoot(requestsRoot) - .setRequests(blockRequests) - .setGasUsed(0) - .setReceiptsRoot(BodyValidation.receiptsRoot(emptyList())) - .hasTransactions(false) - .hasOmmers(false) - .setReceiptsRoot(BodyValidation.receiptsRoot(emptyList())) - .setLogsBloom(LogsBloomFilter.empty()) - .setParentHash(blockchainSetupUtil.getBlockchain().getChainHeadHash()); - - final Block block = blockDataGenerator.block(blockOptions); - assertThat(block).isNotNull(); - assertThat( - new MainnetBlockBodyValidator(protocolSchedule) - .validateBodyLight( - blockchainSetupUtil.getProtocolContext(), - block, - emptyList(), - expectedRequests, - NONE, - BodyValidationMode.FULL)) - .isFalse(); - } -} diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/PragueWithdrawalRequestValidatorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/PragueWithdrawalRequestValidatorTest.java deleted file mode 100644 index 8756f85592..0000000000 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/PragueWithdrawalRequestValidatorTest.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * 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; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.hyperledger.besu.ethereum.mainnet.WithdrawalRequestValidatorTestFixtures.blockWithMoreThanMaximumWithdrawalRequests; -import static org.hyperledger.besu.ethereum.mainnet.WithdrawalRequestValidatorTestFixtures.blockWithWithdrawalRequestsAndWithdrawalRequestsRoot; -import static org.hyperledger.besu.ethereum.mainnet.WithdrawalRequestValidatorTestFixtures.blockWithWithdrawalRequestsMismatch; - -import org.hyperledger.besu.ethereum.core.Request; -import org.hyperledger.besu.ethereum.mainnet.WithdrawalRequestValidatorTestFixtures.WithdrawalRequestTestParameter; -import org.hyperledger.besu.ethereum.mainnet.requests.WithdrawalRequestValidator; - -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.stream.Stream; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -class PragueWithdrawalRequestValidatorTest { - - @ParameterizedTest(name = "{index}: {0}") - @MethodSource("paramsForValidateWithdrawalRequestParameter") - public void validateWithdrawalRequestParameter( - final String description, - final Optional> maybeRequests, - final boolean expectedValidity) { - assertThat(new WithdrawalRequestValidator().validateParameter(maybeRequests)) - .isEqualTo(expectedValidity); - } - - private static Stream paramsForValidateWithdrawalRequestParameter() { - return Stream.of( - Arguments.of( - "Allowed WithdrawalRequests - validating empty WithdrawalRequests", - Optional.empty(), - false), - Arguments.of( - "Allowed WithdrawalRequests - validating present WithdrawalRequests", - Optional.of(List.of()), - true)); - } - - @ParameterizedTest(name = "{index}: {0}") - @MethodSource("validateWithdrawalRequestsInBlockParamsForPrague") - public void validateWithdrawalRequestsInBlock_WhenPrague( - final WithdrawalRequestTestParameter param, final boolean expectedValidity) { - assertThat( - new WithdrawalRequestValidator() - .validate(param.block, new ArrayList<>(param.expectedWithdrawalRequest), List.of())) - .isEqualTo(expectedValidity); - } - - private static Stream validateWithdrawalRequestsInBlockParamsForPrague() { - return Stream.of( - Arguments.of(blockWithWithdrawalRequestsAndWithdrawalRequestsRoot(), true), - Arguments.of(blockWithWithdrawalRequestsMismatch(), false), - Arguments.of(blockWithMoreThanMaximumWithdrawalRequests(), false)); - } - - @Test - void dryRunDetector() { - assertThat(true) - .withFailMessage("This test is here so gradle --dry-run executes this class") - .isTrue(); - } -} diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/SystemCallProcessorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/SystemCallProcessorTest.java index e1d3906e73..14275f7d12 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/SystemCallProcessorTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/SystemCallProcessorTest.java @@ -87,10 +87,10 @@ public class SystemCallProcessorTest { } @Test - void shouldReturnNullWhenContractDoesNotExist() { + void shouldReturnEmptyWhenContractDoesNotExist() { final MutableWorldState worldState = InMemoryKeyValueStorageProvider.createInMemoryWorldState(); Bytes actualOutput = processSystemCall(worldState); - assertThat(actualOutput).isNull(); + assertThat(actualOutput).isEqualTo(Bytes.EMPTY); } Bytes processSystemCall(final MutableWorldState worldState) { diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/ValidationTestUtils.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/ValidationTestUtils.java index fa912a6de8..4e1ac520b5 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/ValidationTestUtils.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/ValidationTestUtils.java @@ -17,7 +17,6 @@ package org.hyperledger.besu.ethereum.mainnet; import org.hyperledger.besu.ethereum.core.Block; import org.hyperledger.besu.ethereum.core.BlockBody; import org.hyperledger.besu.ethereum.core.BlockHeader; -import org.hyperledger.besu.ethereum.core.Request; import org.hyperledger.besu.ethereum.core.Transaction; import org.hyperledger.besu.ethereum.core.Withdrawal; import org.hyperledger.besu.ethereum.rlp.BytesValueRLPInput; @@ -59,11 +58,7 @@ public final class ValidationTestUtils { input.isEndOfCurrentList() ? Optional.empty() : Optional.of(input.readList(Withdrawal::readFrom)); - final Optional> requests = - input.isEndOfCurrentList() - ? Optional.empty() - : Optional.of(input.readList(Request::readFrom)); - return new BlockBody(transactions, ommers, withdrawals, requests); + return new BlockBody(transactions, ommers, withdrawals); } public static Block readBlock(final long num) throws IOException { diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/WithdrawalRequestValidatorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/WithdrawalRequestValidatorTest.java deleted file mode 100644 index f93067d94f..0000000000 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/WithdrawalRequestValidatorTest.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * 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; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.hyperledger.besu.ethereum.mainnet.WithdrawalRequestValidatorTestFixtures.blockWithWithdrawalRequestsAndWithdrawalRequestsRoot; -import static org.hyperledger.besu.ethereum.mainnet.WithdrawalRequestValidatorTestFixtures.blockWithWithdrawalRequestsWithoutWithdrawalRequestsRoot; -import static org.hyperledger.besu.ethereum.mainnet.WithdrawalRequestValidatorTestFixtures.blockWithoutWithdrawalRequestsAndWithdrawalRequestsRoot; -import static org.hyperledger.besu.ethereum.mainnet.WithdrawalRequestValidatorTestFixtures.blockWithoutWithdrawalRequestsWithWithdrawalRequestsRoot; - -import org.hyperledger.besu.ethereum.core.Request; -import org.hyperledger.besu.ethereum.mainnet.WithdrawalRequestValidatorTestFixtures.WithdrawalRequestTestParameter; -import org.hyperledger.besu.ethereum.mainnet.requests.ProhibitedRequestsValidator; - -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.stream.Stream; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -class WithdrawalRequestValidatorTest { - - @ParameterizedTest(name = "{index}: {0}") - @MethodSource("paramsForValidateWithdrawalRequestParameter") - public void validateWithdrawalRequestParameter( - final String description, - final Optional> maybeWithdrawalRequests, - final boolean expectedValidity) { - assertThat(new ProhibitedRequestsValidator().validateParameter(maybeWithdrawalRequests)) - .isEqualTo(expectedValidity); - } - - private static Stream paramsForValidateWithdrawalRequestParameter() { - return Stream.of( - Arguments.of( - "Prohibited WithdrawalRequests - validating empty WithdrawalRequests", - Optional.empty(), - true), - Arguments.of( - "Prohibited WithdrawalRequests - validating present WithdrawalRequests", - Optional.of(List.of()), - false)); - } - - @ParameterizedTest(name = "{index}: {0}") - @MethodSource("validateWithdrawalRequestsInBlockParamsForProhibited") - public void validateWithdrawalRequestsInBlock_WhenProhibited( - final WithdrawalRequestTestParameter param, final boolean expectedValidity) { - - var list = param.expectedWithdrawalRequest; - var requests = new ArrayList(list).stream().toList(); - - assertThat(new ProhibitedRequestsValidator().validate(param.block, requests, List.of())) - .isEqualTo(expectedValidity); - } - - private static Stream validateWithdrawalRequestsInBlockParamsForProhibited() { - return Stream.of( - Arguments.of(blockWithWithdrawalRequestsAndWithdrawalRequestsRoot(), false), - Arguments.of(blockWithWithdrawalRequestsWithoutWithdrawalRequestsRoot(), false), - Arguments.of(blockWithoutWithdrawalRequestsWithWithdrawalRequestsRoot(), false), - Arguments.of(blockWithoutWithdrawalRequestsAndWithdrawalRequestsRoot(), true)); - } - - @Test - void dryRunDetector() { - assertThat(true) - .withFailMessage("This test is here so gradle --dry-run executes this class") - .isTrue(); - } -} diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/WithdrawalRequestValidatorTestFixtures.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/WithdrawalRequestValidatorTestFixtures.java deleted file mode 100644 index e719810c28..0000000000 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/WithdrawalRequestValidatorTestFixtures.java +++ /dev/null @@ -1,186 +0,0 @@ -/* - * 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; - -import static org.hyperledger.besu.ethereum.mainnet.requests.WithdrawalRequestValidator.MAX_WITHDRAWAL_REQUESTS_PER_BLOCK; - -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.BLSPublicKey; -import org.hyperledger.besu.datatypes.GWei; -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.ethereum.core.Block; -import org.hyperledger.besu.ethereum.core.BlockDataGenerator; -import org.hyperledger.besu.ethereum.core.Request; -import org.hyperledger.besu.ethereum.core.WithdrawalRequest; - -import java.util.List; -import java.util.Optional; -import java.util.stream.IntStream; - -import org.apache.tuweni.bytes.Bytes32; -import org.apache.tuweni.bytes.Bytes48; - -public class WithdrawalRequestValidatorTestFixtures { - - private static final BlockDataGenerator blockDataGenerator = new BlockDataGenerator(); - - static WithdrawalRequestTestParameter blockWithWithdrawalRequestsAndWithdrawalRequestsRoot() { - final WithdrawalRequest withdrawalRequest = createWithdrawalRequest(); - final Optional> maybeWithdrawalRequests = - Optional.of(java.util.List.of(withdrawalRequest)); - - final BlockDataGenerator.BlockOptions blockOptions = - BlockDataGenerator.BlockOptions.create() - .setRequestsRoot(BodyValidation.requestsRoot(maybeWithdrawalRequests.get())) - .setRequests(maybeWithdrawalRequests); - final Block block = blockDataGenerator.block(blockOptions); - - return new WithdrawalRequestTestParameter( - "Block with withdrawal requests and withdrawal_requests_root", - block, - Optional.of(java.util.List.of(withdrawalRequest))); - } - - static WithdrawalRequestTestParameter blockWithoutWithdrawalRequestsWithWithdrawalRequestsRoot() { - final BlockDataGenerator.BlockOptions blockOptions = - BlockDataGenerator.BlockOptions.create() - .setRequestsRoot(Hash.EMPTY) - .setRequests(Optional.empty()); - final Block block = blockDataGenerator.block(blockOptions); - - return new WithdrawalRequestTestParameter( - "Block with withdrawal_requests_root but without withdrawal requests", - block, - Optional.empty()); - } - - static WithdrawalRequestTestParameter blockWithWithdrawalRequestsWithoutWithdrawalRequestsRoot() { - final WithdrawalRequest withdrawalRequest = createWithdrawalRequest(); - final Optional> requests = Optional.of(java.util.List.of(withdrawalRequest)); - - final BlockDataGenerator.BlockOptions blockOptions = - BlockDataGenerator.BlockOptions.create().setRequests(requests); - final Block block = blockDataGenerator.block(blockOptions); - - return new WithdrawalRequestTestParameter( - "Block with withdrawal requests but without withdrawal_requests_root", - block, - Optional.of(java.util.List.of(withdrawalRequest))); - } - - static WithdrawalRequestTestParameter blockWithoutWithdrawalRequestsAndWithdrawalRequestsRoot() { - - final BlockDataGenerator.BlockOptions blockOptions = - BlockDataGenerator.BlockOptions.create().setRequests(Optional.empty()); - final Block block = blockDataGenerator.block(blockOptions); - - return new WithdrawalRequestTestParameter( - "Block without withdrawal requests and withdrawal_requests_root", block, Optional.empty()); - } - - static WithdrawalRequestTestParameter blockWithWithdrawalRequestsRootMismatch() { - final WithdrawalRequest withdrawalRequest = createWithdrawalRequest(); - - final Optional> requests = Optional.of(java.util.List.of(withdrawalRequest)); - - final BlockDataGenerator.BlockOptions blockOptions = - BlockDataGenerator.BlockOptions.create().setRequestsRoot(Hash.EMPTY).setRequests(requests); - final Block block = blockDataGenerator.block(blockOptions); - - return new WithdrawalRequestTestParameter( - "Block with withdrawal_requests_root mismatch", - block, - Optional.of(java.util.List.of(withdrawalRequest))); - } - - static WithdrawalRequestTestParameter blockWithWithdrawalRequestsMismatch() { - final WithdrawalRequest withdrawalRequest = createWithdrawalRequest(); - - final Optional> requests = - Optional.of(java.util.List.of(withdrawalRequest, withdrawalRequest)); - - final BlockDataGenerator.BlockOptions blockOptions = - BlockDataGenerator.BlockOptions.create() - .setRequestsRoot(BodyValidation.requestsRoot(requests.get())) - .setRequests(requests); - final Block block = blockDataGenerator.block(blockOptions); - - return new WithdrawalRequestTestParameter( - "Block with withdrawal requests mismatch", - block, - Optional.of(java.util.List.of(withdrawalRequest, withdrawalRequest)), - List.of(createWithdrawalRequest())); - } - - static WithdrawalRequestTestParameter blockWithMoreThanMaximumWithdrawalRequests() { - final List withdrawalRequest = - IntStream.range(0, MAX_WITHDRAWAL_REQUESTS_PER_BLOCK + 1) - .mapToObj(__ -> createWithdrawalRequest()) - .toList(); - - final Optional> maybeWithdrawalRequest = Optional.of(withdrawalRequest); - final Optional> maybeRequests = - Optional.of(withdrawalRequest.stream().map(r -> (Request) r).toList()); - - final BlockDataGenerator.BlockOptions blockOptions = - BlockDataGenerator.BlockOptions.create() - .setRequestsRoot(BodyValidation.requestsRoot(maybeRequests.get())) - .setRequests(maybeRequests); - final Block block = blockDataGenerator.block(blockOptions); - - return new WithdrawalRequestTestParameter( - "Block with more than maximum withdrawal requests", block, maybeWithdrawalRequest); - } - - static WithdrawalRequest createWithdrawalRequest() { - return new WithdrawalRequest( - Address.extract(Bytes32.random()), BLSPublicKey.wrap(Bytes48.random()), GWei.ONE); - } - - static class WithdrawalRequestTestParameter { - - String description; - Block block; - Optional> maybeWithdrawalRequest; - List expectedWithdrawalRequest; - - public WithdrawalRequestTestParameter( - final String description, - final Block block, - final Optional> maybeWithdrawalRequest) { - this( - description, - block, - maybeWithdrawalRequest, - maybeWithdrawalRequest.orElseGet(java.util.List::of)); - } - - public WithdrawalRequestTestParameter( - final String description, - final Block block, - final Optional> maybeWithdrawalRequest, - final List expectedWithdrawalRequest) { - this.description = description; - this.block = block; - this.maybeWithdrawalRequest = maybeWithdrawalRequest; - this.expectedWithdrawalRequest = expectedWithdrawalRequest; - } - - @Override - public String toString() { - return description; - } - } -} diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/requests/MainnetRequestsValidatorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/requests/MainnetRequestsValidatorTest.java new file mode 100644 index 0000000000..410a726304 --- /dev/null +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/requests/MainnetRequestsValidatorTest.java @@ -0,0 +1,58 @@ +/* + * Copyright contributors to 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.requests; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.hyperledger.besu.datatypes.RequestType; +import org.hyperledger.besu.ethereum.core.Request; + +import java.util.List; +import java.util.Optional; + +import org.apache.tuweni.bytes.Bytes; +import org.junit.jupiter.api.Test; + +class MainnetRequestsValidatorTest { + + @Test + void validateFalseWhenNoRequests() { + MainnetRequestsValidator validator = new MainnetRequestsValidator(); + assertFalse(validator.validate(Optional.empty())); + } + + @Test + void validateFalseWhenRequestsNotInOrder() { + MainnetRequestsValidator validator = new MainnetRequestsValidator(); + List requests = + List.of( + new Request(RequestType.WITHDRAWAL, Bytes.of(3)), + new Request(RequestType.DEPOSIT, Bytes.of(1)), + new Request(RequestType.CONSOLIDATION, Bytes.of(2))); + assertFalse(validator.validate(Optional.of(requests))); + } + + @Test + void validateTrueForValidRequests() { + MainnetRequestsValidator validator = new MainnetRequestsValidator(); + List requests = + List.of( + new Request(RequestType.DEPOSIT, Bytes.of(1)), + new Request(RequestType.WITHDRAWAL, Bytes.of(2)), + new Request(RequestType.CONSOLIDATION, Bytes.of(3))); + assertTrue(validator.validate(Optional.of(requests))); + } +} diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/requests/ProhibitedRequestValidatorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/requests/ProhibitedRequestValidatorTest.java new file mode 100644 index 0000000000..3694a58a4b --- /dev/null +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/requests/ProhibitedRequestValidatorTest.java @@ -0,0 +1,47 @@ +/* + * Copyright contributors to 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.requests; + +import org.hyperledger.besu.datatypes.RequestType; +import org.hyperledger.besu.ethereum.core.Request; + +import java.util.List; +import java.util.Optional; + +import org.apache.tuweni.bytes.Bytes; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; + +class ProhibitedRequestValidatorTest { + + @Test + void validateTrueWhenNoRequests() { + ProhibitedRequestValidator validator = new ProhibitedRequestValidator(); + Assertions.assertThat(validator.validate(Optional.empty())).isTrue(); + } + + @Test + void validateFalseWhenHasEmptyListOfRequests() { + ProhibitedRequestValidator validator = new ProhibitedRequestValidator(); + Assertions.assertThat(validator.validate(Optional.of(List.of()))).isFalse(); + } + + @Test + void validateFalseWhenHasRequests() { + ProhibitedRequestValidator validator = new ProhibitedRequestValidator(); + List requests = List.of(new Request(RequestType.DEPOSIT, Bytes.of(1))); + Assertions.assertThat(validator.validate(Optional.of(requests))).isFalse(); + } +} diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/transaction/TransactionSimulatorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/transaction/TransactionSimulatorTest.java index 73fa402abb..c6c676c415 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/transaction/TransactionSimulatorTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/transaction/TransactionSimulatorTest.java @@ -858,6 +858,7 @@ public class TransactionSimulatorTest { final int numberOfBlobs) { BlobsWithCommitments bwc = new BlobTestFixture().createBlobsWithCommitments(numberOfBlobs); return new CallParameter( + Optional.of(BigInteger.ONE), Address.fromHexString("0x0"), Address.fromHexString("0x0"), gasLimit, diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/BonsaiWorldStateKeyValueStorageTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/BonsaiWorldStateKeyValueStorageTest.java index 02818407b4..464f35bae7 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/BonsaiWorldStateKeyValueStorageTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/BonsaiWorldStateKeyValueStorageTest.java @@ -17,7 +17,7 @@ package org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage; import static org.assertj.core.api.Assertions.assertThat; import static org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier.TRIE_BRANCH_STORAGE; import static org.hyperledger.besu.ethereum.trie.diffbased.common.storage.DiffBasedWorldStateKeyValueStorage.WORLD_ROOT_HASH_KEY; -import static org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration.DEFAULT_BONSAI_MAX_LAYERS_TO_LOAD; +import static org.hyperledger.besu.ethereum.worldstate.DiffBasedSubStorageConfiguration.DEFAULT_MAX_LAYERS_TO_LOAD; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; @@ -40,6 +40,7 @@ import org.hyperledger.besu.ethereum.trie.patricia.StoredMerklePatriciaTrie; import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; import org.hyperledger.besu.ethereum.worldstate.FlatDbMode; import org.hyperledger.besu.ethereum.worldstate.ImmutableDataStorageConfiguration; +import org.hyperledger.besu.ethereum.worldstate.ImmutableDiffBasedSubStorageConfiguration; import org.hyperledger.besu.ethereum.worldstate.StateTrieAccountValue; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; @@ -472,10 +473,13 @@ public class BonsaiWorldStateKeyValueStorageTest { new NoOpMetricsSystem(), ImmutableDataStorageConfiguration.builder() .dataStorageFormat(DataStorageFormat.BONSAI) - .bonsaiMaxLayersToLoad(DEFAULT_BONSAI_MAX_LAYERS_TO_LOAD) - .unstable( - ImmutableDataStorageConfiguration.Unstable.builder() - .bonsaiCodeStoredByCodeHashEnabled(useCodeHashStorage) + .diffBasedSubStorageConfiguration( + ImmutableDiffBasedSubStorageConfiguration.builder() + .maxLayersToLoad(DEFAULT_MAX_LAYERS_TO_LOAD) + .unstable( + ImmutableDiffBasedSubStorageConfiguration.DiffBasedUnstable.builder() + .codeStoredByCodeHashEnabled(useCodeHashStorage) + .build()) .build()) .build()); } diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/common/storage/flat/FlatDbStrategyProviderTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/common/storage/flat/BonsaiFlatDbStrategyProviderTest.java similarity index 74% rename from ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/common/storage/flat/FlatDbStrategyProviderTest.java rename to ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/common/storage/flat/BonsaiFlatDbStrategyProviderTest.java index b3c709b89f..08b821bd67 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/common/storage/flat/FlatDbStrategyProviderTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/common/storage/flat/BonsaiFlatDbStrategyProviderTest.java @@ -15,15 +15,17 @@ package org.hyperledger.besu.ethereum.trie.diffbased.common.storage.flat; import static org.assertj.core.api.Assertions.assertThat; -import static org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration.DEFAULT_BONSAI_MAX_LAYERS_TO_LOAD; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier; -import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.flat.FullFlatDbStrategy; -import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.flat.PartialFlatDbStrategy; +import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.flat.BonsaiFlatDbStrategyProvider; +import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.flat.BonsaiFullFlatDbStrategy; +import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.flat.BonsaiPartialFlatDbStrategy; import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; +import org.hyperledger.besu.ethereum.worldstate.DiffBasedSubStorageConfiguration; import org.hyperledger.besu.ethereum.worldstate.FlatDbMode; import org.hyperledger.besu.ethereum.worldstate.ImmutableDataStorageConfiguration; +import org.hyperledger.besu.ethereum.worldstate.ImmutableDiffBasedSubStorageConfiguration; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; import org.hyperledger.besu.plugin.services.storage.SegmentedKeyValueStorage; @@ -42,9 +44,10 @@ import org.junit.jupiter.params.provider.ValueSource; import org.mockito.junit.jupiter.MockitoExtension; @ExtendWith(MockitoExtension.class) -class FlatDbStrategyProviderTest { - private final FlatDbStrategyProvider flatDbStrategyProvider = - new FlatDbStrategyProvider(new NoOpMetricsSystem(), DataStorageConfiguration.DEFAULT_CONFIG); +class BonsaiFlatDbStrategyProviderTest { + private final BonsaiFlatDbStrategyProvider flatDbStrategyProvider = + new BonsaiFlatDbStrategyProvider( + new NoOpMetricsSystem(), DataStorageConfiguration.DEFAULT_CONFIG); private final SegmentedKeyValueStorage composedWorldStateStorage = new SegmentedInMemoryKeyValueStorage( List.of( @@ -74,7 +77,7 @@ class FlatDbStrategyProviderTest { assertThat(flatDbStrategyProvider.flatDbMode).isEqualTo(FlatDbMode.FULL); assertThat(flatDbStrategyProvider.flatDbStrategy).isNotNull(); assertThat(flatDbStrategyProvider.getFlatDbStrategy(composedWorldStateStorage)) - .isInstanceOf(FullFlatDbStrategy.class); + .isInstanceOf(BonsaiFullFlatDbStrategy.class); assertThat(flatDbStrategyProvider.flatDbStrategy.codeStorageStrategy) .isInstanceOf(CodeHashCodeStorageStrategy.class); } @@ -85,14 +88,17 @@ class FlatDbStrategyProviderTest { final DataStorageConfiguration dataStorageConfiguration = ImmutableDataStorageConfiguration.builder() .dataStorageFormat(DataStorageFormat.BONSAI) - .bonsaiMaxLayersToLoad(DEFAULT_BONSAI_MAX_LAYERS_TO_LOAD) - .unstable( - ImmutableDataStorageConfiguration.Unstable.builder() - .bonsaiCodeStoredByCodeHashEnabled(codeByHashEnabled) + .diffBasedSubStorageConfiguration( + ImmutableDiffBasedSubStorageConfiguration.builder() + .maxLayersToLoad(DiffBasedSubStorageConfiguration.DEFAULT_MAX_LAYERS_TO_LOAD) + .unstable( + ImmutableDiffBasedSubStorageConfiguration.DiffBasedUnstable.builder() + .codeStoredByCodeHashEnabled(codeByHashEnabled) + .build()) .build()) .build(); - final FlatDbStrategyProvider flatDbStrategyProvider = - new FlatDbStrategyProvider(new NoOpMetricsSystem(), dataStorageConfiguration); + final BonsaiFlatDbStrategyProvider flatDbStrategyProvider = + new BonsaiFlatDbStrategyProvider(new NoOpMetricsSystem(), dataStorageConfiguration); flatDbStrategyProvider.loadFlatDbStrategy(composedWorldStateStorage); final Class expectedCodeStorageClass = @@ -110,14 +116,17 @@ class FlatDbStrategyProviderTest { final DataStorageConfiguration dataStorageConfiguration = ImmutableDataStorageConfiguration.builder() .dataStorageFormat(DataStorageFormat.BONSAI) - .bonsaiMaxLayersToLoad(DEFAULT_BONSAI_MAX_LAYERS_TO_LOAD) - .unstable( - ImmutableDataStorageConfiguration.Unstable.builder() - .bonsaiCodeStoredByCodeHashEnabled(codeByHashEnabled) + .diffBasedSubStorageConfiguration( + ImmutableDiffBasedSubStorageConfiguration.builder() + .maxLayersToLoad(DiffBasedSubStorageConfiguration.DEFAULT_MAX_LAYERS_TO_LOAD) + .unstable( + ImmutableDiffBasedSubStorageConfiguration.DiffBasedUnstable.builder() + .codeStoredByCodeHashEnabled(codeByHashEnabled) + .build()) .build()) .build(); - final FlatDbStrategyProvider flatDbStrategyProvider = - new FlatDbStrategyProvider(new NoOpMetricsSystem(), dataStorageConfiguration); + final BonsaiFlatDbStrategyProvider flatDbStrategyProvider = + new BonsaiFlatDbStrategyProvider(new NoOpMetricsSystem(), dataStorageConfiguration); final SegmentedKeyValueStorageTransaction transaction = composedWorldStateStorage.startTransaction(); @@ -140,14 +149,17 @@ class FlatDbStrategyProviderTest { final DataStorageConfiguration dataStorageConfiguration = ImmutableDataStorageConfiguration.builder() .dataStorageFormat(DataStorageFormat.BONSAI) - .bonsaiMaxLayersToLoad(DEFAULT_BONSAI_MAX_LAYERS_TO_LOAD) - .unstable( - ImmutableDataStorageConfiguration.Unstable.builder() - .bonsaiCodeStoredByCodeHashEnabled(codeByHashEnabled) + .diffBasedSubStorageConfiguration( + ImmutableDiffBasedSubStorageConfiguration.builder() + .maxLayersToLoad(DiffBasedSubStorageConfiguration.DEFAULT_MAX_LAYERS_TO_LOAD) + .unstable( + ImmutableDiffBasedSubStorageConfiguration.DiffBasedUnstable.builder() + .codeStoredByCodeHashEnabled(codeByHashEnabled) + .build()) .build()) .build(); - final FlatDbStrategyProvider flatDbStrategyProvider = - new FlatDbStrategyProvider(new NoOpMetricsSystem(), dataStorageConfiguration); + final BonsaiFlatDbStrategyProvider flatDbStrategyProvider = + new BonsaiFlatDbStrategyProvider(new NoOpMetricsSystem(), dataStorageConfiguration); final SegmentedKeyValueStorageTransaction transaction = composedWorldStateStorage.startTransaction(); @@ -171,7 +183,7 @@ class FlatDbStrategyProviderTest { assertThat(flatDbStrategyProvider.flatDbMode).isEqualTo(FlatDbMode.PARTIAL); assertThat(flatDbStrategyProvider.flatDbStrategy).isNotNull(); assertThat(flatDbStrategyProvider.getFlatDbStrategy(composedWorldStateStorage)) - .isInstanceOf(PartialFlatDbStrategy.class); + .isInstanceOf(BonsaiPartialFlatDbStrategy.class); } private void updateFlatDbMode(final FlatDbMode flatDbMode) { diff --git a/ethereum/core/src/test/resources/org/hyperledger/besu/ethereum/chain/genesis_prague.json b/ethereum/core/src/test/resources/org/hyperledger/besu/ethereum/chain/genesis_prague.json index d99071b328..f9aa3ff466 100644 --- a/ethereum/core/src/test/resources/org/hyperledger/besu/ethereum/chain/genesis_prague.json +++ b/ethereum/core/src/test/resources/org/hyperledger/besu/ethereum/chain/genesis_prague.json @@ -4073,5 +4073,6 @@ "number": "0x0", "gasUsed": "0x0", "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "baseFeePerGas": "0x3b9aca00" + "baseFeePerGas": "0x3b9aca00", + "targetBlobCount": "0x1" } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/EthPeers.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/EthPeers.java index d1a54d4d3d..d19c7dfca2 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/EthPeers.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/EthPeers.java @@ -17,6 +17,7 @@ package org.hyperledger.besu.ethereum.eth.manager; import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.eth.SnapProtocol; import org.hyperledger.besu.ethereum.eth.manager.EthPeer.DisconnectCallback; +import org.hyperledger.besu.ethereum.eth.manager.peertask.PeerSelector; import org.hyperledger.besu.ethereum.eth.peervalidation.PeerValidator; import org.hyperledger.besu.ethereum.eth.sync.ChainHeadTracker; import org.hyperledger.besu.ethereum.eth.sync.SnapServerChecker; @@ -26,6 +27,7 @@ import org.hyperledger.besu.ethereum.forkid.ForkId; import org.hyperledger.besu.ethereum.forkid.ForkIdManager; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; import org.hyperledger.besu.ethereum.p2p.peers.Peer; +import org.hyperledger.besu.ethereum.p2p.peers.PeerId; import org.hyperledger.besu.ethereum.p2p.rlpx.RlpxAgent; import org.hyperledger.besu.ethereum.p2p.rlpx.connections.PeerConnection; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.messages.DisconnectMessage; @@ -61,7 +63,7 @@ import org.apache.tuweni.bytes.Bytes; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class EthPeers { +public class EthPeers implements PeerSelector { private static final Logger LOG = LoggerFactory.getLogger(EthPeers.class); public static final Comparator TOTAL_DIFFICULTY = Comparator.comparing((final EthPeer p) -> p.chainState().getEstimatedTotalDifficulty()); @@ -465,6 +467,22 @@ public class EthPeers { this.trailingPeerRequirementsSupplier = tprSupplier; } + // Part of the PeerSelector interface, to be split apart later + @Override + public Optional getPeer(final Predicate filter) { + return streamAvailablePeers() + .filter(filter) + .filter(EthPeer::hasAvailableRequestCapacity) + .filter(EthPeer::isFullyValidated) + .min(LEAST_TO_MOST_BUSY); + } + + // Part of the PeerSelector interface, to be split apart later + @Override + public Optional getPeerByPeerId(final PeerId peerId) { + return Optional.ofNullable(activeConnections.get(peerId.getId())); + } + @FunctionalInterface public interface ConnectCallback { void onPeerConnected(EthPeer newPeer); diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/peertask/InvalidPeerTaskResponseException.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/peertask/InvalidPeerTaskResponseException.java new file mode 100644 index 0000000000..824c0860d7 --- /dev/null +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/peertask/InvalidPeerTaskResponseException.java @@ -0,0 +1,26 @@ +/* + * 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.eth.manager.peertask; + +public class InvalidPeerTaskResponseException extends Exception { + + public InvalidPeerTaskResponseException() { + super(); + } + + public InvalidPeerTaskResponseException(final Throwable cause) { + super(cause); + } +} diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/peertask/NoAvailablePeerException.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/peertask/NoAvailablePeerException.java new file mode 100644 index 0000000000..40c600d6fb --- /dev/null +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/peertask/NoAvailablePeerException.java @@ -0,0 +1,17 @@ +/* + * 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.eth.manager.peertask; + +public class NoAvailablePeerException extends Exception {} diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/peertask/PeerSelector.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/peertask/PeerSelector.java new file mode 100644 index 0000000000..8f7ab33e42 --- /dev/null +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/peertask/PeerSelector.java @@ -0,0 +1,42 @@ +/* + * 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.eth.manager.peertask; + +import org.hyperledger.besu.ethereum.eth.manager.EthPeer; +import org.hyperledger.besu.ethereum.p2p.peers.PeerId; + +import java.util.Optional; +import java.util.function.Predicate; + +/** Selects the EthPeers for the PeerTaskExecutor */ +public interface PeerSelector { + + /** + * Gets a peer matching the supplied filter + * + * @param filter a Predicate\ matching desirable peers + * @return a peer matching the supplied conditions + */ + Optional getPeer(final Predicate filter); + + /** + * Attempts to get the EthPeer identified by peerId + * + * @param peerId the peerId of the desired EthPeer + * @return An Optional\ containing the EthPeer identified by peerId if present in the + * PeerSelector, or empty otherwise + */ + Optional getPeerByPeerId(PeerId peerId); +} diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/peertask/PeerTask.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/peertask/PeerTask.java new file mode 100644 index 0000000000..1243846ac3 --- /dev/null +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/peertask/PeerTask.java @@ -0,0 +1,83 @@ +/* + * 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.eth.manager.peertask; + +import org.hyperledger.besu.ethereum.eth.manager.EthPeer; +import org.hyperledger.besu.ethereum.p2p.rlpx.wire.MessageData; +import org.hyperledger.besu.ethereum.p2p.rlpx.wire.SubProtocol; + +import java.util.function.Predicate; + +/** + * Represents a task to be executed on an EthPeer by the PeerTaskExecutor + * + * @param The type of the result of this PeerTask + */ +public interface PeerTask { + /** + * Returns the SubProtocol used for this PeerTask + * + * @return the SubProtocol used for this PeerTask + */ + SubProtocol getSubProtocol(); + + /** + * Gets the request data to send to the EthPeer + * + * @return the request data to send to the EthPeer + */ + MessageData getRequestMessage(); + + /** + * Parses the MessageData response from the EthPeer + * + * @param messageData the response MessageData to be parsed + * @return a T built from the response MessageData + * @throws InvalidPeerTaskResponseException if the response messageData is invalid + */ + T parseResponse(MessageData messageData) throws InvalidPeerTaskResponseException; + + /** + * Gets the number of times this task may be attempted against other peers + * + * @return the number of times this task may be attempted against other peers + */ + default int getRetriesWithOtherPeer() { + return 5; + } + + /** + * Gets the number of times this task may be attempted against the same peer + * + * @return the number of times this task may be attempted against the same peer + */ + default int getRetriesWithSamePeer() { + return 5; + } + + /** + * Gets a Predicate that checks if an EthPeer is suitable for this PeerTask + * + * @return a Predicate that checks if an EthPeer is suitable for this PeerTask + */ + Predicate getPeerRequirementFilter(); + + /** + * Checks if the supplied result is considered a success + * + * @return true if the supplied result is considered a success + */ + boolean isSuccess(T result); +} diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/peertask/PeerTaskExecutor.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/peertask/PeerTaskExecutor.java new file mode 100644 index 0000000000..984cedccec --- /dev/null +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/peertask/PeerTaskExecutor.java @@ -0,0 +1,196 @@ +/* + * 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.eth.manager.peertask; + +import org.hyperledger.besu.ethereum.eth.manager.EthPeer; +import org.hyperledger.besu.ethereum.p2p.rlpx.connections.PeerConnection.PeerNotConnected; +import org.hyperledger.besu.ethereum.p2p.rlpx.wire.MessageData; +import org.hyperledger.besu.metrics.BesuMetricCategory; +import org.hyperledger.besu.plugin.services.MetricsSystem; +import org.hyperledger.besu.plugin.services.metrics.Counter; +import org.hyperledger.besu.plugin.services.metrics.LabelledGauge; +import org.hyperledger.besu.plugin.services.metrics.LabelledMetric; +import org.hyperledger.besu.plugin.services.metrics.OperationTimer; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicInteger; + +/** Manages the execution of PeerTasks, respecting their PeerTaskRetryBehavior */ +public class PeerTaskExecutor { + + private final PeerSelector peerSelector; + private final PeerTaskRequestSender requestSender; + + private final LabelledMetric requestTimer; + private final LabelledMetric timeoutCounter; + private final LabelledMetric invalidResponseCounter; + private final LabelledMetric internalExceptionCounter; + private final LabelledGauge inflightRequestGauge; + private final Map inflightRequestCountByClassName; + + public PeerTaskExecutor( + final PeerSelector peerSelector, + final PeerTaskRequestSender requestSender, + final MetricsSystem metricsSystem) { + this.peerSelector = peerSelector; + this.requestSender = requestSender; + requestTimer = + metricsSystem.createLabelledTimer( + BesuMetricCategory.PEERS, + "request_time", + "Time taken to send a request and receive a response", + "taskName"); + timeoutCounter = + metricsSystem.createLabelledCounter( + BesuMetricCategory.PEERS, + "timeout_total", + "Counter of the number of timeouts occurred", + "taskName"); + invalidResponseCounter = + metricsSystem.createLabelledCounter( + BesuMetricCategory.PEERS, + "invalid_response_total", + "Counter of the number of invalid responses received", + "taskName"); + internalExceptionCounter = + metricsSystem.createLabelledCounter( + BesuMetricCategory.PEERS, + "internal_exception_total", + "Counter of the number of internal exceptions occurred", + "taskName"); + inflightRequestGauge = + metricsSystem.createLabelledGauge( + BesuMetricCategory.PEERS, + "inflight_request_gauge", + "Gauge of the number of inflight requests", + "taskName"); + inflightRequestCountByClassName = new ConcurrentHashMap<>(); + } + + public PeerTaskExecutorResult execute(final PeerTask peerTask) { + PeerTaskExecutorResult executorResult; + int retriesRemaining = peerTask.getRetriesWithOtherPeer(); + final Collection usedEthPeers = new HashSet<>(); + do { + Optional peer = + peerSelector.getPeer( + (candidatePeer) -> + peerTask.getPeerRequirementFilter().test(candidatePeer) + && !usedEthPeers.contains(candidatePeer)); + if (peer.isEmpty()) { + executorResult = + new PeerTaskExecutorResult<>( + Optional.empty(), PeerTaskExecutorResponseCode.NO_PEER_AVAILABLE); + continue; + } + usedEthPeers.add(peer.get()); + executorResult = executeAgainstPeer(peerTask, peer.get()); + } while (retriesRemaining-- > 0 + && executorResult.responseCode() != PeerTaskExecutorResponseCode.SUCCESS); + + return executorResult; + } + + public PeerTaskExecutorResult executeAgainstPeer( + final PeerTask peerTask, final EthPeer peer) { + String taskClassName = peerTask.getClass().getSimpleName(); + AtomicInteger inflightRequestCountForThisTaskClass = + inflightRequestCountByClassName.computeIfAbsent( + taskClassName, + (k) -> { + AtomicInteger inflightRequests = new AtomicInteger(0); + inflightRequestGauge.labels(inflightRequests::get, taskClassName); + return inflightRequests; + }); + MessageData requestMessageData = peerTask.getRequestMessage(); + PeerTaskExecutorResult executorResult; + int retriesRemaining = peerTask.getRetriesWithSamePeer(); + do { + try { + T result; + try (final OperationTimer.TimingContext ignored = + requestTimer.labels(taskClassName).startTimer()) { + inflightRequestCountForThisTaskClass.incrementAndGet(); + + MessageData responseMessageData = + requestSender.sendRequest(peerTask.getSubProtocol(), requestMessageData, peer); + + result = peerTask.parseResponse(responseMessageData); + } finally { + inflightRequestCountForThisTaskClass.decrementAndGet(); + } + + if (peerTask.isSuccess(result)) { + peer.recordUsefulResponse(); + executorResult = + new PeerTaskExecutorResult<>( + Optional.ofNullable(result), PeerTaskExecutorResponseCode.SUCCESS); + } else { + // At this point, the result is most likely empty. Technically, this is a valid result, so + // we don't penalise the peer, but it's also a useless result, so we return + // INVALID_RESPONSE code + executorResult = + new PeerTaskExecutorResult<>( + Optional.ofNullable(result), PeerTaskExecutorResponseCode.INVALID_RESPONSE); + } + + } catch (PeerNotConnected e) { + executorResult = + new PeerTaskExecutorResult<>( + Optional.empty(), PeerTaskExecutorResponseCode.PEER_DISCONNECTED); + + } catch (InterruptedException | TimeoutException e) { + peer.recordRequestTimeout(requestMessageData.getCode()); + timeoutCounter.labels(taskClassName).inc(); + executorResult = + new PeerTaskExecutorResult<>(Optional.empty(), PeerTaskExecutorResponseCode.TIMEOUT); + + } catch (InvalidPeerTaskResponseException e) { + peer.recordUselessResponse(e.getMessage()); + invalidResponseCounter.labels(taskClassName).inc(); + executorResult = + new PeerTaskExecutorResult<>( + Optional.empty(), PeerTaskExecutorResponseCode.INVALID_RESPONSE); + + } catch (ExecutionException e) { + internalExceptionCounter.labels(taskClassName).inc(); + executorResult = + new PeerTaskExecutorResult<>( + Optional.empty(), PeerTaskExecutorResponseCode.INTERNAL_SERVER_ERROR); + } + } while (retriesRemaining-- > 0 + && executorResult.responseCode() != PeerTaskExecutorResponseCode.SUCCESS + && executorResult.responseCode() != PeerTaskExecutorResponseCode.PEER_DISCONNECTED + && sleepBetweenRetries()); + + return executorResult; + } + + private boolean sleepBetweenRetries() { + try { + // sleep for 1 second to match implemented wait between retries in AbstractRetryingPeerTask + Thread.sleep(1000); + return true; + } catch (InterruptedException e) { + return false; + } + } +} diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/peertask/PeerTaskExecutorResponseCode.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/peertask/PeerTaskExecutorResponseCode.java new file mode 100644 index 0000000000..327461de15 --- /dev/null +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/peertask/PeerTaskExecutorResponseCode.java @@ -0,0 +1,24 @@ +/* + * 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.eth.manager.peertask; + +public enum PeerTaskExecutorResponseCode { + SUCCESS, + NO_PEER_AVAILABLE, + PEER_DISCONNECTED, + INTERNAL_SERVER_ERROR, + TIMEOUT, + INVALID_RESPONSE +} diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/peertask/PeerTaskExecutorResult.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/peertask/PeerTaskExecutorResult.java new file mode 100644 index 0000000000..86dec85c29 --- /dev/null +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/peertask/PeerTaskExecutorResult.java @@ -0,0 +1,20 @@ +/* + * 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.eth.manager.peertask; + +import java.util.Optional; + +public record PeerTaskExecutorResult( + Optional result, PeerTaskExecutorResponseCode responseCode) {} diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/peertask/PeerTaskRequestSender.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/peertask/PeerTaskRequestSender.java new file mode 100644 index 0000000000..7a597eca8e --- /dev/null +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/peertask/PeerTaskRequestSender.java @@ -0,0 +1,56 @@ +/* + * 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.eth.manager.peertask; + +import org.hyperledger.besu.ethereum.eth.manager.EthPeer; +import org.hyperledger.besu.ethereum.eth.manager.RequestManager.ResponseStream; +import org.hyperledger.besu.ethereum.p2p.rlpx.connections.PeerConnection; +import org.hyperledger.besu.ethereum.p2p.rlpx.wire.MessageData; +import org.hyperledger.besu.ethereum.p2p.rlpx.wire.SubProtocol; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +public class PeerTaskRequestSender { + private static final long DEFAULT_TIMEOUT_MS = 5_000; + + private final long timeoutMs; + + public PeerTaskRequestSender() { + this.timeoutMs = DEFAULT_TIMEOUT_MS; + } + + public PeerTaskRequestSender(final long timeoutMs) { + this.timeoutMs = timeoutMs; + } + + public MessageData sendRequest( + final SubProtocol subProtocol, final MessageData requestMessageData, final EthPeer ethPeer) + throws PeerConnection.PeerNotConnected, + ExecutionException, + InterruptedException, + TimeoutException { + ResponseStream responseStream = + ethPeer.send(requestMessageData, subProtocol.getName(), ethPeer.getConnection()); + final CompletableFuture responseMessageDataFuture = new CompletableFuture<>(); + responseStream.then( + (boolean streamClosed, MessageData message, EthPeer peer) -> { + responseMessageDataFuture.complete(message); + }); + return responseMessageDataFuture.get(timeoutMs, TimeUnit.MILLISECONDS); + } +} diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/SnapServer.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/SnapServer.java index dcbd97ed66..4490430699 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/SnapServer.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/SnapServer.java @@ -26,7 +26,6 @@ import org.hyperledger.besu.ethereum.eth.messages.snap.GetTrieNodesMessage; import org.hyperledger.besu.ethereum.eth.messages.snap.SnapV1; import org.hyperledger.besu.ethereum.eth.messages.snap.StorageRangeMessage; import org.hyperledger.besu.ethereum.eth.messages.snap.TrieNodesMessage; -import org.hyperledger.besu.ethereum.eth.sync.DefaultSynchronizer; import org.hyperledger.besu.ethereum.eth.sync.snapsync.SnapSyncConfiguration; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.MessageData; import org.hyperledger.besu.ethereum.proof.WorldStateProofProvider; @@ -50,7 +49,6 @@ import java.util.NavigableMap; import java.util.Optional; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicLong; import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -85,7 +83,6 @@ class SnapServer implements BesuEvents.InitialSyncCompletionListener { static final Hash HASH_LAST = Hash.wrap(Bytes32.leftPad(Bytes.fromHexString("FF"), (byte) 0xFF)); private final AtomicBoolean isStarted = new AtomicBoolean(false); - private final AtomicLong listenerId = new AtomicLong(); private final EthMessages snapMessages; private final WorldStateStorageCoordinator worldStateStorageCoordinator; @@ -112,14 +109,9 @@ class SnapServer implements BesuEvents.InitialSyncCompletionListener { this.protocolContext = Optional.of(protocolContext); registerResponseConstructors(); - // subscribe to initial sync completed events to start/stop snap server: - this.protocolContext - .flatMap(ProtocolContext::getSynchronizer) - .filter(z -> z instanceof DefaultSynchronizer) - .map(DefaultSynchronizer.class::cast) - .ifPresentOrElse( - z -> this.listenerId.set(z.subscribeInitialSync(this)), - () -> LOGGER.warn("SnapServer created without reference to sync status")); + // subscribe to initial sync completed events to start/stop snap server, + // not saving the listenerId since we never need to unsubscribe. + protocolContext.getSynchronizer().subscribeInitialSync(this); } /** diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/task/GetBodiesFromPeerTask.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/task/GetBodiesFromPeerTask.java index 56a85b040b..dcacb31289 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/task/GetBodiesFromPeerTask.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/task/GetBodiesFromPeerTask.java @@ -20,7 +20,6 @@ import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.core.Block; import org.hyperledger.besu.ethereum.core.BlockBody; import org.hyperledger.besu.ethereum.core.BlockHeader; -import org.hyperledger.besu.ethereum.core.Request; import org.hyperledger.besu.ethereum.core.Transaction; import org.hyperledger.besu.ethereum.core.Withdrawal; import org.hyperledger.besu.ethereum.eth.manager.EthContext; @@ -151,41 +150,34 @@ public class GetBodiesFromPeerTask extends AbstractPeerRequestTask> private final Bytes32 transactionsRoot; private final Bytes32 ommersHash; private final Bytes32 withdrawalsRoot; - private final Bytes32 requestsRoot; + // TODO should requestsHash be included in this? public BodyIdentifier( - final Bytes32 transactionsRoot, - final Bytes32 ommersHash, - final Bytes32 withdrawalsRoot, - final Bytes32 requestsRoot) { + final Bytes32 transactionsRoot, final Bytes32 ommersHash, final Bytes32 withdrawalsRoot) { this.transactionsRoot = transactionsRoot; this.ommersHash = ommersHash; this.withdrawalsRoot = withdrawalsRoot; - this.requestsRoot = requestsRoot; } public BodyIdentifier(final BlockBody body) { - this(body.getTransactions(), body.getOmmers(), body.getWithdrawals(), body.getRequests()); + this(body.getTransactions(), body.getOmmers(), body.getWithdrawals()); } public BodyIdentifier( final List transactions, final List ommers, - final Optional> withdrawals, - final Optional> requests) { + final Optional> withdrawals) { this( BodyValidation.transactionsRoot(transactions), BodyValidation.ommersHash(ommers), - withdrawals.map(BodyValidation::withdrawalsRoot).orElse(null), - requests.map(BodyValidation::requestsRoot).orElse(null)); + withdrawals.map(BodyValidation::withdrawalsRoot).orElse(null)); } public BodyIdentifier(final BlockHeader header) { this( header.getTransactionsRoot(), header.getOmmersHash(), - header.getWithdrawalsRoot().orElse(null), - header.getRequestsRoot().orElse(null)); + header.getWithdrawalsRoot().orElse(null)); } @Override @@ -195,13 +187,12 @@ public class GetBodiesFromPeerTask extends AbstractPeerRequestTask> BodyIdentifier that = (BodyIdentifier) o; return Objects.equals(transactionsRoot, that.transactionsRoot) && Objects.equals(ommersHash, that.ommersHash) - && Objects.equals(withdrawalsRoot, that.withdrawalsRoot) - && Objects.equals(requestsRoot, that.requestsRoot); + && Objects.equals(withdrawalsRoot, that.withdrawalsRoot); } @Override public int hashCode() { - return Objects.hash(transactionsRoot, ommersHash, withdrawalsRoot, requestsRoot); + return Objects.hash(transactionsRoot, ommersHash, withdrawalsRoot); } } } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/task/GetHeadersFromPeerByNumberTask.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/task/GetHeadersFromPeerByNumberTask.java index b4f5aa4f48..c95af228ee 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/task/GetHeadersFromPeerByNumberTask.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/task/GetHeadersFromPeerByNumberTask.java @@ -43,25 +43,15 @@ public class GetHeadersFromPeerByNumberTask extends AbstractGetHeadersFromPeerTa this.blockNumber = blockNumber; } - public static AbstractGetHeadersFromPeerTask startingAtNumber( - final ProtocolSchedule protocolSchedule, - final EthContext ethContext, - final long firstBlockNumber, - final int segmentLength, - final MetricsSystem metricsSystem) { - return new GetHeadersFromPeerByNumberTask( - protocolSchedule, ethContext, firstBlockNumber, segmentLength, 0, false, metricsSystem); - } - public static AbstractGetHeadersFromPeerTask endingAtNumber( final ProtocolSchedule protocolSchedule, final EthContext ethContext, - final long lastlockNumber, + final long lastBlockNumber, final int segmentLength, final int skip, final MetricsSystem metricsSystem) { return new GetHeadersFromPeerByNumberTask( - protocolSchedule, ethContext, lastlockNumber, segmentLength, skip, true, metricsSystem); + protocolSchedule, ethContext, lastBlockNumber, segmentLength, skip, true, metricsSystem); } public static AbstractGetHeadersFromPeerTask forSingleNumber( diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/peervalidation/AbstractPeerBlockValidator.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/peervalidation/AbstractPeerBlockValidator.java index 9de0a77144..dfc5b49d9b 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/peervalidation/AbstractPeerBlockValidator.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/peervalidation/AbstractPeerBlockValidator.java @@ -54,13 +54,6 @@ abstract class AbstractPeerBlockValidator implements PeerValidator { this.chainHeightEstimationBuffer = chainHeightEstimationBuffer; } - protected AbstractPeerBlockValidator( - final ProtocolSchedule protocolSchedule, - final MetricsSystem metricsSystem, - final long blockNumber) { - this(protocolSchedule, metricsSystem, blockNumber, DEFAULT_CHAIN_HEIGHT_ESTIMATION_BUFFER); - } - @Override public CompletableFuture validatePeer( final EthContext ethContext, final EthPeer ethPeer) { diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/DefaultSynchronizer.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/DefaultSynchronizer.java index b7dc2adb16..2384437299 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/DefaultSynchronizer.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/DefaultSynchronizer.java @@ -388,10 +388,12 @@ public class DefaultSynchronizer implements Synchronizer, UnverifiedForkchoiceLi return syncState.unsubscribeSyncStatus(listenerId); } + @Override public long subscribeInitialSync(final BesuEvents.InitialSyncCompletionListener listener) { return syncState.subscribeCompletionReached(listener); } + @Override public boolean unsubscribeInitialSync(final long listenerId) { return syncState.unsubscribeInitialConditionReached(listenerId); } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/SyncTargetManager.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/SyncTargetManager.java index 2acfa54d04..c4ac358b80 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/SyncTargetManager.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/SyncTargetManager.java @@ -47,6 +47,7 @@ public class SyncTargetManager extends AbstractSyncTargetManager { private static final int LOG_INFO_REPEAT_DELAY = 120; private static final int SECONDS_PER_REQUEST = 6; // 5s per request + 1s wait between retries + private final SynchronizerConfiguration config; private final WorldStateStorageCoordinator worldStateStorageCoordinator; private final ProtocolSchedule protocolSchedule; private final ProtocolContext protocolContext; @@ -65,6 +66,7 @@ public class SyncTargetManager extends AbstractSyncTargetManager { final MetricsSystem metricsSystem, final FastSyncState fastSyncState) { super(config, protocolSchedule, protocolContext, ethContext, metricsSystem); + this.config = config; this.worldStateStorageCoordinator = worldStateStorageCoordinator; this.protocolSchedule = protocolSchedule; this.protocolContext = protocolContext; @@ -82,15 +84,17 @@ public class SyncTargetManager extends AbstractSyncTargetManager { throttledLog( LOG::debug, String.format( - "Unable to find sync target. Currently checking %d peers for usefulness. Pivot block: %d", - ethContext.getEthPeers().peerCount(), pivotBlockHeader.getNumber()), + "Unable to find sync target. Waiting for %d peers minimum. Currently checking %d peers for usefulness. Pivot block: %d", + config.getSyncMinimumPeerCount(), + ethContext.getEthPeers().peerCount(), + pivotBlockHeader.getNumber()), logDebug, LOG_DEBUG_REPEAT_DELAY); throttledLog( LOG::info, String.format( - "Unable to find sync target. Currently checking %d peers for usefulness.", - ethContext.getEthPeers().peerCount()), + "Unable to find sync target. Waiting for %d peers minimum. Currently checking %d peers for usefulness.", + config.getSyncMinimumPeerCount(), ethContext.getEthPeers().peerCount()), logInfo, LOG_INFO_REPEAT_DELAY); return completedFuture(Optional.empty()); diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncTargetManager.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncTargetManager.java index 6bb9e3b7ad..b46b09b7ca 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncTargetManager.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncTargetManager.java @@ -37,6 +37,7 @@ import org.slf4j.LoggerFactory; class FullSyncTargetManager extends AbstractSyncTargetManager { private static final Logger LOG = LoggerFactory.getLogger(FullSyncTargetManager.class); + private final SynchronizerConfiguration config; private final ProtocolContext protocolContext; private final EthContext ethContext; private final SyncTerminationCondition terminationCondition; @@ -49,6 +50,7 @@ class FullSyncTargetManager extends AbstractSyncTargetManager { final MetricsSystem metricsSystem, final SyncTerminationCondition terminationCondition) { super(config, protocolSchedule, protocolContext, ethContext, metricsSystem); + this.config = config; this.protocolContext = protocolContext; this.ethContext = ethContext; this.terminationCondition = terminationCondition; @@ -77,7 +79,8 @@ class FullSyncTargetManager extends AbstractSyncTargetManager { final Optional maybeBestPeer = ethContext.getEthPeers().bestPeerWithHeightEstimate(); if (!maybeBestPeer.isPresent()) { LOG.info( - "Unable to find sync target. Currently checking {} peers for usefulness", + "Unable to find sync target. Waiting for {} peers minimum. Currently checking {} peers for usefulness", + config.getSyncMinimumPeerCount(), ethContext.getEthPeers().peerCount()); return completedFuture(Optional.empty()); } else { diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/request/StorageRangeDataRequest.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/request/StorageRangeDataRequest.java index 4c50926303..c405e2525e 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/request/StorageRangeDataRequest.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/request/StorageRangeDataRequest.java @@ -179,6 +179,10 @@ public class StorageRangeDataRequest extends SnapDataRequest { final StackTrie.TaskElement taskElement = stackTrie.getElement(startKeyHash); + if (null == taskElement) { + return Stream.empty(); + } + findNewBeginElementInRange(storageRoot, taskElement.proofs(), taskElement.keys(), endKeyHash) .ifPresent( missingRightElement -> { diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/request/heal/TrieNodeHealingRequest.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/request/heal/TrieNodeHealingRequest.java index 7e206232c5..e622108725 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/request/heal/TrieNodeHealingRequest.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/request/heal/TrieNodeHealingRequest.java @@ -32,6 +32,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.Optional; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Stream; import org.apache.tuweni.bytes.Bytes; @@ -44,7 +45,7 @@ public abstract class TrieNodeHealingRequest extends SnapDataRequest private final Bytes location; protected Bytes data; - protected boolean requiresPersisting = true; + protected AtomicBoolean requiresPersisting = new AtomicBoolean(true); protected TrieNodeHealingRequest(final Hash nodeHash, final Hash rootHash, final Bytes location) { super(TRIE_NODE, rootHash); @@ -65,7 +66,7 @@ public abstract class TrieNodeHealingRequest extends SnapDataRequest return 0; } int saved = 0; - if (requiresPersisting) { + if (requiresPersisting.getAndSet(false)) { checkNotNull(data, "Must set data before node can be persisted."); saved = doPersist( @@ -143,7 +144,7 @@ public abstract class TrieNodeHealingRequest extends SnapDataRequest } public boolean isRequiresPersisting() { - return requiresPersisting; + return requiresPersisting.get(); } public Bytes32 getNodeHash() { @@ -173,7 +174,7 @@ public abstract class TrieNodeHealingRequest extends SnapDataRequest } public void setRequiresPersisting(final boolean requiresPersisting) { - this.requiresPersisting = requiresPersisting; + this.requiresPersisting.set(requiresPersisting); } private boolean nodeIsHashReferencedDescendant(final Node node) { diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/tasks/CompleteBlocksTask.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/tasks/CompleteBlocksTask.java index 524851af5f..82216ae09f 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/tasks/CompleteBlocksTask.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/tasks/CompleteBlocksTask.java @@ -19,7 +19,6 @@ import static java.util.Collections.emptyList; import static java.util.concurrent.CompletableFuture.completedFuture; import static java.util.stream.Collectors.toMap; -import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.core.Block; import org.hyperledger.besu.ethereum.core.BlockBody; import org.hyperledger.besu.ethereum.core.BlockHeader; @@ -75,7 +74,7 @@ public class CompleteBlocksTask extends AbstractRetryingPeerTask> { this.headers = headers; this.blocks = headers.stream() - .filter(this::hasEmptyBody) + .filter(BlockHeader::hasEmptyBlock) .collect( toMap( BlockHeader::getNumber, @@ -93,8 +92,7 @@ public class CompleteBlocksTask extends AbstractRetryingPeerTask> { Collections.emptyList(), isWithdrawalsEnabled(protocolSchedule, header) ? Optional.of(Collections.emptyList()) - : Optional.empty(), - Optional.empty()); + : Optional.empty()); } private boolean isWithdrawalsEnabled( @@ -102,15 +100,6 @@ public class CompleteBlocksTask extends AbstractRetryingPeerTask> { return protocolSchedule.getByBlockHeader(header).getWithdrawalsProcessor().isPresent(); } - private boolean hasEmptyBody(final BlockHeader header) { - return header.getOmmersHash().equals(Hash.EMPTY_LIST_HASH) - && header.getTransactionsRoot().equals(Hash.EMPTY_TRIE_HASH) - && header - .getWithdrawalsRoot() - .map(wsRoot -> wsRoot.equals(Hash.EMPTY_TRIE_HASH)) - .orElse(true); - } - public static CompleteBlocksTask forHeaders( final ProtocolSchedule protocolSchedule, final EthContext ethContext, diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/tasks/GetReceiptsForHeadersTask.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/tasks/GetReceiptsForHeadersTask.java index 58c4d3a7af..2e46483438 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/tasks/GetReceiptsForHeadersTask.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/tasks/GetReceiptsForHeadersTask.java @@ -42,7 +42,7 @@ import org.slf4j.LoggerFactory; public class GetReceiptsForHeadersTask extends AbstractRetryingPeerTask>> { private static final Logger LOG = LoggerFactory.getLogger(GetReceiptsForHeadersTask.class); - private static final int DEFAULT_RETRIES = 5; + protected static final int DEFAULT_RETRIES = 5; private final EthContext ethContext; @@ -65,14 +65,6 @@ public class GetReceiptsForHeadersTask completeEmptyReceipts(headers); } - public static GetReceiptsForHeadersTask forHeaders( - final EthContext ethContext, - final List headers, - final int maxRetries, - final MetricsSystem metricsSystem) { - return new GetReceiptsForHeadersTask(ethContext, headers, maxRetries, metricsSystem); - } - public static GetReceiptsForHeadersTask forHeaders( final EthContext ethContext, final List headers, diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/NewPooledTransactionHashesMessageHandler.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/NewPooledTransactionHashesMessageHandler.java index ab909eada1..f2e9378fd4 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/NewPooledTransactionHashesMessageHandler.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/NewPooledTransactionHashesMessageHandler.java @@ -45,11 +45,11 @@ class NewPooledTransactionHashesMessageHandler implements EthMessages.MessageCal @Override public void exec(final EthMessage message) { - final Capability capability = message.getPeer().getConnection().capability(EthProtocol.NAME); - final NewPooledTransactionHashesMessage transactionsMessage = - NewPooledTransactionHashesMessage.readFrom(message.getData(), capability); - final Instant startedAt = now(); if (isEnabled.get()) { + final Capability capability = message.getPeer().getConnection().capability(EthProtocol.NAME); + final NewPooledTransactionHashesMessage transactionsMessage = + NewPooledTransactionHashesMessage.readFrom(message.getData(), capability); + final Instant startedAt = now(); scheduler.scheduleTxWorkerTask( () -> transactionsMessageProcessor.processNewPooledTransactionHashesMessage( diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/PeerTransactionTracker.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/PeerTransactionTracker.java index da95900429..1dfb974fbd 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/PeerTransactionTracker.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/PeerTransactionTracker.java @@ -34,7 +34,8 @@ import java.util.stream.Collectors; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class PeerTransactionTracker implements EthPeer.DisconnectCallback { +public class PeerTransactionTracker + implements EthPeer.DisconnectCallback, PendingTransactionDroppedListener { private static final Logger LOG = LoggerFactory.getLogger(PeerTransactionTracker.class); private static final int MAX_TRACKED_SEEN_TRANSACTIONS = 100_000; @@ -122,13 +123,14 @@ public class PeerTransactionTracker implements EthPeer.DisconnectCallback { } private Set createTransactionsSet() { - return Collections.newSetFromMap( - new LinkedHashMap<>(1 << 4, 0.75f, true) { - @Override - protected boolean removeEldestEntry(final Map.Entry eldest) { - return size() > MAX_TRACKED_SEEN_TRANSACTIONS; - } - }); + return Collections.synchronizedSet( + Collections.newSetFromMap( + new LinkedHashMap<>(16, 0.75f, true) { + @Override + protected boolean removeEldestEntry(final Map.Entry eldest) { + return size() > MAX_TRACKED_SEEN_TRANSACTIONS; + } + })); } @Override @@ -175,4 +177,11 @@ public class PeerTransactionTracker implements EthPeer.DisconnectCallback { private String logPeerSet(final Set peers) { return peers.stream().map(EthPeer::getLoggableId).collect(Collectors.joining(",")); } + + @Override + public void onTransactionDropped(final Transaction transaction, final RemovalReason reason) { + if (reason.stopTracking()) { + seenTransactions.values().stream().forEach(st -> st.remove(transaction.getHash())); + } + } } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/PendingTransactionDroppedListener.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/PendingTransactionDroppedListener.java index d1b8d84d2b..57c492dd03 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/PendingTransactionDroppedListener.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/PendingTransactionDroppedListener.java @@ -19,5 +19,5 @@ import org.hyperledger.besu.ethereum.core.Transaction; @FunctionalInterface public interface PendingTransactionDroppedListener { - void onTransactionDropped(Transaction transaction); + void onTransactionDropped(Transaction transaction, final RemovalReason reason); } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/RemovalReason.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/RemovalReason.java new file mode 100644 index 0000000000..d5f0e10c17 --- /dev/null +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/RemovalReason.java @@ -0,0 +1,32 @@ +/* + * 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.eth.transactions; + +/** The reason why a pending tx has been removed */ +public interface RemovalReason { + /** + * Return a label that identify this reason to be used in the metric system. + * + * @return a label + */ + String label(); + + /** + * Return true if we should stop tracking the tx as already seen + * + * @return true if no more tracking is needed + */ + boolean stopTracking(); +} diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPool.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPool.java index 7bbf1abe3b..19bcfe0b36 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPool.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPool.java @@ -61,6 +61,7 @@ import java.util.HashMap; import java.util.IntSummaryStatistics; import java.util.List; import java.util.Map; +import java.util.NoSuchElementException; import java.util.Optional; import java.util.OptionalLong; import java.util.Set; @@ -77,6 +78,8 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import com.google.common.annotations.VisibleForTesting; +import com.google.common.collect.ListMultimap; +import com.google.common.collect.Multimaps; import org.apache.tuweni.bytes.Bytes; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -107,8 +110,10 @@ public class TransactionPool implements BlockAddedObserver { private final SaveRestoreManager saveRestoreManager = new SaveRestoreManager(); private final Set
localSenders = ConcurrentHashMap.newKeySet(); private final EthScheduler.OrderedProcessor blockAddedEventOrderedProcessor; - private final Map mapOfBlobsInTransactionPool = - new HashMap<>(); + private final ListMultimap + mapOfBlobsInTransactionPool = + Multimaps.synchronizedListMultimap( + Multimaps.newListMultimap(new HashMap<>(), () -> new ArrayList<>(1))); public TransactionPool( final Supplier pendingTransactionsSupplier, @@ -132,7 +137,8 @@ public class TransactionPool implements BlockAddedObserver { initializeBlobMetrics(); initLogForReplay(); subscribePendingTransactions(this::mapBlobsOnTransactionAdded); - subscribeDroppedTransactions(this::unmapBlobsOnTransactionDropped); + subscribeDroppedTransactions( + (transaction, reason) -> unmapBlobsOnTransactionDropped(transaction)); } private void initLogForReplay() { @@ -660,6 +666,7 @@ public class TransactionPool implements BlockAddedObserver { } final List blobQuads = maybeBlobsWithCommitments.get().getBlobQuads(); + blobQuads.forEach(bq -> mapOfBlobsInTransactionPool.put(bq.versionedHash(), bq)); } @@ -672,15 +679,18 @@ public class TransactionPool implements BlockAddedObserver { } final List blobQuads = maybeBlobsWithCommitments.get().getBlobQuads(); - blobQuads.forEach(bq -> mapOfBlobsInTransactionPool.remove(bq.versionedHash())); + + blobQuads.forEach(bq -> mapOfBlobsInTransactionPool.remove(bq.versionedHash(), bq)); } public BlobsWithCommitments.BlobQuad getBlobQuad(final VersionedHash vh) { - BlobsWithCommitments.BlobQuad blobQuad = mapOfBlobsInTransactionPool.get(vh); - if (blobQuad == null) { - blobQuad = cacheForBlobsOfTransactionsAddedToABlock.get(vh); + try { + // returns an empty list if the key is not present, so getFirst() will throw + return mapOfBlobsInTransactionPool.get(vh).getFirst(); + } catch (NoSuchElementException e) { + // do nothing } - return blobQuad; + return cacheForBlobsOfTransactionsAddedToABlock.get(vh); } public boolean isEnabled() { @@ -711,7 +721,9 @@ public class TransactionPool implements BlockAddedObserver { void subscribe() { onAddedListenerId = pendingTransactions.subscribePendingTransactions(this::onAdded); - onDroppedListenerId = pendingTransactions.subscribeDroppedTransactions(this::onDropped); + onDroppedListenerId = + pendingTransactions.subscribeDroppedTransactions( + (transaction, reason) -> onDropped(transaction, reason)); } void unsubscribe() { @@ -719,8 +731,8 @@ public class TransactionPool implements BlockAddedObserver { pendingTransactions.unsubscribeDroppedTransactions(onDroppedListenerId); } - private void onDropped(final Transaction transaction) { - onDroppedListeners.forEach(listener -> listener.onTransactionDropped(transaction)); + private void onDropped(final Transaction transaction, final RemovalReason reason) { + onDroppedListeners.forEach(listener -> listener.onTransactionDropped(transaction, reason)); } private void onAdded(final Transaction transaction) { diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionsMessageHandler.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionsMessageHandler.java index 3160d1a9c5..b6bbf442da 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionsMessageHandler.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionsMessageHandler.java @@ -43,9 +43,10 @@ class TransactionsMessageHandler implements EthMessages.MessageCallback { @Override public void exec(final EthMessage message) { - final TransactionsMessage transactionsMessage = TransactionsMessage.readFrom(message.getData()); - final Instant startedAt = now(); if (isEnabled.get()) { + final TransactionsMessage transactionsMessage = + TransactionsMessage.readFrom(message.getData()); + final Instant startedAt = now(); scheduler.scheduleTxWorkerTask( () -> transactionsMessageProcessor.processTransactionsMessage( diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/AbstractPrioritizedTransactions.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/AbstractPrioritizedTransactions.java index 470e7f5b7b..fce565a807 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/AbstractPrioritizedTransactions.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/AbstractPrioritizedTransactions.java @@ -137,7 +137,7 @@ public abstract class AbstractPrioritizedTransactions extends AbstractSequential protected void internalRemove( final NavigableMap senderTxs, final PendingTransaction removedTx, - final RemovalReason removalReason) { + final LayeredRemovalReason removalReason) { orderByFee.remove(removedTx); } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/AbstractSequentialTransactionsLayer.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/AbstractSequentialTransactionsLayer.java index f7d71ca372..cf7195e690 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/AbstractSequentialTransactionsLayer.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/AbstractSequentialTransactionsLayer.java @@ -15,8 +15,8 @@ package org.hyperledger.besu.ethereum.eth.transactions.layered; import static org.hyperledger.besu.ethereum.eth.transactions.layered.AddReason.MOVE; -import static org.hyperledger.besu.ethereum.eth.transactions.layered.RemovalReason.LayerMoveReason.EVICTED; -import static org.hyperledger.besu.ethereum.eth.transactions.layered.RemovalReason.LayerMoveReason.FOLLOW_INVALIDATED; +import static org.hyperledger.besu.ethereum.eth.transactions.layered.LayeredRemovalReason.LayerMoveReason.EVICTED; +import static org.hyperledger.besu.ethereum.eth.transactions.layered.LayeredRemovalReason.LayerMoveReason.FOLLOW_INVALIDATED; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.ethereum.eth.manager.EthScheduler; @@ -24,7 +24,7 @@ import org.hyperledger.besu.ethereum.eth.transactions.BlobCache; import org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolMetrics; -import org.hyperledger.besu.ethereum.eth.transactions.layered.RemovalReason.PoolRemovalReason; +import org.hyperledger.besu.ethereum.eth.transactions.layered.LayeredRemovalReason.PoolRemovalReason; import java.util.Map; import java.util.NavigableMap; diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/AbstractTransactionsLayer.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/AbstractTransactionsLayer.java index ca980b219d..330a828018 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/AbstractTransactionsLayer.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/AbstractTransactionsLayer.java @@ -20,12 +20,12 @@ import static org.hyperledger.besu.ethereum.eth.transactions.TransactionAddedRes import static org.hyperledger.besu.ethereum.eth.transactions.TransactionAddedResult.REJECTED_UNDERPRICED_REPLACEMENT; import static org.hyperledger.besu.ethereum.eth.transactions.TransactionAddedResult.TRY_NEXT_LAYER; import static org.hyperledger.besu.ethereum.eth.transactions.layered.AddReason.MOVE; -import static org.hyperledger.besu.ethereum.eth.transactions.layered.RemovalReason.LayerMoveReason.EVICTED; -import static org.hyperledger.besu.ethereum.eth.transactions.layered.RemovalReason.PoolRemovalReason.BELOW_MIN_SCORE; -import static org.hyperledger.besu.ethereum.eth.transactions.layered.RemovalReason.PoolRemovalReason.CONFIRMED; -import static org.hyperledger.besu.ethereum.eth.transactions.layered.RemovalReason.PoolRemovalReason.CROSS_LAYER_REPLACED; -import static org.hyperledger.besu.ethereum.eth.transactions.layered.RemovalReason.PoolRemovalReason.REPLACED; -import static org.hyperledger.besu.ethereum.eth.transactions.layered.RemovalReason.RemovedFrom.POOL; +import static org.hyperledger.besu.ethereum.eth.transactions.layered.LayeredRemovalReason.LayerMoveReason.EVICTED; +import static org.hyperledger.besu.ethereum.eth.transactions.layered.LayeredRemovalReason.PoolRemovalReason.BELOW_MIN_SCORE; +import static org.hyperledger.besu.ethereum.eth.transactions.layered.LayeredRemovalReason.PoolRemovalReason.CONFIRMED; +import static org.hyperledger.besu.ethereum.eth.transactions.layered.LayeredRemovalReason.PoolRemovalReason.CROSS_LAYER_REPLACED; +import static org.hyperledger.besu.ethereum.eth.transactions.layered.LayeredRemovalReason.PoolRemovalReason.REPLACED; +import static org.hyperledger.besu.ethereum.eth.transactions.layered.LayeredRemovalReason.RemovedFrom.POOL; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Hash; @@ -295,7 +295,9 @@ public abstract class AbstractTransactionsLayer implements TransactionsLayer { if (remainingPromotionsPerType[txType.ordinal()] > 0) { senderTxs.pollFirstEntry(); processRemove( - senderTxs, candidateTx.getTransaction(), RemovalReason.LayerMoveReason.PROMOTED); + senderTxs, + candidateTx.getTransaction(), + LayeredRemovalReason.LayerMoveReason.PROMOTED); metrics.incrementRemoved(candidateTx, "promoted", name()); if (senderTxs.isEmpty()) { @@ -386,7 +388,7 @@ public abstract class AbstractTransactionsLayer implements TransactionsLayer { decreaseCounters(replacedTx); metrics.incrementRemoved(replacedTx, REPLACED.label(), name()); internalReplaced(replacedTx); - notifyTransactionDropped(replacedTx); + notifyTransactionDropped(replacedTx, REPLACED); } protected abstract void internalReplaced(final PendingTransaction replacedTx); @@ -415,7 +417,7 @@ public abstract class AbstractTransactionsLayer implements TransactionsLayer { protected PendingTransaction processRemove( final NavigableMap senderTxs, final Transaction transaction, - final RemovalReason removalReason) { + final LayeredRemovalReason removalReason) { final PendingTransaction removedTx = pendingTransactions.remove(transaction.getHash()); if (removedTx != null) { @@ -423,7 +425,7 @@ public abstract class AbstractTransactionsLayer implements TransactionsLayer { metrics.incrementRemoved(removedTx, removalReason.label(), name()); internalRemove(senderTxs, removedTx, removalReason); if (removalReason.removedFrom().equals(POOL)) { - notifyTransactionDropped(removedTx); + notifyTransactionDropped(removedTx, removalReason); } } return removedTx; @@ -432,7 +434,7 @@ public abstract class AbstractTransactionsLayer implements TransactionsLayer { protected PendingTransaction processEvict( final NavigableMap senderTxs, final PendingTransaction evictedTx, - final RemovalReason reason) { + final LayeredRemovalReason reason) { final PendingTransaction removedTx = pendingTransactions.remove(evictedTx.getHash()); if (removedTx != null) { decreaseCounters(evictedTx); @@ -545,7 +547,7 @@ public abstract class AbstractTransactionsLayer implements TransactionsLayer { protected abstract void internalRemove( final NavigableMap senderTxs, final PendingTransaction pendingTransaction, - final RemovalReason removalReason); + final LayeredRemovalReason removalReason); protected abstract PendingTransaction getEvictable(); @@ -606,9 +608,10 @@ public abstract class AbstractTransactionsLayer implements TransactionsLayer { listener -> listener.onTransactionAdded(pendingTransaction.getTransaction())); } - protected void notifyTransactionDropped(final PendingTransaction pendingTransaction) { + protected void notifyTransactionDropped( + final PendingTransaction pendingTransaction, final LayeredRemovalReason reason) { onDroppedListeners.forEach( - listener -> listener.onTransactionDropped(pendingTransaction.getTransaction())); + listener -> listener.onTransactionDropped(pendingTransaction.getTransaction(), reason)); } @Override diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/BaseFeePrioritizedTransactions.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/BaseFeePrioritizedTransactions.java index c06fb53e33..df9b1537a3 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/BaseFeePrioritizedTransactions.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/BaseFeePrioritizedTransactions.java @@ -15,7 +15,7 @@ package org.hyperledger.besu.ethereum.eth.transactions.layered; import static org.hyperledger.besu.ethereum.eth.transactions.layered.AddReason.MOVE; -import static org.hyperledger.besu.ethereum.eth.transactions.layered.RemovalReason.LayerMoveReason.DEMOTED; +import static org.hyperledger.besu.ethereum.eth.transactions.layered.LayeredRemovalReason.LayerMoveReason.DEMOTED; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.core.BlockHeader; diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/EndLayer.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/EndLayer.java index c76d2ab97a..c451dd48d1 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/EndLayer.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/EndLayer.java @@ -14,7 +14,7 @@ */ package org.hyperledger.besu.ethereum.eth.transactions.layered; -import static org.hyperledger.besu.ethereum.eth.transactions.layered.RemovalReason.PoolRemovalReason.DROPPED; +import static org.hyperledger.besu.ethereum.eth.transactions.layered.LayeredRemovalReason.PoolRemovalReason.DROPPED; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Hash; @@ -25,7 +25,7 @@ import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactionAddedLis import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactionDroppedListener; import org.hyperledger.besu.ethereum.eth.transactions.TransactionAddedResult; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolMetrics; -import org.hyperledger.besu.ethereum.eth.transactions.layered.RemovalReason.PoolRemovalReason; +import org.hyperledger.besu.ethereum.eth.transactions.layered.LayeredRemovalReason.PoolRemovalReason; import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; import org.hyperledger.besu.util.Subscribers; @@ -78,7 +78,7 @@ public class EndLayer implements TransactionsLayer { @Override public TransactionAddedResult add( final PendingTransaction pendingTransaction, final int gap, final AddReason reason) { - notifyTransactionDropped(pendingTransaction); + notifyTransactionDropped(pendingTransaction, DROPPED); metrics.incrementRemoved(pendingTransaction, DROPPED.label(), name()); ++droppedCount; return TransactionAddedResult.DROPPED; @@ -152,9 +152,10 @@ public class EndLayer implements TransactionsLayer { onDroppedListeners.unsubscribe(id); } - protected void notifyTransactionDropped(final PendingTransaction pendingTransaction) { + protected void notifyTransactionDropped( + final PendingTransaction pendingTransaction, final LayeredRemovalReason reason) { onDroppedListeners.forEach( - listener -> listener.onTransactionDropped(pendingTransaction.getTransaction())); + listener -> listener.onTransactionDropped(pendingTransaction.getTransaction(), reason)); } @Override diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/LayeredPendingTransactions.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/LayeredPendingTransactions.java index a79c05e3e6..bde1568e98 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/LayeredPendingTransactions.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/LayeredPendingTransactions.java @@ -21,8 +21,8 @@ import static org.hyperledger.besu.ethereum.eth.transactions.TransactionAddedRes import static org.hyperledger.besu.ethereum.eth.transactions.TransactionAddedResult.INTERNAL_ERROR; import static org.hyperledger.besu.ethereum.eth.transactions.TransactionAddedResult.NONCE_TOO_FAR_IN_FUTURE_FOR_SENDER; import static org.hyperledger.besu.ethereum.eth.transactions.layered.AddReason.NEW; -import static org.hyperledger.besu.ethereum.eth.transactions.layered.RemovalReason.PoolRemovalReason.INVALIDATED; -import static org.hyperledger.besu.ethereum.eth.transactions.layered.RemovalReason.PoolRemovalReason.RECONCILED; +import static org.hyperledger.besu.ethereum.eth.transactions.layered.LayeredRemovalReason.PoolRemovalReason.INVALIDATED; +import static org.hyperledger.besu.ethereum.eth.transactions.layered.LayeredRemovalReason.PoolRemovalReason.RECONCILED; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Hash; diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/RemovalReason.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/LayeredRemovalReason.java similarity index 67% rename from ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/RemovalReason.java rename to ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/LayeredRemovalReason.java index 8acd026b14..563c7ebd4a 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/RemovalReason.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/LayeredRemovalReason.java @@ -14,10 +14,12 @@ */ package org.hyperledger.besu.ethereum.eth.transactions.layered; +import org.hyperledger.besu.ethereum.eth.transactions.RemovalReason; + import java.util.Locale; /** The reason why a pending tx has been removed */ -public interface RemovalReason { +interface LayeredRemovalReason extends RemovalReason { /** * From where the tx has been removed * @@ -25,13 +27,6 @@ public interface RemovalReason { */ RemovedFrom removedFrom(); - /** - * Return a label that identify this reason to be used in the metric system. - * - * @return a label - */ - String label(); - /** There are 2 kinds of removals, from a layer and from the pool. */ enum RemovedFrom { /** @@ -50,37 +45,53 @@ public interface RemovalReason { } /** The reason why the tx has been removed from the pool */ - enum PoolRemovalReason implements RemovalReason { - /** Tx removed since it is confirmed on chain, as part of an imported block. */ - CONFIRMED, - /** Tx removed since it has been replaced by another one added in the same layer. */ - REPLACED, - /** Tx removed since it has been replaced by another one added in another layer. */ - CROSS_LAYER_REPLACED, - /** Tx removed when the pool is full, to make space for new incoming txs. */ - DROPPED, + enum PoolRemovalReason implements LayeredRemovalReason { + /** + * Tx removed since it is confirmed on chain, as part of an imported block. Keep tracking since + * makes no sense to reprocess a confirmed. + */ + CONFIRMED(false), + /** + * Tx removed since it has been replaced by another one added in the same layer. Keep tracking + * since makes no sense to reprocess a replaced tx. + */ + REPLACED(false), + /** + * Tx removed since it has been replaced by another one added in another layer. Keep tracking + * since makes no sense to reprocess a replaced tx. + */ + CROSS_LAYER_REPLACED(false), + /** + * Tx removed when the pool is full, to make space for new incoming txs. Stop tracking it so we + * could re-accept it in the future. + */ + DROPPED(true), /** * Tx removed since found invalid after it was added to the pool, for example during txs - * selection for a new block proposal. + * selection for a new block proposal. Keep tracking since we do not want to reprocess an + * invalid tx. */ - INVALIDATED, + INVALIDATED(false), /** * Special case, when for a sender, discrepancies are found between the world state view and the * pool view, then all the txs for this sender are removed and added again. Discrepancies, are * rare, and can happen during a short windows when a new block is being imported and the world - * state being updated. + * state being updated. Keep tracking since it is removed and re-added. */ - RECONCILED, + RECONCILED(false), /** * When a pending tx is penalized its score is decreased, if at some point its score is lower - * than the configured minimum then the pending tx is removed from the pool. + * than the configured minimum then the pending tx is removed from the pool. Stop tracking it so + * we could re-accept it in the future. */ - BELOW_MIN_SCORE; + BELOW_MIN_SCORE(true); private final String label; + private final boolean stopTracking; - PoolRemovalReason() { + PoolRemovalReason(final boolean stopTracking) { this.label = name().toLowerCase(Locale.ROOT); + this.stopTracking = stopTracking; } @Override @@ -92,10 +103,15 @@ public interface RemovalReason { public String label() { return label; } + + @Override + public boolean stopTracking() { + return stopTracking; + } } /** The reason why the tx has been moved across layers */ - enum LayerMoveReason implements RemovalReason { + enum LayerMoveReason implements LayeredRemovalReason { /** * When the current layer is full, and this tx needs to be moved to the lower layer, in order to * free space. @@ -132,5 +148,15 @@ public interface RemovalReason { public String label() { return label; } + + /** + * We need to continue to track a tx when is moved between layers + * + * @return always false + */ + @Override + public boolean stopTracking() { + return false; + } } } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/ReadyTransactions.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/ReadyTransactions.java index 7c7ddcdaeb..d8fbf1e2a1 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/ReadyTransactions.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/ReadyTransactions.java @@ -14,7 +14,7 @@ */ package org.hyperledger.besu.ethereum.eth.transactions.layered; -import static org.hyperledger.besu.ethereum.eth.transactions.layered.RemovalReason.LayerMoveReason.PROMOTED; +import static org.hyperledger.besu.ethereum.eth.transactions.layered.LayeredRemovalReason.LayerMoveReason.PROMOTED; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.ethereum.core.BlockHeader; @@ -109,7 +109,7 @@ public class ReadyTransactions extends AbstractSequentialTransactionsLayer { protected void internalRemove( final NavigableMap senderTxs, final PendingTransaction removedTx, - final RemovalReason removalReason) { + final LayeredRemovalReason removalReason) { orderByMaxFee.remove(removedTx); if (!senderTxs.isEmpty()) { orderByMaxFee.add(senderTxs.firstEntry().getValue()); diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/SparseTransactions.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/SparseTransactions.java index 7a20f94540..a04805073f 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/SparseTransactions.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/SparseTransactions.java @@ -14,8 +14,8 @@ */ package org.hyperledger.besu.ethereum.eth.transactions.layered; -import static org.hyperledger.besu.ethereum.eth.transactions.layered.RemovalReason.LayerMoveReason.PROMOTED; -import static org.hyperledger.besu.ethereum.eth.transactions.layered.RemovalReason.PoolRemovalReason.INVALIDATED; +import static org.hyperledger.besu.ethereum.eth.transactions.layered.LayeredRemovalReason.LayerMoveReason.PROMOTED; +import static org.hyperledger.besu.ethereum.eth.transactions.layered.LayeredRemovalReason.PoolRemovalReason.INVALIDATED; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.ethereum.core.BlockHeader; @@ -26,7 +26,7 @@ import org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction; import org.hyperledger.besu.ethereum.eth.transactions.TransactionAddedResult; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolMetrics; -import org.hyperledger.besu.ethereum.eth.transactions.layered.RemovalReason.PoolRemovalReason; +import org.hyperledger.besu.ethereum.eth.transactions.layered.LayeredRemovalReason.PoolRemovalReason; import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; import java.util.ArrayList; @@ -278,7 +278,7 @@ public class SparseTransactions extends AbstractTransactionsLayer { protected void internalRemove( final NavigableMap senderTxs, final PendingTransaction removedTx, - final RemovalReason removalReason) { + final LayeredRemovalReason removalReason) { sparseEvictionOrder.remove(removedTx); diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/TransactionsLayer.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/TransactionsLayer.java index 16ce957fb8..2e40b685f6 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/TransactionsLayer.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/TransactionsLayer.java @@ -22,7 +22,7 @@ import org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction; import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactionAddedListener; import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactionDroppedListener; import org.hyperledger.besu.ethereum.eth.transactions.TransactionAddedResult; -import org.hyperledger.besu.ethereum.eth.transactions.layered.RemovalReason.PoolRemovalReason; +import org.hyperledger.besu.ethereum.eth.transactions.layered.LayeredRemovalReason.PoolRemovalReason; import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; import java.util.List; diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/sorter/AbstractPendingTransactionsSorter.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/sorter/AbstractPendingTransactionsSorter.java index 0e1737d65b..2ff7da7c52 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/sorter/AbstractPendingTransactionsSorter.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/sorter/AbstractPendingTransactionsSorter.java @@ -18,6 +18,10 @@ import static org.hyperledger.besu.ethereum.eth.transactions.TransactionAddedRes import static org.hyperledger.besu.ethereum.eth.transactions.TransactionAddedResult.ALREADY_KNOWN; import static org.hyperledger.besu.ethereum.eth.transactions.TransactionAddedResult.NONCE_TOO_FAR_IN_FUTURE_FOR_SENDER; import static org.hyperledger.besu.ethereum.eth.transactions.TransactionAddedResult.REJECTED_UNDERPRICED_REPLACEMENT; +import static org.hyperledger.besu.ethereum.eth.transactions.sorter.SequencedRemovalReason.EVICTED; +import static org.hyperledger.besu.ethereum.eth.transactions.sorter.SequencedRemovalReason.INVALID; +import static org.hyperledger.besu.ethereum.eth.transactions.sorter.SequencedRemovalReason.REPLACED; +import static org.hyperledger.besu.ethereum.eth.transactions.sorter.SequencedRemovalReason.TIMED_EVICTION; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Hash; @@ -160,7 +164,7 @@ public abstract class AbstractPendingTransactionsSorter implements PendingTransa .setMessage("Evicted {} due to age") .addArgument(transactionInfo::toTraceLog) .log(); - removeTransaction(transactionInfo.getTransaction()); + removeTransaction(transactionInfo.getTransaction(), TIMED_EVICTION); }); } @@ -196,9 +200,9 @@ public abstract class AbstractPendingTransactionsSorter implements PendingTransa return transactionAddedStatus; } - void removeTransaction(final Transaction transaction) { + void removeTransaction(final Transaction transaction, final SequencedRemovalReason reason) { removeTransaction(transaction, false); - notifyTransactionDropped(transaction); + notifyTransactionDropped(transaction, reason); } @Override @@ -256,12 +260,12 @@ public abstract class AbstractPendingTransactionsSorter implements PendingTransa } if (result.stop()) { - transactionsToRemove.forEach(this::removeTransaction); + transactionsToRemove.forEach(tx -> removeTransaction(tx, INVALID)); return; } } } - transactionsToRemove.forEach(this::removeTransaction); + transactionsToRemove.forEach(tx -> removeTransaction(tx, INVALID)); } } @@ -324,7 +328,7 @@ public abstract class AbstractPendingTransactionsSorter implements PendingTransa .setMessage("Tracked transaction by sender {}") .addArgument(pendingTxsForSender::toTraceLog) .log(); - maybeReplacedTransaction.ifPresent(this::removeTransaction); + maybeReplacedTransaction.ifPresent(tx -> removeTransaction(tx, REPLACED)); return ADDED; } @@ -354,8 +358,10 @@ public abstract class AbstractPendingTransactionsSorter implements PendingTransa pendingTransactionSubscribers.forEach(listener -> listener.onTransactionAdded(transaction)); } - private void notifyTransactionDropped(final Transaction transaction) { - transactionDroppedListeners.forEach(listener -> listener.onTransactionDropped(transaction)); + private void notifyTransactionDropped( + final Transaction transaction, final SequencedRemovalReason reason) { + transactionDroppedListeners.forEach( + listener -> listener.onTransactionDropped(transaction, reason)); } @Override @@ -491,7 +497,7 @@ public abstract class AbstractPendingTransactionsSorter implements PendingTransa // remove backward to avoid gaps for (int i = txsToEvict.size() - 1; i >= 0; i--) { - removeTransaction(txsToEvict.get(i).getTransaction()); + removeTransaction(txsToEvict.get(i).getTransaction(), EVICTED); } } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/sorter/SequencedRemovalReason.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/sorter/SequencedRemovalReason.java new file mode 100644 index 0000000000..90ee9a9660 --- /dev/null +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/sorter/SequencedRemovalReason.java @@ -0,0 +1,45 @@ +/* + * 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.eth.transactions.sorter; + +import org.hyperledger.besu.ethereum.eth.transactions.RemovalReason; + +import java.util.Locale; + +/** The reason why a pending tx has been removed */ +enum SequencedRemovalReason implements RemovalReason { + EVICTED(true), + TIMED_EVICTION(true), + REPLACED(false), + INVALID(false); + + private final String label; + private final boolean stopTracking; + + SequencedRemovalReason(final boolean stopTracking) { + this.label = name().toLowerCase(Locale.ROOT); + this.stopTracking = stopTracking; + } + + @Override + public String label() { + return label; + } + + @Override + public boolean stopTracking() { + return stopTracking; + } +} diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/peertask/PeerTaskExecutorTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/peertask/PeerTaskExecutorTest.java new file mode 100644 index 0000000000..0262e276da --- /dev/null +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/peertask/PeerTaskExecutorTest.java @@ -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.eth.manager.peertask; + +import org.hyperledger.besu.ethereum.eth.manager.EthPeer; +import org.hyperledger.besu.ethereum.p2p.rlpx.connections.PeerConnection; +import org.hyperledger.besu.ethereum.p2p.rlpx.wire.MessageData; +import org.hyperledger.besu.ethereum.p2p.rlpx.wire.SubProtocol; +import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; + +import java.util.Optional; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeoutException; +import java.util.function.Predicate; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; + +public class PeerTaskExecutorTest { + private @Mock PeerSelector peerSelector; + private @Mock PeerTaskRequestSender requestSender; + private @Mock PeerTask peerTask; + private @Mock SubProtocol subprotocol; + private @Mock MessageData requestMessageData; + private @Mock MessageData responseMessageData; + private @Mock EthPeer ethPeer; + private AutoCloseable mockCloser; + + private PeerTaskExecutor peerTaskExecutor; + + @BeforeEach + public void beforeTest() { + mockCloser = MockitoAnnotations.openMocks(this); + peerTaskExecutor = new PeerTaskExecutor(peerSelector, requestSender, new NoOpMetricsSystem()); + } + + @AfterEach + public void afterTest() throws Exception { + mockCloser.close(); + } + + @Test + public void testExecuteAgainstPeerWithNoRetriesAndSuccessfulFlow() + throws PeerConnection.PeerNotConnected, + ExecutionException, + InterruptedException, + TimeoutException, + InvalidPeerTaskResponseException { + + Object responseObject = new Object(); + + Mockito.when(peerTask.getRequestMessage()).thenReturn(requestMessageData); + Mockito.when(peerTask.getRetriesWithSamePeer()).thenReturn(0); + Mockito.when(peerTask.getSubProtocol()).thenReturn(subprotocol); + Mockito.when(subprotocol.getName()).thenReturn("subprotocol"); + Mockito.when(requestSender.sendRequest(subprotocol, requestMessageData, ethPeer)) + .thenReturn(responseMessageData); + Mockito.when(peerTask.parseResponse(responseMessageData)).thenReturn(responseObject); + Mockito.when(peerTask.isSuccess(responseObject)).thenReturn(true); + + PeerTaskExecutorResult result = peerTaskExecutor.executeAgainstPeer(peerTask, ethPeer); + + Mockito.verify(ethPeer).recordUsefulResponse(); + + Assertions.assertNotNull(result); + Assertions.assertTrue(result.result().isPresent()); + Assertions.assertSame(responseObject, result.result().get()); + Assertions.assertEquals(PeerTaskExecutorResponseCode.SUCCESS, result.responseCode()); + } + + @Test + public void testExecuteAgainstPeerWithNoRetriesAndPartialSuccessfulFlow() + throws PeerConnection.PeerNotConnected, + ExecutionException, + InterruptedException, + TimeoutException, + InvalidPeerTaskResponseException { + + Object responseObject = new Object(); + + Mockito.when(peerTask.getRequestMessage()).thenReturn(requestMessageData); + Mockito.when(peerTask.getRetriesWithSamePeer()).thenReturn(0); + Mockito.when(peerTask.getSubProtocol()).thenReturn(subprotocol); + Mockito.when(subprotocol.getName()).thenReturn("subprotocol"); + Mockito.when(requestSender.sendRequest(subprotocol, requestMessageData, ethPeer)) + .thenReturn(responseMessageData); + Mockito.when(peerTask.parseResponse(responseMessageData)).thenReturn(responseObject); + Mockito.when(peerTask.isSuccess(responseObject)).thenReturn(false); + + PeerTaskExecutorResult result = peerTaskExecutor.executeAgainstPeer(peerTask, ethPeer); + + Assertions.assertNotNull(result); + Assertions.assertTrue(result.result().isPresent()); + Assertions.assertEquals(PeerTaskExecutorResponseCode.INVALID_RESPONSE, result.responseCode()); + } + + @Test + public void testExecuteAgainstPeerWithRetriesAndSuccessfulFlowAfterFirstFailure() + throws PeerConnection.PeerNotConnected, + ExecutionException, + InterruptedException, + TimeoutException, + InvalidPeerTaskResponseException { + Object responseObject = new Object(); + int requestMessageDataCode = 123; + + Mockito.when(peerTask.getRequestMessage()).thenReturn(requestMessageData); + Mockito.when(peerTask.getRetriesWithSamePeer()).thenReturn(2); + + Mockito.when(peerTask.getSubProtocol()).thenReturn(subprotocol); + Mockito.when(subprotocol.getName()).thenReturn("subprotocol"); + Mockito.when(requestSender.sendRequest(subprotocol, requestMessageData, ethPeer)) + .thenThrow(new TimeoutException()) + .thenReturn(responseMessageData); + Mockito.when(requestMessageData.getCode()).thenReturn(requestMessageDataCode); + Mockito.when(peerTask.parseResponse(responseMessageData)).thenReturn(responseObject); + Mockito.when(peerTask.isSuccess(responseObject)).thenReturn(true); + + PeerTaskExecutorResult result = peerTaskExecutor.executeAgainstPeer(peerTask, ethPeer); + + Mockito.verify(ethPeer).recordRequestTimeout(requestMessageDataCode); + Mockito.verify(ethPeer).recordUsefulResponse(); + + Assertions.assertNotNull(result); + Assertions.assertTrue(result.result().isPresent()); + Assertions.assertSame(responseObject, result.result().get()); + Assertions.assertEquals(PeerTaskExecutorResponseCode.SUCCESS, result.responseCode()); + } + + @Test + public void testExecuteAgainstPeerWithNoRetriesAndPeerNotConnected() + throws PeerConnection.PeerNotConnected, + ExecutionException, + InterruptedException, + TimeoutException { + + Mockito.when(peerTask.getRequestMessage()).thenReturn(requestMessageData); + Mockito.when(peerTask.getRetriesWithSamePeer()).thenReturn(0); + Mockito.when(peerTask.getSubProtocol()).thenReturn(subprotocol); + Mockito.when(subprotocol.getName()).thenReturn("subprotocol"); + Mockito.when(requestSender.sendRequest(subprotocol, requestMessageData, ethPeer)) + .thenThrow(new PeerConnection.PeerNotConnected("")); + + PeerTaskExecutorResult result = peerTaskExecutor.executeAgainstPeer(peerTask, ethPeer); + + Assertions.assertNotNull(result); + Assertions.assertTrue(result.result().isEmpty()); + Assertions.assertEquals(PeerTaskExecutorResponseCode.PEER_DISCONNECTED, result.responseCode()); + } + + @Test + public void testExecuteAgainstPeerWithNoRetriesAndTimeoutException() + throws PeerConnection.PeerNotConnected, + ExecutionException, + InterruptedException, + TimeoutException { + int requestMessageDataCode = 123; + + Mockito.when(peerTask.getRequestMessage()).thenReturn(requestMessageData); + Mockito.when(peerTask.getRetriesWithSamePeer()).thenReturn(0); + Mockito.when(peerTask.getSubProtocol()).thenReturn(subprotocol); + Mockito.when(subprotocol.getName()).thenReturn("subprotocol"); + Mockito.when(requestSender.sendRequest(subprotocol, requestMessageData, ethPeer)) + .thenThrow(new TimeoutException()); + Mockito.when(requestMessageData.getCode()).thenReturn(requestMessageDataCode); + + PeerTaskExecutorResult result = peerTaskExecutor.executeAgainstPeer(peerTask, ethPeer); + + Mockito.verify(ethPeer).recordRequestTimeout(requestMessageDataCode); + + Assertions.assertNotNull(result); + Assertions.assertTrue(result.result().isEmpty()); + Assertions.assertEquals(PeerTaskExecutorResponseCode.TIMEOUT, result.responseCode()); + } + + @Test + public void testExecuteAgainstPeerWithNoRetriesAndInvalidResponseMessage() + throws PeerConnection.PeerNotConnected, + ExecutionException, + InterruptedException, + TimeoutException, + InvalidPeerTaskResponseException { + + Mockito.when(peerTask.getRequestMessage()).thenReturn(requestMessageData); + Mockito.when(peerTask.getRetriesWithSamePeer()).thenReturn(0); + Mockito.when(peerTask.getSubProtocol()).thenReturn(subprotocol); + Mockito.when(subprotocol.getName()).thenReturn("subprotocol"); + Mockito.when(requestSender.sendRequest(subprotocol, requestMessageData, ethPeer)) + .thenReturn(responseMessageData); + Mockito.when(peerTask.parseResponse(responseMessageData)) + .thenThrow(new InvalidPeerTaskResponseException()); + + PeerTaskExecutorResult result = peerTaskExecutor.executeAgainstPeer(peerTask, ethPeer); + + Mockito.verify(ethPeer).recordUselessResponse(null); + + Assertions.assertNotNull(result); + Assertions.assertTrue(result.result().isEmpty()); + Assertions.assertEquals(PeerTaskExecutorResponseCode.INVALID_RESPONSE, result.responseCode()); + } + + @Test + @SuppressWarnings("unchecked") + public void testExecuteWithNoRetriesAndSuccessFlow() + throws PeerConnection.PeerNotConnected, + ExecutionException, + InterruptedException, + TimeoutException, + InvalidPeerTaskResponseException { + Object responseObject = new Object(); + + Mockito.when(peerSelector.getPeer(Mockito.any(Predicate.class))) + .thenReturn(Optional.of(ethPeer)); + + Mockito.when(peerTask.getRequestMessage()).thenReturn(requestMessageData); + Mockito.when(peerTask.getRetriesWithOtherPeer()).thenReturn(0); + Mockito.when(peerTask.getRetriesWithSamePeer()).thenReturn(0); + Mockito.when(peerTask.getSubProtocol()).thenReturn(subprotocol); + Mockito.when(subprotocol.getName()).thenReturn("subprotocol"); + Mockito.when(requestSender.sendRequest(subprotocol, requestMessageData, ethPeer)) + .thenReturn(responseMessageData); + Mockito.when(peerTask.parseResponse(responseMessageData)).thenReturn(responseObject); + Mockito.when(peerTask.isSuccess(responseObject)).thenReturn(true); + + PeerTaskExecutorResult result = peerTaskExecutor.executeAgainstPeer(peerTask, ethPeer); + + Mockito.verify(ethPeer).recordUsefulResponse(); + + Assertions.assertNotNull(result); + Assertions.assertTrue(result.result().isPresent()); + Assertions.assertSame(responseObject, result.result().get()); + Assertions.assertEquals(PeerTaskExecutorResponseCode.SUCCESS, result.responseCode()); + } + + @Test + @SuppressWarnings("unchecked") + public void testExecuteWithPeerSwitchingAndSuccessFlow() + throws PeerConnection.PeerNotConnected, + ExecutionException, + InterruptedException, + TimeoutException, + InvalidPeerTaskResponseException { + Object responseObject = new Object(); + int requestMessageDataCode = 123; + EthPeer peer2 = Mockito.mock(EthPeer.class); + + Mockito.when(peerSelector.getPeer(Mockito.any(Predicate.class))) + .thenReturn(Optional.of(ethPeer)) + .thenReturn(Optional.of(peer2)); + + Mockito.when(peerTask.getRequestMessage()).thenReturn(requestMessageData); + Mockito.when(peerTask.getRetriesWithOtherPeer()).thenReturn(2); + Mockito.when(peerTask.getRetriesWithSamePeer()).thenReturn(0); + Mockito.when(peerTask.getSubProtocol()).thenReturn(subprotocol); + Mockito.when(requestSender.sendRequest(subprotocol, requestMessageData, ethPeer)) + .thenThrow(new TimeoutException()); + Mockito.when(requestMessageData.getCode()).thenReturn(requestMessageDataCode); + Mockito.when(requestSender.sendRequest(subprotocol, requestMessageData, peer2)) + .thenReturn(responseMessageData); + Mockito.when(peerTask.parseResponse(responseMessageData)).thenReturn(responseObject); + Mockito.when(peerTask.isSuccess(responseObject)).thenReturn(true); + + PeerTaskExecutorResult result = peerTaskExecutor.execute(peerTask); + + Mockito.verify(ethPeer).recordRequestTimeout(requestMessageDataCode); + Mockito.verify(peer2).recordUsefulResponse(); + + Assertions.assertNotNull(result); + Assertions.assertTrue(result.result().isPresent()); + Assertions.assertSame(responseObject, result.result().get()); + Assertions.assertEquals(PeerTaskExecutorResponseCode.SUCCESS, result.responseCode()); + } +} diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/peertask/PeerTaskRequestSenderTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/peertask/PeerTaskRequestSenderTest.java new file mode 100644 index 0000000000..4041fb6303 --- /dev/null +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/peertask/PeerTaskRequestSenderTest.java @@ -0,0 +1,75 @@ +/* + * 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.eth.manager.peertask; + +import org.hyperledger.besu.ethereum.eth.manager.EthPeer; +import org.hyperledger.besu.ethereum.eth.manager.RequestManager; +import org.hyperledger.besu.ethereum.p2p.rlpx.connections.PeerConnection; +import org.hyperledger.besu.ethereum.p2p.rlpx.wire.MessageData; +import org.hyperledger.besu.ethereum.p2p.rlpx.wire.SubProtocol; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Mockito; + +public class PeerTaskRequestSenderTest { + + private PeerTaskRequestSender peerTaskRequestSender; + + @BeforeEach + public void beforeTest() { + peerTaskRequestSender = new PeerTaskRequestSender(); + } + + @Test + public void testSendRequest() + throws PeerConnection.PeerNotConnected, ExecutionException, InterruptedException { + SubProtocol subprotocol = Mockito.mock(SubProtocol.class); + MessageData requestMessageData = Mockito.mock(MessageData.class); + MessageData responseMessageData = Mockito.mock(MessageData.class); + EthPeer peer = Mockito.mock(EthPeer.class); + PeerConnection peerConnection = Mockito.mock(PeerConnection.class); + RequestManager.ResponseStream responseStream = + Mockito.mock(RequestManager.ResponseStream.class); + + Mockito.when(peer.getConnection()).thenReturn(peerConnection); + Mockito.when(subprotocol.getName()).thenReturn("subprotocol"); + Mockito.when(peer.send(requestMessageData, "subprotocol", peerConnection)) + .thenReturn(responseStream); + + CompletableFuture actualResponseMessageDataFuture = + CompletableFuture.supplyAsync( + () -> { + try { + return peerTaskRequestSender.sendRequest(subprotocol, requestMessageData, peer); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + Thread.sleep(500); + ArgumentCaptor responseCallbackArgumentCaptor = + ArgumentCaptor.forClass(RequestManager.ResponseCallback.class); + Mockito.verify(responseStream).then(responseCallbackArgumentCaptor.capture()); + RequestManager.ResponseCallback responseCallback = responseCallbackArgumentCaptor.getValue(); + responseCallback.exec(false, responseMessageData, peer); + + Assertions.assertSame(responseMessageData, actualResponseMessageDataFuture.get()); + } +} diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/snap/SnapServerTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/snap/SnapServerTest.java index e168b7e2fe..2844603429 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/snap/SnapServerTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/snap/SnapServerTest.java @@ -38,7 +38,7 @@ import org.hyperledger.besu.ethereum.rlp.RLP; import org.hyperledger.besu.ethereum.trie.CompactEncoding; import org.hyperledger.besu.ethereum.trie.MerkleTrie; import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.BonsaiWorldStateKeyValueStorage; -import org.hyperledger.besu.ethereum.trie.diffbased.common.storage.flat.FlatDbStrategyProvider; +import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.flat.BonsaiFlatDbStrategyProvider; import org.hyperledger.besu.ethereum.trie.patricia.SimpleMerklePatriciaTrie; import org.hyperledger.besu.ethereum.trie.patricia.StoredMerklePatriciaTrie; import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; @@ -85,7 +85,8 @@ public class SnapServerTest { // force a full flat db with code stored by code hash: final BonsaiWorldStateKeyValueStorage inMemoryStorage = new BonsaiWorldStateKeyValueStorage( - new FlatDbStrategyProvider(noopMetrics, DataStorageConfiguration.DEFAULT_BONSAI_CONFIG) { + new BonsaiFlatDbStrategyProvider( + noopMetrics, DataStorageConfiguration.DEFAULT_BONSAI_CONFIG) { @Override public FlatDbMode getFlatDbMode() { return FlatDbMode.FULL; diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/task/GetBodiesFromPeerTaskTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/task/GetBodiesFromPeerTaskTest.java index b8546ad532..38a56bae93 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/task/GetBodiesFromPeerTaskTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/task/GetBodiesFromPeerTaskTest.java @@ -18,16 +18,11 @@ import static java.util.Collections.emptyList; import static org.assertj.core.api.Assertions.assertThat; import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.BLSPublicKey; -import org.hyperledger.besu.datatypes.BLSSignature; import org.hyperledger.besu.datatypes.GWei; import org.hyperledger.besu.ethereum.core.Block; import org.hyperledger.besu.ethereum.core.BlockBody; import org.hyperledger.besu.ethereum.core.BlockHeader; -import org.hyperledger.besu.ethereum.core.DepositRequest; -import org.hyperledger.besu.ethereum.core.Request; import org.hyperledger.besu.ethereum.core.Withdrawal; -import org.hyperledger.besu.ethereum.core.WithdrawalRequest; import org.hyperledger.besu.ethereum.eth.manager.ethtaskutils.PeerMessageTaskTest; import java.util.ArrayList; @@ -35,7 +30,6 @@ import java.util.List; import java.util.Optional; import java.util.stream.Collectors; -import org.apache.tuweni.bytes.Bytes32; import org.apache.tuweni.units.bigints.UInt64; import org.junit.jupiter.api.Test; @@ -80,58 +74,11 @@ public class GetBodiesFromPeerTaskTest extends PeerMessageTaskTest> final BlockBody emptyBodyBlock = BlockBody.empty(); // Block with no tx, no ommers, 1 withdrawal final BlockBody bodyBlockWithWithdrawal = - new BlockBody(emptyList(), emptyList(), Optional.of(List.of(withdrawal)), Optional.empty()); + new BlockBody(emptyList(), emptyList(), Optional.of(List.of(withdrawal))); assertThat( new GetBodiesFromPeerTask.BodyIdentifier(emptyBodyBlock) .equals(new GetBodiesFromPeerTask.BodyIdentifier(bodyBlockWithWithdrawal))) .isFalse(); } - - @Test - public void assertBodyIdentifierUsesDepositRequestsToGenerateBodyIdentifiers() { - final Request deposit = - new DepositRequest( - BLSPublicKey.fromHexString( - "0xb10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e"), - Bytes32.fromHexString( - "0x0017a7fcf06faf493d30bbe2632ea7c2383cd86825e12797165de7aa35589483"), - GWei.of(32000000000L), - BLSSignature.fromHexString( - "0xa889db8300194050a2636c92a95bc7160515867614b7971a9500cdb62f9c0890217d2901c3241f86fac029428fc106930606154bd9e406d7588934a5f15b837180b17194d6e44bd6de23e43b163dfe12e369dcc75a3852cd997963f158217eb5"), - UInt64.ONE); - - // Empty body block - final BlockBody emptyBodyBlock = BlockBody.empty(); - // Block with no tx, no ommers, 1 deposit - final BlockBody bodyBlockWithDeposit = - new BlockBody(emptyList(), emptyList(), Optional.empty(), Optional.of(List.of(deposit))); - - assertThat( - new GetBodiesFromPeerTask.BodyIdentifier(emptyBodyBlock) - .equals(new GetBodiesFromPeerTask.BodyIdentifier(bodyBlockWithDeposit))) - .isFalse(); - } - - @Test - public void assertBodyIdentifierUsesWithdrawalRequestsToGenerateBodyIdentifiers() { - final WithdrawalRequest withdrawalRequest = - new WithdrawalRequest( - Address.fromHexString("0x763c396673F9c391DCe3361A9A71C8E161388000"), - BLSPublicKey.fromHexString( - "0xb10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e"), - GWei.ONE); - - // Empty body block - final BlockBody emptyBodyBlock = BlockBody.empty(); - // Block with no tx, no ommers, 1 validator exit - final BlockBody bodyBlockWithValidatorExit = - new BlockBody( - emptyList(), emptyList(), Optional.empty(), Optional.of(List.of(withdrawalRequest))); - - assertThat( - new GetBodiesFromPeerTask.BodyIdentifier(emptyBodyBlock) - .equals(new GetBodiesFromPeerTask.BodyIdentifier(bodyBlockWithValidatorExit))) - .isFalse(); - } } diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/task/GetHeadersFromPeerByNumberTaskTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/task/GetHeadersFromPeerByNumberTaskTest.java index 5e0c5dea25..6a1b6a2687 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/task/GetHeadersFromPeerByNumberTaskTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/task/GetHeadersFromPeerByNumberTaskTest.java @@ -57,7 +57,7 @@ public class GetHeadersFromPeerByNumberTaskTest extends PeerMessageTaskTest generateDataToBeRequested() { final int count = 3; final List requestedHeaders = new ArrayList<>(count); - for (long i = 0; i < count; i++) { + for (long i = count - 1; i >= 0; i--) { requestedHeaders.add(blockchain.getBlockHeader(5 + i).get()); } return requestedHeaders; @@ -66,9 +66,13 @@ public class GetHeadersFromPeerByNumberTaskTest extends PeerMessageTaskTest>> createTask( final List requestedData) { - final BlockHeader firstHeader = requestedData.get(0); - return GetHeadersFromPeerByNumberTask.startingAtNumber( - protocolSchedule, ethContext, firstHeader.getNumber(), requestedData.size(), metricsSystem); + return GetHeadersFromPeerByNumberTask.endingAtNumber( + protocolSchedule, + ethContext, + requestedData.getFirst().getNumber(), + requestedData.size(), + 0, + metricsSystem); } @Test diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/messages/MessageWrapperTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/messages/MessageWrapperTest.java index b35bc98a35..0256b09653 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/messages/MessageWrapperTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/messages/MessageWrapperTest.java @@ -259,8 +259,7 @@ public class MessageWrapperTest { new BlockBody( Collections.emptyList(), Collections.emptyList(), - Optional.of(Collections.emptyList()), - Optional.empty())); + Optional.of(Collections.emptyList()))); } @Test @@ -284,8 +283,7 @@ public class MessageWrapperTest { new BlockBody( Collections.emptyList(), Collections.emptyList(), - Optional.of(Collections.emptyList()), - Optional.empty())); + Optional.of(Collections.emptyList()))); } @Test diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/backwardsync/ChainForTestCreator.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/backwardsync/ChainForTestCreator.java index fcf39dd0f8..de398f68f3 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/backwardsync/ChainForTestCreator.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/backwardsync/ChainForTestCreator.java @@ -62,6 +62,7 @@ public class ChainForTestCreator { null, null, null, + null, new MainnetBlockHeaderFunctions()); } @@ -89,7 +90,8 @@ public class ChainForTestCreator { blockHeader.getBlobGasUsed().orElse(null), blockHeader.getExcessBlobGas().orElse(null), blockHeader.getParentBeaconBlockRoot().orElse(null), - blockHeader.getRequestsRoot().orElse(null), + blockHeader.getRequestsHash().orElse(null), + blockHeader.getTargetBlobCount().orElse(null), blockHeader.getExecutionWitness().orElse(null), new MainnetBlockHeaderFunctions()); } @@ -142,6 +144,7 @@ public class ChainForTestCreator { null, null, null, + null, new MainnetBlockHeaderFunctions()); } } diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/CompleteTaskStepTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/CompleteTaskStepTest.java index 2bfc58a3b8..b78f2b10e8 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/CompleteTaskStepTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/CompleteTaskStepTest.java @@ -116,7 +116,7 @@ public class CompleteTaskStepTest { @Test public void shouldMarkSnapsyncTaskCompleteWhenData() { - final List> requests = TaskGenerator.createAccountRequest(true); + final List> requests = TaskGenerator.createAccountRequest(true, false); requests.stream() .map(StubTask.class::cast) .forEach( @@ -132,7 +132,7 @@ public class CompleteTaskStepTest { @Test public void shouldMarkSnapsyncTaskAsFailedWhenNoData() { - final List> requests = TaskGenerator.createAccountRequest(false); + final List> requests = TaskGenerator.createAccountRequest(false, false); requests.stream() .map(StubTask.class::cast) .forEach( diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/PersistDataStepTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/PersistDataStepTest.java index 0364dc7581..963293be0c 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/PersistDataStepTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/PersistDataStepTest.java @@ -17,6 +17,9 @@ package org.hyperledger.besu.ethereum.eth.sync.snapsync; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.fail; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import org.hyperledger.besu.datatypes.Hash; @@ -25,12 +28,15 @@ import org.hyperledger.besu.ethereum.eth.sync.snapsync.request.AccountRangeDataR import org.hyperledger.besu.ethereum.eth.sync.snapsync.request.BytecodeRequest; import org.hyperledger.besu.ethereum.eth.sync.snapsync.request.SnapDataRequest; import org.hyperledger.besu.ethereum.eth.sync.snapsync.request.StorageRangeDataRequest; +import org.hyperledger.besu.ethereum.eth.sync.snapsync.request.heal.AccountTrieNodeHealingRequest; import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.BonsaiWorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.trie.patricia.StoredMerklePatriciaTrie; import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; +import org.hyperledger.besu.ethereum.worldstate.WorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; import org.hyperledger.besu.services.tasks.Task; +import java.util.Collections; import java.util.List; import org.apache.tuweni.bytes.Bytes; @@ -39,9 +45,12 @@ import org.junit.jupiter.api.Test; public class PersistDataStepTest { + private final WorldStateKeyValueStorage worldStateKeyValueStorage = + spy( + new InMemoryKeyValueStorageProvider() + .createWorldStateStorage(DataStorageConfiguration.DEFAULT_CONFIG)); private final WorldStateStorageCoordinator worldStateStorageCoordinator = - new InMemoryKeyValueStorageProvider() - .createWorldStateStorageCoordinator(DataStorageConfiguration.DEFAULT_CONFIG); + new WorldStateStorageCoordinator(worldStateKeyValueStorage); private final SnapSyncProcessState snapSyncState = mock(SnapSyncProcessState.class); private final SnapWorldDownloadState downloadState = mock(SnapWorldDownloadState.class); @@ -59,7 +68,7 @@ public class PersistDataStepTest { @Test public void shouldPersistDataWhenPresent() { - final List> tasks = TaskGenerator.createAccountRequest(true); + final List> tasks = TaskGenerator.createAccountRequest(true, false); final List> result = persistDataStep.persist(tasks); assertThat(result).isSameAs(tasks); @@ -67,9 +76,36 @@ public class PersistDataStepTest { assertDataPersisted(tasks); } + @Test + public void shouldPersistTrieNodeHealDataOnlyOnce() { + + final Bytes stateTrieNode = + Bytes.fromHexString( + "0xe2a0310e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf602"); + final Hash hash = Hash.hash(stateTrieNode); + final Bytes location = Bytes.of(0x02); + final AccountTrieNodeHealingRequest accountTrieNodeDataRequest = + SnapDataRequest.createAccountTrieNodeDataRequest(hash, location, Collections.emptySet()); + accountTrieNodeDataRequest.setData(stateTrieNode); + + final BonsaiWorldStateKeyValueStorage.Updater updater = + (BonsaiWorldStateKeyValueStorage.Updater) spy(worldStateKeyValueStorage.updater()); + when(worldStateKeyValueStorage.updater()) + .thenReturn(updater) + .thenReturn(mock(BonsaiWorldStateKeyValueStorage.Updater.class)); + + List> result = + persistDataStep.persist(List.of(new StubTask(accountTrieNodeDataRequest))); + + persistDataStep.persist(List.of(new StubTask(accountTrieNodeDataRequest))); + + verify(updater, times(1)).putAccountStateTrieNode(location, hash, stateTrieNode); + assertDataPersisted(result); + } + @Test public void shouldSkipPersistDataWhenNoData() { - final List> tasks = TaskGenerator.createAccountRequest(false); + final List> tasks = TaskGenerator.createAccountRequest(false, false); final List> result = persistDataStep.persist(tasks); assertThat(result).isSameAs(tasks); @@ -80,6 +116,25 @@ public class PersistDataStepTest { .isEmpty(); } + @Test + public void shouldHandleNullTaskElementInTrie() { + // Create a StorageRangeDataRequest where taskElement might be null or incomplete + List> tasks = TaskGenerator.createAccountRequest(false, true); + + try { + List> result = persistDataStep.persist(tasks); + + // check for proper handling of null taskElement + assertThat(result).isSameAs(tasks); + assertThat(result) + .isNotNull(); // Make sure the result isn't null even with the bad taskElement + } catch (NullPointerException e) { + fail( + "NullPointerException occurred during persist step, taskElement might be null: " + + e.getMessage()); + } + } + private void assertDataPersisted(final List> tasks) { tasks.forEach( task -> { @@ -110,6 +165,14 @@ public class PersistDataStepTest { .getStrategy(BonsaiWorldStateKeyValueStorage.class) .getCode(Hash.wrap(data.getCodeHash()), Hash.wrap(data.getAccountHash()))) .isPresent(); + } else if (task.getData() instanceof AccountTrieNodeHealingRequest) { + final AccountTrieNodeHealingRequest data = + (AccountTrieNodeHealingRequest) task.getData(); + assertThat( + worldStateStorageCoordinator + .getStrategy(BonsaiWorldStateKeyValueStorage.class) + .getTrieNodeUnsafe(data.getLocation())) + .isPresent(); } else { fail("not expected message"); } diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/TaskGenerator.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/TaskGenerator.java index 0e3915bc77..0b3a17cccf 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/TaskGenerator.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/TaskGenerator.java @@ -44,7 +44,8 @@ import org.apache.tuweni.bytes.Bytes32; public class TaskGenerator { - public static List> createAccountRequest(final boolean withData) { + public static List> createAccountRequest( + final boolean withData, final boolean withNullTaskElement) { final BonsaiWorldStateKeyValueStorage worldStateKeyValueStorage = new BonsaiWorldStateKeyValueStorage( @@ -91,7 +92,8 @@ public class TaskGenerator { rootHash, accountHash, stateTrieAccountValue.getStorageRoot(), - withData); + withData, + withNullTaskElement); final BytecodeRequest bytecodeRequest = createBytecodeDataRequest( worldStateKeyValueStorage, @@ -112,7 +114,8 @@ public class TaskGenerator { final Hash rootHash, final Hash accountHash, final Bytes32 storageRoot, - final boolean withData) { + final boolean withData, + final boolean withNullTaskElement) { final RangeStorageEntriesCollector collector = RangeStorageEntriesCollector.createCollector( @@ -140,6 +143,11 @@ public class TaskGenerator { request.setProofValid(true); request.addResponse(null, worldStateProofProvider, slots, new ArrayDeque<>()); } + + if (withNullTaskElement) { + // setting isValidProof to true to simulate a null task element. + request.setProofValid(true); + } return request; } diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/tasks/CompleteBlocksTaskTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/tasks/CompleteBlocksTaskTest.java index e8049af736..ba0fad675e 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/tasks/CompleteBlocksTaskTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/tasks/CompleteBlocksTaskTest.java @@ -116,19 +116,14 @@ public class CompleteBlocksTaskTest extends RetryingMessageTaskTest> final Block block1 = new Block( header1, - new BlockBody( - Collections.emptyList(), - Collections.emptyList(), - Optional.empty(), - Optional.empty())); + new BlockBody(Collections.emptyList(), Collections.emptyList(), Optional.empty())); final Block block2 = new Block( header2, new BlockBody( Collections.emptyList(), Collections.emptyList(), - Optional.of(Collections.emptyList()), - Optional.empty())); + Optional.of(Collections.emptyList()))); final List expectedBlocks = asList(block1, block2); final EthTask> task = @@ -164,18 +159,14 @@ public class CompleteBlocksTaskTest extends RetryingMessageTaskTest> new Block( header2, new BlockBody( - Collections.emptyList(), - Collections.emptyList(), - Optional.of(withdrawals), - Optional.empty())); + Collections.emptyList(), Collections.emptyList(), Optional.of(withdrawals))); final Block block3 = new Block( header3, new BlockBody( Collections.emptyList(), Collections.emptyList(), - Optional.of(Collections.emptyList()), - Optional.empty())); + Optional.of(Collections.emptyList()))); final List expected = asList(block1, block2, block3); final RespondingEthPeer respondingPeer = diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/tasks/GetReceiptsForHeadersTaskTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/tasks/GetReceiptsForHeadersTaskTest.java index 2b28e8a5c9..bdae7c043e 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/tasks/GetReceiptsForHeadersTaskTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/tasks/GetReceiptsForHeadersTaskTest.java @@ -30,11 +30,19 @@ import java.util.List; import java.util.Map; import com.google.common.collect.ImmutableMap; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; public class GetReceiptsForHeadersTaskTest extends RetryingMessageTaskTest>> { + @BeforeEach + @Override + public void resetMaxRetries() { + maxRetries = GetReceiptsForHeadersTask.DEFAULT_RETRIES; + } + @Override protected Map> generateDataToBeRequested() { // Setup data to be requested and expected response @@ -50,8 +58,7 @@ public class GetReceiptsForHeadersTaskTest protected EthTask>> createTask( final Map> requestedData) { final List headersToComplete = new ArrayList<>(requestedData.keySet()); - return GetReceiptsForHeadersTask.forHeaders( - ethContext, headersToComplete, maxRetries, metricsSystem); + return GetReceiptsForHeadersTask.forHeaders(ethContext, headersToComplete, metricsSystem); } @Test @@ -68,4 +75,13 @@ public class GetReceiptsForHeadersTaskTest assertThat(createTask(expected).run()).isCompletedWithValue(expected); } + + @Override + @Test + @Disabled + public void failsWhenPeerReturnsPartialResultThenStops() { + // Test is not valid when more than 4 retries are allowed, as is always the case with + // GetReceiptsForHeadersTask, because the peer is forcefully disconnected after failing + // too many times + } } diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/AbstractTransactionPoolTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/AbstractTransactionPoolTest.java index e5ec06fd35..656751bed1 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/AbstractTransactionPoolTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/AbstractTransactionPoolTest.java @@ -17,7 +17,6 @@ package org.hyperledger.besu.ethereum.eth.transactions; import static java.util.Arrays.asList; import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; -import static java.util.stream.Collectors.toList; import static org.assertj.core.api.Assertions.assertThat; import static org.hyperledger.besu.ethereum.mainnet.ValidationResult.valid; import static org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason.EXCEEDS_BLOCK_GAS_LIMIT; @@ -29,275 +28,55 @@ import static org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason import static org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason.TRANSACTION_REPLACEMENT_UNDERPRICED; import static org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason.TX_FEECAP_EXCEEDED; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.ArgumentMatchers.nullable; -import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoInteractions; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; import static org.mockito.quality.Strictness.LENIENT; -import org.hyperledger.besu.config.GenesisConfigFile; -import org.hyperledger.besu.crypto.KeyPair; -import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.TransactionType; import org.hyperledger.besu.datatypes.Wei; -import org.hyperledger.besu.ethereum.ProtocolContext; -import org.hyperledger.besu.ethereum.chain.BadBlockManager; -import org.hyperledger.besu.ethereum.chain.MutableBlockchain; -import org.hyperledger.besu.ethereum.core.BlobTestFixture; import org.hyperledger.besu.ethereum.core.Block; -import org.hyperledger.besu.ethereum.core.BlockBody; import org.hyperledger.besu.ethereum.core.BlockHeader; -import org.hyperledger.besu.ethereum.core.BlockHeaderBuilder; -import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture; import org.hyperledger.besu.ethereum.core.Difficulty; -import org.hyperledger.besu.ethereum.core.ExecutionContextTestFixture; -import org.hyperledger.besu.ethereum.core.MiningParameters; -import org.hyperledger.besu.ethereum.core.PrivacyParameters; import org.hyperledger.besu.ethereum.core.Transaction; -import org.hyperledger.besu.ethereum.core.TransactionReceipt; -import org.hyperledger.besu.ethereum.core.TransactionTestFixture; -import org.hyperledger.besu.ethereum.eth.manager.EthContext; import org.hyperledger.besu.ethereum.eth.manager.EthPeer; -import org.hyperledger.besu.ethereum.eth.manager.EthProtocolManager; import org.hyperledger.besu.ethereum.eth.manager.EthProtocolManagerTestUtil; -import org.hyperledger.besu.ethereum.eth.manager.EthScheduler; import org.hyperledger.besu.ethereum.eth.manager.RespondingEthPeer; import org.hyperledger.besu.ethereum.eth.messages.EthPV65; -import org.hyperledger.besu.ethereum.eth.transactions.layered.LayeredTransactionPoolBaseFeeTest; -import org.hyperledger.besu.ethereum.eth.transactions.sorter.LegacyTransactionPoolBaseFeeTest; -import org.hyperledger.besu.ethereum.mainnet.MainnetBlockHeaderFunctions; -import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; -import org.hyperledger.besu.ethereum.mainnet.ProtocolScheduleBuilder; -import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; -import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecAdapters; import org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams; -import org.hyperledger.besu.ethereum.mainnet.TransactionValidatorFactory; import org.hyperledger.besu.ethereum.mainnet.ValidationResult; import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason; -import org.hyperledger.besu.evm.account.Account; -import org.hyperledger.besu.evm.internal.EvmConfiguration; -import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; -import org.hyperledger.besu.plugin.services.MetricsSystem; import org.hyperledger.besu.plugin.services.TransactionPoolValidatorService; -import org.hyperledger.besu.plugin.services.txvalidator.PluginTransactionPoolValidator; -import org.hyperledger.besu.plugin.services.txvalidator.PluginTransactionPoolValidatorFactory; -import org.hyperledger.besu.testutil.DeterministicEthScheduler; import org.hyperledger.besu.util.number.Percentage; -import java.math.BigInteger; -import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Optional; import java.util.Set; -import java.util.function.BiFunction; -import java.util.function.Consumer; -import java.util.function.Function; import java.util.stream.Stream; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.DisabledIf; import org.junit.jupiter.api.condition.EnabledIf; import org.junit.jupiter.api.extension.ExtendWith; -import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; import org.junit.jupiter.params.provider.ValueSource; -import org.mockito.Answers; import org.mockito.ArgumentCaptor; -import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.junit.jupiter.MockitoSettings; @SuppressWarnings("unchecked") @ExtendWith(MockitoExtension.class) @MockitoSettings(strictness = LENIENT) -public abstract class AbstractTransactionPoolTest { - - protected static final KeyPair KEY_PAIR1 = - SignatureAlgorithmFactory.getInstance().generateKeyPair(); - private static final KeyPair KEY_PAIR2 = - SignatureAlgorithmFactory.getInstance().generateKeyPair(); - protected static final Wei BASE_FEE_FLOOR = Wei.of(7L); - protected static final Wei DEFAULT_MIN_GAS_PRICE = Wei.of(50L); - - protected final EthScheduler ethScheduler = new DeterministicEthScheduler(); - - @Mock(answer = Answers.RETURNS_DEEP_STUBS) - protected TransactionValidatorFactory transactionValidatorFactory; - - @Mock protected PendingTransactionAddedListener listener; - - @Mock protected TransactionsMessageSender transactionsMessageSender; - @Mock protected NewPooledTransactionHashesMessageSender newPooledTransactionHashesMessageSender; - @Mock protected ProtocolSpec protocolSpec; - - protected ProtocolSchedule protocolSchedule; - - protected final MetricsSystem metricsSystem = new NoOpMetricsSystem(); - protected MutableBlockchain blockchain; - protected TransactionBroadcaster transactionBroadcaster; - - protected PendingTransactions transactions; - protected final Transaction transaction0 = createTransaction(0); - protected final Transaction transaction1 = createTransaction(1); - protected final Transaction transactionBlob = createBlobTransaction(2); - - protected final Transaction transactionOtherSender = createTransaction(1, KEY_PAIR2); - private ExecutionContextTestFixture executionContext; - protected ProtocolContext protocolContext; - protected TransactionPool transactionPool; - protected long blockGasLimit; - protected EthProtocolManager ethProtocolManager; - protected EthContext ethContext; - private PeerTransactionTracker peerTransactionTracker; - private ArgumentCaptor syncTaskCapture; - - protected abstract PendingTransactions createPendingTransactions( - final TransactionPoolConfiguration poolConfig, - final BiFunction - transactionReplacementTester); - - protected TransactionTestFixture createBaseTransactionGasPriceMarket( - final int transactionNumber) { - return new TransactionTestFixture() - .nonce(transactionNumber) - .gasLimit(blockGasLimit) - .type(TransactionType.FRONTIER); - } - - protected TransactionTestFixture createBaseTransactionBaseFeeMarket(final int nonce) { - return new TransactionTestFixture() - .nonce(nonce) - .gasLimit(blockGasLimit) - .gasPrice(null) - .maxFeePerGas(Optional.of(Wei.of(5000L))) - .maxPriorityFeePerGas(Optional.of(Wei.of(1000L))) - .type(TransactionType.EIP1559); - } - - protected abstract ExecutionContextTestFixture createExecutionContextTestFixture(); - - protected static ExecutionContextTestFixture createExecutionContextTestFixtureBaseFeeMarket() { - final var genesisConfigFile = GenesisConfigFile.fromResource("/txpool-test-genesis.json"); - final ProtocolSchedule protocolSchedule = - new ProtocolScheduleBuilder( - genesisConfigFile.getConfigOptions(), - BigInteger.valueOf(1), - ProtocolSpecAdapters.create(0, Function.identity()), - new PrivacyParameters(), - false, - EvmConfiguration.DEFAULT, - MiningParameters.MINING_DISABLED, - new BadBlockManager(), - false, - new NoOpMetricsSystem()) - .createProtocolSchedule(); - final ExecutionContextTestFixture executionContextTestFixture = - ExecutionContextTestFixture.builder(genesisConfigFile) - .protocolSchedule(protocolSchedule) - .build(); - - final Block block = - new Block( - new BlockHeaderTestFixture() - .gasLimit( - executionContextTestFixture - .getBlockchain() - .getChainHeadBlock() - .getHeader() - .getGasLimit()) - .difficulty(Difficulty.ONE) - .baseFeePerGas(Wei.of(10L)) - .parentHash(executionContextTestFixture.getBlockchain().getChainHeadHash()) - .number(executionContextTestFixture.getBlockchain().getChainHeadBlockNumber() + 1) - .buildHeader(), - new BlockBody(List.of(), List.of())); - executionContextTestFixture.getBlockchain().appendBlock(block, List.of()); - - return executionContextTestFixture; - } - - protected abstract FeeMarket getFeeMarket(); - - @BeforeEach - public void setUp() { - executionContext = createExecutionContextTestFixture(); - protocolContext = executionContext.getProtocolContext(); - blockchain = executionContext.getBlockchain(); - when(protocolSpec.getTransactionValidatorFactory()).thenReturn(transactionValidatorFactory); - when(protocolSpec.getFeeMarket()).thenReturn(getFeeMarket()); - protocolSchedule = spy(executionContext.getProtocolSchedule()); - doReturn(protocolSpec).when(protocolSchedule).getByBlockHeader(any()); - blockGasLimit = blockchain.getChainHeadBlock().getHeader().getGasLimit(); - ethProtocolManager = EthProtocolManagerTestUtil.create(); - ethContext = spy(ethProtocolManager.ethContext()); - - final EthScheduler ethScheduler = spy(ethContext.getScheduler()); - syncTaskCapture = ArgumentCaptor.forClass(Runnable.class); - doNothing().when(ethScheduler).scheduleSyncWorkerTask(syncTaskCapture.capture()); - doReturn(ethScheduler).when(ethContext).getScheduler(); - - peerTransactionTracker = new PeerTransactionTracker(ethContext.getEthPeers()); - transactionBroadcaster = - spy( - new TransactionBroadcaster( - ethContext, - peerTransactionTracker, - transactionsMessageSender, - newPooledTransactionHashesMessageSender)); - - transactionPool = createTransactionPool(); - blockchain.observeBlockAdded(transactionPool); - } - - protected TransactionPool createTransactionPool() { - return createTransactionPool(b -> b.minGasPrice(Wei.of(2))); - } - - private TransactionPool createTransactionPool( - final Consumer configConsumer) { - final ImmutableTransactionPoolConfiguration.Builder configBuilder = - ImmutableTransactionPoolConfiguration.builder(); - configConsumer.accept(configBuilder); - final TransactionPoolConfiguration poolConfig = configBuilder.build(); - - final TransactionPoolReplacementHandler transactionReplacementHandler = - new TransactionPoolReplacementHandler( - poolConfig.getPriceBump(), poolConfig.getBlobPriceBump()); - - final BiFunction transactionReplacementTester = - (t1, t2) -> - transactionReplacementHandler.shouldReplace( - t1, t2, protocolContext.getBlockchain().getChainHeadHeader()); - - transactions = spy(createPendingTransactions(poolConfig, transactionReplacementTester)); - - final TransactionPool txPool = - new TransactionPool( - () -> transactions, - protocolSchedule, - protocolContext, - transactionBroadcaster, - ethContext, - new TransactionPoolMetrics(metricsSystem), - poolConfig, - new BlobCache()); - txPool.setEnabled(); - return txPool; - } +public abstract class AbstractTransactionPoolTest extends AbstractTransactionPoolTestBase { @ParameterizedTest @ValueSource(booleans = {true, false}) @@ -466,21 +245,21 @@ public abstract class AbstractTransactionPoolTest { public void shouldReAddBlobTxsWhenReorgHappens() { givenTransactionIsValid(transaction0); givenTransactionIsValid(transaction1); - givenTransactionIsValid(transactionBlob); + givenTransactionIsValid(transactionWithBlobs); addAndAssertRemoteTransactionsValid(transaction0); addAndAssertRemoteTransactionsValid(transaction1); - addAndAssertRemoteTransactionsValid(transactionBlob); + addAndAssertRemoteTransactionsValid(transactionWithBlobs); final BlockHeader commonParent = getHeaderForCurrentChainHead(); final Block originalFork1 = appendBlock(Difficulty.of(1000), commonParent, transaction0); final Block originalFork2 = appendBlock(Difficulty.of(10), originalFork1.getHeader(), transaction1); final Block originalFork3 = - appendBlock(Difficulty.of(1), originalFork2.getHeader(), transactionBlob); + appendBlock(Difficulty.of(1), originalFork2.getHeader(), transactionWithBlobs); assertTransactionNotPending(transaction0); assertTransactionNotPending(transaction1); - assertTransactionNotPending(transactionBlob); + assertTransactionNotPending(transactionWithBlobs); final Block reorgFork1 = appendBlock(Difficulty.ONE, commonParent); verifyChainHeadIs(originalFork3); @@ -493,14 +272,15 @@ public abstract class AbstractTransactionPoolTest { assertTransactionPending(transaction0); assertTransactionPending(transaction1); - assertTransactionPending(transactionBlob); + assertTransactionPending(transactionWithBlobs); - Optional maybeBlob = transactions.getTransactionByHash(transactionBlob.getHash()); + Optional maybeBlob = + transactions.getTransactionByHash(transactionWithBlobs.getHash()); assertThat(maybeBlob).isPresent(); Transaction restoredBlob = maybeBlob.get(); - assertThat(restoredBlob).isEqualTo(transactionBlob); + assertThat(restoredBlob).isEqualTo(transactionWithBlobs); assertThat(restoredBlob.getBlobsWithCommitments().get().getBlobQuads()) - .isEqualTo(transactionBlob.getBlobsWithCommitments().get().getBlobQuads()); + .isEqualTo(transactionWithBlobs.getBlobsWithCommitments().get().getBlobQuads()); } @ParameterizedTest @@ -1281,272 +1061,4 @@ public abstract class AbstractTransactionPoolTest { .map(PendingTransaction::getTransaction) .containsExactlyInAnyOrder(transaction1, transaction2a, transaction3); } - - private static TransactionPoolValidatorService getTransactionPoolValidatorServiceReturning( - final String errorMessage) { - return new TransactionPoolValidatorService() { - @Override - public PluginTransactionPoolValidator createTransactionValidator() { - return (transaction, isLocal, hasPriority) -> Optional.ofNullable(errorMessage); - } - - @Override - public void registerPluginTransactionValidatorFactory( - final PluginTransactionPoolValidatorFactory pluginTransactionPoolValidatorFactory) {} - }; - } - - @SuppressWarnings("unused") - private static boolean isBaseFeeMarket(final ExtensionContext extensionContext) { - final Class cz = extensionContext.getTestClass().get(); - - return cz.equals(LegacyTransactionPoolBaseFeeTest.class) - || cz.equals(LayeredTransactionPoolBaseFeeTest.class); - } - - protected void assertTransactionNotPending(final Transaction transaction) { - assertThat(transactions.getTransactionByHash(transaction.getHash())).isEmpty(); - } - - protected void addAndAssertRemoteTransactionInvalid(final Transaction tx) { - transactionPool.addRemoteTransactions(List.of(tx)); - - verify(transactionBroadcaster, never()).onTransactionsAdded(singletonList(tx)); - assertTransactionNotPending(tx); - } - - protected void assertTransactionPending(final Transaction t) { - assertThat(transactions.getTransactionByHash(t.getHash())).contains(t); - } - - protected void addAndAssertRemoteTransactionsValid(final Transaction... txs) { - addAndAssertRemoteTransactionsValid(false, txs); - } - - protected void addAndAssertRemotePriorityTransactionsValid(final Transaction... txs) { - addAndAssertRemoteTransactionsValid(true, txs); - } - - protected void addAndAssertRemoteTransactionsValid( - final boolean hasPriority, final Transaction... txs) { - transactionPool.addRemoteTransactions(List.of(txs)); - - verify(transactionBroadcaster) - .onTransactionsAdded( - argThat(btxs -> btxs.size() == txs.length && btxs.containsAll(List.of(txs)))); - Arrays.stream(txs).forEach(this::assertTransactionPending); - assertThat(transactions.getLocalTransactions()).doesNotContain(txs); - if (hasPriority) { - assertThat(transactions.getPriorityTransactions()).contains(txs); - } - } - - protected void addAndAssertTransactionViaApiValid( - final Transaction tx, final boolean disableLocalPriority) { - final ValidationResult result = - transactionPool.addTransactionViaApi(tx); - - assertThat(result.isValid()).isTrue(); - assertTransactionPending(tx); - verify(transactionBroadcaster).onTransactionsAdded(singletonList(tx)); - assertThat(transactions.getLocalTransactions()).contains(tx); - if (disableLocalPriority) { - assertThat(transactions.getPriorityTransactions()).doesNotContain(tx); - } else { - assertThat(transactions.getPriorityTransactions()).contains(tx); - } - } - - protected void addAndAssertTransactionViaApiInvalid( - final Transaction tx, final TransactionInvalidReason invalidReason) { - final ValidationResult result = - transactionPool.addTransactionViaApi(tx); - - assertThat(result.isValid()).isFalse(); - assertThat(result.getInvalidReason()).isEqualTo(invalidReason); - assertTransactionNotPending(tx); - verify(transactionBroadcaster, never()).onTransactionsAdded(singletonList(tx)); - } - - @SuppressWarnings("unchecked") - protected void givenTransactionIsValid(final Transaction transaction) { - when(transactionValidatorFactory - .get() - .validate(eq(transaction), any(Optional.class), any(Optional.class), any())) - .thenReturn(valid()); - when(transactionValidatorFactory - .get() - .validateForSender( - eq(transaction), nullable(Account.class), any(TransactionValidationParams.class))) - .thenReturn(valid()); - } - - protected abstract Block appendBlock( - final Difficulty difficulty, - final BlockHeader parentBlock, - final Transaction... transactionsToAdd); - - protected Transaction createTransactionGasPriceMarket( - final int transactionNumber, final Wei maxPrice) { - return createBaseTransaction(transactionNumber).gasPrice(maxPrice).createTransaction(KEY_PAIR1); - } - - protected Transaction createTransactionBaseFeeMarket(final int nonce, final Wei maxPrice) { - return createBaseTransaction(nonce) - .maxFeePerGas(Optional.of(maxPrice)) - .maxPriorityFeePerGas(Optional.of(maxPrice.divide(5L))) - .createTransaction(KEY_PAIR1); - } - - protected abstract TransactionTestFixture createBaseTransaction(final int nonce); - - protected Transaction createTransaction( - final int transactionNumber, final Optional maybeChainId) { - return createBaseTransaction(transactionNumber) - .chainId(maybeChainId) - .createTransaction(KEY_PAIR1); - } - - protected abstract Transaction createTransaction(final int nonce, final Wei maxPrice); - - protected Transaction createTransaction(final int nonce) { - return createTransaction(nonce, Optional.of(BigInteger.ONE)); - } - - protected Transaction createTransaction(final int nonce, final KeyPair keyPair) { - return createBaseTransaction(nonce).createTransaction(keyPair); - } - - protected void verifyChainHeadIs(final Block forkBlock2) { - assertThat(blockchain.getChainHeadHash()).isEqualTo(forkBlock2.getHash()); - } - - protected BlockHeader getHeaderForCurrentChainHead() { - return blockchain.getBlockHeader(blockchain.getChainHeadHash()).get(); - } - - protected void appendBlock(final Transaction... transactionsToAdd) { - appendBlock(Difficulty.ONE, getHeaderForCurrentChainHead(), transactionsToAdd); - } - - protected void protocolSupportsTxReplayProtection( - final long chainId, final boolean isSupportedAtCurrentBlock) { - when(protocolSpec.isReplayProtectionSupported()).thenReturn(isSupportedAtCurrentBlock); - when(protocolSchedule.getChainId()).thenReturn(Optional.of(BigInteger.valueOf(chainId))); - } - - protected void protocolDoesNotSupportTxReplayProtection() { - when(protocolSchedule.getChainId()).thenReturn(Optional.empty()); - } - - protected Transaction createTransactionWithoutChainId(final int transactionNumber) { - return createTransaction(transactionNumber, Optional.empty()); - } - - protected void whenBlockBaseFeeIs(final Wei baseFee) { - final BlockHeader header = - BlockHeaderBuilder.fromHeader(blockchain.getChainHeadHeader()) - .baseFee(baseFee) - .blockHeaderFunctions(new MainnetBlockHeaderFunctions()) - .parentHash(blockchain.getChainHeadHash()) - .buildBlockHeader(); - blockchain.appendBlock(new Block(header, BlockBody.empty()), emptyList()); - } - - protected Transaction createFrontierTransaction(final int transactionNumber, final Wei gasPrice) { - return new TransactionTestFixture() - .nonce(transactionNumber) - .gasPrice(gasPrice) - .gasLimit(blockGasLimit) - .type(TransactionType.FRONTIER) - .createTransaction(KEY_PAIR1); - } - - protected Transaction createBlobTransaction(final int nonce) { - return new TransactionTestFixture() - .nonce(nonce) - .gasLimit(blockGasLimit) - .gasPrice(null) - .maxFeePerGas(Optional.of(Wei.of(5000L))) - .maxPriorityFeePerGas(Optional.of(Wei.of(1000L))) - .type(TransactionType.BLOB) - .blobsWithCommitments(Optional.of(new BlobTestFixture().createBlobsWithCommitments(6))) - .createTransaction(KEY_PAIR1); - } - - protected int addTxAndGetPendingTxsCount( - final Wei genesisBaseFee, - final Wei minGasPrice, - final Wei lastBlockBaseFee, - final Wei txMaxFeePerGas, - final boolean isLocal, - final boolean hasPriority) { - when(protocolSpec.getFeeMarket()).thenReturn(FeeMarket.london(0, Optional.of(genesisBaseFee))); - whenBlockBaseFeeIs(lastBlockBaseFee); - - final Transaction transaction = createTransaction(0, txMaxFeePerGas); - if (hasPriority) { - transactionPool = - createTransactionPool( - b -> b.minGasPrice(minGasPrice).prioritySenders(Set.of(transaction.getSender()))); - } else { - transactionPool = - createTransactionPool(b -> b.minGasPrice(minGasPrice).noLocalPriority(true)); - } - - givenTransactionIsValid(transaction); - - if (isLocal) { - transactionPool.addTransactionViaApi(transaction); - } else { - transactionPool.addRemoteTransactions(List.of(transaction)); - } - - return transactions.size(); - } - - protected Block appendBlockGasPriceMarket( - final Difficulty difficulty, - final BlockHeader parentBlock, - final Transaction[] transactionsToAdd) { - final List transactionList = asList(transactionsToAdd); - final Block block = - new Block( - new BlockHeaderTestFixture() - .difficulty(difficulty) - .gasLimit(parentBlock.getGasLimit()) - .parentHash(parentBlock.getHash()) - .number(parentBlock.getNumber() + 1) - .buildHeader(), - new BlockBody(transactionList, emptyList())); - final List transactionReceipts = - transactionList.stream() - .map(transaction -> new TransactionReceipt(1, 1, emptyList(), Optional.empty())) - .collect(toList()); - blockchain.appendBlock(block, transactionReceipts); - return block; - } - - protected Block appendBlockBaseFeeMarket( - final Difficulty difficulty, - final BlockHeader parentBlock, - final Transaction[] transactionsToAdd) { - final List transactionList = asList(transactionsToAdd); - final Block block = - new Block( - new BlockHeaderTestFixture() - .baseFeePerGas(Wei.of(10L)) - .gasLimit(parentBlock.getGasLimit()) - .difficulty(difficulty) - .parentHash(parentBlock.getHash()) - .number(parentBlock.getNumber() + 1) - .buildHeader(), - new BlockBody(transactionList, emptyList())); - final List transactionReceipts = - transactionList.stream() - .map(transaction -> new TransactionReceipt(1, 1, emptyList(), Optional.empty())) - .collect(toList()); - blockchain.appendBlock(block, transactionReceipts); - return block; - } } diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/AbstractTransactionPoolTestBase.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/AbstractTransactionPoolTestBase.java new file mode 100644 index 0000000000..c3ca24a4e1 --- /dev/null +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/AbstractTransactionPoolTestBase.java @@ -0,0 +1,585 @@ +/* + * 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.eth.transactions; + +import static java.util.Arrays.asList; +import static java.util.Collections.emptyList; +import static java.util.Collections.singletonList; +import static java.util.stream.Collectors.toList; +import static org.assertj.core.api.Assertions.assertThat; +import static org.hyperledger.besu.ethereum.mainnet.ValidationResult.valid; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.argThat; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.nullable; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.quality.Strictness.LENIENT; + +import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.crypto.KeyPair; +import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; +import org.hyperledger.besu.datatypes.BlobsWithCommitments; +import org.hyperledger.besu.datatypes.TransactionType; +import org.hyperledger.besu.datatypes.Wei; +import org.hyperledger.besu.ethereum.ProtocolContext; +import org.hyperledger.besu.ethereum.chain.BadBlockManager; +import org.hyperledger.besu.ethereum.chain.MutableBlockchain; +import org.hyperledger.besu.ethereum.core.BlobTestFixture; +import org.hyperledger.besu.ethereum.core.Block; +import org.hyperledger.besu.ethereum.core.BlockBody; +import org.hyperledger.besu.ethereum.core.BlockHeader; +import org.hyperledger.besu.ethereum.core.BlockHeaderBuilder; +import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture; +import org.hyperledger.besu.ethereum.core.Difficulty; +import org.hyperledger.besu.ethereum.core.ExecutionContextTestFixture; +import org.hyperledger.besu.ethereum.core.MiningParameters; +import org.hyperledger.besu.ethereum.core.PrivacyParameters; +import org.hyperledger.besu.ethereum.core.Transaction; +import org.hyperledger.besu.ethereum.core.TransactionReceipt; +import org.hyperledger.besu.ethereum.core.TransactionTestFixture; +import org.hyperledger.besu.ethereum.eth.manager.EthContext; +import org.hyperledger.besu.ethereum.eth.manager.EthProtocolManager; +import org.hyperledger.besu.ethereum.eth.manager.EthProtocolManagerTestUtil; +import org.hyperledger.besu.ethereum.eth.manager.EthScheduler; +import org.hyperledger.besu.ethereum.eth.transactions.layered.LayeredTransactionPoolBaseFeeTest; +import org.hyperledger.besu.ethereum.eth.transactions.sorter.LegacyTransactionPoolBaseFeeTest; +import org.hyperledger.besu.ethereum.mainnet.MainnetBlockHeaderFunctions; +import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; +import org.hyperledger.besu.ethereum.mainnet.ProtocolScheduleBuilder; +import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; +import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecAdapters; +import org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams; +import org.hyperledger.besu.ethereum.mainnet.TransactionValidatorFactory; +import org.hyperledger.besu.ethereum.mainnet.ValidationResult; +import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; +import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason; +import org.hyperledger.besu.evm.account.Account; +import org.hyperledger.besu.evm.internal.EvmConfiguration; +import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; +import org.hyperledger.besu.plugin.services.MetricsSystem; +import org.hyperledger.besu.plugin.services.TransactionPoolValidatorService; +import org.hyperledger.besu.plugin.services.txvalidator.PluginTransactionPoolValidator; +import org.hyperledger.besu.plugin.services.txvalidator.PluginTransactionPoolValidatorFactory; +import org.hyperledger.besu.testutil.DeterministicEthScheduler; + +import java.math.BigInteger; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.function.BiFunction; +import java.util.function.Consumer; +import java.util.function.Function; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.mockito.Answers; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.mockito.junit.jupiter.MockitoSettings; + +@SuppressWarnings("unchecked") +@ExtendWith(MockitoExtension.class) +@MockitoSettings(strictness = LENIENT) +public abstract class AbstractTransactionPoolTestBase { + + protected static final KeyPair KEY_PAIR1 = + SignatureAlgorithmFactory.getInstance().generateKeyPair(); + private static final KeyPair KEY_PAIR2 = + SignatureAlgorithmFactory.getInstance().generateKeyPair(); + protected static final Wei BASE_FEE_FLOOR = Wei.of(7L); + protected static final Wei DEFAULT_MIN_GAS_PRICE = Wei.of(50L); + + protected final EthScheduler ethScheduler = new DeterministicEthScheduler(); + + @Mock(answer = Answers.RETURNS_DEEP_STUBS) + protected TransactionValidatorFactory transactionValidatorFactory; + + @Mock protected PendingTransactionAddedListener listener; + + @Mock protected TransactionsMessageSender transactionsMessageSender; + @Mock protected NewPooledTransactionHashesMessageSender newPooledTransactionHashesMessageSender; + @Mock protected ProtocolSpec protocolSpec; + + protected ProtocolSchedule protocolSchedule; + + protected final MetricsSystem metricsSystem = new NoOpMetricsSystem(); + protected MutableBlockchain blockchain; + protected TransactionBroadcaster transactionBroadcaster; + + protected PendingTransactions transactions; + protected final Transaction transaction0 = createTransaction(0); + protected final Transaction transaction1 = createTransaction(1); + protected final Transaction transactionWithBlobs = createBlobTransaction(2); + protected final Transaction transactionWithBlobsReplacement = + createReplacementTransactionWithBlobs(2); + protected final Transaction transactionWithSameBlobs = + createBlobTransactionWithSameBlobs(3, transactionWithBlobs.getBlobsWithCommitments().get()); + protected final Transaction transactionWithSameBlobsReplacement = + createReplacementTransactionWithBlobs(3); + + protected final Transaction transactionOtherSender = createTransaction(1, KEY_PAIR2); + private ExecutionContextTestFixture executionContext; + protected ProtocolContext protocolContext; + protected TransactionPool transactionPool; + protected long blockGasLimit; + protected EthProtocolManager ethProtocolManager; + protected EthContext ethContext; + protected ArgumentCaptor syncTaskCapture; + protected PeerTransactionTracker peerTransactionTracker; + private BlobTestFixture blobTestFixture; + + protected abstract PendingTransactions createPendingTransactions( + final TransactionPoolConfiguration poolConfig, + final BiFunction + transactionReplacementTester); + + protected TransactionTestFixture createBaseTransactionGasPriceMarket( + final int transactionNumber) { + return new TransactionTestFixture() + .nonce(transactionNumber) + .gasLimit(blockGasLimit) + .type(TransactionType.FRONTIER); + } + + protected TransactionTestFixture createBaseTransactionBaseFeeMarket(final int nonce) { + return new TransactionTestFixture() + .nonce(nonce) + .gasLimit(blockGasLimit) + .gasPrice(null) + .maxFeePerGas(Optional.of(Wei.of(5000L))) + .maxPriorityFeePerGas(Optional.of(Wei.of(1000L))) + .type(TransactionType.EIP1559); + } + + protected abstract ExecutionContextTestFixture createExecutionContextTestFixture(); + + protected static ExecutionContextTestFixture createExecutionContextTestFixtureBaseFeeMarket() { + final var genesisConfigFile = GenesisConfigFile.fromResource("/txpool-test-genesis.json"); + final ProtocolSchedule protocolSchedule = + new ProtocolScheduleBuilder( + genesisConfigFile.getConfigOptions(), + BigInteger.valueOf(1), + ProtocolSpecAdapters.create(0, Function.identity()), + new PrivacyParameters(), + false, + EvmConfiguration.DEFAULT, + MiningParameters.MINING_DISABLED, + new BadBlockManager(), + false, + new NoOpMetricsSystem()) + .createProtocolSchedule(); + final ExecutionContextTestFixture executionContextTestFixture = + ExecutionContextTestFixture.builder(genesisConfigFile) + .protocolSchedule(protocolSchedule) + .build(); + + final Block block = + new Block( + new BlockHeaderTestFixture() + .gasLimit( + executionContextTestFixture + .getBlockchain() + .getChainHeadBlock() + .getHeader() + .getGasLimit()) + .difficulty(Difficulty.ONE) + .baseFeePerGas(Wei.of(10L)) + .parentHash(executionContextTestFixture.getBlockchain().getChainHeadHash()) + .number(executionContextTestFixture.getBlockchain().getChainHeadBlockNumber() + 1) + .buildHeader(), + new BlockBody(List.of(), List.of())); + executionContextTestFixture.getBlockchain().appendBlock(block, List.of()); + + return executionContextTestFixture; + } + + protected abstract FeeMarket getFeeMarket(); + + @BeforeEach + public void setUp() { + executionContext = createExecutionContextTestFixture(); + protocolContext = executionContext.getProtocolContext(); + blockchain = executionContext.getBlockchain(); + when(protocolSpec.getTransactionValidatorFactory()).thenReturn(transactionValidatorFactory); + when(protocolSpec.getFeeMarket()).thenReturn(getFeeMarket()); + protocolSchedule = spy(executionContext.getProtocolSchedule()); + doReturn(protocolSpec).when(protocolSchedule).getByBlockHeader(any()); + blockGasLimit = blockchain.getChainHeadBlock().getHeader().getGasLimit(); + ethProtocolManager = EthProtocolManagerTestUtil.create(); + ethContext = spy(ethProtocolManager.ethContext()); + + final EthScheduler ethScheduler = spy(ethContext.getScheduler()); + syncTaskCapture = ArgumentCaptor.forClass(Runnable.class); + doNothing().when(ethScheduler).scheduleSyncWorkerTask(syncTaskCapture.capture()); + doReturn(ethScheduler).when(ethContext).getScheduler(); + + peerTransactionTracker = new PeerTransactionTracker(ethContext.getEthPeers()); + transactionBroadcaster = + spy( + new TransactionBroadcaster( + ethContext, + peerTransactionTracker, + transactionsMessageSender, + newPooledTransactionHashesMessageSender)); + + transactionPool = createTransactionPool(); + blockchain.observeBlockAdded(transactionPool); + } + + protected TransactionPool createTransactionPool() { + return createTransactionPool(b -> b.minGasPrice(Wei.of(2))); + } + + TransactionPool createTransactionPool( + final Consumer configConsumer) { + final ImmutableTransactionPoolConfiguration.Builder configBuilder = + ImmutableTransactionPoolConfiguration.builder(); + configConsumer.accept(configBuilder); + final TransactionPoolConfiguration poolConfig = configBuilder.build(); + + final TransactionPoolReplacementHandler transactionReplacementHandler = + new TransactionPoolReplacementHandler( + poolConfig.getPriceBump(), poolConfig.getBlobPriceBump()); + + final BiFunction transactionReplacementTester = + (t1, t2) -> + transactionReplacementHandler.shouldReplace( + t1, t2, protocolContext.getBlockchain().getChainHeadHeader()); + + transactions = spy(createPendingTransactions(poolConfig, transactionReplacementTester)); + + final TransactionPool txPool = + new TransactionPool( + () -> transactions, + protocolSchedule, + protocolContext, + transactionBroadcaster, + ethContext, + new TransactionPoolMetrics(metricsSystem), + poolConfig, + new BlobCache()); + txPool.setEnabled(); + return txPool; + } + + static TransactionPoolValidatorService getTransactionPoolValidatorServiceReturning( + final String errorMessage) { + return new TransactionPoolValidatorService() { + @Override + public PluginTransactionPoolValidator createTransactionValidator() { + return (transaction, isLocal, hasPriority) -> Optional.ofNullable(errorMessage); + } + + @Override + public void registerPluginTransactionValidatorFactory( + final PluginTransactionPoolValidatorFactory pluginTransactionPoolValidatorFactory) {} + }; + } + + @SuppressWarnings("unused") + private static boolean isBaseFeeMarket(final ExtensionContext extensionContext) { + final Class cz = extensionContext.getTestClass().get(); + + return cz.equals(LegacyTransactionPoolBaseFeeTest.class) + || cz.equals(LayeredTransactionPoolBaseFeeTest.class) + || cz.equals(BlobV1TransactionPoolTest.class); + } + + protected void assertTransactionNotPending(final Transaction transaction) { + assertThat(transactions.getTransactionByHash(transaction.getHash())).isEmpty(); + } + + protected void addAndAssertRemoteTransactionInvalid(final Transaction tx) { + transactionPool.addRemoteTransactions(List.of(tx)); + + verify(transactionBroadcaster, never()).onTransactionsAdded(singletonList(tx)); + assertTransactionNotPending(tx); + } + + protected void assertTransactionPending(final Transaction t) { + assertThat(transactions.getTransactionByHash(t.getHash())).contains(t); + } + + protected void addAndAssertRemoteTransactionsValid(final Transaction... txs) { + addAndAssertRemoteTransactionsValid(false, txs); + } + + protected void addAndAssertRemotePriorityTransactionsValid(final Transaction... txs) { + addAndAssertRemoteTransactionsValid(true, txs); + } + + protected void addAndAssertRemoteTransactionsValid( + final boolean hasPriority, final Transaction... txs) { + transactionPool.addRemoteTransactions(List.of(txs)); + + verify(transactionBroadcaster) + .onTransactionsAdded( + argThat(btxs -> btxs.size() == txs.length && btxs.containsAll(List.of(txs)))); + Arrays.stream(txs).forEach(this::assertTransactionPending); + assertThat(transactions.getLocalTransactions()).doesNotContain(txs); + if (hasPriority) { + assertThat(transactions.getPriorityTransactions()).contains(txs); + } + } + + protected void addAndAssertTransactionViaApiValid( + final Transaction tx, final boolean disableLocalPriority) { + final ValidationResult result = + transactionPool.addTransactionViaApi(tx); + + assertThat(result.isValid()).isTrue(); + assertTransactionPending(tx); + verify(transactionBroadcaster).onTransactionsAdded(singletonList(tx)); + assertThat(transactions.getLocalTransactions()).contains(tx); + if (disableLocalPriority) { + assertThat(transactions.getPriorityTransactions()).doesNotContain(tx); + } else { + assertThat(transactions.getPriorityTransactions()).contains(tx); + } + } + + protected void addAndAssertTransactionViaApiInvalid( + final Transaction tx, final TransactionInvalidReason invalidReason) { + final ValidationResult result = + transactionPool.addTransactionViaApi(tx); + + assertThat(result.isValid()).isFalse(); + assertThat(result.getInvalidReason()).isEqualTo(invalidReason); + assertTransactionNotPending(tx); + verify(transactionBroadcaster, never()).onTransactionsAdded(singletonList(tx)); + } + + @SuppressWarnings("unchecked") + protected void givenTransactionIsValid(final Transaction transaction) { + when(transactionValidatorFactory + .get() + .validate(eq(transaction), any(Optional.class), any(Optional.class), any())) + .thenReturn(valid()); + when(transactionValidatorFactory + .get() + .validateForSender( + eq(transaction), nullable(Account.class), any(TransactionValidationParams.class))) + .thenReturn(valid()); + } + + protected abstract Block appendBlock( + final Difficulty difficulty, + final BlockHeader parentBlock, + final Transaction... transactionsToAdd); + + protected Transaction createTransactionGasPriceMarket( + final int transactionNumber, final Wei maxPrice) { + return createBaseTransaction(transactionNumber).gasPrice(maxPrice).createTransaction(KEY_PAIR1); + } + + protected Transaction createTransactionBaseFeeMarket(final int nonce, final Wei maxPrice) { + return createBaseTransaction(nonce) + .maxFeePerGas(Optional.of(maxPrice)) + .maxPriorityFeePerGas(Optional.of(maxPrice.divide(5L))) + .createTransaction(KEY_PAIR1); + } + + protected abstract TransactionTestFixture createBaseTransaction(final int nonce); + + protected Transaction createTransaction( + final int transactionNumber, final Optional maybeChainId) { + return createBaseTransaction(transactionNumber) + .chainId(maybeChainId) + .createTransaction(KEY_PAIR1); + } + + protected abstract Transaction createTransaction(final int nonce, final Wei maxPrice); + + protected Transaction createTransaction(final int nonce) { + return createTransaction(nonce, Optional.of(BigInteger.ONE)); + } + + protected Transaction createTransaction(final int nonce, final KeyPair keyPair) { + return createBaseTransaction(nonce).createTransaction(keyPair); + } + + protected void verifyChainHeadIs(final Block forkBlock2) { + assertThat(blockchain.getChainHeadHash()).isEqualTo(forkBlock2.getHash()); + } + + protected BlockHeader getHeaderForCurrentChainHead() { + return blockchain.getBlockHeader(blockchain.getChainHeadHash()).get(); + } + + protected void appendBlock(final Transaction... transactionsToAdd) { + appendBlock(Difficulty.ONE, getHeaderForCurrentChainHead(), transactionsToAdd); + } + + protected void protocolSupportsTxReplayProtection( + final long chainId, final boolean isSupportedAtCurrentBlock) { + when(protocolSpec.isReplayProtectionSupported()).thenReturn(isSupportedAtCurrentBlock); + when(protocolSchedule.getChainId()).thenReturn(Optional.of(BigInteger.valueOf(chainId))); + } + + protected void protocolDoesNotSupportTxReplayProtection() { + when(protocolSchedule.getChainId()).thenReturn(Optional.empty()); + } + + protected Transaction createTransactionWithoutChainId(final int transactionNumber) { + return createTransaction(transactionNumber, Optional.empty()); + } + + protected void whenBlockBaseFeeIs(final Wei baseFee) { + final BlockHeader header = + BlockHeaderBuilder.fromHeader(blockchain.getChainHeadHeader()) + .baseFee(baseFee) + .blockHeaderFunctions(new MainnetBlockHeaderFunctions()) + .parentHash(blockchain.getChainHeadHash()) + .buildBlockHeader(); + blockchain.appendBlock(new Block(header, BlockBody.empty()), emptyList()); + } + + protected Transaction createFrontierTransaction(final int transactionNumber, final Wei gasPrice) { + return new TransactionTestFixture() + .nonce(transactionNumber) + .gasPrice(gasPrice) + .gasLimit(blockGasLimit) + .type(TransactionType.FRONTIER) + .createTransaction(KEY_PAIR1); + } + + protected Transaction createBlobTransaction(final int nonce) { + if (blobTestFixture == null) { + blobTestFixture = new BlobTestFixture(); + } + return new TransactionTestFixture() + .nonce(nonce) + .gasLimit(blockGasLimit) + .gasPrice(null) + .maxFeePerGas(Optional.of(Wei.of(5000L))) + .maxPriorityFeePerGas(Optional.of(Wei.of(1000L))) + .type(TransactionType.BLOB) + .blobsWithCommitments(Optional.of(blobTestFixture.createBlobsWithCommitments(6))) + .createTransaction(KEY_PAIR1); + } + + protected Transaction createBlobTransactionWithSameBlobs( + final int nonce, final BlobsWithCommitments blobsWithCommitments) { + return new TransactionTestFixture() + .nonce(nonce) + .gasLimit(blockGasLimit) + .gasPrice(null) + .maxFeePerGas(Optional.of(Wei.of(5000L))) + .maxPriorityFeePerGas(Optional.of(Wei.of(1000L))) + .type(TransactionType.BLOB) + .blobsWithCommitments(Optional.of(blobsWithCommitments)) + .createTransaction(KEY_PAIR1); + } + + protected Transaction createReplacementTransactionWithBlobs(final int nonce) { + if (blobTestFixture == null) { + blobTestFixture = new BlobTestFixture(); + } + return new TransactionTestFixture() + .nonce(nonce) + .gasLimit(blockGasLimit) + .gasPrice(null) + .maxFeePerGas(Optional.of(Wei.of(5000L * 10))) + .maxPriorityFeePerGas(Optional.of(Wei.of(1000L * 10))) + .maxFeePerBlobGas(Optional.of(Wei.of(5000L))) + .type(TransactionType.BLOB) + .blobsWithCommitments(Optional.of(blobTestFixture.createBlobsWithCommitments(6))) + .createTransaction(KEY_PAIR1); + } + + protected int addTxAndGetPendingTxsCount( + final Wei genesisBaseFee, + final Wei minGasPrice, + final Wei lastBlockBaseFee, + final Wei txMaxFeePerGas, + final boolean isLocal, + final boolean hasPriority) { + when(protocolSpec.getFeeMarket()).thenReturn(FeeMarket.london(0, Optional.of(genesisBaseFee))); + whenBlockBaseFeeIs(lastBlockBaseFee); + + final Transaction transaction = createTransaction(0, txMaxFeePerGas); + if (hasPriority) { + transactionPool = + createTransactionPool( + b -> b.minGasPrice(minGasPrice).prioritySenders(Set.of(transaction.getSender()))); + } else { + transactionPool = + createTransactionPool(b -> b.minGasPrice(minGasPrice).noLocalPriority(true)); + } + + givenTransactionIsValid(transaction); + + if (isLocal) { + transactionPool.addTransactionViaApi(transaction); + } else { + transactionPool.addRemoteTransactions(List.of(transaction)); + } + + return transactions.size(); + } + + protected Block appendBlockGasPriceMarket( + final Difficulty difficulty, + final BlockHeader parentBlock, + final Transaction[] transactionsToAdd) { + final List transactionList = asList(transactionsToAdd); + final Block block = + new Block( + new BlockHeaderTestFixture() + .difficulty(difficulty) + .gasLimit(parentBlock.getGasLimit()) + .parentHash(parentBlock.getHash()) + .number(parentBlock.getNumber() + 1) + .buildHeader(), + new BlockBody(transactionList, emptyList())); + final List transactionReceipts = + transactionList.stream() + .map(transaction -> new TransactionReceipt(1, 1, emptyList(), Optional.empty())) + .collect(toList()); + blockchain.appendBlock(block, transactionReceipts); + return block; + } + + protected Block appendBlockBaseFeeMarket( + final Difficulty difficulty, + final BlockHeader parentBlock, + final Transaction[] transactionsToAdd) { + final List transactionList = asList(transactionsToAdd); + final Block block = + new Block( + new BlockHeaderTestFixture() + .baseFeePerGas(Wei.of(10L)) + .gasLimit(parentBlock.getGasLimit()) + .difficulty(difficulty) + .parentHash(parentBlock.getHash()) + .number(parentBlock.getNumber() + 1) + .buildHeader(), + new BlockBody(transactionList, emptyList())); + final List transactionReceipts = + transactionList.stream() + .map(transaction -> new TransactionReceipt(1, 1, emptyList(), Optional.empty())) + .collect(toList()); + blockchain.appendBlock(block, transactionReceipts); + return block; + } +} diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/BlobV1TransactionPoolTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/BlobV1TransactionPoolTest.java new file mode 100644 index 0000000000..aa81215a66 --- /dev/null +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/BlobV1TransactionPoolTest.java @@ -0,0 +1,141 @@ +/* + * 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.eth.transactions; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.hyperledger.besu.datatypes.BlobsWithCommitments; +import org.hyperledger.besu.datatypes.Wei; +import org.hyperledger.besu.ethereum.core.Block; +import org.hyperledger.besu.ethereum.core.BlockHeader; +import org.hyperledger.besu.ethereum.core.Difficulty; +import org.hyperledger.besu.ethereum.core.ExecutionContextTestFixture; +import org.hyperledger.besu.ethereum.core.Transaction; +import org.hyperledger.besu.ethereum.core.TransactionTestFixture; +import org.hyperledger.besu.ethereum.eth.transactions.sorter.BaseFeePendingTransactionsSorter; +import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; +import org.hyperledger.besu.testutil.TestClock; + +import java.time.ZoneId; +import java.util.List; +import java.util.Optional; +import java.util.function.BiFunction; + +import org.junit.jupiter.api.Test; + +public class BlobV1TransactionPoolTest extends AbstractTransactionPoolTestBase { + + @Override + protected PendingTransactions createPendingTransactions( + final TransactionPoolConfiguration poolConfig, + final BiFunction + transactionReplacementTester) { + + return new BaseFeePendingTransactionsSorter( + poolConfig, + TestClock.system(ZoneId.systemDefault()), + metricsSystem, + protocolContext.getBlockchain()::getChainHeadHeader); + } + + @Override + protected Transaction createTransaction(final int transactionNumber, final Wei maxPrice) { + return createTransactionBaseFeeMarket(transactionNumber, maxPrice); + } + + @Override + protected TransactionTestFixture createBaseTransaction(final int transactionNumber) { + return createBaseTransactionBaseFeeMarket(transactionNumber); + } + + @Override + protected ExecutionContextTestFixture createExecutionContextTestFixture() { + return createExecutionContextTestFixtureBaseFeeMarket(); + } + + @Override + protected FeeMarket getFeeMarket() { + return FeeMarket.london(0L, Optional.of(BASE_FEE_FLOOR)); + } + + @Override + protected Block appendBlock( + final Difficulty difficulty, + final BlockHeader parentBlock, + final Transaction... transactionsToAdd) { + return appendBlockBaseFeeMarket(difficulty, parentBlock, transactionsToAdd); + } + + @Test + public void shouldReturnBlobWhenTransactionAddedToPool() { + givenTransactionIsValid(transactionWithBlobs); + + addAndAssertRemoteTransactionsValid(transactionWithBlobs); + + assertTransactionPending(transactionWithBlobs); + // assert that the blobs are returned from the tx pool + final List expectedBlobQuads = + transactionWithBlobs.getBlobsWithCommitments().get().getBlobQuads(); + + expectedBlobQuads.forEach( + bq -> assertThat(transactionPool.getBlobQuad(bq.versionedHash())).isEqualTo(bq)); + } + + @Test + public void shouldNotReturnBlobsWhenAllTxsContainingBlobsHaveBeenReplaced() { + givenTransactionIsValid(transactionWithBlobs); + givenTransactionIsValid(transactionWithBlobsReplacement); + givenTransactionIsValid(transactionWithSameBlobs); // contains same blobs as transactionBlob + givenTransactionIsValid(transactionWithSameBlobsReplacement); + + addAndAssertRemoteTransactionsValid(transactionWithBlobs); + assertTransactionPending(transactionWithBlobs); + + final List expectedBlobQuads = + transactionWithBlobs.getBlobsWithCommitments().get().getBlobQuads(); + + // assert that the blobs are returned from the tx pool + expectedBlobQuads.forEach( + bq -> assertThat(transactionPool.getBlobQuad(bq.versionedHash())).isEqualTo(bq)); + + // add different transaction that contains the same blobs + addAndAssertRemoteTransactionsValid(transactionWithSameBlobs); + + assertTransactionPending(transactionWithBlobs); + assertTransactionPending(transactionWithSameBlobs); + // assert that the blobs are still returned from the tx pool + expectedBlobQuads.forEach( + bq -> assertThat(transactionPool.getBlobQuad(bq.versionedHash())).isEqualTo(bq)); + + // replace the second blob transaction with tx with different blobs + addAndAssertRemoteTransactionsValid(transactionWithSameBlobsReplacement); + assertTransactionPending(transactionWithSameBlobsReplacement); + assertTransactionNotPending(transactionWithSameBlobs); + + // assert that the blob is still returned from the tx pool + expectedBlobQuads.forEach( + bq -> assertThat(transactionPool.getBlobQuad(bq.versionedHash())).isEqualTo(bq)); + + // replace the first blob transaction with tx with different blobs + addAndAssertRemoteTransactionsValid(transactionWithBlobsReplacement); + assertTransactionPending(transactionWithBlobsReplacement); + assertTransactionNotPending(transactionWithBlobs); + + // All txs containing the expected blobs have been replaced, + // so the blobs should no longer be returned from the tx pool + expectedBlobQuads.forEach( + bq -> assertThat(transactionPool.getBlobQuad(bq.versionedHash())).isNull()); + } +} diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/PeerTransactionTrackerTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/PeerTransactionTrackerTest.java index 520f664148..77576cae74 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/PeerTransactionTrackerTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/PeerTransactionTrackerTest.java @@ -65,6 +65,28 @@ public class PeerTransactionTrackerTest { assertThat(tracker.claimTransactionsToSendToPeer(ethPeer2)).containsOnly(transaction3); } + @Test + public void shouldStopTrackingSeenTransactionsWhenRemovalReasonSaysSo() { + tracker.markTransactionsAsSeen(ethPeer1, ImmutableSet.of(transaction2)); + + assertThat(tracker.hasSeenTransaction(transaction2.getHash())).isTrue(); + + tracker.onTransactionDropped(transaction2, createRemovalReason(true)); + + assertThat(tracker.hasSeenTransaction(transaction2.getHash())).isFalse(); + } + + @Test + public void shouldKeepTrackingSeenTransactionsWhenRemovalReasonSaysSo() { + tracker.markTransactionsAsSeen(ethPeer1, ImmutableSet.of(transaction2)); + + assertThat(tracker.hasSeenTransaction(transaction2.getHash())).isTrue(); + + tracker.onTransactionDropped(transaction2, createRemovalReason(false)); + + assertThat(tracker.hasSeenTransaction(transaction2.getHash())).isTrue(); + } + @Test public void shouldExcludeAlreadySeenTransactionsAsACollectionFromTransactionsToSend() { tracker.markTransactionsAsSeen(ethPeer1, ImmutableSet.of(transaction1, transaction2)); @@ -125,4 +147,19 @@ public class PeerTransactionTrackerTest { assertThat(tracker.hasPeerSeenTransaction(ethPeer1, transaction1)).isFalse(); assertThat(tracker.hasPeerSeenTransaction(ethPeer2, transaction2)).isFalse(); } + + private RemovalReason createRemovalReason(final boolean stopTracking) { + return new RemovalReason() { + + @Override + public String label() { + return ""; + } + + @Override + public boolean stopTracking() { + return stopTracking; + } + }; + } } diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/LayeredPendingTransactionsTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/LayeredPendingTransactionsTest.java index 4fa3fa727a..5f6126326d 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/LayeredPendingTransactionsTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/LayeredPendingTransactionsTest.java @@ -22,8 +22,8 @@ import static org.hyperledger.besu.ethereum.eth.transactions.TransactionAddedRes import static org.hyperledger.besu.ethereum.eth.transactions.TransactionAddedResult.REJECTED_UNDERPRICED_REPLACEMENT; import static org.hyperledger.besu.ethereum.eth.transactions.layered.AddReason.MOVE; import static org.hyperledger.besu.ethereum.eth.transactions.layered.AddReason.NEW; -import static org.hyperledger.besu.ethereum.eth.transactions.layered.RemovalReason.PoolRemovalReason.DROPPED; -import static org.hyperledger.besu.ethereum.eth.transactions.layered.RemovalReason.PoolRemovalReason.REPLACED; +import static org.hyperledger.besu.ethereum.eth.transactions.layered.LayeredRemovalReason.PoolRemovalReason.DROPPED; +import static org.hyperledger.besu.ethereum.eth.transactions.layered.LayeredRemovalReason.PoolRemovalReason.REPLACED; import static org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason.GAS_PRICE_BELOW_CURRENT_BASE_FEE; import static org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason.UPFRONT_COST_EXCEEDS_BALANCE; import static org.hyperledger.besu.plugin.data.TransactionSelectionResult.BLOB_PRICE_BELOW_CURRENT_MIN; @@ -281,7 +281,7 @@ public class LayeredPendingTransactionsTest extends BaseTransactionPoolTest { assertThat(smallLayers.evictedCollector.getEvictedTransactions()) .map(PendingTransaction::getTransaction) .contains(firstTxs.get(0)); - verify(droppedListener).onTransactionDropped(firstTxs.get(0)); + verify(droppedListener).onTransactionDropped(firstTxs.get(0), DROPPED); } @Test diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/LayersTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/LayersTest.java index b5503ba81c..0decabaaaf 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/LayersTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/LayersTest.java @@ -21,13 +21,13 @@ import static org.hyperledger.besu.datatypes.TransactionType.ACCESS_LIST; import static org.hyperledger.besu.datatypes.TransactionType.BLOB; import static org.hyperledger.besu.datatypes.TransactionType.EIP1559; import static org.hyperledger.besu.datatypes.TransactionType.FRONTIER; +import static org.hyperledger.besu.ethereum.eth.transactions.layered.LayeredRemovalReason.PoolRemovalReason.INVALIDATED; import static org.hyperledger.besu.ethereum.eth.transactions.layered.LayersTest.Sender.S1; import static org.hyperledger.besu.ethereum.eth.transactions.layered.LayersTest.Sender.S2; import static org.hyperledger.besu.ethereum.eth.transactions.layered.LayersTest.Sender.S3; import static org.hyperledger.besu.ethereum.eth.transactions.layered.LayersTest.Sender.S4; import static org.hyperledger.besu.ethereum.eth.transactions.layered.LayersTest.Sender.SP1; import static org.hyperledger.besu.ethereum.eth.transactions.layered.LayersTest.Sender.SP2; -import static org.hyperledger.besu.ethereum.eth.transactions.layered.RemovalReason.PoolRemovalReason.INVALIDATED; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -1409,7 +1409,8 @@ public class LayersTest extends BaseTransactionPoolTest { this.pending = new LayeredPendingTransactions(poolConfig, this.prio, ethScheduler); this.pending.subscribePendingTransactions(notificationsChecker::collectAddNotification); - this.pending.subscribeDroppedTransactions(notificationsChecker::collectDropNotification); + this.pending.subscribeDroppedTransactions( + (tx, reason) -> notificationsChecker.collectDropNotification(tx)); } @Override diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/ReplayTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/ReplayTest.java index 18ce6f49ed..847f5f2b91 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/ReplayTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/ReplayTest.java @@ -16,7 +16,7 @@ package org.hyperledger.besu.ethereum.eth.transactions.layered; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.fail; -import static org.hyperledger.besu.ethereum.eth.transactions.layered.RemovalReason.PoolRemovalReason.INVALIDATED; +import static org.hyperledger.besu.ethereum.eth.transactions.layered.LayeredRemovalReason.PoolRemovalReason.INVALIDATED; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/sorter/AbstractPendingTransactionsTestBase.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/sorter/AbstractPendingTransactionsTestBase.java index 89e278318e..2cce07ba1e 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/sorter/AbstractPendingTransactionsTestBase.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/sorter/AbstractPendingTransactionsTestBase.java @@ -18,6 +18,10 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.hyperledger.besu.ethereum.eth.transactions.TransactionAddedResult.ADDED; import static org.hyperledger.besu.ethereum.eth.transactions.TransactionAddedResult.ALREADY_KNOWN; import static org.hyperledger.besu.ethereum.eth.transactions.TransactionAddedResult.REJECTED_UNDERPRICED_REPLACEMENT; +import static org.hyperledger.besu.ethereum.eth.transactions.sorter.SequencedRemovalReason.EVICTED; +import static org.hyperledger.besu.ethereum.eth.transactions.sorter.SequencedRemovalReason.INVALID; +import static org.hyperledger.besu.ethereum.eth.transactions.sorter.SequencedRemovalReason.REPLACED; +import static org.hyperledger.besu.ethereum.eth.transactions.sorter.SequencedRemovalReason.TIMED_EVICTION; import static org.hyperledger.besu.plugin.data.TransactionSelectionResult.SELECTED; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -292,9 +296,9 @@ public abstract class AbstractPendingTransactionsTestBase { transactions.subscribeDroppedTransactions(droppedListener); - transactions.removeTransaction(transaction1); + transactions.removeTransaction(transaction1, TIMED_EVICTION); - verify(droppedListener).onTransactionDropped(transaction1); + verify(droppedListener).onTransactionDropped(transaction1, TIMED_EVICTION); } @Test @@ -304,13 +308,13 @@ public abstract class AbstractPendingTransactionsTestBase { final long id = transactions.subscribeDroppedTransactions(droppedListener); - transactions.removeTransaction(transaction1); + transactions.removeTransaction(transaction1, EVICTED); - verify(droppedListener).onTransactionDropped(transaction1); + verify(droppedListener).onTransactionDropped(transaction1, EVICTED); transactions.unsubscribeDroppedTransactions(id); - transactions.removeTransaction(transaction2); + transactions.removeTransaction(transaction2, EVICTED); verifyNoMoreInteractions(droppedListener); } @@ -321,9 +325,9 @@ public abstract class AbstractPendingTransactionsTestBase { transactions.subscribeDroppedTransactions(droppedListener); - transactions.removeTransaction(transaction1); + transactions.removeTransaction(transaction1, REPLACED); - verify(droppedListener).onTransactionDropped(transaction1); + verify(droppedListener).onTransactionDropped(transaction1, REPLACED); } @Test @@ -473,7 +477,7 @@ public abstract class AbstractPendingTransactionsTestBase { public void shouldReturnEmptyOptionalAsMaximumNonceWhenLastTransactionForSenderRemoved() { final Transaction transaction = transactionWithNonceAndSender(1, KEYS1); transactions.addTransaction(createRemotePendingTransaction(transaction), Optional.empty()); - transactions.removeTransaction(transaction); + transactions.removeTransaction(transaction, INVALID); assertThat(transactions.getNextNonceForSender(SENDER1)).isEmpty(); } @@ -822,6 +826,8 @@ public abstract class AbstractPendingTransactionsTestBase { .build(), Optional.of(clock)); + twoHourEvictionTransactionPool.subscribeDroppedTransactions(droppedListener); + twoHourEvictionTransactionPool.addTransaction( createRemotePendingTransaction(transaction1, clock.millis()), Optional.empty()); assertThat(twoHourEvictionTransactionPool.size()).isEqualTo(1); @@ -832,6 +838,7 @@ public abstract class AbstractPendingTransactionsTestBase { twoHourEvictionTransactionPool.evictOldTransactions(); assertThat(twoHourEvictionTransactionPool.size()).isEqualTo(1); assertThat(metricsSystem.getCounterValue(REMOVED_COUNTER, REMOTE, DROPPED)).isEqualTo(1); + verify(droppedListener).onTransactionDropped(transaction1, TIMED_EVICTION); } @Test @@ -949,7 +956,8 @@ public abstract class AbstractPendingTransactionsTestBase { public void shouldPrioritizeGasPriceThenTimeAddedToPool() { // Make sure the 100 gas price TX isn't dropped transactions.subscribeDroppedTransactions( - transaction -> assertThat(transaction.getGasPrice().get().toLong()).isLessThan(100)); + (transaction, reason) -> + assertThat(transaction.getGasPrice().get().toLong()).isLessThan(100)); // Fill the pool with transactions from random senders final List lowGasPriceTransactions = diff --git a/ethereum/evmtool/build.gradle b/ethereum/evmtool/build.gradle index c4c83883b5..b62287b0ca 100644 --- a/ethereum/evmtool/build.gradle +++ b/ethereum/evmtool/build.gradle @@ -65,8 +65,6 @@ dependencies { testImplementation 'org.mockito:mockito-core' testImplementation 'org.mockito:mockito-junit-jupiter' - testRuntimeOnly 'org.junit.vintage:junit-vintage-engine' - // No logging in graalvm EvmTool nativeImageClasspath 'org.slf4j:slf4j-nop' } diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/BenchmarkSubCommand.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/BenchmarkSubCommand.java index 829bf2d58e..5b20912ca1 100644 --- a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/BenchmarkSubCommand.java +++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/BenchmarkSubCommand.java @@ -19,6 +19,7 @@ import static picocli.CommandLine.ScopeType.INHERIT; import org.hyperledger.besu.BesuInfo; import org.hyperledger.besu.evmtool.benchmarks.AltBN128Benchmark; +import org.hyperledger.besu.evmtool.benchmarks.BLS12Benchmark; import org.hyperledger.besu.evmtool.benchmarks.BenchmarkExecutor; import org.hyperledger.besu.evmtool.benchmarks.ECRecoverBenchmark; import org.hyperledger.besu.evmtool.benchmarks.ModExpBenchmark; @@ -56,7 +57,9 @@ public class BenchmarkSubCommand implements Runnable { // blake2f EcRecover(new ECRecoverBenchmark()), ModExp(new ModExpBenchmark()), - Secp256k1(new Secp256k1Benchmark()); + Secp256k1(new Secp256k1Benchmark()), + // bls12 + Bls12(new BLS12Benchmark()); final BenchmarkExecutor benchmarkExecutor; diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/CodeValidateSubCommand.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/CodeValidateSubCommand.java index d8be71cde1..bc5ef06f03 100644 --- a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/CodeValidateSubCommand.java +++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/CodeValidateSubCommand.java @@ -86,7 +86,7 @@ public class CodeValidateSubCommand implements Runnable { String fork = parentCommand != null && parentCommand.hasFork() ? parentCommand.getFork() - : EvmSpecVersion.PRAGUE.getName(); + : EvmSpecVersion.OSAKA.getName(); evm = Suppliers.memoize( diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EOFTestSubCommand.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EOFTestSubCommand.java index 94f8b2cd49..7906cfd953 100644 --- a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EOFTestSubCommand.java +++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EOFTestSubCommand.java @@ -94,7 +94,7 @@ public class EOFTestSubCommand implements Runnable { } ProtocolSpec protocolSpec = ReferenceTestProtocolSchedules.getInstance() - .geSpecByName(fork == null ? EvmSpecVersion.PRAGUE.getName() : fork); + .geSpecByName(fork == null ? EvmSpecVersion.OSAKA.getName() : fork); evm = protocolSpec.getEvm(); final JavaType javaType = @@ -181,7 +181,7 @@ public class EOFTestSubCommand implements Runnable { continue; } TestResult actualResult; - if (evmVersion.ordinal() < EvmSpecVersion.PRAGUE_EOF.ordinal()) { + if (evmVersion.ordinal() < EvmSpecVersion.OSAKA.ordinal()) { actualResult = failed("EOF_InvalidCode"); } else { actualResult = considerCode(code); @@ -224,7 +224,7 @@ public class EOFTestSubCommand implements Runnable { return failed(re.getMessage()); } if (codeBytes.isEmpty()) { - return passed(); + return failed("invalid_magic code is zero-length"); } var layout = EOFLayout.parseEOF(codeBytes); diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EvmToolCommand.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EvmToolCommand.java index f9d7c0db47..2574d4b8e3 100644 --- a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EvmToolCommand.java +++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EvmToolCommand.java @@ -529,9 +529,7 @@ public class EvmToolCommand implements Runnable { messageFrame .getExceptionalHaltReason() .ifPresent(haltReason -> out.println(haltReason)); - messageFrame - .getRevertReason() - .ifPresent(bytes -> out.println(new String(bytes.toArrayUnsafe(), UTF_8))); + messageFrame.getRevertReason().ifPresent(bytes -> out.println(bytes.toHexString())); } } } diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/MainnetGenesisFileModule.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/MainnetGenesisFileModule.java index 0ce7bf98f5..8dc8a74c1f 100644 --- a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/MainnetGenesisFileModule.java +++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/MainnetGenesisFileModule.java @@ -157,15 +157,16 @@ class MainnetGenesisFileModule extends GenesisFileModule { .chainId(chainId))), Map.entry( "prague", - createSchedule( - new StubGenesisConfigOptions().pragueTime(0).baseFeePerGas(0x0a).chainId(chainId))), - Map.entry( - "pragueeof", createSchedule( new StubGenesisConfigOptions() - .pragueEOFTime(0) + .pragueTime(0) + .osakaTime(0) // TODO remove this once osaka_devnet_0 launches .baseFeePerGas(0x0a) .chainId(chainId))), + Map.entry( + "osaka", + createSchedule( + new StubGenesisConfigOptions().osakaTime(0).baseFeePerGas(0x0a).chainId(chainId))), Map.entry( "futureeips", createSchedule( diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/PrettyPrintSubCommand.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/PrettyPrintSubCommand.java index e24c24a21e..c6fac36563 100644 --- a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/PrettyPrintSubCommand.java +++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/PrettyPrintSubCommand.java @@ -101,7 +101,7 @@ public class PrettyPrintSubCommand implements Runnable { "Pretty printing of legacy EVM is not supported. Patches welcome!"); } else { - String fork = EvmSpecVersion.PRAGUE.getName(); + String fork = EvmSpecVersion.OSAKA.getName(); if (parentCommand.hasFork()) { fork = parentCommand.getFork(); } diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/T8nExecutor.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/T8nExecutor.java index fb0ccf4912..ba55fdf29e 100644 --- a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/T8nExecutor.java +++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/T8nExecutor.java @@ -34,19 +34,15 @@ import org.hyperledger.besu.datatypes.VersionedHash; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.chain.Blockchain; import org.hyperledger.besu.ethereum.core.BlockHeader; -import org.hyperledger.besu.ethereum.core.ConsolidationRequest; -import org.hyperledger.besu.ethereum.core.DepositRequest; import org.hyperledger.besu.ethereum.core.Request; import org.hyperledger.besu.ethereum.core.Transaction; import org.hyperledger.besu.ethereum.core.TransactionReceipt; -import org.hyperledger.besu.ethereum.core.WithdrawalRequest; import org.hyperledger.besu.ethereum.mainnet.BodyValidation; import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; import org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams; import org.hyperledger.besu.ethereum.mainnet.requests.ProcessRequestContext; -import org.hyperledger.besu.ethereum.mainnet.requests.RequestUtil; import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult; import org.hyperledger.besu.ethereum.referencetests.BonsaiReferenceTestWorldState; import org.hyperledger.besu.ethereum.referencetests.ReferenceTestEnv; @@ -530,41 +526,14 @@ public class T8nExecutor { receipts, new CachingBlockHashLookup(blockHeader, blockchain), OperationTracer.NO_TRACING); - Optional> maybeRequests = rpc.process(context); - Hash requestRoot = BodyValidation.requestsRoot(maybeRequests.orElse(List.of())); - - resultObject.put("requestsRoot", requestRoot.toHexString()); - var deposits = resultObject.putArray("depositRequests"); - RequestUtil.filterRequestsOfType(maybeRequests.orElse(List.of()), DepositRequest.class) - .forEach( - deposit -> { - var obj = deposits.addObject(); - obj.put("pubkey", deposit.getPubkey().toHexString()); - obj.put("withdrawalCredentials", deposit.getWithdrawalCredentials().toHexString()); - obj.put("amount", deposit.getAmount().toHexString()); - obj.put("signature", deposit.getSignature().toHexString()); - obj.put("index", deposit.getIndex().toHexString()); - }); - - var withdrawalRequests = resultObject.putArray("withdrawalRequests"); - RequestUtil.filterRequestsOfType(maybeRequests.orElse(List.of()), WithdrawalRequest.class) - .forEach( - wr -> { - var obj = withdrawalRequests.addObject(); - obj.put("sourceAddress", wr.getSourceAddress().toHexString()); - obj.put("validatorPubkey", wr.getValidatorPubkey().toHexString()); - obj.put("amount", wr.getAmount().toHexString()); - }); - - var consolidationRequests = resultObject.putArray("consolidationRequests"); - RequestUtil.filterRequestsOfType(maybeRequests.orElse(List.of()), ConsolidationRequest.class) - .forEach( - cr -> { - var obj = consolidationRequests.addObject(); - obj.put("sourceAddress", cr.getSourceAddress().toHexString()); - obj.put("sourcePubkey", cr.getSourcePubkey().toHexString()); - obj.put("targetPubkey", cr.getTargetPubkey().toHexString()); - }); + Optional> maybeRequests = Optional.of(rpc.process(context)); + Hash requestsHash = BodyValidation.requestsHash(maybeRequests.orElse(List.of())); + + resultObject.put("requestsHash", requestsHash.toHexString()); + ArrayNode requests = resultObject.putArray("requests"); + maybeRequests + .orElseGet(List::of) + .forEach(request -> requests.add(request.getData().toHexString())); } worldState.persist(blockHeader); diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/benchmarks/BLS12Benchmark.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/benchmarks/BLS12Benchmark.java new file mode 100644 index 0000000000..a95f48c0df --- /dev/null +++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/benchmarks/BLS12Benchmark.java @@ -0,0 +1,390 @@ +/* + * 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.evmtool.benchmarks; + +import org.hyperledger.besu.evm.EvmSpecVersion; +import org.hyperledger.besu.evm.precompile.AbstractBLS12PrecompiledContract; +import org.hyperledger.besu.evm.precompile.BLS12G1AddPrecompiledContract; +import org.hyperledger.besu.evm.precompile.BLS12G1MulPrecompiledContract; +import org.hyperledger.besu.evm.precompile.BLS12G1MultiExpPrecompiledContract; +import org.hyperledger.besu.evm.precompile.BLS12G2AddPrecompiledContract; +import org.hyperledger.besu.evm.precompile.BLS12G2MulPrecompiledContract; +import org.hyperledger.besu.evm.precompile.BLS12G2MultiExpPrecompiledContract; +import org.hyperledger.besu.evm.precompile.BLS12MapFp2ToG2PrecompiledContract; +import org.hyperledger.besu.evm.precompile.BLS12MapFpToG1PrecompiledContract; +import org.hyperledger.besu.evm.precompile.BLS12PairingPrecompiledContract; + +import java.io.PrintStream; +import java.util.LinkedHashMap; +import java.util.Map; + +import org.apache.tuweni.bytes.Bytes; + +/** Benchmark BLS12-381 G1 and G2 MSM */ +public class BLS12Benchmark extends BenchmarkExecutor { + + /** Benchmark BLS12-381 G1 and G2 MSM with default warmup and iterations */ + public BLS12Benchmark() { + super(MATH_WARMUP, MATH_ITERATIONS); + } + + static final String[] scalars = { + "4e826175762bd086135d18ae935fb085ab3e12b0f5aa4ea3aac99a1c41afae34", + "7257faefdb84241d947a02c5d19daee65333d6277dfe7212849528eb7812bede", + "d291f31a5a96f170cc6dc8144562f8c7dbe67afe79c2a2ec53222bc129cbeba4", + "b99e32c244f2de2fc6b462a55584229818c5c4cdfd2c74454d7d85e58d8a4809", + "cdb41b97d135aff1d848c3ee8885073a972cbdb92ab5f1dc79e89840ef51f6a3", + "d4c909fae1c3b026ebcdb4a1885c1f5d8b6cb4aaa9cf8712e8a3add53da55bf0", + "4dd3dd8562816ac0bd72081d2dea42d27078a5618ff525bef4fd2628a6fb4326", + "0c68f33b013b0bc960b4e905e75e225bf27e468692d0f271e7e30af23b905393", + "2c2dd13c6858693241613d34d45cfcf05c5f71fcb5b34483d8ef3133e5af6304", + "0b4fca47643819aeea5fa85035ffa735c0945fbe6e1170f9639ca478b45a41fd", + "1e76ab4951f522acc99225ef30b9b4936d27134e76d86222e8b916c9cde4bc78", + "36b4741673e3f433bf460632c2a89b279e8032d7b236c402f4720b361c865a04", + "e40cded572e8ad87da276d41d08edafe10576b526776b8e71c6d80bdf6239932", + "25ea3392dff756934628f586ada2225f5af0e03078d704cde4da460875698e6b", + "450648e218031d8307ae71a369d95a86ebe14db8f5d394697633a379be496976", + "f03b5f08231c44cedcea848dc18a42bef0895ba4696e8ec7ecaa0615a5158883", + "9fa8482dda8cc2f20cd9b4dc63f72be23a7652e7e5fe1436b90b477adb735ed1", + "0978dda7cb30dd643e472b0a3f8196fc51fad22d30f0f01d7cb570d85d7b353b", + "387b7f3f892cc754b5dc6c724d89b791934f6914778b5c84a6892abe6b999ab1", + "1d2b5094b14b26c9ed3100222f19bbbb289f2638c29f5fbbafd68574873d4287", + "cd7aabd84ffd41b589dec5d4af4b17681218e1fa16a3e9855385d35b18dfd2b2", + "d3c6c9bb36e9d5647eadd40ac68b57e0fa17352f558f270b8f7724f6dd3f19d4", + "7d7f485c07f94d37c80e6710515863b780883e2beee772bc7d7c1cc0f10ed245", + "8d7bd0d7a9ff1fc481fc6b9a6d1c58d6bf01d7017f7a3bd1b826d38076d1c6fd", + "f939c5d735bef50e7d22408012d3bb664179d098a42fa2f2dfe2bdb8f9b6c074", + "b02686dd55be9fc6a791cac72a2c32b5e6f86c0f5b92b52f2efc72ac2043837d", + "11073c2c13655c6802ae8918403d17106d630b7519bc61dc6e592bca5f7392c8", + "fb8130bbf0067026d67d44e464b568db99e0dc02dc48fe8a4753d806cd647d3f", + "a558312bdbefc905932e51cb05eab0cd546a8f9a41a135746eac247840ca434e", + "9b5026e422f16837ca568490bd4ebba629391319b9b076d7c644989991a00c94", + "c480e504a8ca9556770dd3b9cd8d515f505098c0450679c158ed54f75d9224c0", + "8b450d2be25e0f596ef0c1a4fa06fbc044f087704469f499aa8967ce8844f080", + }; + + static final String[] g1PointPairs = { + "0000000000000000000000000000000009f5bf486941d9a9f8c742fa43ee279d75419d4c11d1fbaed1dc19c624e168dcfe50ce4673d7ca6d42051dc7b799d7b3000000000000000000000000000000000aa47f7618e3dbe09730b9d378ac113dd841f7e42dfb390ff486e2820345208e2d7433244eedb233bcb807c08c55919e", + "000000000000000000000000000000000786d2c808ffaa25cc78e484da52b01698ad8eb55846961d2b62fd578432f3466da7e22cc34298fec4e34e33b88243b300000000000000000000000000000000015e8b79f94e318336bc50f0cdc4c9bde81052ffd0fd48c5b915be878a1a1b2f3a71d7587fd9892a44c9ec71fac5bb80", + "0000000000000000000000000000000016206b9006c026c95c2879f2b950a074b2660333962e21d06d3cf1a9d6ff33921349f286a9002b515b384104a32076de0000000000000000000000000000000009b72f249f9037ca7cec181df2f5798d0a8253d86dd61ca6e416cd1652bd4c400a5689e6d29783fa1a8578700470146d", + "00000000000000000000000000000000093f21aaaaf2044cdf9a80ca3afa75db4e32aa2870fb6b9dbb22493956d6e01a7f566d567b67307b1ca91355669b28d100000000000000000000000000000000083b0a9758f5b562b930f24456e56845a87352a9b28367df59f46b570af1b8b3f2a4d4a7e9d272faf2fdb53d5077cf51", + "0000000000000000000000000000000003cc0abeff05a8d78ee0e94d8cf71d6d0a5889968b99e5b9c6a3d283d7fcf44caf8c11619c75020bf9dc8e8fb451407d0000000000000000000000000000000005171356814d04c944564fbe478f1c953c96d5b8b269813d0a31272346c078956103eb2808ae2c83528066a9e54736fd", + "000000000000000000000000000000000437b80cfb19bc01e0050bb3def6da7dcfc7b26c4eb35b2f922685062bfac10d78b02d86ab45025286bb9f3293c2560f000000000000000000000000000000001934da79acc0e74284af492d5fb1f942ac5ff8660f18769f4f241ec724df952c9286eee55683b4c495f1cb4c3e1fbbf4", + "0000000000000000000000000000000006310c85629fe02d094c224f83dbfebd9cb950ccb28832000771663bb93cf4cb8ad8016f0fc4ee42f8584ad8ce00498a0000000000000000000000000000000014264f7c2fe86174729843b3db54cdb76b5a892fc73a5e67083b937448634e516a93e170934c1b8a30c71a8405735bb3", + "000000000000000000000000000000000b6539f785b36fd3dc041676bd37c77033c26e3881b4b47fbd093eb28c7ce9ecef7c9b588850e08ec06793d0e0034d95000000000000000000000000000000000401571cd8ef0289d239bf7b0115708e2ba04a577548c38a5b283cd3bf945185e2f7ba744ba345e60a61b9405865a67a", + "000000000000000000000000000000001861eb880875a3f7bb7a45eb2dd32adffb68abf1682a5268a68fd9691db119c72f7f21cb98884619ec09f4f9a9189816000000000000000000000000000000000233a0e8c1f4c7dc3e4672f7a6a1e226bb07f445790f5d0c5b1437a3030e4b4e95645c9d0aae16e570d79af0830b8ada", + "000000000000000000000000000000000f99c56935dea38c1691645d3ab576a762b5559c31c46edbc8c70b74c3b40f79c84c4623cc72206732a620beec0ed10d000000000000000000000000000000000786714ffa00436d9e53f898e98a5fd3bc799dfe0eac8f7ab4204b2c9b464329aa14bc58aa23ab1606113b8a90a98b81", + "00000000000000000000000000000000005e8658e3105fe051190127fba5db7d2ec47655bed72acc1c4a9b985b1330932b6e339d76d9f56b2b8d6e8b8cba1f420000000000000000000000000000000019e18081a769839b3849222e2f9bef86f50f398409d776e7e5f462bef75e8769a7257139826ae4dab7be8a344e43eb35", + "0000000000000000000000000000000005cdf9c9f5091d495d7c8707505c9051fd6bc2e01899bdb24d8f55e97e0c034b2ea2173c73250acf3814a3751659b653000000000000000000000000000000000adbeed0c8abdd5650502e96a14ec1b0af697d27f1de92e82a4d70dd763a7c83df1e1483a73155a7362ab6e830cb5b60", + "0000000000000000000000000000000006aa3ff84449d8326edc0971e18dd77d06ef2f7214c8849dc9db9e9541f2788e84f1713daa2fd014308321930f474493000000000000000000000000000000000f39da6466995da0227cef277bb50692373896bca7b0c6dad3fa6241e367186fce75cfe67337e59660adea207cf21578", + "0000000000000000000000000000000011079caf8ecad1b7fc8a5e52fa02e2cc54fdeff788ce74d94de474e964736da7bbd48fe103908fdfaf21e618cd8bd570000000000000000000000000000000001391f3f5ac9d63bc769e3462323a25349fb879849966a14c28d7ea4c43656dec785e9c10e600fb2c77960185a25a5a30", + "00000000000000000000000000000000030ada1568c82dbe97fc8b7f3f0119014513ea86a109f76d4e0fab865515c1a2a2f062da5d2fec52585fcbc61b62822700000000000000000000000000000000141e65d12ff426e2a6b665f7860e8dae8d1de1e4e3a3a062032a555d79e820bbfd727cf769980bde73dd181db7b4ef4b", + "000000000000000000000000000000000e17d2ed1881b7513d2323e606c6551036c86f1c455657e8c7d56bd95ab906d9b2cb56a244ddbe59e7552d1eebb1e19400000000000000000000000000000000176bfc0dd0953a54f5c3c162a7b5d30375cfda78da80975757cf9496b9aa015263efb035a0361c794c89478896cd1e82", + "000000000000000000000000000000001560b598256b713e21cb49b0e16849456d555788a93d1bb778ad7f8f4b090cf0aa115a5f0535eac2276fd1d81d10db44000000000000000000000000000000000d6d0b42990da37fd54801164a148adebcf4ed22874ab64f78f6d323a3bf07ce8470214c4bfb4a0a2e5d979d34f8091f", + "000000000000000000000000000000000a17df46b5bb50ed8c065aab3b551a1a174d85758169a57f952c08a6878466efc0faad3439b341f9e863e360fd2450f7000000000000000000000000000000000e20917637b3f270025909ecdc1946aed29389d60af02933b3da348ab6ac5380198c8fc6985547c7438452c7d977ac41", + "00000000000000000000000000000000139e3c560a50d7fb86e3b59fbac5445f9c0ab0978b3cf1d6d51d5dbfd86b8233c1a0d13a3bc3c2f266d1d938519c801a0000000000000000000000000000000014fd5a3ca318171ef34723ee5cf58b4736105cc69e5c3a10da3fb895e45f1569fc5ede086a5737281280f11ad7d77b1d", + "0000000000000000000000000000000006419acd10144ced4f53b8a875f6ff40b777af68ecf3e7245243b9c74037fc128ed2c9e6304e629deac852007695b615000000000000000000000000000000001234916bc5701e0b43af04174cf25b780da79f643f5dcb98748b3ee9c5cd9d39e8c026948745970cc1d7e839616ef649", + "00000000000000000000000000000000105f212197eb701ed73f5c3ef3a6504d10e20ce70de26a76f3f1e5ce444d1a24e2384d63d4dfd3998d6cd938505adaeb0000000000000000000000000000000016e5f4d98bac752563aefee58920392f3db9c24873c42cd7d0ac7f26a412502dafea025fc63a7b45f8ff5f390a76c7e7", + "0000000000000000000000000000000010e3a266c9fe2ef7bd6da2a11ad73466d398177738a69629a55fdd33ec088600d750f4b270213f091b25f67d7d4687d50000000000000000000000000000000016eabfcc65d89e64317145fd2dfd397841a20c54518ce9133cc38768fe8a12aa937b25fb088a0f92cd9de81b45b1ee24", + "00000000000000000000000000000000196205afe922e753f3b9907caedf380fc506bae61e12bf48483560c32f7f62d28c94b3a3661cd8e09f6445893f471e60000000000000000000000000000000000385e8e99fec6bec5a6ca1c1b947317a7f98b9d6860228a752cbf909153a5ab045a9fafc3d0d10f4d38e3e29311fb9e3", + "0000000000000000000000000000000014ca7e56d5209106aed424aa92d8b9a746da0eca913aaf5dbee3cb010fcd7db0a969eb5b8ba56a222d29424db5d2ee43000000000000000000000000000000000df722a8de5dc9333df241f1b8eec12c3c3c34194f065dabe9177c00928279db561ddc648d074975921fd6ca9fe795b2", + "0000000000000000000000000000000017f9ffb90222613c6e03da79ce610a53c10b218ab1a57e3b8c136ea22360f52965f9b1d349f25ea2e7d71a669c8b12d200000000000000000000000000000000150f4c0c65de339cdf44826213be1c5307fe820c80f44729276af0d5e3f1e8c1b7eedba77ab58f742f9f045493a4f583", + "000000000000000000000000000000001643c91e1ea8ead940645595352fb680642deba457b2222b415144fe64d0031b8efc4de5d7c42f63c6e64a7be988514200000000000000000000000000000000143b72204f89fa6fcd6f603e370904e532acbe51930495bce552e3eb2081453806a432a18e52874e495b989111b22435", + "00000000000000000000000000000000165b7fe90a6e39a14a11eb729aae227f35cf9ae240bed66c296e616c7a4912183e985532d5a5e1200cb42a5392b33baa00000000000000000000000000000000056a849e23ffcb32e04a1aa50b3402efe8854173180c8ebca1c55e52a59629e8557c6c8f3914cb03e9088e371ef2f835", + "00000000000000000000000000000000066f0bc365eb53a05bc9561d32af5d32acc0796f5a76eaa1c8f15f1b0a3ac6f3bc911bca630749dcc64ed2f9c4e25d56000000000000000000000000000000000f9ba6af35d2f116f4341b03caf175bc27f007d5645866dc3b3bee8665d45f204f73e0e25cdcfa339b2946773919e804", + "00000000000000000000000000000000104673bac88cbacfd38a26aca0a5435407e2086f2c666c89b5769393bfc247a10937ec3441c6c274760b590d2622a9df0000000000000000000000000000000019cb77c56ad20e574cdd0681bfc1131f069f58ad8e3a5e8898cc100a4c59e503a400e095d44bc5cdffb2ec8c07825ece", + "00000000000000000000000000000000039faa653341ea8e2ddfdf2bdc5de84d8a1a9027abedab3cadf5c1fb69262f0db7ea94ac8bb2abfb132a000d390b58f80000000000000000000000000000000012aadfad64ca2203860ef91a1cb88cbf817be2676ad25c7cd55bc84a6012621a41909fe28325276aa3cad5baf1be6cb0", + "00000000000000000000000000000000004dba2a3ff8eb3ef159ff2e66c65f51016efb2f755ef41089f84960dca19a62d6677ecc59ad1a7ca3abf4d11944d53d00000000000000000000000000000000002a928c7e135f095226050069ea0b219d42b8865cbae0d3ba9f10aa283dfa7c28f1778adc0225356eb2579379b57263", + "0000000000000000000000000000000017979ff6656fc8d015b8b5d486ae947000d277ce55a69b19d63f63ab654aaf0892dda72dfbc082bc3bef59f96af872a20000000000000000000000000000000019ac1fe79cb8a3373f7224d4115beaf742cb3bdafd954aad002c2ba24874392f6a0ba5f5b225d3c3c3cf82979254cbe0" + }; + + String[] g2PointPairs = { + "000000000000000000000000000000000bb1edbc28a9930c190f6f1d49f8964c13c13940242e9d8688717ed57149389453e048e3e43a38ca28fd8a07ac60e5960000000000000000000000000000000016ba918cddac3b49dcf808317f7490e5dd49e6594ee9ee9b584261a1ce43a3882b3e1362863537fe6ca429dc17f28e3c0000000000000000000000000000000017ad94874960ed6d0443ca1b8906f84adec505795684c54e155ee8de878b219bf65ed125f3dbf42e3905fbf985e59764000000000000000000000000000000001782e9b75fea3c4d072bb86858c76cc368a67a1f2597a4724e2c79f7c787b4737c2f642dc32ab10ed66f40ae675b1a6e", + "00000000000000000000000000000000031c2efcc72f74504a2057906f93bef5d47b2482b1eb6d4442563988798b1385010a64f8e1b38a93e6e06283f4bf43d1000000000000000000000000000000000733cfcab23720f699b4c02de7a211482c84e6eeb62a3d901b557fdfdf484ce27c33f56fdcbd542430d72fd78d2ceab400000000000000000000000000000000152daff8a24165368b963d4f4560856a74be3f0dd3879bf4d75e34eb70c201661921460085ca06188371fc9fbfdd8eaf0000000000000000000000000000000008a6c6a920452e4ff0c8de495b93c9e971af127a5c0d0143fb61d0c981883709c64d837f41842729f8ce926f8634a11a", + "00000000000000000000000000000000149c85c410022026a7a89b7f52b9b3e3d3f3629ca7aafb0e21cdb9539856990fa7f8bdbeb19915a072c37f1af35d72e00000000000000000000000000000000002776e9edde84ae38e88cc3bac626066ca752d3f1d381b3919e5f3ee1c15b5b513dae00444cce37c732e1a0b6868207c0000000000000000000000000000000004e5b747b2cdd32bdb52e1fba8138f5e44ac98f365aaff35c99399eb115af904c569995d8ed4d87ceda4407e0c5569d90000000000000000000000000000000015f6a5da3f739d2b9365c6031298cd875a6746b3e866e4605f8b82e20e282f3424cd8bd86ff35652ac3d25a3696bb294", + "00000000000000000000000000000000100f6cc96dcfc630d73141bb8be25ba2256ea81f2d7f55ed0cbe50333715673cc36a8f37a10f3222111afce400bc9ba70000000000000000000000000000000015ad4090a4a27d9939a1f5768dadb247e17cae0f101c5e3b588cfd303e4424a0a937cd02127708af7b1c20eb9405329200000000000000000000000000000000084cc62a4313b2a8d0396d8cbfe0ffa08171062042dfcfd773dd88d83a164c1cc435de4d7e04b36d9146f914e6880efe00000000000000000000000000000000099c27c3a74eb6eab8556fd8861c9a96a7b7032745161fcad09cca9cba13f992d54c3b13e4bce08cba158996ce4dc7e3", + "0000000000000000000000000000000016437f645c71e932c9c62f6076e25adb6e8e2ba2a124d01762a8fef382730352d7b8d0cebefb51d7912c78532ef4cc000000000000000000000000000000000018568a31a5005deeaa6a0750965f856bae2a5fc3f76b5743ee45852a177ab7fc0eabd9c402e53e2ffd3bec7f600e65a40000000000000000000000000000000000312e67aac16d8433565047121cfed6cf8c968e1d090996342d6c417e778407f62be6b73034f855422904b4f0dce31c00000000000000000000000000000000023bd285eaf6a36e8362b0b647d121ed980aeaf4523f65ab587312ec4eac28612637a39a0f05898bdf711b68bd32be79", + "00000000000000000000000000000000195e4ef43e2515cc7d19bfd3aa814b9f9e2ed4913f65fa8edf38e66aa64ab98eed6c0b54d6146d9455059a900b325ae9000000000000000000000000000000001158355772c7af7533a7fd22fefcec6855ebe7ba2a0d74e8f549f64dc363ef00495bd1f363686a8518a118e4a103674f000000000000000000000000000000001670781d5d8c7a080e2dc286347a7036ef8cea3d4a865996e5232c2a6e92b23eb74020c1fb6171bd0045d04e4fa07bce000000000000000000000000000000000eb69584271e1671710581dbb381aa40fad35b28e63578c5fdb1b408d13d5f77654d1aa99c9856ac150ff4824ee7aba7", + "000000000000000000000000000000000e86e03117fb5327c9deac44c0053dcb9956b1d0c6e948a43aef6c07f5ff8c2e3bc3cf8e6e06fa54923ecb8ede6d9ac80000000000000000000000000000000016095c62b00a2297aff748c7c7ae2e48c1e92c8509d05e5cd91af473442f3db56289d5f0078a8af722bede285b244c9a000000000000000000000000000000000399422a0d7d1618f5ad1cdee685d5c91cdb257b4743e7c8504328df81e6a345f073d46477ef2ed27b85f4a87033b5e80000000000000000000000000000000002c8853c746b06ac0bb83ea3444ccd2beb1595e42047a09e9321375ca51cdfd0eabe5c7d4c7e603df44c404af5b84755", + "000000000000000000000000000000000e6d721b7ceb4c026c387fba083484264cdb87c979ab45aceb0c800ef0af7b67ca495b4e8e929077f6b2d70552843551000000000000000000000000000000000076523e8c6900242bfda291399fd6a0900cb0b7745d7c150a27b692ddf047a6bc2b5bd20aefcb38a9550d45beef2ebb0000000000000000000000000000000004eb54c19ed6a4ba9be94d17fa361dd677c5e9c0ac27f15f3da745cc9245ca5114570a8a44570d643ca6fec24c5a8e9a0000000000000000000000000000000001fbd43e2c73b106c9e59ba823a264d5926addf6988e2cc97847bad292359cf77702597c9df33b0251f328da8f209cc0", + "000000000000000000000000000000001557006e7c861c31d73400a9eda26c9bdf064756f557688d65fc6d5655053457db932c4d3db10407a4ae592047ff842d0000000000000000000000000000000019cca0f57689d18ce2161e0930274f6cdf3f6a71f10070e7257a0698e5a9b5d384f52623bbbbdb540d3e9a64c10e921b000000000000000000000000000000000a61fb9a3484336cf570943a7bf1edddd02b73d736cd11fd6032c2fab8194781126d62f4bf23f5dd2c1bbb71659f2b500000000000000000000000000000000017b2533e34dcc2d571b34068b6d3195d15436efa3848d66b108060b5d15e5f285fc22a4aa323a2e3813c82f78dd4cacb", + "0000000000000000000000000000000014a079a52523718313ba0ea828e16f1f7fc053ffd40359e583672b81253ba4e0ce2ee25ff8682bff102780a81f1f5eea00000000000000000000000000000000127944d2093486199de71b90ef794c172eeb1096d0f1690d7338424d96acdfbaac3733c937359e48204860d744778de6000000000000000000000000000000000735d8a013b801883de71f0b942cb138c0ad8a7372412c5c364a1f952664ad3589621021a23a0fe1c961f428d527b53f0000000000000000000000000000000015536982fda409e63704a7b3cf623bfca1bdaf462e906085acded40f299d37ac4614622781310aa1afd82066fdb7beb0", + "000000000000000000000000000000000d0f91fedd8bf219e9abec47875720b58cf95b022bf4eee856df2a0e6fb07504d7ebc9685fe5a95318004833b7f616800000000000000000000000000000000014c82ce968273fc7873cfa4e41ef9933ae3608d2aeb4a278243338022d870b63c65d0f3ee5b434a96a366099f78aa2fb00000000000000000000000000000000198ae019725ab641f7b8b3e24f69d72132a3c90f45708b27b7346ac8949f7d7bb3ae986e7e2c718b58bd79e99143a8ef00000000000000000000000000000000056374901ba836eff22b7c24587e62831e3a088b46f921107598a3f94509b13f6776250f6d011e14d1566cb3e641f22b", + "000000000000000000000000000000000b469b60961ff21ba768adb10a2a64e4782a3ac7e703a7637259a51781308ff6d2837c9fd28be2975ba4211a60a0d88e000000000000000000000000000000000dbe8ca42b9596dd0657d415eb6321c7d32c0e475d97cf25672bb97f3ec375d90d57ae078d3777f279eee381bd66e6b50000000000000000000000000000000007b31b123718b7f235fcee6a78f7a130d4f5d03c22f4869438ff0fb3806c7aecbdce535db9c8b61bf48b3c550fc9404c0000000000000000000000000000000002d982b4bf793d6da748b9a6adee65a7fa093e4175a53c763f2e23dd1fff051e0488fe987887dbd45b194353513898a1", + "0000000000000000000000000000000010b07b05683f03aa5c03681cb0726f72d43e2653d0e1c9538811f6b858755ff9b680f146c573c21a953c753c1519e10f0000000000000000000000000000000018df2ce2418f296e147059ac69b26834a07595ef62d94506b0b7b7b58457e740089cdb6fa7a52e945b6ce28133392779000000000000000000000000000000000aba7561bd4db53d4f5f1f0dcb943ac841604f786712b257dda889962f2e85c55a97410d13bb115409b014927f1e19d70000000000000000000000000000000014f72efe6f6c259c8adecee7027b1707cd141d1507dd266b7e2e7bb287a5f0b71f8decaa1697adee1bf51cf1c4558181", + "000000000000000000000000000000000e0faba97d411f80e2e3b9a6d39d7f8501f2043b3eb8649128f21c530d976ff865b5ff3f5f691a0437b611427de5ec4e000000000000000000000000000000000d65fc0c62ed95528f08997c3b9ec5bbd81cd8bc66d2a9d3090719f851a144165b54ab6e7b8a619a1286fefc856fdd4c0000000000000000000000000000000007422cfcdcb04bf8863d005dd88856ff639e2b94985c0804fc20a939ad70c263d91a45706df9d9c6d7a5b18f801fcafb0000000000000000000000000000000017ca5d23734591abc516172fff615b87e219b478b8d8e64e316ca71a2c64c66f9a526cf7e4a4a63873ca94e63d82cd29", + "000000000000000000000000000000000bd718cd80fe3a576c196b42c5ed99311d32cfed42d66d3a084c719215359d0654dc18bd56a23db6a7fadf9fb08187b10000000000000000000000000000000003b20b43a55669e51f34aac5f1c9c93a8b9f93c3b16ccdb11026fa2fb637ade15bd96b256703454a1c50a8856764f7d30000000000000000000000000000000000545144715836136b237cd5b1355946208c60d2ab03e0db14ed6d0098d14c985d198a65556d71d87a9d5593093259a90000000000000000000000000000000012d88272dc634dd86c47edf10c84c5482063bc9bc194f9cfce16bb75b54338cb3e68bd63ade2e65013513fc827700b6e", + "0000000000000000000000000000000014862df8fb650ae94f6f642b9b494f89dd7adf12e41ae73775ec65e53239eae2f9025340bee6e673071275f215779e160000000000000000000000000000000003170cd693576ec1af09e1b5ef5197a23c83de1d123bf8dd61811a5cb86e251c907154c1e97783ef52812caefb3bb58b000000000000000000000000000000001002d75b4532d5cb5b8d86de02516f80b901290e1143ea098ffd8a1e1a8332f7dc716db3ef22e639e3d01592599abd82000000000000000000000000000000001666c5981bf1de72590e79e0563421e851d404825aeb4b02c12dff618945250affeb42138a6e383b2804abcd586cdd3f", + "0000000000000000000000000000000013be6288dc1ec813dcb80a244c2701cbe65af0185fc5a9fe479979f97ed25805fa6a5e0f9cd1644df8d03288daa24475000000000000000000000000000000001822963965705a42d91ff958bb6a23162b560d3dfbf43b165bfc679dfd765093497e7695e3201e89867b414782e47cd60000000000000000000000000000000019b7376b974d00abcf4a325eb93721e89005ae5b701fa14c4ee063929c6f4e37ffdc3612ec0d5287c4b19c3cb800c1f80000000000000000000000000000000018c899e91c3bd7d52ece713413e2e733be459c53d6e08b62c34140115d9ebf112ce7b1e4969f75408ac50a8f1b057064", + "000000000000000000000000000000000cac21c55ff3d3f836c684c9bd87050101ecbfbf947c1e9aabdd5b8c65643b38034372c5c29a9e31e6bddbb92759dabb00000000000000000000000000000000003da40ca1b9ff45aef983a8fac73051c5ffa5061277354391c08d9a8230eea8190286111a5798825af3d12b1d672b9d000000000000000000000000000000000cdeebb1738c02ff85d19664d1b020f4f1665f507e918584fd9a1d0547401400386426cf40079df25ef30e254d216350000000000000000000000000000000001339d03d31f99756141568b165ec6c6b19247e87c75e58a2cea15fc88f7d2be371e410e0b0eb0b1a12deab13133d13ad", + "0000000000000000000000000000000003b746c6ff13a38d21a02fa1411fd4afebe3b7feaa19d73514ae9db9d1d71209ebd3a882f9bb3d2e281398bb83a66bc5000000000000000000000000000000000d9b460577687f06263d7cb76c222b15b8935790e48b07dd567571e409495da5db324fb107b9a136f17f58660ffaf9530000000000000000000000000000000018c0a41dcb3b48eef7596342d56ca471dd2f34a1fcf44f997b2c6614b45cffc7355d71270b517d873a38a520d32c0b7100000000000000000000000000000000118d21253a52bf38a59303f3eb2c747ff951e6853fced9ecb5e4ebd969d741612d43e552067c001bd3d8630f077907b5", + "00000000000000000000000000000000009c9b846d3b8262703bcd56a584a423f2d6ea0009a242f45d60ac04146206a1fd0bf2d709cebb5276b32a34d08937af0000000000000000000000000000000014485fa2c535058ded72048ae7e3194434f6beabf94bc7048d23949a69f541c3fbfdb4270bf05e128a1d6648c9a59534000000000000000000000000000000000714427d464c715ca5720174ad15540598272fc4b9a5a0657106a4e9abe130935ebf6bce5749df1880000f06bd1922b8000000000000000000000000000000000e8916b52c09791dffb80f221d8868c2af09ace7304cd04de1c7c1a3d593d2be349c106b908e37fba49de0e72688a16d", + "00000000000000000000000000000000008ec6c01d64c02bd587df809ef7d363b415f736080bc76c6440c4fc2a32830e802907ba906c49661964927641866f22000000000000000000000000000000000e8a4da56e0d8f93b3dc6a4f0c8279208758423bfd592d8f4e911f75cf3452ef38ca771b496e26be08314e686a7524e200000000000000000000000000000000031aa3a4b68776131eb25ce44ee3e5d6703207731a5c1e4744a8af4f1e22d272dfb32ab1fa37a93f3fcb3c8cfa63626c0000000000000000000000000000000008270d9d15296d653b3e10ab4147f0a467d0f862629f9d248aefd1ad7ac318cfdcc05319da14cbe9fa475887dbef437b", + "000000000000000000000000000000000d4cf12bc66952beebf74f7720bcac085313954003e9d0b5be9bef06765e499c0f085966a42514dd42249735e1232ca8000000000000000000000000000000000b94b3dcd69b0024624d46bd3caf65a72f497a5317cfa1511c5b11b4b71d2927cd7ad08b8c9e60b81291cdf12b2e2b610000000000000000000000000000000012ae5a383c683e41ece77ecb31a33896efd6d0243b1b5d883e6d7a54f1d5a3dfcbd2257a2c5136e3e50d229854043b4600000000000000000000000000000000069dd28d9abbfe62498f362e1eadbbf92fa7cc8cc82e6c4cfaef68941e3aae3dbe62fc2105bcedb378165d50a64cbd89", + "0000000000000000000000000000000009c798c8f428a12bd81c0b98efe660c4249b2cd2fbbdefaadca483e23c7e7b0dd8a9b2c955dfb8990ba066a3252b5c1200000000000000000000000000000000039247ffd499e097ce042b0e249c6650c366c9a790f8d246271954992aa3d209b7c23962132f1f37b8ba05142312d4c70000000000000000000000000000000010d3e9a11526543ac2bea261a897a248548c4ccca19d63ef4b76d3ee323c9c68f251f01b1ed61af4cdbb1835e7afafc40000000000000000000000000000000002b778080e00200bf874dc37d40f6fa9bc111f066373a3dfde706dbb15c897b1fcac3b4bd5eff354330869f30be74296", + "0000000000000000000000000000000002353771bf8f24b6340365cd7c5fa34e1af4a6d485c6f0d2db82d5f193e649e92d952556b6ea4daf095ac0a9e4e759570000000000000000000000000000000013d62324d07334f3a5b1bf9eb09a0eed954839e43a93599852abea9b39be0d08a82364688067e1689d4457a15fc33d6c0000000000000000000000000000000015f2b988a767cd395d5d3523b93783a1fe615d89eb5b2184a25af1cb4d2b23a40756552c4f5e6a9e4cd09d6bb881791d000000000000000000000000000000000c23f17079a62bf4b73af2b7b4d39c539ab1034b113b89e56e5adf2d3c7d78e5ef1da1fd59878535b9ae56b6928cc22f", + "0000000000000000000000000000000011667822e52fb4ab060f818f9c186cf5014e7abf62ad1376bbd560630fb8ab74c6cf32dc34c258d2472f5469c1d08a760000000000000000000000000000000006520d658fed38850a9d53e40054b717c837d43ce0c7ec26d869f726e39d0f0478f1483ed50555b3277f4db14b9d707300000000000000000000000000000000147429837f309e14de5345c5cdf0b738b85159bab006cfb11d55becc4f99c45f49cf4a4dbd322ac78ef6b0903e186f080000000000000000000000000000000009d29a5195dc5825328bd84e2e01865fcb71b2da240d715032c362d68a3e22009bcf084ec6865134a0435820ac68a69b", + "000000000000000000000000000000001725a9af0c2665b1dbf421f8c219b713e7cf3605b6c263cfa514345c0b3c089efabf04c99bce50d66e76661b1fe197a1000000000000000000000000000000001789a23499b823b093a65bdf31a11c242c95c3dc20580e60724403dd4e26581a73dd14d39b0822241530b98c3bd780a8000000000000000000000000000000000def0588cadc12088d34101bbe503f4dcfe7e1ffbd1b73e8c4366634414f0e92d7c06bc1b63944bc389d9fa8091722d100000000000000000000000000000000121db986bbd7bed4ca3ce10a57b3870e06d3dd5aaef06275e8c9f646779b492a8b2710a4a80201c193f3a7bddb30fd3d", + "0000000000000000000000000000000011e5eef691643dedb64737ec9b7789b4dd882bbd0f8417a6d2d2a3ba3b4f77706883edaed7cceab0b763a0f5a1aab58700000000000000000000000000000000153052c193256204bdc57137b8e57434a051f298fa8865d4cefe79b99c19d536fa1a98a15575920df4e5def869a808f0000000000000000000000000000000000ca8c19e3b556bb24d21d9a3c86b4a22e9d75da7979e53cf60ccab3b10ee428697c468578fa5a091f996fea8b770b8730000000000000000000000000000000005c8a385229f99de9bfdfc72333acfdb1184ebf8c423ef7ff56f765c59dadac6ce879d1a3ebaf01801d525bdf001df53", + "000000000000000000000000000000001244954d9e9a61f1152d6d01f2fbe739bb15a087162560e7aeb075dc2c807883b967aa00ad9e859e9a729872ba5f4ea100000000000000000000000000000000155e743d267f2b81b0b8f632a077dbf046dd9329f7a47963828e3e4ff9a5d2ec7e6f556374ee633a0db8839b74b9f28a0000000000000000000000000000000001b0fb50e9dfb7045df383629b697f0d21cbe2ac5f20a45d8f3a427a40eb2909910cd70fa95f9f35ac2704b3a2d73f870000000000000000000000000000000015340b22b90ba30ee0266e1ce7a68be54b35244b9bf7ce83be16d5f7ecad9ec14357a2d63df7c0555c1e0eaa977fa0a0", + "00000000000000000000000000000000051b3961911aecbd714268edbc881c7461025d999c4e23c12994d676b853f2d02932f26733a4bdf306caa155a915a01a0000000000000000000000000000000015749ff11a27b093f24988c9578460acaffc376b2b7027091174e073ada104ddd56152cefbed70485b59fce651cb0b5200000000000000000000000000000000184cf9f1c1ffe553283c6b30e16c4f6ca2db7a23ae675ffef7d2b0f38c1f491dd0b5f2cbcd2c09f95ae3d9f5977aa7c5000000000000000000000000000000001002d00af1ad50c4cccadc59316dd9c246cb1ad31253d430a5dc4ab9b9a90dc9a5377345badcd367b31b9727a3fb368a", + "00000000000000000000000000000000132b08fe8d911ede6727cc3a519310527ebafb55cb616637f44187b1bae5853773d4b5bca7f58bed803a086d47a9388e0000000000000000000000000000000003be761bd2a8b89a0802c20b4dfffedd4072d699bdd7db97c17f887b5a93c0cfac9c8e57f69649879c59b060e93fe4570000000000000000000000000000000004baa66dde1c1f6500680a955a313fe79172215948989b1daf4f0859d340eef5d70328b9f94c5e5d43d86a9902b55e81000000000000000000000000000000000ce5defbb703c6510e737114194429659d53a9f4011818b5bf35ffbbb281db85f7936f84b40d5a844e2e668a26a2a0d0", + "0000000000000000000000000000000015c253e204c58e012dd3e9f232096d93588d8471e1ad461067c3ed2599d7fd77c8feb23e6f8a18bdb5777f6640b0b3570000000000000000000000000000000010b5b066f7cd958318e56c181b6777e4acdf3e50466d0a8ea3973164f0c57069a4310705112414ba3f8acef50adfe1850000000000000000000000000000000009abf68d5b5171543116c24102869c785d11344518b91c4d40d07d85d2d437fdaa5f693513c436aa92caa4317de29471000000000000000000000000000000000ee58454ba9d19e308791fac39f48a1f6569e1a842184177906e61cfe902d90c6b79ada57298ae1c57cff09c43a6921b", + "000000000000000000000000000000000a2ee22112a95fae9392643ecac169b730198e8917c86297c88cc57581b8b563216f38e27df12e4b76d82cba96a41fc70000000000000000000000000000000003bb647b0edb1d2f058c7942c14f6054317f2e1c280e56dad85a789d302de382049c913837e129957c3b2959f3723957000000000000000000000000000000000817676f2e030a451c12e9241a6ed788f0aae24a3fb9cad323169c7a956bc450cae6ce717306922090493183ef5d447900000000000000000000000000000000091db623c0815f2b9848e1d292203f6adda8ba1b6c6a7bd6bc414e53dd95f3033fd93782a95688de7a8888cd04cd02da", + }; + + @Override + public void runBenchmark( + final PrintStream output, final Boolean attemptNative, final String fork) { + + EvmSpecVersion forkVersion = EvmSpecVersion.fromName(fork); + + if (forkVersion.compareTo(EvmSpecVersion.PRAGUE) < 0) { + output.printf("EIP2537 is not available before Prague\n"); + return; + } + + if (!AbstractBLS12PrecompiledContract.isAvailable()) { + output.printf( + "BLS12-381 not available on this platform %s %s %s\n", + System.getProperty("os.name"), + System.getProperty("os.version"), + System.getProperty("os.arch")); + return; + } + + benchmarkG1Add(output); + benchmarkG1Mul(output); + benchmarkG1MultiExp32Pairs(output); + benchmarkMapFpToG1(output); + benchmarkG2Add(output); + benchmarkG2Mul(output); + benchmarkG2MultiExp32Pairs(output); + benchmarkMapFp2ToG2(output); + benchmarkBlsPairing(output); + } + + private void benchmarkG1Add(final PrintStream output) { + final Map testCases = new LinkedHashMap<>(); + for (int i = 0; i < g1PointPairs.length - 1; i++) { + testCases.put("G1 Add " + i, Bytes.fromHexString(g1PointPairs[i] + g1PointPairs[i + 1])); + } + + BLS12G1AddPrecompiledContract g1addContract = new BLS12G1AddPrecompiledContract(); + warmup = MATH_WARMUP / testCases.size(); + iterations = MATH_ITERATIONS / testCases.size(); + double execTime = Double.MIN_VALUE; // a way to dodge divide by zero + long gasCost = 0; + for (final Map.Entry testCase : testCases.entrySet()) { + execTime += runPrecompileBenchmark(testCase.getValue(), g1addContract); + gasCost += g1addContract.gasRequirement(testCase.getValue()); + } + execTime /= testCases.size(); + gasCost /= testCases.size(); + output.printf( + "Bls12 G1 Add %,6d avg gas @%,7.1f µs /%,8.1f MGps%n", + gasCost, execTime * 1_000_000, gasCost / execTime / 1_000_000); + } + + private void benchmarkG1Mul(final PrintStream output) { + final Map testCases = new LinkedHashMap<>(); + for (int i = 0; i < g1PointPairs.length; i++) { + testCases.put("G1 Mul " + i, Bytes.fromHexString(g1PointPairs[i] + scalars[i])); + } + + BLS12G1MulPrecompiledContract g1addContract = new BLS12G1MulPrecompiledContract(); + warmup = MATH_WARMUP / testCases.size(); + iterations = MATH_ITERATIONS / testCases.size(); + double execTime = Double.MIN_VALUE; // a way to dodge divide by zero + long gasCost = 0; + for (final Map.Entry testCase : testCases.entrySet()) { + execTime += runPrecompileBenchmark(testCase.getValue(), g1addContract); + gasCost += g1addContract.gasRequirement(testCase.getValue()); + } + execTime /= testCases.size(); + gasCost /= testCases.size(); + output.printf( + "Bls12 G1 Mul %,6d avg gas @%,7.1f µs /%,8.1f MGps%n", + gasCost, execTime * 1_000_000, gasCost / execTime / 1_000_000); + } + + private void benchmarkG1MultiExp32Pairs(final PrintStream output) { + final Map testCases = new LinkedHashMap<>(); + + // add test cases for 2, 4, 8, 16, and 32 point/scalar pairs + for (int i = 1; i <= 5; i++) { + StringBuilder g1msmPairs = new StringBuilder(); + for (int j = 0; j < 1 << i; j++) { + g1msmPairs.append(g1PointPairs[j]).append(scalars[j]); + } + testCases.put("G1 MSM, " + (1 << i) + " pairs", Bytes.fromHexString(g1msmPairs.toString())); + } + + BLS12G1MultiExpPrecompiledContract g1msmContract = new BLS12G1MultiExpPrecompiledContract(); + warmup = MATH_WARMUP / testCases.size(); + iterations = MATH_ITERATIONS / testCases.size(); + double execTime = Double.MIN_VALUE; // a way to dodge divide by zero + long gasCost = 0; + for (final Map.Entry testCase : testCases.entrySet()) { + execTime += runPrecompileBenchmark(testCase.getValue(), g1msmContract); + gasCost += g1msmContract.gasRequirement(testCase.getValue()); + } + output.printf( + "Bls12 G1 MSM %,9d total gas @%,7.1f µs /%,8.1f MGps%n", + gasCost, execTime * 1_000_000, gasCost / execTime / 1_000_000); + } + + private void benchmarkMapFpToG1(final PrintStream output) { + final Map testCases = new LinkedHashMap<>(); + for (int i = 0; i < g1PointPairs.length; i++) { + testCases.put("Map Fp to G1 " + i, Bytes.fromHexString(g1PointPairs[i].substring(0, 128))); + } + + BLS12MapFpToG1PrecompiledContract g1MapFpToG1Contract = new BLS12MapFpToG1PrecompiledContract(); + warmup = MATH_WARMUP / testCases.size(); + iterations = MATH_ITERATIONS / testCases.size(); + double execTime = Double.MIN_VALUE; // a way to dodge divide by zero + long gasCost = 0; + for (final Map.Entry testCase : testCases.entrySet()) { + execTime += runPrecompileBenchmark(testCase.getValue(), g1MapFpToG1Contract); + gasCost += g1MapFpToG1Contract.gasRequirement(testCase.getValue()); + } + execTime /= testCases.size(); + gasCost /= testCases.size(); + output.printf( + "Bls12 MapFpToG1 %,6d avg gas @%,7.1f µs /%,8.1f MGps%n", + gasCost, execTime * 1_000_000, gasCost / execTime / 1_000_000); + } + + private void benchmarkG2Add(final PrintStream output) { + final Map testCases = new LinkedHashMap<>(); + for (int i = 0; i < g2PointPairs.length - 1; i++) { + testCases.put("G2 Add " + i, Bytes.fromHexString(g2PointPairs[i] + g2PointPairs[i + 1])); + } + + BLS12G2AddPrecompiledContract g1addContract = new BLS12G2AddPrecompiledContract(); + warmup = MATH_WARMUP / testCases.size(); + iterations = MATH_ITERATIONS / testCases.size(); + double execTime = Double.MIN_VALUE; // a way to dodge divide by zero + long gasCost = 0; + for (final Map.Entry testCase : testCases.entrySet()) { + execTime += runPrecompileBenchmark(testCase.getValue(), g1addContract); + gasCost += g1addContract.gasRequirement(testCase.getValue()); + } + execTime /= testCases.size(); + gasCost /= testCases.size(); + output.printf( + "Bls12 G2 Add %,6d avg gas @%,7.1f µs /%,8.1f MGps%n", + gasCost, execTime * 1_000_000, gasCost / execTime / 1_000_000); + } + + private void benchmarkG2Mul(final PrintStream output) { + final Map testCases = new LinkedHashMap<>(); + for (int i = 0; i < g2PointPairs.length; i++) { + testCases.put("G2 Mul " + i, Bytes.fromHexString(g2PointPairs[i] + scalars[i])); + } + + BLS12G2MulPrecompiledContract g1addContract = new BLS12G2MulPrecompiledContract(); + warmup = MATH_WARMUP / testCases.size(); + iterations = MATH_ITERATIONS / testCases.size(); + double execTime = Double.MIN_VALUE; // a way to dodge divide by zero + long gasCost = 0; + for (final Map.Entry testCase : testCases.entrySet()) { + execTime += runPrecompileBenchmark(testCase.getValue(), g1addContract); + gasCost += g1addContract.gasRequirement(testCase.getValue()); + } + execTime /= testCases.size(); + gasCost /= testCases.size(); + output.printf( + "Bls12 G2 Mul %,6d avg gas @%,7.1f µs /%,8.1f MGps%n", + gasCost, execTime * 1_000_000, gasCost / execTime / 1_000_000); + } + + private void benchmarkG2MultiExp32Pairs(final PrintStream output) { + final Map testCases = new LinkedHashMap<>(); + + // add test cases for 2, 4, 8, 16, and 32 point/scalar pairs + for (int i = 1; i <= 5; i++) { + StringBuilder g2msmPairs = new StringBuilder(); + for (int j = 0; j < 1 << i; j++) { + g2msmPairs.append(g2PointPairs[j]).append(scalars[j]); + } + testCases.put("G2 MSM, " + (1 << i) + " pairs", Bytes.fromHexString(g2msmPairs.toString())); + } + + BLS12G2MultiExpPrecompiledContract g2msmContract = new BLS12G2MultiExpPrecompiledContract(); + warmup = MATH_WARMUP / testCases.size(); + iterations = MATH_ITERATIONS / testCases.size(); + double execTime = Double.MIN_VALUE; // a way to dodge divide by zero + long gasCost = 0; + for (final Map.Entry testCase : testCases.entrySet()) { + execTime += runPrecompileBenchmark(testCase.getValue(), g2msmContract); + gasCost += g2msmContract.gasRequirement(testCase.getValue()); + } + output.printf( + "Bls12 G2 MSM %,9d total gas @%,7.1f µs /%,8.1f MGps%n", + gasCost, execTime * 1_000_000, gasCost / execTime / 1_000_000); + } + + private void benchmarkMapFp2ToG2(final PrintStream output) { + final Map testCases = new LinkedHashMap<>(); + for (int i = 0; i < g2PointPairs.length; i++) { + testCases.put("Map Fp2 to G2 " + i, Bytes.fromHexString(g2PointPairs[i].substring(0, 256))); + } + + BLS12MapFp2ToG2PrecompiledContract g1MapFp2ToG2Contract = + new BLS12MapFp2ToG2PrecompiledContract(); + warmup = MATH_WARMUP / testCases.size(); + iterations = MATH_ITERATIONS / testCases.size(); + double execTime = Double.MIN_VALUE; // a way to dodge divide by zero + long gasCost = 0; + for (final Map.Entry testCase : testCases.entrySet()) { + execTime += runPrecompileBenchmark(testCase.getValue(), g1MapFp2ToG2Contract); + gasCost += g1MapFp2ToG2Contract.gasRequirement(testCase.getValue()); + } + execTime /= testCases.size(); + gasCost /= testCases.size(); + output.printf( + "Bls12 MapFp2G1 %,6d avg gas @%,7.1f µs /%,8.1f MGps%n", + gasCost, execTime * 1_000_000, gasCost / execTime / 1_000_000); + } + + private void benchmarkBlsPairing(final PrintStream output) { + final Map testCases = new LinkedHashMap<>(); + + // add test cases for 2, 4, 8, 16, and 32 point/scalar pairs + for (int i = 1; i <= 5; i++) { + StringBuilder pairs = new StringBuilder(); + for (int j = 0; j < 1 << i; j++) { + pairs.append(g1PointPairs[j]).append(g2PointPairs[j]); + } + testCases.put("BLS Pairing, " + (1 << i) + " pairs", Bytes.fromHexString(pairs.toString())); + } + + BLS12PairingPrecompiledContract blsPairingContract = new BLS12PairingPrecompiledContract(); + warmup = MATH_WARMUP / testCases.size(); + iterations = MATH_ITERATIONS / testCases.size(); + double execTime = Double.MIN_VALUE; // a way to dodge divide by zero + long gasCost = 0; + for (final Map.Entry testCase : testCases.entrySet()) { + execTime += runPrecompileBenchmark(testCase.getValue(), blsPairingContract); + gasCost += blsPairingContract.gasRequirement(testCase.getValue()); + } + + output.printf( + "Bls12 Pairing %,9d total gas @%,7.1f µs /%,8.1f MGps%n", + gasCost, execTime * 1_000_000, gasCost / execTime / 1_000_000); + } +} diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/benchmarks/BenchmarkExecutor.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/benchmarks/BenchmarkExecutor.java index 082fae7f69..35d5de5d66 100644 --- a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/benchmarks/BenchmarkExecutor.java +++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/benchmarks/BenchmarkExecutor.java @@ -30,8 +30,8 @@ import org.hyperledger.besu.evm.gascalculator.GasCalculator; import org.hyperledger.besu.evm.gascalculator.HomesteadGasCalculator; import org.hyperledger.besu.evm.gascalculator.IstanbulGasCalculator; import org.hyperledger.besu.evm.gascalculator.LondonGasCalculator; +import org.hyperledger.besu.evm.gascalculator.OsakaGasCalculator; import org.hyperledger.besu.evm.gascalculator.PetersburgGasCalculator; -import org.hyperledger.besu.evm.gascalculator.PragueEOFGasCalculator; import org.hyperledger.besu.evm.gascalculator.PragueGasCalculator; import org.hyperledger.besu.evm.gascalculator.ShanghaiGasCalculator; import org.hyperledger.besu.evm.precompile.PrecompiledContract; @@ -142,17 +142,11 @@ public abstract class BenchmarkExecutor { case LONDON, PARIS -> new LondonGasCalculator(); case SHANGHAI -> new ShanghaiGasCalculator(); case CANCUN -> new CancunGasCalculator(); + case CANCUN_EOF -> new OsakaGasCalculator(); case PRAGUE -> new PragueGasCalculator(); - case CANCUN_EOF, - PRAGUE_EOF, - OSAKA, - AMSTERDAM, - BOGOTA, - POLIS, - BANGKOK, - FUTURE_EIPS, - EXPERIMENTAL_EIPS -> - new PragueEOFGasCalculator(); + case OSAKA -> new OsakaGasCalculator(); + case AMSTERDAM, BOGOTA, POLIS, BANGKOK, FUTURE_EIPS, EXPERIMENTAL_EIPS -> + new OsakaGasCalculator(); }; } diff --git a/ethereum/evmtool/src/test/benchmarks/bench-caliper.sh b/ethereum/evmtool/src/test/benchmarks/bench-caliper.sh index 48d628aae2..8d00cb57a7 100755 --- a/ethereum/evmtool/src/test/benchmarks/bench-caliper.sh +++ b/ethereum/evmtool/src/test/benchmarks/bench-caliper.sh @@ -1,6 +1,6 @@ #!/usr/bin/env sh ## -## Copyright contributors to Hyperledger Besu. +## Copyright contributors to 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 diff --git a/ethereum/evmtool/src/test/benchmarks/bench-loop.sh b/ethereum/evmtool/src/test/benchmarks/bench-loop.sh index e3f747530f..4dfa70875c 100755 --- a/ethereum/evmtool/src/test/benchmarks/bench-loop.sh +++ b/ethereum/evmtool/src/test/benchmarks/bench-loop.sh @@ -1,6 +1,6 @@ #!/usr/bin/env sh ## -## Copyright contributors to Hyperledger Besu. +## Copyright contributors to 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 diff --git a/ethereum/evmtool/src/test/benchmarks/bench-mainnet.sh b/ethereum/evmtool/src/test/benchmarks/bench-mainnet.sh index 084799e96a..0763950d40 100755 --- a/ethereum/evmtool/src/test/benchmarks/bench-mainnet.sh +++ b/ethereum/evmtool/src/test/benchmarks/bench-mainnet.sh @@ -1,6 +1,6 @@ #!/usr/bin/env sh ## -## Copyright contributors to Hyperledger Besu. +## Copyright contributors to 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 diff --git a/ethereum/evmtool/src/test/benchmarks/bench-static.sh b/ethereum/evmtool/src/test/benchmarks/bench-static.sh index 6ae063d3b0..5b36e7cc21 100755 --- a/ethereum/evmtool/src/test/benchmarks/bench-static.sh +++ b/ethereum/evmtool/src/test/benchmarks/bench-static.sh @@ -1,6 +1,6 @@ #!/usr/bin/env sh ## -## Copyright contributors to Hyperledger Besu. +## Copyright contributors to 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 diff --git a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/block-test/prague-eof-rjump.json b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/block-test/osaka-eof-rjump.json similarity index 92% rename from ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/block-test/prague-eof-rjump.json rename to ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/block-test/osaka-eof-rjump.json index b9d2e54179..a6c5bcc62c 100644 --- a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/block-test/prague-eof-rjump.json +++ b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/block-test/osaka-eof-rjump.json @@ -4,13 +4,13 @@ "stdin" ], "stdin": { - "tests/prague/eip7692_eof_v1/eip4200_relative_jumps/test_rjump.py::test_rjump_zero[fork_PragueEIP7692-blockchain_test]": { - "network": "Prague", + "tests/osaka/eip7692_eof_v1/eip4200_relative_jumps/test_rjump.py::test_rjump_zero[fork_Osaka-blockchain_test]": { + "network": "Osaka", "genesisBlockHeader": { "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "uncleHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", "coinbase": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x34ccf8774a5b8833da9451a3f7f8a0af0147956c058f0831dab07c348d7ac0d9", + "stateRoot": "0xbeb30acb62768b375f7e7d36f6ba9240cb692ebd0ee04c9321c756cf4ff1c437", "transactionsTrie": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "receiptTrie": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", @@ -27,8 +27,8 @@ "blobGasUsed": "0x00", "excessBlobGas": "0x00", "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", - "requestsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "hash": "0xc9397e8a1b99cbb2b885852fde56de8fa686091a4f4430163f5237d7aaf33a14" + "requestsHash": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "hash": "0x367310df4a31070aa9a5c92cb61ab8bb2742db0162619ed77594fbec6f0ddbd9" }, "pre": { "0x00000000219ab540356cbb839cbe05303d7705fa": { @@ -75,6 +75,12 @@ "code": "0x3373fffffffffffffffffffffffffffffffffffffffe146090573615156028575f545f5260205ff35b366038141561012e5760115f54600182026001905f5b5f82111560595781019083028483029004916001019190603e565b90939004341061012e57600154600101600155600354806003026004013381556001015f3581556001016020359055600101600355005b6003546002548082038060101160a4575060105b5f5b81811460dd5780604c02838201600302600401805490600101805490600101549160601b83528260140152906034015260010160a6565b910180921460ed579060025560f8565b90505f6002555f6003555b5f548061049d141561010757505f5b60015460028282011161011c5750505f610122565b01600290035b5f555f600155604c025ff35b5f5ffd", "storage": {} }, + "0x00b42dbf2194e931e80326d950320f7d9dbeac02": { + "nonce": "0x01", + "balance": "0x00", + "code": "0x3373fffffffffffffffffffffffffffffffffffffffe146098573615156028575f545f5260205ff35b36606014156101445760115f54600182026001905f5b5f82111560595781019083028483029004916001019190603e565b90939004341061014457600154600101600155600354806004026004013381556001015f35815560010160203581556001016040359055600101600355005b6003546002548082038060011160ac575060015b5f5b81811460f15780607402838201600402600401805490600101805490600101805490600101549260601b84529083601401528260340152906054015260010160ae565b9101809214610103579060025561010e565b90505f6002555f6003555b5f548061049d141561011d57505f5b6001546001828201116101325750505f610138565b01600190035b5f555f6001556074025ff35b5f5ffd", + "storage": {} + }, "0x0aae40965e6800cd9b1f4b05ff21581047e3f91e": { "nonce": "0x01", "balance": "0x00", @@ -161,12 +167,18 @@ "code": "0x3373fffffffffffffffffffffffffffffffffffffffe146090573615156028575f545f5260205ff35b366038141561012e5760115f54600182026001905f5b5f82111560595781019083028483029004916001019190603e565b90939004341061012e57600154600101600155600354806003026004013381556001015f3581556001016020359055600101600355005b6003546002548082038060101160a4575060105b5f5b81811460dd5780604c02838201600302600401805490600101805490600101549160601b83528260140152906034015260010160a6565b910180921460ed579060025560f8565b90505f6002555f6003555b5f548061049d141561010757505f5b60015460028282011161011c5750505f610122565b01600290035b5f555f600155604c025ff35b5f5ffd", "storage": {} }, + "0x00b42dbf2194e931e80326d950320f7d9dbeac02": { + "nonce": "0x01", + "balance": "0x00", + "code": "0x3373fffffffffffffffffffffffffffffffffffffffe146098573615156028575f545f5260205ff35b36606014156101445760115f54600182026001905f5b5f82111560595781019083028483029004916001019190603e565b90939004341061014457600154600101600155600354806004026004013381556001015f35815560010160203581556001016040359055600101600355005b6003546002548082038060011160ac575060015b5f5b81811460f15780607402838201600402600401805490600101805490600101805490600101549260601b84529083601401528260340152906054015260010160ae565b9101809214610103579060025561010e565b90505f6002555f6003555b5f548061049d141561011d57505f5b6001546001828201116101325750505f610138565b01600190035b5f555f6001556074025ff35b5f5ffd", + "storage": {} + }, "0x0aae40965e6800cd9b1f4b05ff21581047e3f91e": { "nonce": "0x01", "balance": "0x00", "code": "0x3373fffffffffffffffffffffffffffffffffffffffe1460575767ffffffffffffffff5f3511605357600143035f3511604b575f35612000014311604b57611fff5f3516545f5260205ff35b5f5f5260205ff35b5f5ffd5b5f35611fff60014303165500", "storage": { - "0x00": "0xc9397e8a1b99cbb2b885852fde56de8fa686091a4f4430163f5237d7aaf33a14" + "0x00": "0x367310df4a31070aa9a5c92cb61ab8bb2742db0162619ed77594fbec6f0ddbd9" } }, "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba": { @@ -182,14 +194,15 @@ "storage": {} } }, - "genesisRLP": "0xf90262f9025ba00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a034ccf8774a5b8833da9451a3f7f8a0af0147956c058f0831dab07c348d7ac0d9a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000808088016345785d8a0000808000a0000000000000000000000000000000000000000000000000000000000000000088000000000000000007a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421c0c0c0c0", + "lastblockhash": "0xfb5d1d0e218fa7873bc188f07f3e0a7c78027ff6e6e199c48ba1facd3c3726fd", + "genesisRLP": "0xf90262f9025ba00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a0beb30acb62768b375f7e7d36f6ba9240cb692ebd0ee04c9321c756cf4ff1c437a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000808088016345785d8a0000808000a0000000000000000000000000000000000000000000000000000000000000000088000000000000000007a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421c0c0c0c0", "blocks": [ { "blockHeader": { - "parentHash": "0xc9397e8a1b99cbb2b885852fde56de8fa686091a4f4430163f5237d7aaf33a14", + "parentHash": "0x367310df4a31070aa9a5c92cb61ab8bb2742db0162619ed77594fbec6f0ddbd9", "uncleHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", "coinbase": "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", - "stateRoot": "0x1a4885d1f64bac16e5ab17fb13e23fb5d1a0ec2ca4519c81714683f69c8d9a84", + "stateRoot": "0x4ab70cbe1abe50d6bb3c8cdb3e9e66111f142cd68ab73870e9ce9e0dd1d6ead2", "transactionsTrie": "0xec9d10cff79619f2df45db8c66526ef3fbd32d283fdd2dcc9b55c0efe643d8c3", "receiptTrie": "0x9593f56abf23bcbb26d27b0c6e46a56415d9103ed6b4d8ac7b4182f9f250cafa", "bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", @@ -206,8 +219,8 @@ "blobGasUsed": "0x00", "excessBlobGas": "0x00", "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", - "requestsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "hash": "0x879cf54bf493b6585db592b1b24ec30a8a7fbe3b9146d3fb20ca36200f2aca87" + "requestsHash": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "hash": "0xfb5d1d0e218fa7873bc188f07f3e0a7c78027ff6e6e199c48ba1facd3c3726fd" }, "transactions": [ { @@ -229,22 +242,22 @@ "withdrawals": [], "depositRequests": [], "withdrawalRequests": [], - "rlp": "0xf902c9f9025fa0c9397e8a1b99cbb2b885852fde56de8fa686091a4f4430163f5237d7aaf33a14a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa01a4885d1f64bac16e5ab17fb13e23fb5d1a0ec2ca4519c81714683f69c8d9a84a0ec9d10cff79619f2df45db8c66526ef3fbd32d283fdd2dcc9b55c0efe643d8c3a09593f56abf23bcbb26d27b0c6e46a56415d9103ed6b4d8ac7b4182f9f250cafab9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800188016345785d8a000082a8648203e800a0000000000000000000000000000000000000000000000000000000000000000088000000000000000007a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421f862f860800a83989680940000000000000000000000000000000000001000808026a0e5d462429669f661291a8dc4c49a092cfd4922b6f3f31c9189a2f4adf5ecd730a001494afaf472fbb80bcb107ffeb918a2b9115f454027840615d6d20d63c69ac0c0c0c0", + "consolidationRequests": [], + "rlp": "0xf902c9f9025fa0367310df4a31070aa9a5c92cb61ab8bb2742db0162619ed77594fbec6f0ddbd9a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa04ab70cbe1abe50d6bb3c8cdb3e9e66111f142cd68ab73870e9ce9e0dd1d6ead2a0ec9d10cff79619f2df45db8c66526ef3fbd32d283fdd2dcc9b55c0efe643d8c3a09593f56abf23bcbb26d27b0c6e46a56415d9103ed6b4d8ac7b4182f9f250cafab9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800188016345785d8a000082a8648203e800a0000000000000000000000000000000000000000000000000000000000000000088000000000000000007a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421f862f860800a83989680940000000000000000000000000000000000001000808026a0e5d462429669f661291a8dc4c49a092cfd4922b6f3f31c9189a2f4adf5ecd730a001494afaf472fbb80bcb107ffeb918a2b9115f454027840615d6d20d63c69ac0c0c0c0", "blocknumber": "1" } ], - "lastblockhash": "0x879cf54bf493b6585db592b1b24ec30a8a7fbe3b9146d3fb20ca36200f2aca87", "sealEngine": "NoProof", "_info": { - "hash": "0xbfd1223f9b5b8dbf202178f7c1f18dc089cb24e54c9cb7fc9831907547e937c4", + "hash": "0xd0cc15d832c8c0b9cf5bdc0eab79c3b632193a11fde3d5ef32bb07e8c65ba6bd", "comment": "`execution-spec-tests` generated test", - "filling-transition-tool": "Hyperledger Besu evm 24.7-develop-8ca7129", + "filling-transition-tool": "Hyperledger Besu evm 24.9-develop-0d63955", "description": "Test function documentation:\nEOF1V4200_0002 (Valid) EOF code containing RJUMP (Zero)", - "url": "https://github.com/ethereum/execution-spec-tests/blob/891a6111370c89d4ce89bf91589c6d5ff6785158/tests/prague/eip7692_eof_v1/eip4200_relative_jumps/test_rjump.py#L63", + "url": "https://github.com/ethereum/execution-spec-tests/blob/96efd737b258eeb8efb615e9123d931b6dfda302/tests/osaka/eip7692_eof_v1/eip4200_relative_jumps/test_rjump.py#L44", "reference-spec": "https://github.com/ethereum/EIPs/blob/master/EIPS/eip-4200.md", "reference-spec-version": "17d4a8d12d2b5e0f2985c866376c16c8c6df7cba" } } }, - "stdout": "Considering tests/prague/eip7692_eof_v1/eip4200_relative_jumps/test_rjump.py::test_rjump_zero[fork_PragueEIP7692-blockchain_test]\nBlock 1 (0x879cf54bf493b6585db592b1b24ec30a8a7fbe3b9146d3fb20ca36200f2aca87) Imported\nChain import successful - tests/prague/eip7692_eof_v1/eip4200_relative_jumps/test_rjump.py::test_rjump_zero[fork_PragueEIP7692-blockchain_test]\n" + "stdout": "Considering tests/osaka/eip7692_eof_v1/eip4200_relative_jumps/test_rjump.py::test_rjump_zero[fork_Osaka-blockchain_test]\nBlock 1 (0xfb5d1d0e218fa7873bc188f07f3e0a7c78027ff6e6e199c48ba1facd3c3726fd) Imported\nChain import successful - tests/osaka/eip7692_eof_v1/eip4200_relative_jumps/test_rjump.py::test_rjump_zero[fork_Osaka-blockchain_test]\n" } diff --git a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/state-test/create-eof.json b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/state-test/create-eof.json index e924043042..72ada37da7 100644 --- a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/state-test/create-eof.json +++ b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/state-test/create-eof.json @@ -45,7 +45,7 @@ }, "out": "0x", "post": { - "CancunEOF": [ + "Osaka": [ { "hash": "0x1a8642a04dae90535f00f53d3a30284c4db051d508a653db89eb100ba9aecbf3", "logs": "0xf48b954a6a6f4ce6b28e4950b7027413f4bdc8f459df6003b6e8d7a1567c8940", @@ -79,7 +79,7 @@ {"pc":5,"section":0,"op":95,"gas":"0x793d71","gasCost":"0x2","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"PUSH0"}, {"pc":6,"section":0,"op":95,"gas":"0x793d6f","gasCost":"0x2","memSize":0,"stack":["0x0"],"depth":1,"refund":0,"opName":"PUSH0"}, {"pc":7,"section":0,"op":238,"immediate":"0x00","gas":"0x793d6d","gasCost":"0x0","memSize":0,"stack":["0x0","0x0"],"depth":1,"refund":0,"opName":"RETURNCONTRACT"}, - {"output":"","gasUsed":"0xe433","test":"create-eof","fork":"CancunEOF","d":0,"g":0,"v":0,"postHash":"0x1a8642a04dae90535f00f53d3a30284c4db051d508a653db89eb100ba9aecbf3","postLogsHash":"0xf48b954a6a6f4ce6b28e4950b7027413f4bdc8f459df6003b6e8d7a1567c8940","pass":true}, + {"output":"","gasUsed":"0xe433","test":"create-eof","fork":"Osaka","d":0,"g":0,"v":0,"postHash":"0x1a8642a04dae90535f00f53d3a30284c4db051d508a653db89eb100ba9aecbf3","postLogsHash":"0xf48b954a6a6f4ce6b28e4950b7027413f4bdc8f459df6003b6e8d7a1567c8940","pass":true}, {"pc":0,"op":239,"gas":"0x794068","gasCost":"0x0","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"INVALID","error":"Bad instruction"}, {"output":"","gasUsed":"0x7a1200","test":"create-eof","fork":"Cancun","d":0,"g":0,"v":0,"postHash":"0xaa80d89bc89f58da8de41d3894bd1a241896ff91f7a5964edaefb39e8e3a4a98","postLogsHash":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","pass":true,"error":"INVALID_OPERATION"} ] diff --git a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/state-test/create-invalid-eof.json b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/state-test/create-invalid-eof.json index e2eb67602e..f3448aa5a2 100644 --- a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/state-test/create-invalid-eof.json +++ b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/state-test/create-invalid-eof.json @@ -45,7 +45,7 @@ }, "out": "0x", "post": { - "Prague": [ + "Osaka": [ { "hash": "0x1a8642a04dae90535f00f53d3a30284c4db051d508a653db89eb100ba9aecbf3", "logs": "0xf48b954a6a6f4ce6b28e4950b7027413f4bdc8f459df6003b6e8d7a1567c8940", @@ -71,7 +71,7 @@ } }, "stdout": [ - {"output":"","gasUsed":"0xd198","test":"create-eof","fork":"Prague","d":0,"g":0,"v":0,"postHash":"0x2a9c58298ba5d4ec86ca682b9fcc9ff67c3fc44dbd39f85a2f9b74bfe4e5178e","postLogsHash":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","pass":false,"error":"Invalid EOF Layout: unexpected_header_kind expected 1 actual 17"}, + {"output":"","gasUsed":"0xd198","test":"create-eof","fork":"Osaka","d":0,"g":0,"v":0,"postHash":"0x2a9c58298ba5d4ec86ca682b9fcc9ff67c3fc44dbd39f85a2f9b74bfe4e5178e","postLogsHash":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","pass":false,"error":"Invalid EOF Layout: unexpected_header_kind expected 1 actual 17"}, {"pc":0,"op":239,"gas":"0x794068","gasCost":"0x0","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"INVALID","error":"Bad instruction"}, {"output":"","gasUsed":"0x7a1200","test":"create-eof","fork":"Cancun","d":0,"g":0,"v":0,"postHash":"0xaa80d89bc89f58da8de41d3894bd1a241896ff91f7a5964edaefb39e8e3a4a98","postLogsHash":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","pass":true,"error":"INVALID_OPERATION"} ] diff --git a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/t8n/prague-deposit.json b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/t8n/prague-deposit.json index 1a32e50e8b..771dc870e6 100644 --- a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/t8n/prague-deposit.json +++ b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/t8n/prague-deposit.json @@ -132,7 +132,9 @@ "stdout": { "alloc": { "0x00000000219ab540356cbb839cbe05303d7705fa": { + "balance": "0x3782dace9d9000000", "code": "0x60806040526004361061003f5760003560e01c806301ffc9a71461004457806322895118146100a4578063621fd130146101ba578063c5f2892f14610244575b600080fd5b34801561005057600080fd5b506100906004803603602081101561006757600080fd5b50357fffffffff000000000000000000000000000000000000000000000000000000001661026b565b604080519115158252519081900360200190f35b6101b8600480360360808110156100ba57600080fd5b8101906020810181356401000000008111156100d557600080fd5b8201836020820111156100e757600080fd5b8035906020019184600183028401116401000000008311171561010957600080fd5b91939092909160208101903564010000000081111561012757600080fd5b82018360208201111561013957600080fd5b8035906020019184600183028401116401000000008311171561015b57600080fd5b91939092909160208101903564010000000081111561017957600080fd5b82018360208201111561018b57600080fd5b803590602001918460018302840111640100000000831117156101ad57600080fd5b919350915035610304565b005b3480156101c657600080fd5b506101cf6110b5565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102095781810151838201526020016101f1565b50505050905090810190601f1680156102365780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561025057600080fd5b506102596110c7565b60408051918252519081900360200190f35b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a70000000000000000000000000000000000000000000000000000000014806102fe57507fffffffff0000000000000000000000000000000000000000000000000000000082167f8564090700000000000000000000000000000000000000000000000000000000145b92915050565b6030861461035d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118056026913960400191505060405180910390fd5b602084146103b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603681526020018061179c6036913960400191505060405180910390fd5b6060821461040f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260298152602001806118786029913960400191505060405180910390fd5b670de0b6b3a7640000341015610470576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118526026913960400191505060405180910390fd5b633b9aca003406156104cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260338152602001806117d26033913960400191505060405180910390fd5b633b9aca00340467ffffffffffffffff811115610535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602781526020018061182b6027913960400191505060405180910390fd5b6060610540826114ba565b90507f649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c589898989858a8a6105756020546114ba565b6040805160a0808252810189905290819060208201908201606083016080840160c085018e8e80828437600083820152601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690910187810386528c815260200190508c8c808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690920188810386528c5181528c51602091820193918e019250908190849084905b83811015610648578181015183820152602001610630565b50505050905090810190601f1680156106755780820380516001836020036101000a031916815260200191505b5086810383528881526020018989808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169092018881038452895181528951602091820193918b019250908190849084905b838110156106ef5781810151838201526020016106d7565b50505050905090810190601f16801561071c5780820380516001836020036101000a031916815260200191505b509d505050505050505050505050505060405180910390a1600060028a8a600060801b604051602001808484808284377fffffffffffffffffffffffffffffffff0000000000000000000000000000000090941691909301908152604080517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0818403018152601090920190819052815191955093508392506020850191508083835b602083106107fc57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016107bf565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610859573d6000803e3d6000fd5b5050506040513d602081101561086e57600080fd5b5051905060006002806108846040848a8c6116fe565b6040516020018083838082843780830192505050925050506040516020818303038152906040526040518082805190602001908083835b602083106108f857805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016108bb565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610955573d6000803e3d6000fd5b5050506040513d602081101561096a57600080fd5b5051600261097b896040818d6116fe565b60405160009060200180848480828437919091019283525050604080518083038152602092830191829052805190945090925082918401908083835b602083106109f457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016109b7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610a51573d6000803e3d6000fd5b5050506040513d6020811015610a6657600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610ada57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610a9d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610b37573d6000803e3d6000fd5b5050506040513d6020811015610b4c57600080fd5b50516040805160208101858152929350600092600292839287928f928f92018383808284378083019250505093505050506040516020818303038152906040526040518082805190602001908083835b60208310610bd957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610b9c565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610c36573d6000803e3d6000fd5b5050506040513d6020811015610c4b57600080fd5b50516040518651600291889160009188916020918201918291908601908083835b60208310610ca957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610c6c565b6001836020036101000a0380198251168184511680821785525050505050509050018367ffffffffffffffff191667ffffffffffffffff1916815260180182815260200193505050506040516020818303038152906040526040518082805190602001908083835b60208310610d4e57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610d11565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610dab573d6000803e3d6000fd5b5050506040513d6020811015610dc057600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610e3457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610df7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610e91573d6000803e3d6000fd5b5050506040513d6020811015610ea657600080fd5b50519050858114610f02576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260548152602001806117486054913960600191505060405180910390fd5b60205463ffffffff11610f60576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806117276021913960400191505060405180910390fd5b602080546001019081905560005b60208110156110a9578160011660011415610fa0578260008260208110610f9157fe5b0155506110ac95505050505050565b600260008260208110610faf57fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061102557805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610fe8565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015611082573d6000803e3d6000fd5b5050506040513d602081101561109757600080fd5b50519250600282049150600101610f6e565b50fe5b50505050505050565b60606110c26020546114ba565b905090565b6020546000908190815b60208110156112f05781600116600114156111e6576002600082602081106110f557fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061116b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161112e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156111c8573d6000803e3d6000fd5b5050506040513d60208110156111dd57600080fd5b505192506112e2565b600283602183602081106111f657fe5b015460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061126b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161122e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156112c8573d6000803e3d6000fd5b5050506040513d60208110156112dd57600080fd5b505192505b6002820491506001016110d1565b506002826112ff6020546114ba565b600060401b6040516020018084815260200183805190602001908083835b6020831061135a57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161131d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790527fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000095909516920191825250604080518083037ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8018152601890920190819052815191955093508392850191508083835b6020831061143f57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611402565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa15801561149c573d6000803e3d6000fd5b5050506040513d60208110156114b157600080fd5b50519250505090565b60408051600880825281830190925260609160208201818036833701905050905060c082901b8060071a60f81b826000815181106114f457fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060061a60f81b8260018151811061153757fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060051a60f81b8260028151811061157a57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060041a60f81b826003815181106115bd57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060031a60f81b8260048151811061160057fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060021a60f81b8260058151811061164357fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060011a60f81b8260068151811061168657fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060001a60f81b826007815181106116c957fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535050919050565b6000808585111561170d578182fd5b83861115611719578182fd5b505082019391909203915056fe4465706f736974436f6e74726163743a206d65726b6c6520747265652066756c6c4465706f736974436f6e74726163743a207265636f6e7374727563746564204465706f7369744461746120646f6573206e6f74206d6174636820737570706c696564206465706f7369745f646174615f726f6f744465706f736974436f6e74726163743a20696e76616c6964207769746864726177616c5f63726564656e7469616c73206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c7565206e6f74206d756c7469706c65206f6620677765694465706f736974436f6e74726163743a20696e76616c6964207075626b6579206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f20686967684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f206c6f774465706f736974436f6e74726163743a20696e76616c6964207369676e6174757265206c656e677468a2646970667358221220dceca8706b29e917dacf25fceef95acac8d90d765ac926663ce4096195952b6164736f6c634300060b0033", + "nonce": "0x1", "storage": { "0x0000000000000000000000000000000000000000000000000000000000000000": "0x85acb6376c2707b118225da41825974c12b5924a05c6a53b988c9cbc33c55b05", "0x0000000000000000000000000000000000000000000000000000000000000001": "0x2f93f18b1befc457f659e486ce25bbe413fe3943ee7634d2afbe83dc512c3d7a", @@ -168,30 +170,28 @@ "0x000000000000000000000000000000000000000000000000000000000000003e": "0x8869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636", "0x000000000000000000000000000000000000000000000000000000000000003f": "0xb5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c", "0x0000000000000000000000000000000000000000000000000000000000000040": "0x985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7" - }, - "balance": "0x3782dace9d9000000", - "nonce": "0x1" - }, - "0x00a3ca265ebcb825b45f985a16cefb49958ce017": { - "code": "0x3373fffffffffffffffffffffffffffffffffffffffe146090573615156028575f545f5260205ff35b366038141561012e5760115f54600182026001905f5b5f82111560595781019083028483029004916001019190603e565b90939004341061012e57600154600101600155600354806003026004013381556001015f3581556001016020359055600101600355005b6003546002548082038060101160a4575060105b5f5b81811460dd5780604c02838201600302600401805490600101805490600101549160601b83528260140152906034015260010160a6565b910180921460ed579060025560f8565b90505f6002555f6003555b5f548061049d141561010757505f5b60015460028282011161011c5750505f610122565b01600290035b5f555f600155604c025ff35b5f5ffd", - "balance": "0x0", - "nonce": "0x1" + } }, "0x000f3df6d732807ef1319fb7b8bb8522d0beac02": { + "balance": "0x0", "code": "0x3373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500", + "nonce": "0x1", "storage": { "0x000000000000000000000000000000000000000000000000000000000000000c": "0x000000000000000000000000000000000000000000000000000000000000000c" - }, + } + }, + "0x00a3ca265ebcb825b45f985a16cefb49958ce017": { "balance": "0x0", + "code": "0x3373fffffffffffffffffffffffffffffffffffffffe146090573615156028575f545f5260205ff35b366038141561012e5760115f54600182026001905f5b5f82111560595781019083028483029004916001019190603e565b90939004341061012e57600154600101600155600354806003026004013381556001015f3581556001016020359055600101600355005b6003546002548082038060101160a4575060105b5f5b81811460dd5780604c02838201600302600401805490600101805490600101549160601b83528260140152906034015260010160a6565b910180921460ed579060025560f8565b90505f6002555f6003555b5f548061049d141561010757505f5b60015460028282011161011c5750505f610122565b01600290035b5f555f600155604c025ff35b5f5ffd", "nonce": "0x1" }, "0x0aae40965e6800cd9b1f4b05ff21581047e3f91e": { + "balance": "0x0", "code": "0x3373fffffffffffffffffffffffffffffffffffffffe1460575767ffffffffffffffff5f3511605357600143035f3511604b575f35612000014311604b57611fff5f3516545f5260205ff35b5f5f5260205ff35b5f5ffd5b5f35611fff60014303165500", + "nonce": "0x1", "storage": { "0x0000000000000000000000000000000000000000000000000000000000000000": "0xe4fb5d47f70d54b4f36777ea4c882cf767f93d8f8170285d97a1b8275dfe4dbb" - }, - "balance": "0x0", - "nonce": "0x1" + } }, "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": { "balance": "0xaa00be18c288efd690", @@ -200,90 +200,77 @@ }, "body": "0xf90404f901ff8007830f42409400000000219ab540356cbb839cbe05303d7705fa8901bc16d674ec800000b9019422895118000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000d0000000000000000000000000000000000000000000000000000000000000011085acb6376c2707b118225da41825974c12b5924a05c6a53b988c9cbc33c55b05000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000325a0ffeb1d6e7ef8e9ee9b64dcdc3b056f9a1d2b94c1572f1949954e712364604575a03d0f42bad795205de84db8d4ab10b9abd0d081ffe560cbf45f6c281768112a69f901ff0107830f42409400000000219ab540356cbb839cbe05303d7705fa8901bc16d674ec800000b9019422895118000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000d0000000000000000000000000000000000000000000000000000000000000011085acb6376c2707b118225da41825974c12b5924a05c6a53b988c9cbc33c55b05000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000326a05bb08e348c9c4b0a2e15d04f4a89d1a210d013205de8d3d93e38e5c1b0c8d8aba04300c0f575d9908d2cbc3413ab82895678bb8f3ef356224dd1e7cb972f2c4855", "result": { - "stateRoot": "0x3aa7839837ee1564276a0a05554e35215353a97c4e255c3aacbcd7c7819daefa", - "txRoot": "0x2b790bf82ef7259a0e4513d1b89a77d81e99672ba68758ef2ba3fde32851d023", - "receiptsRoot": "0x9c8d7a917ecb3ff2566f264abbf39131e51b08b07eb2b69cb46989d79d985593", - "logsHash": "0x43e31613bfefc1f55d8b3ca2b61f933f3838d523dc11cb5d7ffdd2ecf0ab5d49", + "blobGasUsed": "0x0", + "currentBaseFee": "0x7", + "currentDifficulty": null, + "currentExcessBlobGas": "0x0", + "gasUsed": "0x24f10", "logsBloom": "0x00000000000000000000400000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000020000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000", + "logsHash": "0x43e31613bfefc1f55d8b3ca2b61f933f3838d523dc11cb5d7ffdd2ecf0ab5d49", "receipts": [ { - "root": "0x", - "status": "0x1", + "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "contractAddress": "0x0000000000000000000000000000000000000000", "cumulativeGasUsed": "0x1431e", - "logsBloom": "0x00000000000000000000400000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000020000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000", + "gasUsed": "0x1431e", "logs": [ { "address": "0x00000000219ab540356cbb839cbe05303d7705fa", + "blockHash": "0xb7b43f46d6ee34eaaad5ab38807b451e0e85bacbe59893afc625550aa7c65262", + "blockNumber": 1, + "data": "0x00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000080040597307000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000", + "logIndex": "0x0", + "removed": "false", "topics": [ "0x649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5" ], - "data": "0x00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000080040597307000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": 1, "transactionHash": "0x1fe5fcd93d503a72e93ef0a4249e6d9c983cecf33474684f62ece959fc3e8212", - "transactionIndex": "0x0", - "blockHash": "0xb7b43f46d6ee34eaaad5ab38807b451e0e85bacbe59893afc625550aa7c65262", - "logIndex": "0x0", - "removed": "false" + "transactionIndex": "0x0" } ], + "logsBloom": "0x00000000000000000000400000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000020000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000", + "root": "0x", + "status": "0x1", "transactionHash": "0x1fe5fcd93d503a72e93ef0a4249e6d9c983cecf33474684f62ece959fc3e8212", - "contractAddress": "0x0000000000000000000000000000000000000000", - "gasUsed": "0x1431e", - "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "transactionIndex": "0x0" }, { - "root": "0x", - "status": "0x1", + "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "contractAddress": "0x0000000000000000000000000000000000000000", "cumulativeGasUsed": "0x24f10", - "logsBloom": "0x00000000000000000000400000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000020000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000", + "gasUsed": "0x10bf2", "logs": [ { "address": "0x00000000219ab540356cbb839cbe05303d7705fa", + "blockHash": "0xb7b43f46d6ee34eaaad5ab38807b451e0e85bacbe59893afc625550aa7c65262", + "blockNumber": 1, + "data": "0x00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000080040597307000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000080100000000000000000000000000000000000000000000000000000000000000", + "logIndex": "0x0", + "removed": "false", "topics": [ "0x649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5" ], - "data": "0x00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000080040597307000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000080100000000000000000000000000000000000000000000000000000000000000", - "blockNumber": 1, "transactionHash": "0x3059d7dbc2df8a05442e50ea529419277c2f45582534f452d2d5676d93273c7d", - "transactionIndex": "0x1", - "blockHash": "0xb7b43f46d6ee34eaaad5ab38807b451e0e85bacbe59893afc625550aa7c65262", - "logIndex": "0x0", - "removed": "false" + "transactionIndex": "0x1" } ], + "logsBloom": "0x00000000000000000000400000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000020000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000", + "root": "0x", + "status": "0x1", "transactionHash": "0x3059d7dbc2df8a05442e50ea529419277c2f45582534f452d2d5676d93273c7d", - "contractAddress": "0x0000000000000000000000000000000000000000", - "gasUsed": "0x10bf2", - "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "transactionIndex": "0x1" } ], - "currentDifficulty": null, - "gasUsed": "0x24f10", - "currentBaseFee": "0x7", - "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "currentExcessBlobGas": "0x0", - "blobGasUsed": "0x0", - "requestsRoot": "0xfba41d6600776bec2258a06e4bc00a34f7a2a1bc0aa802976d038ef4e3379d29", - "depositRequests": [ - { - "pubkey": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", - "withdrawalCredentials": "0x0000000000000000000000000000000000000000000000000000000000000002", - "amount": "0x0000000773594000", - "signature": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003", - "index": "0x0000000000000000" - }, - { - "pubkey": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", - "withdrawalCredentials": "0x0000000000000000000000000000000000000000000000000000000000000002", - "amount": "0x0000000773594000", - "signature": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003", - "index": "0x0000000000000001" - } + "receiptsRoot": "0x9c8d7a917ecb3ff2566f264abbf39131e51b08b07eb2b69cb46989d79d985593", + "requests": [ + "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200405973070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200405973070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030100000000000000", + "0x", + "0x" ], - "withdrawalRequests": [], - "consolidationRequests":[] + "requestsHash": "0x158ac6beda33cd9341831552555f64c95e074e7024f6c4553c1ed7557077b4c7", + "stateRoot": "0x3aa7839837ee1564276a0a05554e35215353a97c4e255c3aacbcd7c7819daefa", + "txRoot": "0x2b790bf82ef7259a0e4513d1b89a77d81e99672ba68758ef2ba3fde32851d023", + "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" } } } \ No newline at end of file diff --git a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/t8n/prague-withdrawal.json b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/t8n/prague-withdrawal.json index 148c7a23e3..35f9843231 100644 --- a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/t8n/prague-withdrawal.json +++ b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/t8n/prague-withdrawal.json @@ -51,23 +51,29 @@ "0x40": "0x985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7" } }, - "0x00a3ca265ebcb825b45f985a16cefb49958ce017": { + "0x09fc772d0857550724b07b850a4323f39112aaaa": { "nonce": "0x01", "balance": "0x00", - "code": "0x3373fffffffffffffffffffffffffffffffffffffffe146090573615156028575f545f5260205ff35b366038141561012e5760115f54600182026001905f5b5f82111560595781019083028483029004916001019190603e565b90939004341061012e57600154600101600155600354806003026004013381556001015f3581556001016020359055600101600355005b6003546002548082038060101160a4575060105b5f5b81811460dd5780604c02838201600302600401805490600101805490600101549160601b83528260140152906034015260010160a6565b910180921460ed579060025560f8565b90505f6002555f6003555b5f548061049d141561010757505f5b60015460028282011161011c5750505f610122565b01600290035b5f555f600155604c025ff35b5f5ffd", - "storage": { - } + "code": "0x3373fffffffffffffffffffffffffffffffffffffffe1460c7573615156028575f545f5260205ff35b36603814156101f05760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff146101f057600182026001905f5b5f821115608057810190830284830290049160010191906065565b9093900434106101f057600154600101600155600354806003026004013381556001015f35815560010160203590553360601b5f5260385f601437604c5fa0600101600355005b6003546002548082038060101160db575060105b5f5b81811461017f5780604c02838201600302600401805490600101805490600101549160601b83528260140152807fffffffffffffffffffffffffffffffff0000000000000000000000000000000016826034015260401c906044018160381c81600701538160301c81600601538160281c81600501538160201c81600401538160181c81600301538160101c81600201538160081c81600101535360010160dd565b9101809214610191579060025561019c565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14156101c957505f5b6001546002828201116101de5750505f6101e4565b01600290035b5f555f600155604c025ff35b5f5ffd", + "storage": {} }, - "0x000f3df6d732807ef1319fb7b8bb8522d0beac02": { + "0x01abea29659e5e97c95107f20bb753cd3e09bbbb": { "nonce": "0x01", "balance": "0x00", - "code": "0x3373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500", + "code": "0x3373fffffffffffffffffffffffffffffffffffffffe1460cf573615156028575f545f5260205ff35b366060141561019a5760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1461019a57600182026001905f5b5f821115608057810190830284830290049160010191906065565b90939004341061019a57600154600101600155600354806004026004013381556001015f358155600101602035815560010160403590553360601b5f5260605f60143760745fa0600101600355005b6003546002548082038060011160e3575060015b5f5b8181146101295780607402838201600402600401805490600101805490600101805490600101549260601b84529083601401528260340152906054015260010160e5565b910180921461013b5790600255610146565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff141561017357505f5b6001546001828201116101885750505f61018e565b01600190035b5f555f6001556074025ff35b5f5ffd", "storage": {} }, "0x0aae40965e6800cd9b1f4b05ff21581047e3f91e": { + "nonce": "0x01", + "balance": "0x00", "code": "0x3373fffffffffffffffffffffffffffffffffffffffe1460575767ffffffffffffffff5f3511605357600143035f3511604b575f35612000014311604b57611fff5f3516545f5260205ff35b5f5f5260205ff35b5f5ffd5b5f35611fff60014303165500", - "balance": "0x0", - "nonce": "0x1" + "storage": {} + }, + "0x000f3df6d732807ef1319fb7b8bb8522d0beac02": { + "nonce": "0x01", + "balance": "0x00", + "code": "0x3373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500", + "storage": {} }, "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": { "nonce": "0x00", @@ -75,10 +81,10 @@ "code": "0x", "storage": {} }, - "0x0000000000000000000000000000000000000200": { + "0x0000000000000000000000000000000000001000": { "nonce": "0x01", "balance": "0xad78ebc5ac62000000", - "code": "0x60386000600037600060006038600060017300a3ca265ebcb825b45f985a16cefb49958ce017620f4240f15060386038600037600060006038600060017300a3ca265ebcb825b45f985a16cefb49958ce017620f4240f15060386070600037600060006038600060017300a3ca265ebcb825b45f985a16cefb49958ce017620f4240f150603860a8600037600060006038600060017300a3ca265ebcb825b45f985a16cefb49958ce017620f4240f150603860e0600037600060006038600060017300a3ca265ebcb825b45f985a16cefb49958ce017620f4240f1506038610118600037600060006038600060017300a3ca265ebcb825b45f985a16cefb49958ce017620f4240f1506038610150600037600060006038600060017300a3ca265ebcb825b45f985a16cefb49958ce017620f4240f1506038610188600037600060006038600060017300a3ca265ebcb825b45f985a16cefb49958ce017620f4240f15060386101c0600037600060006038600060017300a3ca265ebcb825b45f985a16cefb49958ce017620f4240f15060386101f8600037600060006038600060017300a3ca265ebcb825b45f985a16cefb49958ce017620f4240f1506038610230600037600060006038600060017300a3ca265ebcb825b45f985a16cefb49958ce017620f4240f1506038610268600037600060006038600060017300a3ca265ebcb825b45f985a16cefb49958ce017620f4240f15060386102a0600037600060006038600060017300a3ca265ebcb825b45f985a16cefb49958ce017620f4240f15060386102d8600037600060006038600060017300a3ca265ebcb825b45f985a16cefb49958ce017620f4240f1506038610310600037600060006038600060017300a3ca265ebcb825b45f985a16cefb49958ce017620f4240f1506038610348600037600060006038600060017300a3ca265ebcb825b45f985a16cefb49958ce017620f4240f150", + "code": "0x60386000600037600060006038600060017309fc772d0857550724b07b850a4323f39112aaaa620f4240f150", "storage": {} } }, @@ -89,12 +95,12 @@ "nonce": "0x0", "gasPrice": "0x7", "gas": "0xf4240", - "to": "0x0000000000000000000000000000000000000200", + "to": "0x0000000000000000000000000000000000001000", "value": "0x0", - "input": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001fffffffffffffffe0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fffffffffffffffe0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005fffffffffffffffe0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007fffffffffffffffe0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009fffffffffffffffe00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bfffffffffffffffe00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000dfffffffffffffffe00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffe0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000", + "input": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000", "v": "0x26", - "r": "0x963cb6620fe5828cbc93bb7139d3f4501067d76275dff648bf48c3c100ca8dd4", - "s": "0x4ac396104a5be4643406718f59a6e74d62a32777f5f6135e55e805e87612013c", + "r": "0xd050db98a60dbe4bbbc6ce154c607f28f1cf803a8882f369b28a5eb4ef1a600f", + "s": "0x7512ca5133bcb887a41f6136cd645839c1bcf0f300325948387a70f3ad9ced1c", "sender": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b" } ], @@ -124,9 +130,9 @@ }, "stdout": { "alloc": { - "0x0000000000000000000000000000000000000200": { - "code": "0x60386000600037600060006038600060017300a3ca265ebcb825b45f985a16cefb49958ce017620f4240f15060386038600037600060006038600060017300a3ca265ebcb825b45f985a16cefb49958ce017620f4240f15060386070600037600060006038600060017300a3ca265ebcb825b45f985a16cefb49958ce017620f4240f150603860a8600037600060006038600060017300a3ca265ebcb825b45f985a16cefb49958ce017620f4240f150603860e0600037600060006038600060017300a3ca265ebcb825b45f985a16cefb49958ce017620f4240f1506038610118600037600060006038600060017300a3ca265ebcb825b45f985a16cefb49958ce017620f4240f1506038610150600037600060006038600060017300a3ca265ebcb825b45f985a16cefb49958ce017620f4240f1506038610188600037600060006038600060017300a3ca265ebcb825b45f985a16cefb49958ce017620f4240f15060386101c0600037600060006038600060017300a3ca265ebcb825b45f985a16cefb49958ce017620f4240f15060386101f8600037600060006038600060017300a3ca265ebcb825b45f985a16cefb49958ce017620f4240f1506038610230600037600060006038600060017300a3ca265ebcb825b45f985a16cefb49958ce017620f4240f1506038610268600037600060006038600060017300a3ca265ebcb825b45f985a16cefb49958ce017620f4240f15060386102a0600037600060006038600060017300a3ca265ebcb825b45f985a16cefb49958ce017620f4240f15060386102d8600037600060006038600060017300a3ca265ebcb825b45f985a16cefb49958ce017620f4240f1506038610310600037600060006038600060017300a3ca265ebcb825b45f985a16cefb49958ce017620f4240f1506038610348600037600060006038600060017300a3ca265ebcb825b45f985a16cefb49958ce017620f4240f150", - "balance": "0xad78ebc5ac61fffff0", + "0x0000000000000000000000000000000000001000": { + "code": "0x60386000600037600060006038600060017309fc772d0857550724b07b850a4323f39112aaaa620f4240f150", + "balance": "0xad78ebc5ac61ffffff", "nonce": "0x1" }, "0x00000000219ab540356cbb839cbe05303d7705fa": { @@ -175,44 +181,18 @@ "balance": "0x0", "nonce": "0x1" }, - "0x00a3ca265ebcb825b45f985a16cefb49958ce017": { - "code": "0x3373fffffffffffffffffffffffffffffffffffffffe146090573615156028575f545f5260205ff35b366038141561012e5760115f54600182026001905f5b5f82111560595781019083028483029004916001019190603e565b90939004341061012e57600154600101600155600354806003026004013381556001015f3581556001016020359055600101600355005b6003546002548082038060101160a4575060105b5f5b81811460dd5780604c02838201600302600401805490600101805490600101549160601b83528260140152906034015260010160a6565b910180921460ed579060025560f8565b90505f6002555f6003555b5f548061049d141561010757505f5b60015460028282011161011c5750505f610122565b01600290035b5f555f600155604c025ff35b5f5ffd", + "0x01abea29659e5e97c95107f20bb753cd3e09bbbb": { + "code": "0x3373fffffffffffffffffffffffffffffffffffffffe1460cf573615156028575f545f5260205ff35b366060141561019a5760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1461019a57600182026001905f5b5f821115608057810190830284830290049160010191906065565b90939004341061019a57600154600101600155600354806004026004013381556001015f358155600101602035815560010160403590553360601b5f5260605f60143760745fa0600101600355005b6003546002548082038060011160e3575060015b5f5b8181146101295780607402838201600402600401805490600101805490600101805490600101549260601b84529083601401528260340152906054015260010160e5565b910180921461013b5790600255610146565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff141561017357505f5b6001546001828201116101885750505f61018e565b01600190035b5f555f6001556074025ff35b5f5ffd", + "balance": "0x0", + "nonce": "0x1" + }, + "0x09fc772d0857550724b07b850a4323f39112aaaa": { + "code": "0x3373fffffffffffffffffffffffffffffffffffffffe1460c7573615156028575f545f5260205ff35b36603814156101f05760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff146101f057600182026001905f5b5f821115608057810190830284830290049160010191906065565b9093900434106101f057600154600101600155600354806003026004013381556001015f35815560010160203590553360601b5f5260385f601437604c5fa0600101600355005b6003546002548082038060101160db575060105b5f5b81811461017f5780604c02838201600302600401805490600101805490600101549160601b83528260140152807fffffffffffffffffffffffffffffffff0000000000000000000000000000000016826034015260401c906044018160381c81600701538160301c81600601538160281c81600501538160201c81600401538160181c81600301538160101c81600201538160081c81600101535360010160dd565b9101809214610191579060025561019c565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14156101c957505f5b6001546002828201116101de5750505f6101e4565b01600290035b5f555f600155604c025ff35b5f5ffd", "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000000000000000000000000000000000000000000e", - "0x0000000000000000000000000000000000000000000000000000000000000004": "0x0000000000000000000000000000000000000000000000000000000000000200", - "0x0000000000000000000000000000000000000000000000000000000000000006": "0x00000000000000000000000000000001fffffffffffffffe0000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000007": "0x0000000000000000000000000000000000000000000000000000000000000200", - "0x0000000000000000000000000000000000000000000000000000000000000009": "0x0000000000000000000000000000000200000000000000000000000000000000", - "0x000000000000000000000000000000000000000000000000000000000000000a": "0x0000000000000000000000000000000000000000000000000000000000000200", - "0x000000000000000000000000000000000000000000000000000000000000000c": "0x00000000000000000000000000000003fffffffffffffffe0000000000000000", - "0x000000000000000000000000000000000000000000000000000000000000000d": "0x0000000000000000000000000000000000000000000000000000000000000200", - "0x000000000000000000000000000000000000000000000000000000000000000f": "0x0000000000000000000000000000000400000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000010": "0x0000000000000000000000000000000000000000000000000000000000000200", - "0x0000000000000000000000000000000000000000000000000000000000000012": "0x00000000000000000000000000000005fffffffffffffffe0000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000013": "0x0000000000000000000000000000000000000000000000000000000000000200", - "0x0000000000000000000000000000000000000000000000000000000000000015": "0x0000000000000000000000000000000600000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000016": "0x0000000000000000000000000000000000000000000000000000000000000200", - "0x0000000000000000000000000000000000000000000000000000000000000018": "0x00000000000000000000000000000007fffffffffffffffe0000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000019": "0x0000000000000000000000000000000000000000000000000000000000000200", - "0x000000000000000000000000000000000000000000000000000000000000001b": "0x0000000000000000000000000000000800000000000000000000000000000000", - "0x000000000000000000000000000000000000000000000000000000000000001c": "0x0000000000000000000000000000000000000000000000000000000000000200", - "0x000000000000000000000000000000000000000000000000000000000000001e": "0x00000000000000000000000000000009fffffffffffffffe0000000000000000", - "0x000000000000000000000000000000000000000000000000000000000000001f": "0x0000000000000000000000000000000000000000000000000000000000000200", - "0x0000000000000000000000000000000000000000000000000000000000000021": "0x0000000000000000000000000000000a00000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000022": "0x0000000000000000000000000000000000000000000000000000000000000200", - "0x0000000000000000000000000000000000000000000000000000000000000024": "0x0000000000000000000000000000000bfffffffffffffffe0000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000025": "0x0000000000000000000000000000000000000000000000000000000000000200", - "0x0000000000000000000000000000000000000000000000000000000000000027": "0x0000000000000000000000000000000c00000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000028": "0x0000000000000000000000000000000000000000000000000000000000000200", - "0x000000000000000000000000000000000000000000000000000000000000002a": "0x0000000000000000000000000000000dfffffffffffffffe0000000000000000", - "0x000000000000000000000000000000000000000000000000000000000000002b": "0x0000000000000000000000000000000000000000000000000000000000000200", - "0x000000000000000000000000000000000000000000000000000000000000002d": "0x0000000000000000000000000000000e00000000000000000000000000000000", - "0x000000000000000000000000000000000000000000000000000000000000002e": "0x0000000000000000000000000000000000000000000000000000000000000200", - "0x0000000000000000000000000000000000000000000000000000000000000030": "0x0000000000000000000000000000000ffffffffffffffffe0000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000031": "0x0000000000000000000000000000000000000000000000000000000000000200", - "0x0000000000000000000000000000000000000000000000000000000000000033": "0x0000000000000000000000000000001000000000000000000000000000000000" + "0x0000000000000000000000000000000000000000000000000000000000000004": "0x0000000000000000000000000000000000000000000000000000000000001000", + "0x0000000000000000000000000000000000000000000000000000000000000006": "0x0000000000000000000000000000000100000000000000000000000000000000" }, - "balance": "0x10", + "balance": "0x1", "nonce": "0x1" }, "0x0aae40965e6800cd9b1f4b05ff21581047e3f91e": { @@ -224,118 +204,51 @@ "nonce": "0x1" }, "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": { - "balance": "0xad78ebc5ac619bbcea", + "balance": "0xad78ebc5ac61f2afcb", "nonce": "0x1" } }, - "body": "0xf903e5f903e28007830f424094000000000000000000000000000000000000020080b90380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001fffffffffffffffe0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fffffffffffffffe0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005fffffffffffffffe0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007fffffffffffffffe0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009fffffffffffffffe00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bfffffffffffffffe00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000dfffffffffffffffe00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffe000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000026a0963cb6620fe5828cbc93bb7139d3f4501067d76275dff648bf48c3c100ca8dd4a04ac396104a5be4643406718f59a6e74d62a32777f5f6135e55e805e87612013c", + "body": "0xf89bf8998007830f424094000000000000000000000000000000000000100080b838000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000026a0d050db98a60dbe4bbbc6ce154c607f28f1cf803a8882f369b28a5eb4ef1a600fa07512ca5133bcb887a41f6136cd645839c1bcf0f300325948387a70f3ad9ced1c", "result": { - "requestsRoot": "0x415d33e444f917658fd3bd6d3d8d88a1f501f9b83ace92ddacac823252c9fa47", - "depositRequests": [], - "withdrawalRequests": [ - { - "sourceAddress": "0x0000000000000000000000000000000000000200", - "validatorPubkey": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", - "amount": "0xfffffffffffffffe" - }, - { - "sourceAddress": "0x0000000000000000000000000000000000000200", - "validatorPubkey": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002", - "amount": "0x0000000000000000" - }, - { - "sourceAddress": "0x0000000000000000000000000000000000000200", - "validatorPubkey": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003", - "amount": "0xfffffffffffffffe" - }, - { - "sourceAddress": "0x0000000000000000000000000000000000000200", - "validatorPubkey": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004", - "amount": "0x0000000000000000" - }, - { - "sourceAddress": "0x0000000000000000000000000000000000000200", - "validatorPubkey": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005", - "amount": "0xfffffffffffffffe" - }, - { - "sourceAddress": "0x0000000000000000000000000000000000000200", - "validatorPubkey": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006", - "amount": "0x0000000000000000" - }, - { - "sourceAddress": "0x0000000000000000000000000000000000000200", - "validatorPubkey": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007", - "amount": "0xfffffffffffffffe" - }, - { - "sourceAddress": "0x0000000000000000000000000000000000000200", - "validatorPubkey": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008", - "amount": "0x0000000000000000" - }, - { - "sourceAddress": "0x0000000000000000000000000000000000000200", - "validatorPubkey": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009", - "amount": "0xfffffffffffffffe" - }, - { - "sourceAddress": "0x0000000000000000000000000000000000000200", - "validatorPubkey": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a", - "amount": "0x0000000000000000" - }, - { - "sourceAddress": "0x0000000000000000000000000000000000000200", - "validatorPubkey": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b", - "amount": "0xfffffffffffffffe" - }, - { - "sourceAddress": "0x0000000000000000000000000000000000000200", - "validatorPubkey": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c", - "amount": "0x0000000000000000" - }, - { - "sourceAddress": "0x0000000000000000000000000000000000000200", - "validatorPubkey": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d", - "amount": "0xfffffffffffffffe" - }, - { - "sourceAddress": "0x0000000000000000000000000000000000000200", - "validatorPubkey": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e", - "amount": "0x0000000000000000" - }, - { - "sourceAddress": "0x0000000000000000000000000000000000000200", - "validatorPubkey": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f", - "amount": "0xfffffffffffffffe" - }, - { - "sourceAddress": "0x0000000000000000000000000000000000000200", - "validatorPubkey": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010", - "amount": "0x0000000000000000" - } + "requestsHash": "0xab205d558af6253557180e19e89356ed4c7d4b13615ee9560840af3df75ddb12", + "requests": [ + "0x", + "0x00000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000", + "0x" ], - "consolidationRequests":[], - "stateRoot": "0xf63d7552dc407993393315e99272781d04eedfcf369a1acd3e386d1e6710229d", - "txRoot": "0x8521df63211790726b6f1a437bb0fd4b27c00e13e7678d324c4cfddb8d834ad2", - "receiptsRoot": "0x4bd8bd5580caf4ed45f873794ad7ff9d6fd2363ae529269b17b891b68d349d75", - "logsHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x23d988164325beeeea1044c9f104ff4fe108038369f26a3327198ce40f827430", + "txRoot": "0x0d36638e52999b7beafa00eb94f7ca23139774cd14229c011d0edc1fc66125c9", + "receiptsRoot": "0x3d22e243cbebced1fafba149bce09285797af6c66ce901ff3ab1caf073fca791", + "logsHash": "0xf69b003be75aaafefa35aa30e6367f732dd9b31a6c97196febc285ee9289bb60", + "logsBloom": "0x00000000000000000000000008000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "receipts": [ { "root": "0x", "status": "0x1", - "cumulativeGasUsed": "0xe52ba", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "logs": null, - "transactionHash": "0x04a2d3f252dcc98edb684f7f15b572aaf980d0c2eea4c620a9f1ff1d275b2207", + "cumulativeGasUsed": "0x1e6e3", + "logsBloom": "0x00000000000000000000000008000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "logs": [ + { + "address": "0x09fc772d0857550724b07b850a4323f39112aaaa", + "topics": [], + "data": "0x00000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000", + "blockNumber": 1, + "transactionHash": "0xa888ec4587b7ba70d0127004a96fbb0a83ccb611e61405094e6514b970bf37f6", + "transactionIndex": "0x0", + "blockHash": "0xb7b43f46d6ee34eaaad5ab38807b451e0e85bacbe59893afc625550aa7c65262", + "logIndex": "0x0", + "removed": "false" + } + ], + "transactionHash": "0xa888ec4587b7ba70d0127004a96fbb0a83ccb611e61405094e6514b970bf37f6", "contractAddress": "0x0000000000000000000000000000000000000000", - "gasUsed": "0xe52ba", + "gasUsed": "0x1e6e3", "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "transactionIndex": "0x0" } ], "currentDifficulty": null, - "gasUsed": "0xe52ba", + "gasUsed": "0x1e6e3", "currentBaseFee": "0x7", "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "currentExcessBlobGas": "0x0", diff --git a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/create-eof-error.json b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/create-eof-error.json index cd4c3fa14a..0b1396f261 100644 --- a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/create-eof-error.json +++ b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/create-eof-error.json @@ -8,7 +8,7 @@ "--coinbase", "4444588443C3A91288C5002483449ABA1054192B", "--fork", - "CancunEOF" + "Osaka" ], "stdin": "", "stdout": "EOF Code Invalid : incompatible_container_kind opcode STOP is only valid for runtime.\n" diff --git a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/create-eof.json b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/create-eof.json index 1fa459916b..6740c86719 100644 --- a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/create-eof.json +++ b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/create-eof.json @@ -8,7 +8,7 @@ "--coinbase", "4444588443C3A91288C5002483449ABA1054192B", "--fork", - "CancunEOF" + "Osaka" ], "stdin": "", "stdout": [ @@ -20,6 +20,6 @@ {"pc":5,"section":0,"op":95,"gas":"0x2540be109","gasCost":"0x2","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"PUSH0"}, {"pc":6,"section":0,"op":95,"gas":"0x2540be107","gasCost":"0x2","memSize":0,"stack":["0x0"],"depth":1,"refund":0,"opName":"PUSH0"}, {"pc":7,"section":0,"op":238,"immediate":"0x00","gas":"0x2540be105","gasCost":"0x0","memSize":0,"stack":["0x0","0x0"],"depth":1,"refund":0,"opName":"RETURNCONTRACT"}, - {"stateRoot":"0x9790b070a5749acec6a7252a867f795df3c2cb5b800fb509ea259a1c0b5d96c1","output":"0x","gasUsed":"0x129b","pass":true,"fork":"CancunEOF"} + {"stateRoot":"0x9790b070a5749acec6a7252a867f795df3c2cb5b800fb509ea259a1c0b5d96c1","output":"0x","gasUsed":"0x129b","pass":true,"fork":"Osaka"} ] } \ No newline at end of file diff --git a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/eof-section.json b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/eof-section.json index 439c69195a..f25557fa7e 100644 --- a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/eof-section.json +++ b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/eof-section.json @@ -7,17 +7,17 @@ "--coinbase", "4444588443C3A91288C5002483449ABA1054192B", "--fork", - "PragueEOF" + "Osaka" ], "stdin": "", "stdout": [ {"pc":0,"section":0,"op":227,"immediate":"0x0002","gas":"0x2540be400","gasCost":"0x5","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"CALLF"}, - {"pc":0,"section":2,"op":229,"immediate":"0x0002","gas":"0x2540be3fb","gasCost":"0x5","memSize":0,"stack":[],"depth":1,"functionDepth":1,"refund":0,"opName":"JUMPF"}, - {"pc":0,"section":1,"op":228,"gas":"0x2540be3f6","gasCost":"0x3","memSize":0,"stack":[],"depth":1,"functionDepth":1,"refund":0,"opName":"RETF"}, + {"pc":11,"section":2,"op":229,"immediate":"0x0001","gas":"0x2540be3fb","gasCost":"0x5","memSize":0,"stack":[],"depth":1,"functionDepth":1,"refund":0,"opName":"JUMPF"}, + {"pc":10,"section":1,"op":228,"gas":"0x2540be3f6","gasCost":"0x3","memSize":0,"stack":[],"depth":1,"functionDepth":1,"refund":0,"opName":"RETF"}, {"pc":3,"section":0,"op":97,"immediate":"0x2015","gas":"0x2540be3f3","gasCost":"0x3","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"PUSH2"}, {"pc":6,"section":0,"op":96,"immediate":"0x01","gas":"0x2540be3f0","gasCost":"0x3","memSize":0,"stack":["0x2015"],"depth":1,"refund":0,"opName":"PUSH1"}, {"pc":8,"section":0,"op":85,"gas":"0x2540be3ed","gasCost":"0x5654","memSize":0,"stack":["0x2015","0x1"],"depth":1,"refund":0,"opName":"SSTORE"}, {"pc":9,"section":0,"op":0,"gas":"0x2540b8d99","gasCost":"0x0","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"STOP"}, - {"stateRoot":"0x761f723ceabb467d438fe74abf025c10bf65592b84ec389850038eb572f2b0fa","output":"0x","gasUsed":"0x5667","pass":true,"fork":"PragueEOF"} + {"stateRoot":"0x761f723ceabb467d438fe74abf025c10bf65592b84ec389850038eb572f2b0fa","output":"0x","gasUsed":"0x5667","pass":true,"fork":"Osaka"} ] } \ No newline at end of file diff --git a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/eof.json b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/eof.json index c9553c9209..ddce2bf2af 100644 --- a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/eof.json +++ b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/eof.json @@ -7,11 +7,11 @@ "--coinbase", "4444588443C3A91288C5002483449ABA1054192B", "--fork", - "PragueEOF" + "Osaka" ], "stdin": "", "stdout": [ {"pc":0,"section":0,"op":0,"gas":"0x2540be400","gasCost":"0x0","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"STOP"}, - {"stateRoot":"0xdae5f2c233bf9fbb7413d06ce744a3345dbf971b5bb5638736c0388f43a61a4b","output":"0x","gasUsed":"0x0","pass":true,"fork":"PragueEOF"} + {"stateRoot":"0xdae5f2c233bf9fbb7413d06ce744a3345dbf971b5bb5638736c0388f43a61a4b","output":"0x","gasUsed":"0x0","pass":true,"fork":"Osaka"} ] } \ No newline at end of file diff --git a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/initcode-error.json b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/initcode-error.json index b88134778e..4225259fa4 100644 --- a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/initcode-error.json +++ b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/initcode-error.json @@ -7,7 +7,7 @@ "--coinbase", "4444588443C3A91288C5002483449ABA1054192B", "--fork", - "CancunEOF" + "Osaka" ], "stdin": "", "stdout": "To evaluate INITCODE mode EOF code use the --create flag\n" diff --git a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/revert.json b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/revert.json index 4798d5da70..32ee526fdd 100644 --- a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/revert.json +++ b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/revert.json @@ -12,7 +12,7 @@ {"pc":7,"op":82,"gas":"0x2540be3fa","gasCost":"0x6","memSize":0,"stack":["0x4e6f7065","0x0"],"depth":1,"refund":0,"opName":"MSTORE"}, {"pc":8,"op":96,"gas":"0x2540be3f4","gasCost":"0x3","memSize":32,"stack":[],"depth":1,"refund":0,"opName":"PUSH1"}, {"pc":10,"op":96,"gas":"0x2540be3f1","gasCost":"0x3","memSize":32,"stack":["0x4"],"depth":1,"refund":0,"opName":"PUSH1"}, - {"pc":12,"op":253,"gas":"0x2540be3ee","gasCost":"0x0","memSize":32,"stack":["0x4","0x1c"],"depth":1,"refund":0,"opName":"REVERT","error":"Nope"}, + {"pc":12,"op":253,"gas":"0x2540be3ee","gasCost":"0x0","memSize":32,"stack":["0x4","0x1c"],"depth":1,"refund":0,"opName":"REVERT","error":"0x4e6f7065"}, {"stateRoot":"0x405bbd98da2aca6dff77f79e0b270270c48d6a3e07b76db675b20e454b50bbcb","output":"0x4e6f7065","gasUsed":"0x12","pass":true,"fork":"Cancun"} ] } \ No newline at end of file diff --git a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/P2PDiscoveryConfiguration.java b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/P2PDiscoveryConfiguration.java new file mode 100644 index 0000000000..721a3100a0 --- /dev/null +++ b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/P2PDiscoveryConfiguration.java @@ -0,0 +1,39 @@ +/* + * 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.p2p.discovery; + +import org.hyperledger.besu.util.number.Percentage; + +import java.util.Collection; +import java.util.List; + +import org.apache.commons.net.util.SubnetUtils; +import org.apache.tuweni.bytes.Bytes; + +public record P2PDiscoveryConfiguration( + Boolean p2pEnabled, + Boolean peerDiscoveryEnabled, + String p2pHost, + String p2pInterface, + Integer p2pPort, + Integer maxPeers, + Boolean isLimitRemoteWireConnectionsEnabled, + Percentage maxRemoteConnectionsPercentage, + Boolean randomPeerPriority, + Collection bannedNodeIds, + List allowedSubnets, + Boolean poaDiscoveryRetryBootnodes, + List bootNodes, + String discoveryDnsUrl) {} diff --git a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/internal/PeerTable.java b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/internal/PeerTable.java index 9f58ab1af9..33bbed0f09 100644 --- a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/internal/PeerTable.java +++ b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/internal/PeerTable.java @@ -26,16 +26,17 @@ import org.hyperledger.besu.ethereum.p2p.peers.Peer; import org.hyperledger.besu.ethereum.p2p.peers.PeerId; import java.util.Arrays; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ForkJoinPool; +import java.util.concurrent.TimeUnit; import java.util.stream.Stream; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; import com.google.common.hash.BloomFilter; -import org.apache.commons.collections4.queue.CircularFifoQueue; import org.apache.tuweni.bytes.Bytes; /** @@ -54,10 +55,7 @@ public class PeerTable { private final Map distanceCache; private BloomFilter idBloom; private int evictionCnt = 0; - private final LinkedHashMapWithMaximumSize ipAddressCheckMap = - new LinkedHashMapWithMaximumSize<>(DEFAULT_BUCKET_SIZE * N_BUCKETS); - private final CircularFifoQueue invalidIPs = - new CircularFifoQueue<>(DEFAULT_BUCKET_SIZE * N_BUCKETS); + private final Cache unresponsiveIPs; /** * Builds a new peer table, where distance is calculated using the provided nodeId as a baseline. @@ -72,6 +70,11 @@ public class PeerTable { .toArray(Bucket[]::new); this.distanceCache = new ConcurrentHashMap<>(); this.maxEntriesCnt = N_BUCKETS * DEFAULT_BUCKET_SIZE; + this.unresponsiveIPs = + CacheBuilder.newBuilder() + .maximumSize(maxEntriesCnt) + .expireAfterWrite(15L, TimeUnit.MINUTES) + .build(); // A bloom filter with 4096 expected insertions of 64-byte keys with a 0.1% false positive // probability yields a memory footprint of ~7.5kb. @@ -140,7 +143,6 @@ public class PeerTable { if (!res.isPresent()) { idBloom.put(id); distanceCache.put(id, distance); - ipAddressCheckMap.put(getKey(peer.getEndpoint()), peer.getEndpoint().getUdpPort()); return AddResult.added(); } @@ -214,26 +216,12 @@ public class PeerTable { public boolean isIpAddressInvalid(final Endpoint endpoint) { final String key = getKey(endpoint); - if (invalidIPs.contains(key)) { - return true; - } - if (ipAddressCheckMap.containsKey(key) && ipAddressCheckMap.get(key) != endpoint.getUdpPort()) { - // This peer has multiple discovery services on the same IP address + TCP port. - invalidIPs.add(key); - for (final Bucket bucket : table) { - bucket.getPeers().stream() - .filter(p -> p.getEndpoint().getHost().equals(endpoint.getHost())) - .forEach(bucket::evict); - } - return true; - } else { - return false; - } + return unresponsiveIPs.getIfPresent(key) != null; } public void invalidateIP(final Endpoint endpoint) { final String key = getKey(endpoint); - invalidIPs.add(key); + unresponsiveIPs.put(key, Integer.MAX_VALUE); } private static String getKey(final Endpoint endpoint) { @@ -313,20 +301,6 @@ public class PeerTable { } } - private static class LinkedHashMapWithMaximumSize extends LinkedHashMap { - private final int maxSize; - - public LinkedHashMapWithMaximumSize(final int maxSize) { - super(maxSize, 0.75f, false); - this.maxSize = maxSize; - } - - @Override - protected boolean removeEldestEntry(final Map.Entry eldest) { - return size() > maxSize; - } - } - static class EvictResult { public enum EvictOutcome { EVICTED, diff --git a/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/discovery/internal/PeerTableTest.java b/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/discovery/internal/PeerTableTest.java index 331711a07f..5d2fc4a43a 100644 --- a/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/discovery/internal/PeerTableTest.java +++ b/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/discovery/internal/PeerTableTest.java @@ -188,15 +188,12 @@ public class PeerTableTest { @Test public void ipAddressIsInvalidReturnsTrue() { final Endpoint endpoint1 = new Endpoint("1.1.1.1", 2, Optional.of(Integer.valueOf(1))); - final Endpoint endpoint2 = new Endpoint("1.1.1.1", 3, Optional.of(Integer.valueOf(1))); final DiscoveryPeer peer1 = DiscoveryPeer.fromIdAndEndpoint(Peer.randomId(), endpoint1); - final DiscoveryPeer peer2 = DiscoveryPeer.fromIdAndEndpoint(Peer.randomId(), endpoint2); final PeerTable table = new PeerTable(Bytes.random(64)); - final PeerTable.AddResult addResult1 = table.tryAdd(peer1); - assertThat(addResult1.getOutcome()).isEqualTo(PeerTable.AddResult.added().getOutcome()); + table.invalidateIP(endpoint1); - assertThat(table.isIpAddressInvalid(peer2.getEndpoint())).isEqualTo(true); + assertThat(table.isIpAddressInvalid(peer1.getEndpoint())).isEqualTo(true); } @Test @@ -216,16 +213,12 @@ public class PeerTableTest { @Test public void invalidIPAddressNotAdded() { final Endpoint endpoint1 = new Endpoint("1.1.1.1", 2, Optional.of(Integer.valueOf(1))); - final Endpoint endpoint2 = new Endpoint("1.1.1.1", 3, Optional.of(Integer.valueOf(1))); final DiscoveryPeer peer1 = DiscoveryPeer.fromIdAndEndpoint(Peer.randomId(), endpoint1); - final DiscoveryPeer peer2 = DiscoveryPeer.fromIdAndEndpoint(Peer.randomId(), endpoint2); final PeerTable table = new PeerTable(Bytes.random(64)); + table.invalidateIP(endpoint1); final PeerTable.AddResult addResult1 = table.tryAdd(peer1); - assertThat(addResult1.getOutcome()).isEqualTo(PeerTable.AddResult.added().getOutcome()); - - final PeerTable.AddResult addResult2 = table.tryAdd(peer2); - assertThat(addResult2.getOutcome()).isEqualTo(PeerTable.AddResult.invalid().getOutcome()); + assertThat(addResult1.getOutcome()).isEqualTo(PeerTable.AddResult.invalid().getOutcome()); } @Test diff --git a/ethereum/referencetests/build.gradle b/ethereum/referencetests/build.gradle index b941194c8c..d8dd42cb2d 100644 --- a/ethereum/referencetests/build.gradle +++ b/ethereum/referencetests/build.gradle @@ -14,6 +14,9 @@ */ configurations { + referenceTestAnnotationProcessor.extendsFrom testAnnotationProcessor + + // we need this because referenceTestImplementation defaults to 'canBeResolved=false'. executionRefTestImplementation.extendsFrom referenceTestImplementation { canBeResolved = true canBeConsumed = false diff --git a/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/BlockchainReferenceTestCase.java b/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/BlockchainReferenceTestCase.java index 6478768960..88feb3ad83 100644 --- a/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/BlockchainReferenceTestCase.java +++ b/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/BlockchainReferenceTestCase.java @@ -40,4 +40,6 @@ public interface BlockchainReferenceTestCase { boolean isExecutable(Block candidateBlock); boolean isValid(Block candidateBlock); + + boolean areAllTransactionsValid(final Block block); } diff --git a/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/BlockchainReferenceTestCaseSpec.java b/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/BlockchainReferenceTestCaseSpec.java index a865e97f70..f97a8e9550 100644 --- a/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/BlockchainReferenceTestCaseSpec.java +++ b/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/BlockchainReferenceTestCaseSpec.java @@ -31,7 +31,6 @@ import org.hyperledger.besu.ethereum.core.Difficulty; import org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider; import org.hyperledger.besu.ethereum.core.MutableWorldState; import org.hyperledger.besu.ethereum.core.ParsedExtraData; -import org.hyperledger.besu.ethereum.core.Request; import org.hyperledger.besu.ethereum.core.Transaction; import org.hyperledger.besu.ethereum.core.Withdrawal; import org.hyperledger.besu.ethereum.mainnet.MainnetBlockHeaderFunctions; @@ -142,6 +141,15 @@ public class BlockchainReferenceTestCaseSpec implements BlockchainReferenceTestC return candidateBlock.isPresent() && candidateBlock.get().valid; } + @Override + public boolean areAllTransactionsValid(final Block block) { + Optional candidateBlock = + Arrays.stream(candidateBlocks) + .filter(cb -> Objects.equals(cb.getBlock(), block)) + .findFirst(); + return candidateBlock.isPresent() && candidateBlock.get().areAllTransactionsValid(); + } + @Override public WorldStateArchive getWorldStateArchive() { return worldStateArchive; @@ -193,7 +201,7 @@ public class BlockchainReferenceTestCaseSpec implements BlockchainReferenceTestC @JsonProperty("mixHash") final String mixHash, @JsonProperty("nonce") final String nonce, @JsonProperty("withdrawalsRoot") final String withdrawalsRoot, - @JsonProperty("requestsRoot") final String requestsRoot, + @JsonProperty("requestsHash") final String requestsHash, @JsonProperty("blobGasUsed") final String blobGasUsed, @JsonProperty("excessBlobGas") final String excessBlobGas, @JsonProperty("parentBeaconBlockRoot") final String parentBeaconBlockRoot, @@ -223,8 +231,9 @@ public class BlockchainReferenceTestCaseSpec implements BlockchainReferenceTestC blobGasUsed != null ? Long.decode(blobGasUsed) : 0, excessBlobGas != null ? BlobGas.fromHexString(excessBlobGas) : null, parentBeaconBlockRoot != null ? Bytes32.fromHexString(parentBeaconBlockRoot) : null, - requestsRoot != null ? Hash.fromHexString(requestsRoot) : null, - null, // TODO MANAGE THAT + requestsHash != null ? Hash.fromHexString(requestsHash) : null, + null, // TODO SLD EIP-7742 use targetBlobCount when reference tests are updated + null, // TODO MANAGE WITNESS FROM VERKLE new BlockHeaderFunctions() { @Override public Hash hash(final BlockHeader header) { @@ -254,14 +263,14 @@ public class BlockchainReferenceTestCaseSpec implements BlockchainReferenceTestC "expectExceptionHomestead", "expectExceptionALL", "hasBigInt", - "rlp_decoded", - "transactionSequence" + "rlp_decoded" }) public static class CandidateBlock { private final Bytes rlp; private final Boolean valid; + private final List transactionSequence; @JsonCreator public CandidateBlock( @@ -272,14 +281,15 @@ public class BlockchainReferenceTestCaseSpec implements BlockchainReferenceTestC @JsonProperty("withdrawals") final Object withdrawals, @JsonProperty("depositRequests") final Object depositRequests, @JsonProperty("withdrawalRequests") final Object withdrawalRequests, - @JsonProperty("consolidationRequests") final Object consolidationRequests) { - boolean blockVaid = true; + @JsonProperty("consolidationRequests") final Object consolidationRequests, + @JsonProperty("transactionSequence") final List transactionSequence) { + boolean blockValid = true; // The BLOCK__WrongCharAtRLP_0 test has an invalid character in its rlp string. Bytes rlpAttempt = null; try { rlpAttempt = Bytes.fromHexString(rlp); } catch (final IllegalArgumentException e) { - blockVaid = false; + blockValid = false; } this.rlp = rlpAttempt; @@ -287,10 +297,24 @@ public class BlockchainReferenceTestCaseSpec implements BlockchainReferenceTestC && transactions == null && uncleHeaders == null && withdrawals == null) { - blockVaid = false; + blockValid = false; } - this.valid = blockVaid; + this.valid = blockValid; + this.transactionSequence = transactionSequence; + } + + public boolean isValid() { + return valid; + } + + public boolean areAllTransactionsValid() { + return transactionSequence == null + || transactionSequence.stream().filter(t -> !t.valid()).count() == 0; + } + + public boolean isExecutable() { + return rlp != null; } public Block getBlock() { @@ -304,10 +328,7 @@ public class BlockchainReferenceTestCaseSpec implements BlockchainReferenceTestC input.readList(inputData -> BlockHeader.readFrom(inputData, blockHeaderFunctions)), input.isEndOfCurrentList() ? Optional.empty() - : Optional.of(input.readList(Withdrawal::readFrom)), - input.isEndOfCurrentList() - ? Optional.empty() - : Optional.of(input.readList(Request::readFrom))); + : Optional.of(input.readList(Withdrawal::readFrom))); return new Block(header, body); } } diff --git a/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/ReferenceTestEnv.java b/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/ReferenceTestEnv.java index 0b70bd6a35..6d9090b333 100644 --- a/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/ReferenceTestEnv.java +++ b/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/ReferenceTestEnv.java @@ -145,7 +145,8 @@ public class ReferenceTestEnv extends BlockHeader { currentBlobGasUsed == null ? null : Long.decode(currentBlobGasUsed), currentExcessBlobGas == null ? null : BlobGas.of(Long.decode(currentExcessBlobGas)), beaconRoot == null ? null : Bytes32.fromHexString(beaconRoot), - null, // requestsRoot + null, // requestsHash + null, // TODO SLD EIP-7742 use targetBlobCount when reference tests are updated null, // execution witnesses new MainnetBlockHeaderFunctions()); this.parentDifficulty = parentDifficulty; diff --git a/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/ReferenceTestProtocolSchedules.java b/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/ReferenceTestProtocolSchedules.java index ba17ab8ed9..1849efbe44 100644 --- a/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/ReferenceTestProtocolSchedules.java +++ b/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/ReferenceTestProtocolSchedules.java @@ -105,8 +105,15 @@ public class ReferenceTestProtocolSchedules { Map.entry( "CancunToPragueAtTime15k", createSchedule(genesisStub.clone().cancunTime(0).pragueTime(15000))), - Map.entry("Prague", createSchedule(genesisStub.clone().pragueEOFTime(0))), - Map.entry("Osaka", createSchedule(genesisStub.clone().futureEipsTime(0))), + Map.entry( + "Prague", + createSchedule( + genesisStub + .clone() + .pragueTime(0) + .osakaTime(0) // TODO remove this once osaka_devnet_0 ships + )), + Map.entry("Osaka", createSchedule(genesisStub.clone().osakaTime(0))), Map.entry("Amsterdam", createSchedule(genesisStub.clone().futureEipsTime(0))), Map.entry("Bogota", createSchedule(genesisStub.clone().futureEipsTime(0))), Map.entry("Polis", createSchedule(genesisStub.clone().futureEipsTime(0))), diff --git a/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/TransactionSequence.java b/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/TransactionSequence.java new file mode 100644 index 0000000000..95345f8268 --- /dev/null +++ b/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/TransactionSequence.java @@ -0,0 +1,22 @@ +/* + * 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.referencetests; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public record TransactionSequence( + @JsonProperty("exception") String exception, + @JsonProperty("rawBytes") String rawBytes, + @JsonProperty("valid") boolean valid) {} diff --git a/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/VerkleReferenceTestCaseSpec.java b/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/VerkleReferenceTestCaseSpec.java index 2edcfc757d..cda981f2f0 100644 --- a/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/VerkleReferenceTestCaseSpec.java +++ b/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/VerkleReferenceTestCaseSpec.java @@ -16,6 +16,7 @@ package org.hyperledger.besu.ethereum.referencetests; import static org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider.createVerkleInMemoryWorldStateArchive; +import org.apache.commons.lang3.NotImplementedException; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.Wei; @@ -167,6 +168,11 @@ public class VerkleReferenceTestCaseSpec implements BlockchainReferenceTestCase return candidateBlock.isPresent() && candidateBlock.get().valid; } + @Override + public boolean areAllTransactionsValid(final Block block) { + throw new NotImplementedException("areAllTransactionsValid not available for verkle test"); + } + @Override public String getSealEngine() { return sealEngine; @@ -220,7 +226,8 @@ public class VerkleReferenceTestCaseSpec implements BlockchainReferenceTestCase null, null, null, - null, // TODO MANAGE THAT + null, + null, new BlockHeaderFunctions() { @Override public Hash hash(final BlockHeader header) { @@ -293,15 +300,12 @@ public class VerkleReferenceTestCaseSpec implements BlockchainReferenceTestCase final MainnetBlockHeaderFunctions blockHeaderFunctions = new MainnetBlockHeaderFunctions(); final BlockHeader header = BlockHeader.readFrom(input, blockHeaderFunctions); final BlockBody body = - new BlockBody( - input.readList(Transaction::readFrom), - input.readList(inputData -> BlockHeader.readFrom(inputData, blockHeaderFunctions)), - input.isEndOfCurrentList() - ? Optional.empty() - : Optional.of(input.readList(Withdrawal::readFrom)), - input.isEndOfCurrentList() - ? Optional.empty() - : Optional.of(input.readList(Request::readFrom))); + new BlockBody( + input.readList(Transaction::readFrom), + input.readList(inputData -> BlockHeader.readFrom(inputData, blockHeaderFunctions)), + input.isEndOfCurrentList() + ? Optional.empty() + : Optional.of(input.readList(Withdrawal::readFrom))); return new Block(header, body); } } diff --git a/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/eof/EOFReferenceTestTools.java b/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/eof/EOFReferenceTestTools.java index 6a736831ff..334bb0be33 100644 --- a/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/eof/EOFReferenceTestTools.java +++ b/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/eof/EOFReferenceTestTools.java @@ -15,6 +15,7 @@ package org.hyperledger.besu.ethereum.eof; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; import java.nio.file.Path; import java.util.Arrays; @@ -33,6 +34,7 @@ import org.hyperledger.besu.ethereum.referencetests.ReferenceTestProtocolSchedul import org.hyperledger.besu.evm.Code; import org.hyperledger.besu.evm.EVM; import org.hyperledger.besu.evm.code.CodeInvalid; +import org.hyperledger.besu.evm.code.CodeV1; import org.hyperledger.besu.evm.code.EOFLayout; import org.hyperledger.besu.testutil.JsonTestParameters; @@ -41,7 +43,7 @@ public class EOFReferenceTestTools { static { final String eips = - System.getProperty("test.ethereum.eof.eips", "Prague,Osaka,Amsterdam,Bogota,Polis,Bangkok"); + System.getProperty("test.ethereum.eof.eips", "Osaka,Amsterdam,Bogota,Polis,Bangkok"); EIPS_TO_RUN = Arrays.asList(eips.split(",")); } @@ -79,6 +81,10 @@ public class EOFReferenceTestTools { if (EIPS_TO_RUN.isEmpty()) { params.ignoreAll(); } + + // EOF was moved from Prague to Osaka + params.ignore("-Prague\\["); + } private EOFReferenceTestTools() { @@ -132,28 +138,37 @@ public class EOFReferenceTestTools { } else { parsedCode = evm.getCodeUncached(code); } + if (expected.result()) { assertThat(parsedCode.isValid()) .withFailMessage( () -> "Valid code failed with " + ((CodeInvalid) parsedCode).getInvalidReason()) .isTrue(); - } else { - assertThat(parsedCode.isValid()) - .withFailMessage("Invalid code expected " + expected.exception() + " but was valid") - .isFalse(); - if (name.contains("eip7692")) { - // if the test is from EEST, validate the exception name. - assertThat(((CodeInvalid) parsedCode).getInvalidReason()) - .withFailMessage( - () -> - "Expected exception :%s actual exception: %s" - .formatted( - expected.exception(), - (parsedCode.isValid() - ? null - : ((CodeInvalid) parsedCode).getInvalidReason()))) - .containsIgnoringCase(expected.exception().replace("EOFException.", "")); + } else if (parsedCode.isValid()) { + if (parsedCode instanceof CodeV1 codeV1 + && expected.exception().contains("EOF_IncompatibleContainerKind")) { + // one last container type check + var parsedMode = codeV1.getEofLayout().containerMode().get(); + String actual = parsedMode == null ? "RUNTIME" : parsedMode.toString(); + String expectedContainerKind = containerKind == null ? "RUNTIME" : containerKind; + assertThat(actual) + .withFailMessage("EOF_IncompatibleContainerKind expected") + .isNotEqualTo(expectedContainerKind); + } else { + fail("Invalid code expected " + expected.exception() + " but was valid"); } + } else if (name.contains("eip7692")) { + // if the test is from EEST, validate the exception name. + assertThat(((CodeInvalid) parsedCode).getInvalidReason()) + .withFailMessage( + () -> + "Expected exception :%s actual exception: %s" + .formatted( + expected.exception(), + (parsedCode.isValid() + ? null + : ((CodeInvalid) parsedCode).getInvalidReason()))) + .containsIgnoringCase(expected.exception().replace("EOFException.", "")); } } else { assertThat(false) diff --git a/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/referencetests/BlockchainReferenceTestCaseSpecTest.java b/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/referencetests/BlockchainReferenceTestCaseSpecTest.java new file mode 100644 index 0000000000..07070375ad --- /dev/null +++ b/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/referencetests/BlockchainReferenceTestCaseSpecTest.java @@ -0,0 +1,312 @@ +/* + * 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.referencetests; + +import org.hyperledger.besu.ethereum.core.Block; +import org.hyperledger.besu.testutil.JsonTestParameters; + +import java.io.IOException; + +import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +class BlockchainReferenceTestCaseSpecTest { + + String jsonValid = + """ + { + "Call1MB1024Calldepth_d0g0v0_London" : { + "_info" : { + "comment" : "", + "filling-rpc-server" : "evm version 1.13.5-unstable-cd295356-20231019", + "filling-tool-version" : "retesteth-0.3.1-cancun+commit.1e18e0b3.Linux.g++", + "generatedTestHash" : "faf65f5956de8021ec3bddb63cb503e48fb2c89c8596bbc2ad793e6f3b39e1dc", + "lllcversion" : "Version: 0.5.14-develop.2023.7.11+commit.c58ab2c6.mod.Linux.g++", + "solidity" : "Version: 0.8.21+commit.d9974bed.Linux.g++", + "source" : "src/GeneralStateTestsFiller/stQuadraticComplexityTest/Call1MB1024CalldepthFiller.json", + "sourceHash" : "d88ac245b033cfc6159f6201b10b65796ba183dfe25c5f5e6d19d6f50a31daec" + }, + "blocks" : [ + { + "blockHeader" : { + "baseFeePerGas" : "0x0a", + "bloom" : "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0xb94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "difficulty" : "0x020000", + "extraData" : "0x00", + "gasLimit" : "0xcd79195900", + "gasUsed" : "0x0249f0", + "hash" : "0xfa70e84a600031d217fae4106b80155ff4af8970a97c8f9bf35efaf6929390a5", + "mixHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "nonce" : "0x0000000000000000", + "number" : "0x01", + "parentHash" : "0xefe355079be4a8cb49404abe2162ac9513c33d657d8f3cefe1ebadb91b1cd0cc", + "receiptTrie" : "0xa0e10907f175886de9bd8cd4ac2c21d1db4109a3a9fecf60f54015ee102803fd", + "stateRoot" : "0x33a1c7342e4b786c8fd736fc7d5c1b2fb3563abab428b356600e6f526de5518a", + "timestamp" : "0x03e8", + "transactionsTrie" : "0x09612e25490525613f1024d5f9a39a220234a3865309a68dee5f2f13eaac5fc1", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "rlp" : "0xf90263f901fba0efe355079be4a8cb49404abe2162ac9513c33d657d8f3cefe1ebadb91b1cd0cca01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794b94f5374fce5edbc8e2a8697c15331677e6ebf0ba033a1c7342e4b786c8fd736fc7d5c1b2fb3563abab428b356600e6f526de5518aa009612e25490525613f1024d5f9a39a220234a3865309a68dee5f2f13eaac5fc1a0a0e10907f175886de9bd8cd4ac2c21d1db4109a3a9fecf60f54015ee102803fdb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830200000185cd79195900830249f08203e800a000000000000000000000000000000000000000000000000000000000000000008800000000000000000af862f860800a830249f094bbbf5374fce5edbc8e2a8697c15331677e6ebf0b0a801ba06843bbbe573744c46cf47f1c126c11a53cffa1bcc3eeb0e0d328e6a73ecc5447a02062c2fbb34bfea606f3cf268b5a94a81d68e748d4d896c514061c03e8acb774c0", + "transactions" : [ + { + "data" : "0x", + "gasLimit" : "0x0249f0", + "gasPrice" : "0x0a", + "nonce" : "0x00", + "r" : "0x6843bbbe573744c46cf47f1c126c11a53cffa1bcc3eeb0e0d328e6a73ecc5447", + "s" : "0x2062c2fbb34bfea606f3cf268b5a94a81d68e748d4d896c514061c03e8acb774", + "sender" : "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "to" : "0xbbbf5374fce5edbc8e2a8697c15331677e6ebf0b", + "v" : "0x1b", + "value" : "0x0a" + } + ], + "uncleHeaders" : [ + ] + } + ], + "genesisBlockHeader" : { + "baseFeePerGas" : "0x0b", + "bloom" : "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0xb94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "difficulty" : "0x020000", + "extraData" : "0x00", + "gasLimit" : "0xcd79195900", + "gasUsed" : "0x00", + "hash" : "0xefe355079be4a8cb49404abe2162ac9513c33d657d8f3cefe1ebadb91b1cd0cc", + "mixHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "nonce" : "0x0000000000000000", + "number" : "0x00", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0x16d6ea0e1b8d4eb9d1bfd2a1031ea72a255d9af13a88b4cfb8253d2f756d57e1", + "timestamp" : "0x00", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "genesisRLP" : "0xf901fbf901f6a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794b94f5374fce5edbc8e2a8697c15331677e6ebf0ba016d6ea0e1b8d4eb9d1bfd2a1031ea72a255d9af13a88b4cfb8253d2f756d57e1a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830200008085cd79195900808000a000000000000000000000000000000000000000000000000000000000000000008800000000000000000bc0c0", + "lastblockhash" : "0xfa70e84a600031d217fae4106b80155ff4af8970a97c8f9bf35efaf6929390a5", + "network" : "London", + "postState" : { + "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0xffffffffffffffffffffffffffe91c9f", + "code" : "0x", + "nonce" : "0x01", + "storage" : { + } + }, + "0xaaa50000fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0fffffffffffff", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "0xb94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x1bc16d674ec80000", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "0xbbbf5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0fffffffffffff", + "code" : "0x60016000540160005561040060005410601b5760016002556047565b60006000620f42406000600073bbbf5374fce5edbc8e2a8697c15331677e6ebf0b620f55c85a03f16001555b00", + "nonce" : "0x00", + "storage" : { + } + } + }, + "pre" : { + "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0xffffffffffffffffffffffffffffffff", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "0xaaa50000fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0fffffffffffff", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "0xbbbf5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0fffffffffffff", + "code" : "0x60016000540160005561040060005410601b5760016002556047565b60006000620f42406000600073bbbf5374fce5edbc8e2a8697c15331677e6ebf0b620f55c85a03f16001555b00", + "nonce" : "0x00", + "storage" : { + } + } + }, + "sealEngine" : "NoProof" + } + } + """; + + String jsonInvalid = + """ + { "ValueOverflow_d0g0v0_EIP150" : { + "_info" : { + "comment" : "", + "filling-rpc-server" : "evm version 1.13.5-unstable-cd295356-20231019", + "filling-tool-version" : "retesteth-0.3.1-cancun+commit.1e18e0b3.Linux.g++", + "generatedTestHash" : "3e97036f37b30c4b22f7816fb9f8321623ec4dd8646b0ab9c76fcf87371a36e3", + "lllcversion" : "Version: 0.5.14-develop.2023.7.11+commit.c58ab2c6.mod.Linux.g++", + "solidity" : "Version: 0.8.21+commit.d9974bed.Linux.g++", + "source" : "src/GeneralStateTestsFiller/stTransactionTest/ValueOverflowFiller.yml", + "sourceHash" : "fa6acc202e029dc360fd6d105ac578d91f184f692359decbfe4f9f50af7fbb67" + }, + "blocks" : [ + { + "expectException" : "TR_RLP_WRONGVALUE", + "rlp" : "0xf9027ef901f6a0a96bbebc0b60fd343eead12143896f9331f436013c0f28cfd13698f0348f4b03a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa0fd1aa19de23712bad2af7f5e2a01afd6f92273527d501b20bb35e1e42b52f1d0a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000018405500000808203e800a00000000000000000000000000000000000000000000000000000000000000000880000000000000000f882f880806482520894d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0a1010000000000000000000000000000000000000000000000000000000000000001801ba0c16787a8e25e941d67691954642876c08f00996163ae7dfadbbfd6cd436f549da06180e5626cae31590f40641fe8f63734316c4bfeb4cdfab6714198c1044d2e28c0", + "transactionSequence" : [ + { + "exception" : "TR_RLP_WRONGVALUE", + "rawBytes" : "0xf880806482520894d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0a1010000000000000000000000000000000000000000000000000000000000000001801ba0c16787a8e25e941d67691954642876c08f00996163ae7dfadbbfd6cd436f549da06180e5626cae31590f40641fe8f63734316c4bfeb4cdfab6714198c1044d2e28", + "valid" : "false" + } + ] + } + ], + "genesisBlockHeader" : { + "bloom" : "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "difficulty" : "0x020000", + "extraData" : "0x00", + "gasLimit" : "0x05500000", + "gasUsed" : "0x00", + "hash" : "0xa96bbebc0b60fd343eead12143896f9331f436013c0f28cfd13698f0348f4b03", + "mixHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "nonce" : "0x0000000000000000", + "number" : "0x00", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0x1751725d1aad5298768fbcf64069b2c1b85aeaffcc561146067d6beedd08052a", + "timestamp" : "0x00", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "genesisRLP" : "0xf901f9f901f4a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa01751725d1aad5298768fbcf64069b2c1b85aeaffcc561146067d6beedd08052aa056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000808405500000808000a00000000000000000000000000000000000000000000000000000000000000000880000000000000000c0c0", + "lastblockhash" : "0xa96bbebc0b60fd343eead12143896f9331f436013c0f28cfd13698f0348f4b03", + "network" : "EIP150", + "postState" : { + "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x3b9aca00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "0xd0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + } + }, + "pre" : { + "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x3b9aca00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "0xd0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + } + }, + "sealEngine" : "NoProof" + } + }"""; + + @Test + void getValidTxs() { + ObjectMapper objectMapper = new ObjectMapper(); + final JavaType javaType = + objectMapper + .getTypeFactory() + .constructParametricType( + JsonTestParameters.JsonTestCaseReader.class, BlockchainReferenceTestCaseSpec.class); + JsonTestParameters.JsonTestCaseReader + blockchainReferenceTestCaseSpec; + try { + blockchainReferenceTestCaseSpec = objectMapper.readValue(jsonValid, javaType); + } catch (final IOException e) { + throw new RuntimeException("Error parsing test case json.", e); + } + + BlockchainReferenceTestCaseSpec call1MB1024CalldepthD0g0v0London = blockchainReferenceTestCaseSpec + .testCaseSpecs + .get("Call1MB1024Calldepth_d0g0v0_London"); + + Assertions.assertEquals(1, blockchainReferenceTestCaseSpec.testCaseSpecs.size()); + Assertions.assertEquals( + 1, + call1MB1024CalldepthD0g0v0London + .getBlocks().size()); + + final Block block = call1MB1024CalldepthD0g0v0London + .getBlocks().getFirst(); + + Assertions.assertTrue(call1MB1024CalldepthD0g0v0London + .areAllTransactionsValid(block)); + } + + @Test + void getInValidTxs() { + ObjectMapper objectMapper = new ObjectMapper(); + final JavaType javaType = + objectMapper + .getTypeFactory() + .constructParametricType( + JsonTestParameters.JsonTestCaseReader.class, BlockchainReferenceTestCaseSpec.class); + JsonTestParameters.JsonTestCaseReader + blockchainReferenceTestCaseSpec; + try { + blockchainReferenceTestCaseSpec = objectMapper.readValue(jsonInvalid, javaType); + } catch (final IOException e) { + throw new RuntimeException("Error parsing test case json.", e); + } + + BlockchainReferenceTestCaseSpec valueOverflow_d0g0v0_EIP150 = blockchainReferenceTestCaseSpec + .testCaseSpecs + .get("ValueOverflow_d0g0v0_EIP150"); + + Assertions.assertEquals(1, blockchainReferenceTestCaseSpec.testCaseSpecs.size()); + Assertions.assertEquals( + 1, + valueOverflow_d0g0v0_EIP150 + .getBlocks().size()); + + final Block block = valueOverflow_d0g0v0_EIP150 + .getBlocks().getFirst(); + + Assertions.assertFalse(valueOverflow_d0g0v0_EIP150 + .areAllTransactionsValid(block)); + + } +} diff --git a/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/vm/BlockchainReferenceTestTools.java b/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/vm/BlockchainReferenceTestTools.java index a648330afe..a6b2b8a678 100644 --- a/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/vm/BlockchainReferenceTestTools.java +++ b/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/vm/BlockchainReferenceTestTools.java @@ -15,7 +15,7 @@ package org.hyperledger.besu.ethereum.vm; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assumptions.assumeThat; +import static org.junit.jupiter.api.Assumptions.assumeFalse; import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.chain.MutableBlockchain; @@ -142,18 +142,15 @@ public class BlockchainReferenceTestTools { } static void verifyJournaledEVMAccountCompatability( - final MutableWorldState worldState, final ProtocolSpec protocolSpec) { + final MutableWorldState worldState, final ProtocolSpec protocolSpec) { EVM evm = protocolSpec.getEvm(); if (evm.getEvmConfiguration().worldUpdaterMode() == WorldUpdaterMode.JOURNALED) { - assumeThat( + assumeFalse( worldState - .streamAccounts(Bytes32.ZERO, Integer.MAX_VALUE) - .anyMatch(AccountState::isEmpty)) - .withFailMessage("Journaled account configured and empty account detected") - .isFalse(); - assumeThat(EvmSpecVersion.SPURIOUS_DRAGON.compareTo(evm.getEvmVersion()) > 0) - .withFailMessage("Journaled account configured and fork prior to the merge specified") - .isFalse(); + .streamAccounts(Bytes32.ZERO, Integer.MAX_VALUE).anyMatch(AccountState::isEmpty), + "Journaled account configured and empty account detected"); + assumeFalse(EvmSpecVersion.SPURIOUS_DRAGON.compareTo(evm.getEvmVersion()) > 0, + "Journaled account configured and fork prior to the merge specified"); } } } diff --git a/ethereum/retesteth/build.gradle b/ethereum/retesteth/build.gradle index 2fe2def439..484953a391 100644 --- a/ethereum/retesteth/build.gradle +++ b/ethereum/retesteth/build.gradle @@ -35,6 +35,7 @@ dependencies { implementation project(':ethereum:api') implementation project(':ethereum:blockcreation') implementation project(':ethereum:core') + implementation project(path: ':ethereum:core', configuration: 'testSupportArtifacts') implementation project(':ethereum:eth') implementation project(':ethereum:p2p') implementation project(':ethereum:rlp') diff --git a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/NoRewardProtocolScheduleWrapper.java b/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/NoRewardProtocolScheduleWrapper.java index e5ff9fde87..a72c5efe71 100644 --- a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/NoRewardProtocolScheduleWrapper.java +++ b/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/NoRewardProtocolScheduleWrapper.java @@ -88,7 +88,7 @@ public class NoRewardProtocolScheduleWrapper implements ProtocolSchedule { Optional.empty(), original.getWithdrawalsValidator(), original.getWithdrawalsProcessor(), - original.getRequestsValidatorCoordinator(), + original.getRequestsValidator(), original.getRequestProcessorCoordinator(), original.getBlockHashProcessor(), original.isPoS(), diff --git a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/RetestethService.java b/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/RetestethService.java index ceca8ebc11..877c597686 100644 --- a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/RetestethService.java +++ b/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/RetestethService.java @@ -30,6 +30,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.EthSendRawTran import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.Web3ClientVersion; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.BlockResultFactory; +import org.hyperledger.besu.ethereum.core.DummySynchronizer; import org.hyperledger.besu.ethereum.core.Synchronizer; import org.hyperledger.besu.ethereum.retesteth.methods.TestGetLogHash; import org.hyperledger.besu.ethereum.retesteth.methods.TestImportRawBlock; diff --git a/evm/src/main/java/org/hyperledger/besu/evm/EvmSpecVersion.java b/evm/src/main/java/org/hyperledger/besu/evm/EvmSpecVersion.java index 7d4344c6bc..d675496d7a 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/EvmSpecVersion.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/EvmSpecVersion.java @@ -55,8 +55,6 @@ public enum EvmSpecVersion { CANCUN_EOF(MainnetHardforkId.CANCUN_EOF, 0x6000, 0xc000, 1), /** Prague evm spec version. */ PRAGUE(MainnetHardforkId.PRAGUE, 0x6000, 0xc000, 0), - /** PragueEOF evm spec version. */ - PRAGUE_EOF(MainnetHardforkId.PRAGUE_EOF, 0x6000, 0xc000, 1), /** Osaka evm spec version. */ OSAKA(MainnetHardforkId.OSAKA, 0x6000, 0xc000, 1), /** Amsterdam evm spec version. */ @@ -183,11 +181,11 @@ public enum EvmSpecVersion { * @return the EVM spec version for that fork, or null if no fork matched. */ public static EvmSpecVersion fromName(final String name) { - // TODO remove once PragueEOF settles + // TODO remove once CancunEOF tests are removed from EEST if ("prague".equalsIgnoreCase(name)) { - return EvmSpecVersion.PRAGUE_EOF; + return EvmSpecVersion.OSAKA; } - // TODO remove once PragueEOF settles + // TODO remove once CancunEOF tests are removed from EEST if ("cancuneof".equalsIgnoreCase(name)) { return EvmSpecVersion.CANCUN_EOF; } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/MainnetEVMs.java b/evm/src/main/java/org/hyperledger/besu/evm/MainnetEVMs.java index 0bf21315db..2c41434b06 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/MainnetEVMs.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/MainnetEVMs.java @@ -23,8 +23,8 @@ import org.hyperledger.besu.evm.gascalculator.GasCalculator; import org.hyperledger.besu.evm.gascalculator.HomesteadGasCalculator; import org.hyperledger.besu.evm.gascalculator.IstanbulGasCalculator; import org.hyperledger.besu.evm.gascalculator.LondonGasCalculator; +import org.hyperledger.besu.evm.gascalculator.OsakaGasCalculator; import org.hyperledger.besu.evm.gascalculator.PetersburgGasCalculator; -import org.hyperledger.besu.evm.gascalculator.PragueEOFGasCalculator; import org.hyperledger.besu.evm.gascalculator.PragueGasCalculator; import org.hyperledger.besu.evm.gascalculator.ShanghaiGasCalculator; import org.hyperledger.besu.evm.gascalculator.SpuriousDragonGasCalculator; @@ -1025,72 +1025,70 @@ public class MainnetEVMs { final GasCalculator gasCalculator, final BigInteger chainID) { registerCancunOperations(registry, gasCalculator, chainID); - - // TODO add EOF operations here once PragueEOF is collapsed into Prague } /** - * PragueEOF evm. + * Osaka evm. * * @param evmConfiguration the evm configuration * @return the evm */ - public static EVM pragueEOF(final EvmConfiguration evmConfiguration) { - return pragueEOF(DEV_NET_CHAIN_ID, evmConfiguration); + public static EVM osaka(final EvmConfiguration evmConfiguration) { + return osaka(DEV_NET_CHAIN_ID, evmConfiguration); } /** - * PragueEOF evm. + * Osaka evm. * * @param chainId the chain id * @param evmConfiguration the evm configuration * @return the evm */ - public static EVM pragueEOF(final BigInteger chainId, final EvmConfiguration evmConfiguration) { - return pragueEOF(new PragueEOFGasCalculator(), chainId, evmConfiguration); + public static EVM osaka(final BigInteger chainId, final EvmConfiguration evmConfiguration) { + return osaka(new OsakaGasCalculator(), chainId, evmConfiguration); } /** - * PragueEOF evm. + * Osaka evm. * * @param gasCalculator the gas calculator * @param chainId the chain id * @param evmConfiguration the evm configuration * @return the evm */ - public static EVM pragueEOF( + public static EVM osaka( final GasCalculator gasCalculator, final BigInteger chainId, final EvmConfiguration evmConfiguration) { return new EVM( - pragueEOFOperations(gasCalculator, chainId), + osakaOperations(gasCalculator, chainId), gasCalculator, evmConfiguration, - EvmSpecVersion.PRAGUE_EOF); + EvmSpecVersion.OSAKA); } /** - * Operation registry for PragueEOF's operations. + * Operation registry for Osaka's operations. * * @param gasCalculator the gas calculator * @param chainId the chain id * @return the operation registry */ - public static OperationRegistry pragueEOFOperations( + public static OperationRegistry osakaOperations( final GasCalculator gasCalculator, final BigInteger chainId) { OperationRegistry operationRegistry = new OperationRegistry(); - registerPragueEOFOperations(operationRegistry, gasCalculator, chainId); + registerOsakaOperations(operationRegistry, gasCalculator, chainId); return operationRegistry; } /** - * Register PragueEOF's operations. + * Register Osaka's operations. * * @param registry the registry * @param gasCalculator the gas calculator * @param chainID the chain id */ - public static void registerPragueEOFOperations( + public static void registerOsakaOperations( final OperationRegistry registry, final GasCalculator gasCalculator, final BigInteger chainID) { @@ -1140,74 +1138,6 @@ public class MainnetEVMs { registry.put(new ReturnContractOperation(gasCalculator)); } - /** - * Osaka evm. - * - * @param evmConfiguration the evm configuration - * @return the evm - */ - public static EVM osaka(final EvmConfiguration evmConfiguration) { - return osaka(DEV_NET_CHAIN_ID, evmConfiguration); - } - - /** - * Osaka evm. - * - * @param chainId the chain id - * @param evmConfiguration the evm configuration - * @return the evm - */ - public static EVM osaka(final BigInteger chainId, final EvmConfiguration evmConfiguration) { - return osaka(new PragueGasCalculator(), chainId, evmConfiguration); - } - - /** - * Osaka evm. - * - * @param gasCalculator the gas calculator - * @param chainId the chain id - * @param evmConfiguration the evm configuration - * @return the evm - */ - public static EVM osaka( - final GasCalculator gasCalculator, - final BigInteger chainId, - final EvmConfiguration evmConfiguration) { - return new EVM( - osakaOperations(gasCalculator, chainId), - gasCalculator, - evmConfiguration, - EvmSpecVersion.OSAKA); - } - - /** - * Operation registry for osaka's operations. - * - * @param gasCalculator the gas calculator - * @param chainId the chain id - * @return the operation registry - */ - public static OperationRegistry osakaOperations( - final GasCalculator gasCalculator, final BigInteger chainId) { - OperationRegistry operationRegistry = new OperationRegistry(); - registerOsakaOperations(operationRegistry, gasCalculator, chainId); - return operationRegistry; - } - - /** - * Register osaka operations. - * - * @param registry the registry - * @param gasCalculator the gas calculator - * @param chainID the chain id - */ - public static void registerOsakaOperations( - final OperationRegistry registry, - final GasCalculator gasCalculator, - final BigInteger chainID) { - registerPragueEOFOperations(registry, gasCalculator, chainID); - } - /** * Amsterdam evm. * diff --git a/evm/src/main/java/org/hyperledger/besu/evm/fluent/EVMExecutor.java b/evm/src/main/java/org/hyperledger/besu/evm/fluent/EVMExecutor.java index 5f3ca91fb4..c0a884195f 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/fluent/EVMExecutor.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/fluent/EVMExecutor.java @@ -168,7 +168,6 @@ public class EVMExecutor { case CANCUN -> cancun(chainId, evmConfiguration); case CANCUN_EOF -> cancunEOF(chainId, evmConfiguration); case PRAGUE -> prague(chainId, evmConfiguration); - case PRAGUE_EOF -> pragueEOF(chainId, evmConfiguration); case OSAKA -> osaka(chainId, evmConfiguration); case AMSTERDAM -> amsterdam(chainId, evmConfiguration); case BOGOTA -> bogota(chainId, evmConfiguration); @@ -529,21 +528,6 @@ public class EVMExecutor { return executor; } - /** - * Instantiate PragueEOF evm executor. - * - * @param chainId the chain ID - * @param evmConfiguration the evm configuration - * @return the evm executor - */ - public static EVMExecutor pragueEOF( - final BigInteger chainId, final EvmConfiguration evmConfiguration) { - final EVMExecutor executor = new EVMExecutor(MainnetEVMs.pragueEOF(chainId, evmConfiguration)); - executor.precompileContractRegistry = - MainnetPrecompiledContracts.prague(executor.evm.getGasCalculator()); - return executor; - } - /** * Instantiate Osaka evm executor. * diff --git a/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/PragueEOFGasCalculator.java b/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/OsakaGasCalculator.java similarity index 89% rename from evm/src/main/java/org/hyperledger/besu/evm/gascalculator/PragueEOFGasCalculator.java rename to evm/src/main/java/org/hyperledger/besu/evm/gascalculator/OsakaGasCalculator.java index 5fa2fe8725..b4155dac52 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/PragueEOFGasCalculator.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/OsakaGasCalculator.java @@ -26,13 +26,13 @@ import static org.hyperledger.besu.datatypes.Address.BLS12_MAP_FP2_TO_G2; *
  • TBD * */ -public class PragueEOFGasCalculator extends PragueGasCalculator { +public class OsakaGasCalculator extends PragueGasCalculator { static final long MIN_RETAINED_GAS = 5_000; static final long MIN_CALLEE_GAS = 2300; /** Instantiates a new Prague Gas Calculator. */ - public PragueEOFGasCalculator() { + public OsakaGasCalculator() { this(BLS12_MAP_FP2_TO_G2.toArrayUnsafe()[19]); } @@ -41,7 +41,7 @@ public class PragueEOFGasCalculator extends PragueGasCalculator { * * @param maxPrecompile the max precompile */ - protected PragueEOFGasCalculator(final int maxPrecompile) { + protected OsakaGasCalculator(final int maxPrecompile) { super(maxPrecompile); } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractExtCallOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractExtCallOperation.java index 02a8900828..e5a411ee4f 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractExtCallOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractExtCallOperation.java @@ -109,15 +109,16 @@ public abstract class AbstractExtCallOperation extends AbstractCallOperation { long inputOffset = inputDataOffset(frame); long inputLength = inputDataLength(frame); + GasCalculator gasCalculator = gasCalculator(); if (!zeroValue && isStatic(frame)) { return new OperationResult( - gasCalculator().callValueTransferGasCost(), ExceptionalHaltReason.ILLEGAL_STATE_CHANGE); + gasCalculator.callValueTransferGasCost(), ExceptionalHaltReason.ILLEGAL_STATE_CHANGE); } if (toBytes.size() > Address.SIZE) { return new OperationResult( - gasCalculator().memoryExpansionGasCost(frame, inputOffset, inputLength) - + (zeroValue ? 0 : gasCalculator().callValueTransferGasCost()) - + gasCalculator().getColdAccountAccessCost(), + gasCalculator.memoryExpansionGasCost(frame, inputOffset, inputLength) + + (zeroValue ? 0 : gasCalculator.callValueTransferGasCost()) + + gasCalculator.getColdAccountAccessCost(), ExceptionalHaltReason.ADDRESS_OUT_OF_RANGE); } Address to = Words.toAddress(toBytes); @@ -125,7 +126,7 @@ public abstract class AbstractExtCallOperation extends AbstractCallOperation { if (contract != null) { final DelegatedCodeGasCostHelper.Result result = - deductDelegatedCodeGasCost(frame, gasCalculator(), contract); + deductDelegatedCodeGasCost(frame, gasCalculator, contract); if (result.status() != DelegatedCodeGasCostHelper.Status.SUCCESS) { return new Operation.OperationResult( result.gasCost(), ExceptionalHaltReason.INSUFFICIENT_GAS); @@ -134,12 +135,12 @@ public abstract class AbstractExtCallOperation extends AbstractCallOperation { boolean accountCreation = contract == null && !zeroValue; long cost = - gasCalculator().memoryExpansionGasCost(frame, inputOffset, inputLength) - + (zeroValue ? 0 : gasCalculator().callValueTransferGasCost()) - + (frame.warmUpAddress(to) - ? gasCalculator().getWarmStorageReadCost() - : gasCalculator().getColdAccountAccessCost()) - + (accountCreation ? gasCalculator().newAccountGasCost() : 0); + gasCalculator.memoryExpansionGasCost(frame, inputOffset, inputLength) + + (zeroValue ? 0 : gasCalculator.callValueTransferGasCost()) + + (frame.warmUpAddress(to) || gasCalculator.isPrecompile(to) + ? gasCalculator.getWarmStorageReadCost() + : gasCalculator.getColdAccountAccessCost()) + + (accountCreation ? gasCalculator.newAccountGasCost() : 0); long currentGas = frame.getRemainingGas() - cost; if (currentGas < 0) { return new OperationResult(cost, ExceptionalHaltReason.INSUFFICIENT_GAS); @@ -163,14 +164,14 @@ public abstract class AbstractExtCallOperation extends AbstractCallOperation { return softFailure(frame, cost); } - long retainedGas = Math.max(currentGas / 64, gasCalculator().getMinRetainedGas()); + long retainedGas = Math.max(currentGas / 64, gasCalculator.getMinRetainedGas()); long childGas = currentGas - retainedGas; final Account account = frame.getWorldUpdater().get(frame.getRecipientAddress()); final Wei balance = (zeroValue || account == null) ? Wei.ZERO : account.getBalance(); // There myst be a minimum gas for a call to have access to. - if (childGas < gasCalculator().getMinCalleeGas()) { + if (childGas < gasCalculator.getMinCalleeGas()) { return softFailure(frame, cost); } // transferring value you don't have is not a halting exception, just a failure diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/CallFOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/CallFOperation.java index c699063415..65b14fe295 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/CallFOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/CallFOperation.java @@ -17,6 +17,7 @@ package org.hyperledger.besu.evm.operation; import org.hyperledger.besu.evm.Code; import org.hyperledger.besu.evm.EVM; import org.hyperledger.besu.evm.code.CodeSection; +import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.gascalculator.GasCalculator; import org.hyperledger.besu.evm.internal.ReturnStack; @@ -30,6 +31,9 @@ public class CallFOperation extends AbstractOperation { /** The Call F success. */ static final OperationResult callfSuccess = new OperationResult(5, null); + static final OperationResult callfStackOverflow = + new OperationResult(5, ExceptionalHaltReason.TOO_MANY_STACK_ITEMS); + /** * Instantiates a new Call F operation. * @@ -49,6 +53,10 @@ public class CallFOperation extends AbstractOperation { int pc = frame.getPC(); int section = code.readBigEndianU16(pc + 1); CodeSection info = code.getCodeSection(section); + int operandStackSize = frame.stackSize(); + if (operandStackSize > 1024 - info.getMaxStackHeight() + info.getInputs()) { + return callfStackOverflow; + } frame.getReturnStack().push(new ReturnStack.ReturnStackItem(frame.getSection(), pc + 2)); frame.setPC(info.getEntryPoint() - 1); // will be +1ed at end of operations loop frame.setSection(section); diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/JumpFOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/JumpFOperation.java index c76caa9667..bda66546d5 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/JumpFOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/JumpFOperation.java @@ -16,6 +16,7 @@ package org.hyperledger.besu.evm.operation; import org.hyperledger.besu.evm.Code; import org.hyperledger.besu.evm.EVM; +import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.gascalculator.GasCalculator; @@ -28,6 +29,9 @@ public class JumpFOperation extends AbstractOperation { /** The Jump F success operation result. */ static final OperationResult jumpfSuccess = new OperationResult(5, null); + static final OperationResult jumpfStackOverflow = + new OperationResult(5, ExceptionalHaltReason.TOO_MANY_STACK_ITEMS); + /** * Instantiates a new Jump F operation. * @@ -46,6 +50,10 @@ public class JumpFOperation extends AbstractOperation { int pc = frame.getPC(); int section = code.readBigEndianU16(pc + 1); var info = code.getCodeSection(section); + int operandStackSize = frame.stackSize(); + if (operandStackSize > 1024 - info.getMaxStackHeight() + info.getInputs()) { + return jumpfStackOverflow; + } frame.setPC(info.getEntryPoint() - 1); // will be +1ed at end of operations loop frame.setSection(section); return jumpfSuccess; diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/ReturnDataLoadOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/ReturnDataLoadOperation.java index 7d8a5e4209..3c04b7b939 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/ReturnDataLoadOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/ReturnDataLoadOperation.java @@ -16,6 +16,7 @@ package org.hyperledger.besu.evm.operation; import static org.hyperledger.besu.evm.internal.Words.clampedToInt; +import org.hyperledger.besu.evm.Code; import org.hyperledger.besu.evm.EVM; import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.gascalculator.GasCalculator; @@ -37,6 +38,11 @@ public class ReturnDataLoadOperation extends AbstractOperation { @Override public OperationResult execute(final MessageFrame frame, final EVM evm) { + Code code = frame.getCode(); + if (code.getEofVersion() == 0) { + return InvalidOperation.INVALID_RESULT; + } + final int offset = clampedToInt(frame.popStackItem()); Bytes returnData = frame.getReturnData(); int retunDataSize = returnData.size(); diff --git a/evm/src/main/java/org/hyperledger/besu/evm/precompile/AbstractBLS12PrecompiledContract.java b/evm/src/main/java/org/hyperledger/besu/evm/precompile/AbstractBLS12PrecompiledContract.java index 67fecb92aa..3f0f5bc4cc 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/precompile/AbstractBLS12PrecompiledContract.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/precompile/AbstractBLS12PrecompiledContract.java @@ -67,6 +67,20 @@ public abstract class AbstractBLS12PrecompiledContract implements PrecompiledCon this.inputLimit = inputLen + 1; } + /** + * Is bls12 supported on this platform + * + * @return true if the native library was loaded. + */ + public static boolean isAvailable() { + try { + return LibGnarkEIP2537.ENABLED; + } catch (UnsatisfiedLinkError | NoClassDefFoundError ule) { + LOG.info("bls12-381 native precompile not available: {}", ule.getMessage()); + } + return false; + } + @Override public String getName() { return name; diff --git a/evm/src/main/java/org/hyperledger/besu/evm/tracing/StandardJsonTracer.java b/evm/src/main/java/org/hyperledger/besu/evm/tracing/StandardJsonTracer.java index a289c665d2..8071fa942f 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/tracing/StandardJsonTracer.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/tracing/StandardJsonTracer.java @@ -14,8 +14,6 @@ */ package org.hyperledger.besu.evm.tracing; -import static com.google.common.base.Strings.padStart; - import org.hyperledger.besu.evm.code.OpcodeInfo; import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; import org.hyperledger.besu.evm.frame.MessageFrame; @@ -127,9 +125,7 @@ public class StandardJsonTracer implements OperationTracer { for (int i = messageFrame.stackSize() - 1; i >= 0; i--) { stack.add("\"" + shortBytes(messageFrame.getStackItem(i)) + "\""); } - pc = - messageFrame.getPC() - - messageFrame.getCode().getCodeSection(messageFrame.getSection()).getEntryPoint(); + pc = messageFrame.getPC() - messageFrame.getCode().getCodeSection(0).getEntryPoint(); section = messageFrame.getSection(); gas = shortNumber(messageFrame.getRemainingGas()); memorySize = messageFrame.memoryWordSize() * 32; @@ -226,7 +222,7 @@ public class StandardJsonTracer implements OperationTracer { .append("\""); } else if (messageFrame.getRevertReason().isPresent()) { sb.append(",\"error\":\"") - .append(quoteEscape(messageFrame.getRevertReason().orElse(Bytes.EMPTY))) + .append(messageFrame.getRevertReason().get().toHexString()) .append("\""); } @@ -234,37 +230,6 @@ public class StandardJsonTracer implements OperationTracer { out.println(sb); } - private static String quoteEscape(final Bytes bytes) { - final StringBuilder result = new StringBuilder(bytes.size()); - for (final byte b : bytes.toArrayUnsafe()) { - final int c = Byte.toUnsignedInt(b); - // list from RFC-4627 section 2 - if (c == '"') { - result.append("\\\""); - } else if (c == '\\') { - result.append("\\\\"); - } else if (c == '/') { - result.append("\\/"); - } else if (c == '\b') { - result.append("\\b"); - } else if (c == '\f') { - result.append("\\f"); - } else if (c == '\n') { - result.append("\\n"); - } else if (c == '\r') { - result.append("\\r"); - } else if (c == '\t') { - result.append("\\t"); - } else if (c <= 0x1F) { - result.append("\\u"); - result.append(padStart(Integer.toHexString(c), 4, '0')); - } else { - result.append((char) b); - } - } - return result.toString(); - } - @Override public void tracePrecompileCall( final MessageFrame frame, final long gasRequirement, final Bytes output) { diff --git a/evm/src/test/java/org/hyperledger/besu/evm/code/CodeFactoryTest.java b/evm/src/test/java/org/hyperledger/besu/evm/code/CodeFactoryTest.java index 6f60ab7865..ac27d3f21e 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/code/CodeFactoryTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/code/CodeFactoryTest.java @@ -594,26 +594,26 @@ class CodeFactoryTest { } private static void validCode(final String str) { - EVM evm = MainnetEVMs.pragueEOF(EvmConfiguration.DEFAULT); + EVM evm = MainnetEVMs.osaka(EvmConfiguration.DEFAULT); Code code = evm.getCodeUncached(bytesFromPrettyPrint(str)); assertThat(code.isValid()).isTrue(); } private static void invalidCode(final String str, final String error) { - EVM evm = MainnetEVMs.pragueEOF(EvmConfiguration.DEFAULT); + EVM evm = MainnetEVMs.osaka(EvmConfiguration.DEFAULT); Code code = evm.getCodeUncached(bytesFromPrettyPrint(str)); assertThat(code.isValid()).isFalse(); assertThat(((CodeInvalid) code).getInvalidReason()).contains(error); } private static void invalidCode(final String str) { - EVM evm = MainnetEVMs.pragueEOF(EvmConfiguration.DEFAULT); + EVM evm = MainnetEVMs.osaka(EvmConfiguration.DEFAULT); Code code = evm.getCodeUncached(bytesFromPrettyPrint(str)); assertThat(code.isValid()).isFalse(); } private static void invalidCodeForCreation(final String str) { - EVM evm = MainnetEVMs.pragueEOF(EvmConfiguration.DEFAULT); + EVM evm = MainnetEVMs.osaka(EvmConfiguration.DEFAULT); Code code = evm.getCodeForCreation(bytesFromPrettyPrint(str)); assertThat(code.isValid()).isFalse(); } diff --git a/evm/src/test/java/org/hyperledger/besu/evm/code/CodeV0Test.java b/evm/src/test/java/org/hyperledger/besu/evm/code/CodeV0Test.java index 3b16b1c923..54d457e628 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/code/CodeV0Test.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/code/CodeV0Test.java @@ -47,7 +47,7 @@ class CodeV0Test { @BeforeEach void startUp() { - evm = MainnetEVMs.pragueEOF(EvmConfiguration.DEFAULT); + evm = MainnetEVMs.osaka(EvmConfiguration.DEFAULT); } @Test diff --git a/evm/src/test/java/org/hyperledger/besu/evm/fluent/EVMExecutorTest.java b/evm/src/test/java/org/hyperledger/besu/evm/fluent/EVMExecutorTest.java index aa9dcdb23f..eaa8dbc8c4 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/fluent/EVMExecutorTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/fluent/EVMExecutorTest.java @@ -131,9 +131,13 @@ class EVMExecutorTest { assertThat(cancunEOFEVM.getChainId()).contains(defaultChainId); EVMExecutor pragueEVM = - EVMExecutor.pragueEOF(defaultChainId.toBigInteger(), EvmConfiguration.DEFAULT); + EVMExecutor.prague(defaultChainId.toBigInteger(), EvmConfiguration.DEFAULT); assertThat(pragueEVM.getChainId()).contains(defaultChainId); + EVMExecutor osakaEVM = + EVMExecutor.osaka(defaultChainId.toBigInteger(), EvmConfiguration.DEFAULT); + assertThat(osakaEVM.getChainId()).contains(defaultChainId); + EVMExecutor futureEipsVM = EVMExecutor.futureEips(EvmConfiguration.DEFAULT); assertThat(futureEipsVM.getChainId()).contains(defaultChainId); } diff --git a/evm/src/test/java/org/hyperledger/besu/evm/gascalculator/PragueEOFGasCalculatorTest.java b/evm/src/test/java/org/hyperledger/besu/evm/gascalculator/OsakaGasCalculatorTest.java similarity index 88% rename from evm/src/test/java/org/hyperledger/besu/evm/gascalculator/PragueEOFGasCalculatorTest.java rename to evm/src/test/java/org/hyperledger/besu/evm/gascalculator/OsakaGasCalculatorTest.java index 46fe1dcba8..3236c13e83 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/gascalculator/PragueEOFGasCalculatorTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/gascalculator/OsakaGasCalculatorTest.java @@ -20,11 +20,11 @@ import org.hyperledger.besu.datatypes.Address; import org.junit.jupiter.api.Test; -class PragueEOFGasCalculatorTest { +class OsakaGasCalculatorTest { @Test void testPrecompileSize() { - PragueEOFGasCalculator subject = new PragueEOFGasCalculator(); + OsakaGasCalculator subject = new OsakaGasCalculator(); assertThat(subject.isPrecompile(Address.precompiled(0x14))).isFalse(); assertThat(subject.isPrecompile(Address.BLS12_MAP_FP2_TO_G2)).isTrue(); } @@ -32,7 +32,7 @@ class PragueEOFGasCalculatorTest { @Test void testNewConstants() { CancunGasCalculator cancunGas = new CancunGasCalculator(); - PragueEOFGasCalculator praugeGasCalculator = new PragueEOFGasCalculator(); + OsakaGasCalculator praugeGasCalculator = new OsakaGasCalculator(); assertThat(praugeGasCalculator.getMinCalleeGas()).isGreaterThan(cancunGas.getMinCalleeGas()); assertThat(praugeGasCalculator.getMinRetainedGas()) diff --git a/evm/src/test/java/org/hyperledger/besu/evm/internal/CodeCacheTest.java b/evm/src/test/java/org/hyperledger/besu/evm/internal/CodeCacheTest.java index 7b8a74b0cd..cffd7ef5fa 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/internal/CodeCacheTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/internal/CodeCacheTest.java @@ -30,7 +30,7 @@ class CodeCacheTest { @Test void testScale() { - EVM evm = MainnetEVMs.pragueEOF(EvmConfiguration.DEFAULT); + EVM evm = MainnetEVMs.osaka(EvmConfiguration.DEFAULT); final Bytes contractBytes = Bytes.fromHexString("0xDEAD" + op + "BEEF" + op + "B0B0" + op + "C0DE" + op + "FACE"); final CodeScale scale = new CodeScale(); diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operation/Create2OperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operation/Create2OperationTest.java index 4b2a5449ed..a70b09a60b 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operation/Create2OperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operation/Create2OperationTest.java @@ -56,7 +56,7 @@ public class Create2OperationTest { private MessageFrame messageFrame; private final WorldUpdater worldUpdater = mock(WorldUpdater.class); private final MutableAccount account = mock(MutableAccount.class); - private final EVM evm = MainnetEVMs.pragueEOF(EvmConfiguration.DEFAULT); + private final EVM evm = MainnetEVMs.osaka(EvmConfiguration.DEFAULT); private final MutableAccount newAccount = mock(MutableAccount.class); private final Create2Operation operation = diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operation/CreateOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operation/CreateOperationTest.java index 482df37fd6..697d87ef1e 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operation/CreateOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operation/CreateOperationTest.java @@ -219,7 +219,7 @@ class CreateOperationTest { @Test void eofV1CannotCall() { - final EVM pragueEvm = MainnetEVMs.pragueEOF(EvmConfiguration.DEFAULT); + final EVM pragueEvm = MainnetEVMs.osaka(EvmConfiguration.DEFAULT); final UInt256 memoryOffset = UInt256.fromHexString("0xFF"); final UInt256 memoryLength = UInt256.valueOf(SIMPLE_CREATE.size()); final MessageFrame messageFrame = @@ -248,7 +248,7 @@ class CreateOperationTest { final UInt256 memoryLength, final UInt256 value, final int depth) { - final EVM evm = MainnetEVMs.pragueEOF(EvmConfiguration.DEFAULT); + final EVM evm = MainnetEVMs.osaka(EvmConfiguration.DEFAULT); final MessageFrame messageFrame = MessageFrame.builder() .type(MessageFrame.Type.CONTRACT_CREATION) diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operation/DataCopyOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operation/DataCopyOperationTest.java index af5922aa07..a4e93bf9d3 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operation/DataCopyOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operation/DataCopyOperationTest.java @@ -15,7 +15,7 @@ package org.hyperledger.besu.evm.operation; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assumptions.assumeThat; +import static org.junit.jupiter.api.Assumptions.assumeTrue; import org.hyperledger.besu.evm.Code; import org.hyperledger.besu.evm.EVM; @@ -36,7 +36,7 @@ import org.junit.jupiter.params.provider.MethodSource; class DataCopyOperationTest { - static EVM evm = MainnetEVMs.pragueEOF(EvmConfiguration.DEFAULT); + static EVM evm = MainnetEVMs.osaka(EvmConfiguration.DEFAULT); static Collection datacopyTestVector() { return Arrays.asList( @@ -136,7 +136,7 @@ class DataCopyOperationTest { "0xef0001010004020001001d04%04x000080000367%016x67%016x67%016xd300%s" .formatted(data.size(), dst, src, len, data.toUnprefixedHexString()); Code code = evm.getCodeUncached(Bytes.fromHexString(eofCode)); - assumeThat(code.isValid()).isTrue(); + assumeTrue(code.isValid()); MessageFrame frame = new TestMessageFrameBuilder() @@ -158,7 +158,7 @@ class DataCopyOperationTest { void legacyCallFails() { DataCopyOperation subject = new DataCopyOperation(new PragueGasCalculator()); Code code = evm.getCodeUncached(Bytes.fromHexString("0x600460046004d3")); - assumeThat(code.isValid()).isTrue(); + assumeTrue(code.isValid()); MessageFrame frame = new TestMessageFrameBuilder() diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operation/EofCreateOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operation/EofCreateOperationTest.java index d5d1212dfb..5e9be62665 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operation/EofCreateOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operation/EofCreateOperationTest.java @@ -62,7 +62,7 @@ class EofCreateOperationTest { @Test void innerContractIsCorrect() { - final EVM evm = MainnetEVMs.cancunEOF(EvmConfiguration.DEFAULT); + final EVM evm = MainnetEVMs.osaka(EvmConfiguration.DEFAULT); Code code = evm.getCodeUncached(INNER_CONTRACT); assertThat(code.isValid()).isTrue(); @@ -92,7 +92,7 @@ class EofCreateOperationTest { @Test void eofCreatePassesInCallData() { Bytes outerContract = EOF_CREATE_CONTRACT; - final EVM evm = MainnetEVMs.cancunEOF(EvmConfiguration.DEFAULT); + final EVM evm = MainnetEVMs.osaka(EvmConfiguration.DEFAULT); Code code = evm.getCodeUncached(outerContract); if (!code.isValid()) { diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operation/ExtCallOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operation/ExtCallOperationTest.java index 93b1011501..ee974c15c5 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operation/ExtCallOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operation/ExtCallOperationTest.java @@ -27,7 +27,7 @@ import org.hyperledger.besu.evm.MainnetEVMs; import org.hyperledger.besu.evm.account.MutableAccount; import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; import org.hyperledger.besu.evm.frame.MessageFrame; -import org.hyperledger.besu.evm.gascalculator.PragueEOFGasCalculator; +import org.hyperledger.besu.evm.gascalculator.OsakaGasCalculator; import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.evm.testutils.TestMessageFrameBuilder; import org.hyperledger.besu.evm.worldstate.WorldUpdater; @@ -44,7 +44,7 @@ public class ExtCallOperationTest { private final WorldUpdater worldUpdater = mock(WorldUpdater.class); private final MutableAccount account = mock(MutableAccount.class); - private static final EVM EOF_EVM = MainnetEVMs.pragueEOF(EvmConfiguration.DEFAULT); + private static final EVM EOF_EVM = MainnetEVMs.osaka(EvmConfiguration.DEFAULT); public static final Code LEGACY_CODE = EOF_EVM.getCodeUncached(Bytes.of(ExtCallOperation.OPCODE, 1)); public static final Code SIMPLE_EOF = @@ -115,7 +115,7 @@ public class ExtCallOperationTest { final Bytes stackItem, final boolean validCode, final boolean warmAddress) { - final ExtCallOperation operation = new ExtCallOperation(new PragueEOFGasCalculator()); + final ExtCallOperation operation = new ExtCallOperation(new OsakaGasCalculator()); final var messageFrame = new TestMessageFrameBuilder() @@ -206,7 +206,7 @@ public class ExtCallOperationTest { final Wei valueSent, final Wei valueWeiHave, final boolean isStatic) { - final ExtCallOperation operation = new ExtCallOperation(new PragueEOFGasCalculator()); + final ExtCallOperation operation = new ExtCallOperation(new OsakaGasCalculator()); final var messageFrame = new TestMessageFrameBuilder() @@ -242,7 +242,7 @@ public class ExtCallOperationTest { @Test void overflowTest() { - final ExtCallOperation operation = new ExtCallOperation(new PragueEOFGasCalculator()); + final ExtCallOperation operation = new ExtCallOperation(new OsakaGasCalculator()); final var messageFrame = new TestMessageFrameBuilder() @@ -281,7 +281,7 @@ public class ExtCallOperationTest { @Test void legacyTest() { - final ExtCallOperation operation = new ExtCallOperation(new PragueEOFGasCalculator()); + final ExtCallOperation operation = new ExtCallOperation(new OsakaGasCalculator()); final var messageFrame = new TestMessageFrameBuilder() diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operation/ExtDelegateCallOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operation/ExtDelegateCallOperationTest.java index 62a10dcc2d..b08635748c 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operation/ExtDelegateCallOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operation/ExtDelegateCallOperationTest.java @@ -27,7 +27,7 @@ import org.hyperledger.besu.evm.MainnetEVMs; import org.hyperledger.besu.evm.account.MutableAccount; import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; import org.hyperledger.besu.evm.frame.MessageFrame; -import org.hyperledger.besu.evm.gascalculator.PragueEOFGasCalculator; +import org.hyperledger.besu.evm.gascalculator.OsakaGasCalculator; import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.evm.testutils.TestMessageFrameBuilder; import org.hyperledger.besu.evm.worldstate.WorldUpdater; @@ -45,7 +45,7 @@ public class ExtDelegateCallOperationTest { private final WorldUpdater worldUpdater = mock(WorldUpdater.class); private final MutableAccount account = mock(MutableAccount.class); // private final MutableAccount targetAccount = mock(MutableAccount.class); - private static final EVM EOF_EVM = MainnetEVMs.pragueEOF(EvmConfiguration.DEFAULT); + private static final EVM EOF_EVM = MainnetEVMs.osaka(EvmConfiguration.DEFAULT); public static final Code LEGACY_CODE = EOF_EVM.getCodeUncached(Bytes.of(ExtDelegateCallOperation.OPCODE, 1)); public static final Code SIMPLE_EOF = @@ -119,7 +119,7 @@ public class ExtDelegateCallOperationTest { final boolean validCode, final boolean warmAddress) { final ExtDelegateCallOperation operation = - new ExtDelegateCallOperation(new PragueEOFGasCalculator()); + new ExtDelegateCallOperation(new OsakaGasCalculator()); final var messageFrame = new TestMessageFrameBuilder() @@ -180,7 +180,7 @@ public class ExtDelegateCallOperationTest { final ExceptionalHaltReason haltReason, final Bytes stackItem) { final ExtDelegateCallOperation operation = - new ExtDelegateCallOperation(new PragueEOFGasCalculator()); + new ExtDelegateCallOperation(new OsakaGasCalculator()); final var messageFrame = new TestMessageFrameBuilder() @@ -227,7 +227,7 @@ public class ExtDelegateCallOperationTest { @Test void overflowTest() { final ExtDelegateCallOperation operation = - new ExtDelegateCallOperation(new PragueEOFGasCalculator()); + new ExtDelegateCallOperation(new OsakaGasCalculator()); final var messageFrame = new TestMessageFrameBuilder() .initialGas(400000) @@ -265,7 +265,7 @@ public class ExtDelegateCallOperationTest { @Test void legacyTest() { final ExtDelegateCallOperation operation = - new ExtDelegateCallOperation(new PragueEOFGasCalculator()); + new ExtDelegateCallOperation(new OsakaGasCalculator()); final var messageFrame = new TestMessageFrameBuilder() diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operation/ExtStaticCallOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operation/ExtStaticCallOperationTest.java index ed306e89c7..6b96b960cd 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operation/ExtStaticCallOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operation/ExtStaticCallOperationTest.java @@ -27,7 +27,7 @@ import org.hyperledger.besu.evm.MainnetEVMs; import org.hyperledger.besu.evm.account.MutableAccount; import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; import org.hyperledger.besu.evm.frame.MessageFrame; -import org.hyperledger.besu.evm.gascalculator.PragueEOFGasCalculator; +import org.hyperledger.besu.evm.gascalculator.OsakaGasCalculator; import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.evm.testutils.TestMessageFrameBuilder; import org.hyperledger.besu.evm.worldstate.WorldUpdater; @@ -44,7 +44,7 @@ public class ExtStaticCallOperationTest { private final WorldUpdater worldUpdater = mock(WorldUpdater.class); private final MutableAccount account = mock(MutableAccount.class); - private static final EVM EOF_EVM = MainnetEVMs.pragueEOF(EvmConfiguration.DEFAULT); + private static final EVM EOF_EVM = MainnetEVMs.osaka(EvmConfiguration.DEFAULT); public static final Code LEGACY_CODE = EOF_EVM.getCodeUncached(Bytes.of(ExtStaticCallOperation.OPCODE, 1)); public static final Code SIMPLE_EOF = @@ -115,8 +115,7 @@ public class ExtStaticCallOperationTest { final Bytes stackItem, final boolean validCode, final boolean warmAddress) { - final ExtStaticCallOperation operation = - new ExtStaticCallOperation(new PragueEOFGasCalculator()); + final ExtStaticCallOperation operation = new ExtStaticCallOperation(new OsakaGasCalculator()); final var messageFrame = new TestMessageFrameBuilder() @@ -152,8 +151,7 @@ public class ExtStaticCallOperationTest { @Test void overflowTest() { - final ExtStaticCallOperation operation = - new ExtStaticCallOperation(new PragueEOFGasCalculator()); + final ExtStaticCallOperation operation = new ExtStaticCallOperation(new OsakaGasCalculator()); final var messageFrame = new TestMessageFrameBuilder() .initialGas(400000) @@ -190,8 +188,7 @@ public class ExtStaticCallOperationTest { @Test void legacyTest() { - final ExtStaticCallOperation operation = - new ExtStaticCallOperation(new PragueEOFGasCalculator()); + final ExtStaticCallOperation operation = new ExtStaticCallOperation(new OsakaGasCalculator()); final var messageFrame = new TestMessageFrameBuilder() diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operation/JumpOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operation/JumpOperationTest.java index 7b9fab338e..c97c81b022 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operation/JumpOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operation/JumpOperationTest.java @@ -56,7 +56,7 @@ class JumpOperationTest { @BeforeEach void init() { - evm = MainnetEVMs.pragueEOF(EvmConfiguration.DEFAULT); + evm = MainnetEVMs.osaka(EvmConfiguration.DEFAULT); } @Test diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operation/SelfDestructOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operation/SelfDestructOperationTest.java index d3a3db754b..8fbd4d142d 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operation/SelfDestructOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operation/SelfDestructOperationTest.java @@ -55,7 +55,7 @@ public class SelfDestructOperationTest { @Mock private WorldUpdater worldUpdater; @Mock private MutableAccount accountOriginator; @Mock private MutableAccount accountBeneficiary; - private final EVM evm = MainnetEVMs.pragueEOF(EvmConfiguration.DEFAULT); + private final EVM evm = MainnetEVMs.osaka(EvmConfiguration.DEFAULT); private final SelfDestructOperation frontierOperation = new SelfDestructOperation(new ConstantinopleGasCalculator()); diff --git a/evm/src/test/java/org/hyperledger/besu/evm/processor/ContractCreationProcessorTest.java b/evm/src/test/java/org/hyperledger/besu/evm/processor/ContractCreationProcessorTest.java index 3420df88dc..8b3d6ac51a 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/processor/ContractCreationProcessorTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/processor/ContractCreationProcessorTest.java @@ -45,7 +45,7 @@ import org.mockito.junit.jupiter.MockitoExtension; class ContractCreationProcessorTest extends AbstractMessageProcessorTest { - EVM evm = MainnetEVMs.pragueEOF(EvmConfiguration.DEFAULT); + EVM evm = MainnetEVMs.osaka(EvmConfiguration.DEFAULT); private ContractCreationProcessor processor; diff --git a/evm/src/test/java/org/hyperledger/besu/evm/toy/EvmToyCommand.java b/evm/src/test/java/org/hyperledger/besu/evm/toy/EvmToyCommand.java index fcf26c3c56..9a5c3cd1ea 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/toy/EvmToyCommand.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/toy/EvmToyCommand.java @@ -32,7 +32,6 @@ import org.hyperledger.besu.evm.worldstate.WorldUpdater; import java.io.PrintStream; import java.math.BigInteger; -import java.nio.charset.StandardCharsets; import java.util.Deque; import java.util.List; @@ -208,9 +207,7 @@ public class EvmToyCommand implements Runnable { out.println(messageFrame.getExceptionalHaltReason().get()); } if (messageFrame.getRevertReason().isPresent()) { - out.println( - new String( - messageFrame.getRevertReason().get().toArrayUnsafe(), StandardCharsets.UTF_8)); + out.println(messageFrame.getRevertReason().get().toHexString()); } } if (messageFrameStack.isEmpty()) { diff --git a/evm/src/test/java/org/hyperledger/besu/evm/tracing/ExtendedOperationTracerTest.java b/evm/src/test/java/org/hyperledger/besu/evm/tracing/ExtendedOperationTracerTest.java index bd043f933b..90c6adff35 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/tracing/ExtendedOperationTracerTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/tracing/ExtendedOperationTracerTest.java @@ -55,7 +55,7 @@ class ExtendedOperationTracerTest { @Test void shouldCallTraceAccountCreationResultIfIsExtendedTracing() { - EVM evm = MainnetEVMs.pragueEOF(EvmConfiguration.DEFAULT); + EVM evm = MainnetEVMs.osaka(EvmConfiguration.DEFAULT); final ContractCreationProcessor contractCreationProcessor = new ContractCreationProcessor(evm, false, Collections.emptyList(), 0); @@ -69,7 +69,7 @@ class ExtendedOperationTracerTest { @Test void shouldNotCallTraceAccountCreationResultIfIsNotExtendedTracing() { - EVM evm = MainnetEVMs.pragueEOF(EvmConfiguration.DEFAULT); + EVM evm = MainnetEVMs.osaka(EvmConfiguration.DEFAULT); final ContractCreationProcessor contractCreationProcessor = new ContractCreationProcessor(evm, false, Collections.emptyList(), 0); diff --git a/gradle.properties b/gradle.properties index 93f56e0137..8a4f06d6d4 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,6 +4,10 @@ org.gradle.welcome=never # version=24.5.6-acme # versionappendcommit=true +# Optional, skip dependency verification for dev/debug builds +# org.gradle.dependency.verification=lenient + + # Set exports/opens flags required by Google Java Format and ErrorProne plugins. (JEP-396) org.gradle.jvmargs=-Xmx4g \ --add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \ @@ -18,4 +22,4 @@ org.gradle.jvmargs=-Xmx4g \ --add-opens jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED \ --add-opens jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED # Could be moved to sonar properties after https://sonarsource.atlassian.net/browse/SONARGRADL-134 -systemProp.sonar.gradle.skipCompile=true \ No newline at end of file +systemProp.sonar.gradle.skipCompile=true diff --git a/gradle/spotless/java.current.license b/gradle/spotless/java.current.license index fb92e548e2..4fe14f4607 100644 --- a/gradle/spotless/java.current.license +++ b/gradle/spotless/java.current.license @@ -1,5 +1,5 @@ /* - * Copyright contributors to Hyperledger Besu. + * Copyright contributors to 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 diff --git a/gradle/spotless/sh.license b/gradle/spotless/sh.license index 97909d3507..15a730d29a 100644 --- a/gradle/spotless/sh.license +++ b/gradle/spotless/sh.license @@ -1,5 +1,5 @@ ## -## Copyright contributors to Hyperledger Besu. +## Copyright contributors to 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 diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml deleted file mode 100644 index 87747b3dcc..0000000000 --- a/gradle/verification-metadata.xml +++ /dev/null @@ -1,6332 +0,0 @@ - - - - true - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/gradle/versions.gradle b/gradle/versions.gradle index 607340d091..e69de29bb2 100644 --- a/gradle/versions.gradle +++ b/gradle/versions.gradle @@ -1,253 +0,0 @@ -/* - * Copyright ConsenSys AG. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -dependencyManagement { - dependencies { - applyMavenExclusions = false - - dependencySet(group:'com.fasterxml.jackson.core', version:'2.17.2') { - entry 'jackson-databind' - entry 'jackson-datatype' - entry 'jackson-datatype-jdk8' - } - - dependency 'com.github.ben-manes.caffeine:caffeine:3.1.8' - - dependency 'com.google.protobuf:protobuf-java:3.25.5' - - dependency 'com.github.oshi:oshi-core:6.6.3' - - dependency 'com.google.auto.service:auto-service:1.1.1' - - dependencySet(group: 'com.google.dagger', version: '2.52') { - entry'dagger-compiler' - entry'dagger' - } - - dependency 'org.hyperledger.besu:besu-errorprone-checks:1.0.0' - - dependency 'com.google.guava:guava:33.3.0-jre' - - dependency 'com.graphql-java:graphql-java:22.2' - - dependency 'com.splunk.logging:splunk-library-javalogging:1.11.8' - - dependency 'com.squareup.okhttp3:okhttp:4.12.0' - - dependency 'commons-codec:commons-codec:1.16.0' - - dependency 'commons-io:commons-io:2.16.1' - - dependency 'commons-net:commons-net:3.11.1' - - dependency 'dnsjava:dnsjava:3.6.1' - - dependencySet(group: 'info.picocli', version: '4.7.6') { - entry 'picocli' - entry 'picocli-codegen' - } - - dependencySet(group: 'io.grpc', version: '1.66.0') { - entry 'grpc-all' - entry 'grpc-core' - entry 'grpc-netty' - entry 'grpc-stub' - } - - dependency 'io.kubernetes:client-java:18.0.1' - - dependency 'io.netty:netty-all:4.1.112.Final' - dependency 'io.netty:netty-tcnative-boringssl-static:2.0.66.Final' - dependency group: 'io.netty', name: 'netty-transport-native-epoll', version:'4.1.112.Final', classifier: 'linux-x86_64' - dependency group: 'io.netty', name: 'netty-transport-native-kqueue', version:'4.1.112.Final', classifier: 'osx-x86_64' - dependency 'io.netty:netty-transport-native-unix-common:4.1.112.Final' - - dependency 'io.opentelemetry:opentelemetry-api:1.41.0' - dependency 'io.opentelemetry:opentelemetry-exporter-otlp:1.41.0' - dependency 'io.opentelemetry:opentelemetry-extension-trace-propagators:1.41.0' - dependency 'io.opentelemetry:opentelemetry-sdk-metrics:1.41.0' - dependency 'io.opentelemetry:opentelemetry-sdk-trace:1.41.0' - dependency 'io.opentelemetry:opentelemetry-sdk:1.41.0' - dependency 'io.opentelemetry:opentelemetry-sdk-extension-autoconfigure:1.41.0' - dependency 'io.opentelemetry.instrumentation:opentelemetry-okhttp-3.0:2.7.0-alpha' - dependency 'io.opentelemetry.proto:opentelemetry-proto:1.3.2-alpha' - dependency 'io.opentelemetry.semconv:opentelemetry-semconv:1.27.0-alpha' - - dependency 'io.opentracing.contrib:opentracing-okhttp3:3.0.0' - dependency 'io.opentracing:opentracing-api:0.33.0' - dependency 'io.opentracing:opentracing-util:0.33.0' - - dependency 'io.pkts:pkts-core:3.0.10' - - dependencySet(group: 'io.prometheus', version: '0.16.0') { - entry 'simpleclient' - entry 'simpleclient_common' - entry 'simpleclient_hotspot' - entry 'simpleclient_pushgateway' - entry 'simpleclient_guava' - } - - dependency 'io.reactivex.rxjava2:rxjava:2.2.21' - - dependencySet(group: 'io.tmio', version: '2.4.2') { - entry 'tuweni-bytes' - entry 'tuweni-config' - entry 'tuweni-concurrent' - entry 'tuweni-crypto' - entry 'tuweni-devp2p' - entry 'tuweni-io' - entry 'tuweni-net' - entry 'tuweni-rlp' - entry 'tuweni-toml' - entry 'tuweni-units' - } - - dependencySet(group: 'io.vertx', version: '4.5.9') { - entry 'vertx-auth-jwt' - entry 'vertx-codegen' - entry 'vertx-core' - entry 'vertx-junit5' - entry 'vertx-unit' - entry 'vertx-web' - entry 'vertx-web-client' - entry 'vertx-auth-jwt' - } - - dependency 'junit:junit:4.13.2' - - dependency 'net.java.dev.jna:jna:5.14.0' - - dependencySet(group: 'org.antlr', version: '4.11.1') { - entry 'antlr4' - entry 'antlr4-runtime' - } - - dependency 'org.apache.commons:commons-collections4:4.4' - dependency 'org.apache.commons:commons-compress:1.27.1' - dependency 'org.apache.commons:commons-lang3:3.17.0' - dependency 'org.apache.commons:commons-text:1.12.0' - - dependencySet(group: 'org.apache.logging.log4j', version: '2.23.1') { - entry 'log4j-api' - entry 'log4j-core' - entry 'log4j-jul' - entry 'log4j-slf4j2-impl' - } - - dependency 'org.assertj:assertj-core:3.26.3' - - dependency 'org.awaitility:awaitility:4.2.2' - - dependencySet(group: 'org.bouncycastle', version: '1.78.1') { - entry'bcpkix-jdk18on' - entry'bcprov-jdk18on' - } - - dependency 'org.fusesource.jansi:jansi:2.4.1' - - dependencySet(group: 'org.hyperledger.besu', version: '0.9.6') { - entry 'arithmetic' - entry 'ipa-multipoint' - entry 'bls12-381' - entry 'secp256k1' - entry 'secp256r1' - entry 'blake2bf' - entry 'gnark' - } - - dependencySet(group: 'org.hyperledger.besu', version: '0.8.4-SNAPSHOT') { - entry 'ipa-multipoint' - } - - dependency 'org.hyperledger.besu:besu-verkle-trie:0.0.3-20241002.133354-5' - - dependencySet(group: 'org.immutables', version: '2.10.1') { - entry 'value-annotations' - entry 'value' - } - - dependency 'org.java-websocket:Java-WebSocket:1.5.7' - - dependencySet(group: 'org.jacoco', version: '0.8.12') { - entry 'org.jacoco.agent' - entry 'org.jacoco.core' - } - - dependency 'org.jetbrains.kotlin:kotlin-stdlib:2.0.20' - - dependencySet(group: 'org.junit.jupiter', version: '5.11.0') { - entry 'junit-jupiter' - entry 'junit-jupiter-api' - entry 'junit-jupiter-engine' - entry 'junit-jupiter-params' - } - - dependency 'org.openjdk.jol:jol-core:0.17' - - dependency 'org.junit.platform:junit-platform-runner:1.9.2' - - dependency 'org.junit.vintage:junit-vintage-engine:5.10.1' - - dependencySet(group: 'org.jupnp', version:'3.0.2') { - entry 'org.jupnp.support' - entry 'org.jupnp' - } - - dependencySet(group: 'org.mockito', version:'5.13.0') { - entry 'mockito-core' - entry 'mockito-junit-jupiter' - } - - dependencySet(group: 'org.openjdk.jmh', version:'1.37') { - entry 'jmh-core' - entry 'jmh-generator-annprocess' - } - - dependency 'org.owasp.encoder:encoder:1.3.1' - - dependency 'org.rocksdb:rocksdbjni:8.3.2' // 8.9.1 causes a bug with a FOREST canary - - dependencySet(group: 'org.slf4j', version:'2.0.16') { - entry 'slf4j-api' - entry 'slf4j-nop' - } - - dependency 'org.springframework.security:spring-security-crypto:6.3.3' - - dependency 'org.testcontainers:testcontainers:1.20.1' - - dependency 'org.web3j:quorum:4.10.0' - dependencySet(group: 'org.web3j', version: '4.12.1') { - entry 'abi' - entry 'besu' - entry 'core' - entry 'crypto' - } - - dependencySet(group: 'org.wiremock', version: '3.9.1') { - entry 'wiremock' - } - - dependency 'org.xerial.snappy:snappy-java:1.1.10.6' - - dependency 'org.yaml:snakeyaml:2.0' - - dependency 'org.apache.maven:maven-artifact:3.9.6' - - dependency 'tech.pegasys:jc-kzg-4844:1.0.0' - - dependency 'tech.pegasys.discovery:discovery:24.6.0' - } -} diff --git a/metrics/core/src/main/java/org/hyperledger/besu/metrics/noop/NoOpMetricsSystem.java b/metrics/core/src/main/java/org/hyperledger/besu/metrics/noop/NoOpMetricsSystem.java index 2d1ee26cfd..5f876fa4d8 100644 --- a/metrics/core/src/main/java/org/hyperledger/besu/metrics/noop/NoOpMetricsSystem.java +++ b/metrics/core/src/main/java/org/hyperledger/besu/metrics/noop/NoOpMetricsSystem.java @@ -253,5 +253,14 @@ public class NoOpMetricsSystem implements ObservableMetricsSystem { "The count of labels used must match the count of labels expected."); Preconditions.checkNotNull(valueSupplier, "No valueSupplier specified"); } + + @Override + public boolean isLabelsObserved(final String... labelValues) { + Preconditions.checkArgument( + labelValues.length == labelCount, + "The count of labels used must match the count of labels expected."); + final String labelValuesString = String.join(",", labelValues); + return labelValuesCache.contains(labelValuesString); + } } } diff --git a/metrics/core/src/main/java/org/hyperledger/besu/metrics/noop/NoOpValueCollector.java b/metrics/core/src/main/java/org/hyperledger/besu/metrics/noop/NoOpValueCollector.java index 144e7f3187..6f36f10d2c 100644 --- a/metrics/core/src/main/java/org/hyperledger/besu/metrics/noop/NoOpValueCollector.java +++ b/metrics/core/src/main/java/org/hyperledger/besu/metrics/noop/NoOpValueCollector.java @@ -36,4 +36,10 @@ public class NoOpValueCollector implements LabelledGauge { } labelValuesCreated.add(labelValuesString); } + + @Override + public boolean isLabelsObserved(final String... labelValues) { + final String labelValuesString = String.join(",", labelValues); + return labelValuesCreated.contains(labelValuesString); + } } diff --git a/metrics/core/src/main/java/org/hyperledger/besu/metrics/opentelemetry/OpenTelemetryGauge.java b/metrics/core/src/main/java/org/hyperledger/besu/metrics/opentelemetry/OpenTelemetryGauge.java index 6aea56586a..e1d785c68e 100644 --- a/metrics/core/src/main/java/org/hyperledger/besu/metrics/opentelemetry/OpenTelemetryGauge.java +++ b/metrics/core/src/main/java/org/hyperledger/besu/metrics/opentelemetry/OpenTelemetryGauge.java @@ -63,6 +63,14 @@ public class OpenTelemetryGauge implements LabelledGauge { } } + @Override + public boolean isLabelsObserved(final String... labelValues) { + Preconditions.checkArgument( + labelValues.length == labelNames.size(), + "label values and label names need the same number of elements"); + return observationsMap.containsKey(getLabels(labelValues)); + } + private Attributes getLabels(final String... labelValues) { final AttributesBuilder labelsBuilder = Attributes.builder(); for (int i = 0; i < labelNames.size(); i++) { diff --git a/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/MetricsConfiguration.java b/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/MetricsConfiguration.java index 4a542fce00..d32823630b 100644 --- a/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/MetricsConfiguration.java +++ b/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/MetricsConfiguration.java @@ -30,13 +30,17 @@ import com.google.common.base.MoreObjects; /** The Metrics configuration. */ public class MetricsConfiguration { - private static final String DEFAULT_METRICS_HOST = "127.0.0.1"; + + /** The constant DEFAULT_METRICS_HOST. */ + public static final String DEFAULT_METRICS_HOST = "127.0.0.1"; /** The constant DEFAULT_METRICS_PORT. */ public static final int DEFAULT_METRICS_PORT = 9545; private static final MetricsProtocol DEFAULT_METRICS_PROTOCOL = MetricsProtocol.PROMETHEUS; - private static final String DEFAULT_METRICS_PUSH_HOST = "127.0.0.1"; + + /** The constant DEFAULT_METRICS_PUSH_HOST. */ + public static final String DEFAULT_METRICS_PUSH_HOST = "127.0.0.1"; /** The constant DEFAULT_METRICS_PUSH_PORT. */ public static final int DEFAULT_METRICS_PUSH_PORT = 9001; diff --git a/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusGauge.java b/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusGauge.java index 83000dfac3..b69e3f9062 100644 --- a/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusGauge.java +++ b/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusGauge.java @@ -47,10 +47,7 @@ public class PrometheusGauge extends Collector implements LabelledGauge { @Override public synchronized void labels(final DoubleSupplier valueSupplier, final String... labelValues) { - if (labelValues.length != labelNames.size()) { - throw new IllegalArgumentException( - "Label values and label names must be the same cardinality"); - } + validateLabelsCardinality(labelValues); if (observationsMap.putIfAbsent(List.of(labelValues), valueSupplier) != null) { final String labelValuesString = String.join(",", labelValues); throw new IllegalArgumentException( @@ -58,6 +55,12 @@ public class PrometheusGauge extends Collector implements LabelledGauge { } } + @Override + public boolean isLabelsObserved(final String... labelValues) { + validateLabelsCardinality(labelValues); + return observationsMap.containsKey(List.of(labelValues)); + } + @Override public List collect() { final List samples = new ArrayList<>(); @@ -68,4 +71,11 @@ public class PrometheusGauge extends Collector implements LabelledGauge { metricName, labelNames, labels, valueSupplier.getAsDouble()))); return List.of(new MetricFamilySamples(metricName, Type.GAUGE, help, samples)); } + + private void validateLabelsCardinality(final String... labelValues) { + if (labelValues.length != labelNames.size()) { + throw new IllegalArgumentException( + "Label values and label names must be the same cardinality"); + } + } } diff --git a/nat/src/main/java/org/hyperledger/besu/nat/kubernetes/KubernetesNatManager.java b/nat/src/main/java/org/hyperledger/besu/nat/kubernetes/KubernetesNatManager.java index f8af2bdddb..6a9c02a31c 100644 --- a/nat/src/main/java/org/hyperledger/besu/nat/kubernetes/KubernetesNatManager.java +++ b/nat/src/main/java/org/hyperledger/besu/nat/kubernetes/KubernetesNatManager.java @@ -84,7 +84,7 @@ public class KubernetesNatManager extends AbstractNatManager { final V1Service service = api .listServiceForAllNamespaces( - null, null, null, null, null, null, null, null, null, null) + null, null, null, null, null, null, null, null, null, null, null) .getItems() .stream() .filter( diff --git a/platform/build.gradle b/platform/build.gradle new file mode 100644 index 0000000000..581b6e4771 --- /dev/null +++ b/platform/build.gradle @@ -0,0 +1,216 @@ +/* + * 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 + */ +plugins { + id 'java-platform' + id 'com.diffplug.spotless' +} + +repositories { + mavenCentral() +} + +javaPlatform { + allowDependencies() +} + +dependencies { + api platform('com.fasterxml.jackson:jackson-bom:2.18.0') + api platform('io.grpc:grpc-bom:1.68.0') + api platform('io.netty:netty-bom:4.1.114.Final') + api platform('io.opentelemetry:opentelemetry-bom:1.43.0') + api platform('io.prometheus:simpleclient_bom:0.16.0') + api platform('io.vertx:vertx-stack-depchain:4.5.10') + api platform('org.apache.logging.log4j:log4j-bom:2.24.1') + api platform('org.assertj:assertj-bom:3.26.3') + api platform('org.immutables:bom:2.10.1') + api platform('org.junit:junit-bom:5.11.2') + api platform('org.mockito:mockito-bom:5.14.2') + api platform('org.slf4j:slf4j-bom:2.0.16') + + constraints { + api project(':acceptance-tests:dsl') + api project(':besu') + api project(':config') + api project(':crypto:algorithms') + api project(':crypto:services') + api project(':ethereum:api') + api project(':ethereum:blockcreation') + api project(':ethereum:core') + api project(':ethereum:eth') + api project(':ethereum:p2p') + api project(':ethereum:permissioning') + api project(':ethereum:referencetests') + api project(':ethereum:rlp') + api project(':evm') + api project(':datatypes') + api project(':plugin-api') + + api 'com.github.ben-manes.caffeine:caffeine:3.1.8' + + api 'com.github.oshi:oshi-core:6.6.5' + + api 'com.google.auto.service:auto-service:1.1.1' + + api 'com.google.dagger:dagger-compiler:2.52' + api 'com.google.dagger:dagger:2.52' + + api 'com.google.guava:guava:33.3.1-jre' + + api 'com.google.protobuf:protobuf-java:3.25.5' + + api 'com.graphql-java:graphql-java:22.3' + + api 'com.splunk.logging:splunk-library-javalogging:1.11.8' + + api 'com.squareup.okhttp3:okhttp:4.12.0' + + api 'commons-io:commons-io:2.17.0' + + api 'commons-net:commons-net:3.11.1' + + api 'dnsjava:dnsjava:3.6.2' + + api 'info.picocli:picocli:4.7.6' + api 'info.picocli:picocli-codegen:4.7.6' + + api 'io.kubernetes:client-java:21.0.1-legacy' + + api 'io.opentelemetry.instrumentation:opentelemetry-okhttp-3.0:2.9.0-alpha' + api 'io.opentelemetry.proto:opentelemetry-proto:1.3.2-alpha' + api 'io.opentelemetry.semconv:opentelemetry-semconv:1.28.0-alpha' + + api 'io.opentracing:opentracing-api:0.33.0' + api 'io.opentracing:opentracing-util:0.33.0' + api 'io.opentracing.contrib:opentracing-okhttp3:3.0.0' + + api 'io.pkts:pkts-core:3.0.10' + + api 'io.tmio:tuweni-bytes:2.4.2' + api 'io.tmio:tuweni-config:2.4.2' + api 'io.tmio:tuweni-concurrent:2.4.2' + api 'io.tmio:tuweni-crypto:2.4.2' + api 'io.tmio:tuweni-devp2p:2.4.2' + api 'io.tmio:tuweni-io:2.4.2' + api 'io.tmio:tuweni-net:2.4.2' + api 'io.tmio:tuweni-rlp:2.4.2' + api 'io.tmio:tuweni-toml:2.4.2' + api 'io.tmio:tuweni-units:2.4.2' + + api 'net.java.dev.jna:jna:5.15.0' + + api 'org.antlr:antlr4:4.11.1' + api 'org.antlr:antlr4-runtime:4.11.1' + + api 'org.apache.commons:commons-collections4:4.4' + api 'org.apache.commons:commons-compress:1.27.1' + api 'org.apache.commons:commons-lang3:3.17.0' + api 'org.apache.commons:commons-text:1.12.0' + + api 'org.apache.maven:maven-artifact:3.9.9' + + api 'org.awaitility:awaitility:4.2.2' + + api 'org.bouncycastle:bcpkix-jdk18on:1.78.1' + api 'org.bouncycastle:bcprov-jdk18on:1.78.1' + + api 'org.fusesource.jansi:jansi:2.4.1' + + api 'org.hibernate.validator:hibernate-validator:8.0.1.Final' + + api 'org.hyperledger.besu:arithmetic:0.9.7' + api 'org.hyperledger.besu:blake2bf:0.9.7' + api 'org.hyperledger.besu:bls12-381:0.9.7' + api 'org.hyperledger.besu:gnark:0.9.7' + api 'org.hyperledger.besu:ipa-multipoint:0.9.7' + api 'org.hyperledger.besu:secp256k1:0.9.7' + api 'org.hyperledger.besu:secp256r1:0.9.7' + + api 'org.hyperledger.besu:besu-errorprone-checks:1.0.0' + + api 'org.jacoco:org.jacoco.agent:0.8.12' + api 'org.jacoco:org.jacoco.core:0.8.12' + + api 'org.junit.platform:junit-platform-runner:1.9.2' + + api 'org.jupnp:org.jupnp:3.0.2' + api 'org.jupnp:org.jupnp.support:3.0.2' + + api 'org.openjdk.jmh:jmh-core:1.37' + api 'org.openjdk.jmh:jmh-generator-annprocess:1.37' + + api 'org.openjdk.jol:jol-core:0.17' + + api 'org.owasp.encoder:encoder:1.3.1' + + api 'org.rocksdb:rocksdbjni:8.3.2' + + api 'org.springframework.security:spring-security-crypto:6.3.3' + + api 'org.wiremock:wiremock:3.9.1' + + api 'org.web3j:abi:4.12.2' + api 'org.web3j:besu:4.12.2' + api 'org.web3j:core:4.12.2' + api 'org.web3j:crypto:4.12.2' + api 'org.web3j:quorum:4.10.0' + + api 'org.xerial.snappy:snappy-java:1.1.10.7' + + api 'tech.pegasys:jc-kzg-4844:1.0.0' + + api 'tech.pegasys.discovery:discovery:24.9.1' + + api 'org.hyperledger.besu:ipa-multipoint:0.8.4-SNAPSHOT' + + api 'org.hyperledger.besu:besu-verkle-trie:0.0.3-20241002.133354-5' + } +} + + +spotless { + // spotless check applied to build.gradle (groovy) files + groovyGradle { + target '*.gradle' + greclipse('4.31').configFile(rootProject.file('gradle/spotless/greclipse.properties')) + endWithNewline() + } +} + +publishing { + publications { + mavenPlatform(MavenPublication) { + from components.javaPlatform + groupId "org.hyperledger.besu" + artifactId 'bom' + version calculateVersion() + + pom { + name = "Besu BOM" + url = 'http://github.com/hyperledger/besu' + licenses { + license { + name = 'The Apache License, Version 2.0' + url = 'http://www.apache.org/licenses/LICENSE-2.0.txt' + } + } + scm { + connection = 'scm:git:git://github.com/hyperledger/besu.git' + developerConnection = 'scm:git:ssh://github.com/hyperledger/besu.git' + url = 'https://github.com/hyperledger/besu' + } + } + } + } +} diff --git a/plugin-api/build.gradle b/plugin-api/build.gradle index 782a7c0176..c58e74d9fd 100644 --- a/plugin-api/build.gradle +++ b/plugin-api/build.gradle @@ -71,7 +71,7 @@ Calculated : ${currentHash} tasks.register('checkAPIChanges', FileStateChecker) { description = "Checks that the API for the Plugin-API project does not change without deliberate thought" files = sourceSets.main.allJava.files - knownHash = 'ZfEX6J5KJiDwcD0Fh51DNUAt1GazIov/A8QgfFz+LhQ=' + knownHash = 'cvmMMf7nUP2AFMnV65lPH/YXnaBJ9vqL2V0Do7GWMCI=' } check.dependsOn('checkAPIChanges') diff --git a/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/BlockBody.java b/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/BlockBody.java index 18a5e07ce6..7c101f414f 100644 --- a/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/BlockBody.java +++ b/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/BlockBody.java @@ -15,7 +15,6 @@ package org.hyperledger.besu.plugin.data; import org.hyperledger.besu.datatypes.Transaction; -import org.hyperledger.besu.plugin.Unstable; import java.util.List; import java.util.Optional; @@ -47,12 +46,4 @@ public interface BlockBody { * @return The list of withdrawals of the block. */ Optional> getWithdrawals(); - - /** - * Returns the list of requests of the block. - * - * @return The list of requests of the block. - */ - @Unstable - Optional> getRequests(); } diff --git a/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/BlockHeader.java b/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/BlockHeader.java index c4e42556e4..3598d2191a 100644 --- a/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/BlockHeader.java +++ b/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/BlockHeader.java @@ -128,7 +128,7 @@ public interface BlockHeader extends ProcessableBlockHeader { * request in the request list portion of the block. */ @Unstable - Optional getRequestsRoot(); + Optional getRequestsHash(); /** * The excess_blob_gas of this header. diff --git a/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/ConsolidationRequest.java b/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/ConsolidationRequest.java deleted file mode 100644 index 5d7e66b4ae..0000000000 --- a/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/ConsolidationRequest.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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.plugin.data; - -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.PublicKey; -import org.hyperledger.besu.plugin.Unstable; - -/** A consolidation request is an operation sent to the Beacon Node for processing. */ -@Unstable -public interface ConsolidationRequest { - - /** - * Withdrawal credential (0x01) associated with the validator - * - * @return withdrawal credential address - */ - Address getSourceAddress(); - - /** - * Public key of the address that sends the consolidation - * - * @return public key of sender - */ - PublicKey getSourcePubkey(); - - /** - * Public key of the address to receives the consolidation - * - * @return public key of target - */ - PublicKey getTargetPubkey(); -} diff --git a/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/DepositRequest.java b/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/DepositRequest.java deleted file mode 100644 index 096554d3c7..0000000000 --- a/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/DepositRequest.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * 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.plugin.data; - -import org.hyperledger.besu.datatypes.BLSSignature; -import org.hyperledger.besu.datatypes.PublicKey; -import org.hyperledger.besu.datatypes.Quantity; -import org.hyperledger.besu.plugin.Unstable; - -import org.apache.tuweni.bytes.Bytes32; -import org.apache.tuweni.units.bigints.UInt64; - -/** - * A deposit is a system-level operation to support validator deposits that are pushed from the EVM - * to beacon chain. - */ -@Unstable -public interface DepositRequest { - - /** - * Public key of the address that sends the deposit - * - * @return public key of sender - */ - PublicKey getPubkey(); - - /** - * Withdrawal credential that contains info that will be used for verifying the destination of - * valid withdrawals - * - * @return withdrawal credential - */ - Bytes32 getWithdrawalCredentials(); - - /** - * Amount of ether to be sent to the deposit contract - * - * @return deposit ether amount - */ - Quantity getAmount(); - - /** - * Signature that will be used together with the public key to verify the validity of this Deposit - * - * @return signature - */ - BLSSignature getSignature(); - - /** - * A monotonically increasing index, starting from 0 that increments by 1 per deposit to uniquely - * identify each deposit - * - * @return deposit index - */ - UInt64 getIndex(); -} diff --git a/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/ProcessableBlockHeader.java b/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/ProcessableBlockHeader.java index db9bfa942e..c7a1c5b99e 100644 --- a/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/ProcessableBlockHeader.java +++ b/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/ProcessableBlockHeader.java @@ -22,6 +22,7 @@ import org.hyperledger.besu.plugin.Unstable; import java.util.Optional; import org.apache.tuweni.bytes.Bytes32; +import org.apache.tuweni.units.bigints.UInt64; /** * The minimum set of data for a BlockHeader, as defined in the getParentBeaconBlockRoot(); + + /** + * The target_blob_count of this header. + * + * @return The target blob count of this header. + */ + @Unstable + // TODO SLD should be Quantity or new subclass of Quantity? + default Optional getTargetBlobCount() { + return Optional.empty(); + } } diff --git a/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/Request.java b/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/Request.java index 2540f91098..0e55f39980 100644 --- a/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/Request.java +++ b/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/Request.java @@ -17,6 +17,8 @@ package org.hyperledger.besu.plugin.data; import org.hyperledger.besu.datatypes.RequestType; import org.hyperledger.besu.plugin.Unstable; +import org.apache.tuweni.bytes.Bytes; + /** A request is an operation sent to the Beacon Node */ @Unstable public interface Request { @@ -27,4 +29,11 @@ public interface Request { * @return The {@link RequestType} representing the type of this request. */ RequestType getType(); + + /** + * Retrieves the data of this request. + * + * @return The data {@link Bytes} of this request. + */ + Bytes getData(); } diff --git a/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/WithdrawalRequest.java b/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/WithdrawalRequest.java deleted file mode 100644 index f07d0d08d0..0000000000 --- a/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/WithdrawalRequest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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.plugin.data; - -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.GWei; -import org.hyperledger.besu.datatypes.PublicKey; -import org.hyperledger.besu.plugin.Unstable; - -/** - * A withdrawal request is an operation sent to the Beacon Node for processing validator withdrawal - * requests (partial or complete) - */ -@Unstable -public interface WithdrawalRequest { - - /** - * Withdrawal credential (0x01) associated with the validator - * - * @return withdrawal credential address - */ - Address getSourceAddress(); - - /** - * Public key of the validator that is going to request a withdrawal - * - * @return public key of validator - */ - PublicKey getValidatorPubkey(); - - /** - * The amount for withdrawal - * - * @return withdrawal amount - */ - GWei getAmount(); -} diff --git a/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/metrics/LabelledGauge.java b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/metrics/LabelledGauge.java index 724e31c58d..5357c6505a 100644 --- a/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/metrics/LabelledGauge.java +++ b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/metrics/LabelledGauge.java @@ -25,4 +25,15 @@ public interface LabelledGauge { * @param labelValues the label values */ void labels(final DoubleSupplier valueSupplier, final String... labelValues); + + /** + * Checks whether the supplied labelValues are already observed by this LabelledGauge + * + * @param labelValues The labelValues to check + * @return true if the supplied labelValues are already observed by this LabelledGauge, false + * otherwise + */ + default boolean isLabelsObserved(final String... labelValues) { + return false; + } } diff --git a/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/transactionpool/TransactionPoolService.java b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/transactionpool/TransactionPoolService.java index 01b1f5768b..ba30fa80ff 100644 --- a/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/transactionpool/TransactionPoolService.java +++ b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/transactionpool/TransactionPoolService.java @@ -14,8 +14,11 @@ */ package org.hyperledger.besu.plugin.services.transactionpool; +import org.hyperledger.besu.datatypes.PendingTransaction; import org.hyperledger.besu.plugin.services.BesuService; +import java.util.Collection; + /** Service to enable and disable the transaction pool. */ public interface TransactionPoolService extends BesuService { /** Enables the transaction pool. */ @@ -23,4 +26,11 @@ public interface TransactionPoolService extends BesuService { /** Disables the transaction pool. */ void enableTransactionPool(); + + /** + * Returns the collection of pending transactions. + * + * @return a collection of pending transactions + */ + Collection getPendingTransactions(); } diff --git a/plugins/rocksdb/build.gradle b/plugins/rocksdb/build.gradle index e5ca782504..d487cf9824 100644 --- a/plugins/rocksdb/build.gradle +++ b/plugins/rocksdb/build.gradle @@ -58,6 +58,4 @@ dependencies { testImplementation 'org.junit.jupiter:junit-jupiter' testImplementation 'org.assertj:assertj-core' testImplementation 'org.mockito:mockito-junit-jupiter' - - testRuntimeOnly 'org.junit.vintage:junit-vintage-engine' } diff --git a/privacy-contracts/src/main/solidity/generateWrappers.sh b/privacy-contracts/src/main/solidity/generateWrappers.sh index 5d7fd7f9fc..625a9360c7 100755 --- a/privacy-contracts/src/main/solidity/generateWrappers.sh +++ b/privacy-contracts/src/main/solidity/generateWrappers.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash ## -## Copyright contributors to Hyperledger Besu. +## Copyright contributors to 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 diff --git a/scripts/dco_check.sh b/scripts/dco_check.sh index dd44675398..68a5438583 100755 --- a/scripts/dco_check.sh +++ b/scripts/dco_check.sh @@ -1,6 +1,6 @@ #!/bin/bash ## -## Copyright contributors to Hyperledger Besu. +## Copyright contributors to 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 diff --git a/settings.gradle b/settings.gradle index 322383b32c..2860c666d9 100644 --- a/settings.gradle +++ b/settings.gradle @@ -62,6 +62,7 @@ include 'metrics:core' include 'metrics:rocksdb' include 'nat' include 'pki' +include 'platform' include 'plugin-api' include 'plugins:rocksdb' include 'privacy-contracts' diff --git a/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/EofContainerSubCommand.java b/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/EofContainerSubCommand.java index 27c4547d26..9b4d6e2e64 100644 --- a/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/EofContainerSubCommand.java +++ b/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/EofContainerSubCommand.java @@ -119,7 +119,7 @@ public class EofContainerSubCommand implements Runnable { .constructParametricType(Map.class, String.class, EOFTestCaseSpec.class); List fuzzingClients = new ArrayList<>(); - EVM evm = MainnetEVMs.pragueEOF(EvmConfiguration.DEFAULT); + EVM evm = MainnetEVMs.osaka(EvmConfiguration.DEFAULT); long validContainers; long totalContainers; diff --git a/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/InternalClient.java b/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/InternalClient.java index a6d7035fe8..5d2adb8e91 100644 --- a/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/InternalClient.java +++ b/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/InternalClient.java @@ -31,7 +31,7 @@ class InternalClient implements FuzzingClient { public InternalClient(final String clientName) { this.name = clientName; - this.evm = MainnetEVMs.pragueEOF(EvmConfiguration.DEFAULT); + this.evm = MainnetEVMs.osaka(EvmConfiguration.DEFAULT); } @Override diff --git a/testutil/build.gradle b/testutil/build.gradle index 5b4f06e7ac..1663c36650 100644 --- a/testutil/build.gradle +++ b/testutil/build.gradle @@ -28,6 +28,10 @@ jar { } } +sonarqube { + skipProject = true +} + dependencies { implementation project(':ethereum:eth') implementation project(':plugin-api') @@ -45,6 +49,4 @@ dependencies { implementation 'org.assertj:assertj-core' implementation 'org.mockito:mockito-core' implementation 'org.web3j:core' - - implementation 'org.testcontainers:testcontainers' } diff --git a/testutil/src/main/java/org/hyperledger/besu/testutil/JsonTestParameters.java b/testutil/src/main/java/org/hyperledger/besu/testutil/JsonTestParameters.java index f95ac9348e..585e3dd5f0 100644 --- a/testutil/src/main/java/org/hyperledger/besu/testutil/JsonTestParameters.java +++ b/testutil/src/main/java/org/hyperledger/besu/testutil/JsonTestParameters.java @@ -341,10 +341,15 @@ public class JsonTestParameters { } } - private static class JsonTestCaseReader { + /** + * Parameterized wrapper for deserialization. + * + * @param the type parameter + */ + public static class JsonTestCaseReader { /** The Test case specs. */ - final Map testCaseSpecs; + public final Map testCaseSpecs; /** * Public constructor. diff --git a/testutil/src/main/java/org/hyperledger/enclave/testutil/TesseraTestHarness.java b/testutil/src/main/java/org/hyperledger/enclave/testutil/TesseraTestHarness.java deleted file mode 100644 index f27224fa1d..0000000000 --- a/testutil/src/main/java/org/hyperledger/enclave/testutil/TesseraTestHarness.java +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Copyright ConsenSys AG. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - */ -package org.hyperledger.enclave.testutil; - -import static com.google.common.io.Files.readLines; - -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Path; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; - -import com.google.common.base.Charsets; -import io.vertx.core.json.JsonArray; -import org.assertj.core.util.Files; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.utility.MountableFile; - -/** The Tessera test harness. */ -public class TesseraTestHarness implements EnclaveTestHarness { - private static final Logger LOG = LoggerFactory.getLogger(TesseraTestHarness.class); - - private final EnclaveConfiguration enclaveConfiguration; - - private boolean isRunning; - private URI nodeURI; - private URI q2TUri; - private URI thirdPartyUri; - - /** The constant TESSERA_VERSION. */ - public static final String TESSERA_VERSION = "22.10.0"; - - private final int thirdPartyPort = 9081; - private final int q2TPort = 9082; - - /** The constant p2pPort. */ - public static final int p2pPort = 9001; - - private final String containerKeyDir = "/tmp/keys/"; - - @SuppressWarnings("rawtypes") - private GenericContainer tesseraContainer; - - private final Optional containerNetwork; - private final String containerName; - - /** - * Instantiates a new Tessera test harness. - * - * @param enclaveConfiguration the enclave configuration - * @param containerNetwork the container network - */ - protected TesseraTestHarness( - final EnclaveConfiguration enclaveConfiguration, final Optional containerNetwork) { - this.enclaveConfiguration = enclaveConfiguration; - this.containerNetwork = containerNetwork; - this.containerName = enclaveConfiguration.getName(); - Runtime.getRuntime().addShutdownHook(new Thread(this::stop)); - } - - @Override - public void start() { - if (!isRunning) { - final File tempFolder = Files.newTemporaryFolder(); - LOG.info("Temporary directory: " + tempFolder.getAbsolutePath()); - final String configFile = createConfigFile(enclaveConfiguration.getName()); - - tesseraContainer = buildTesseraContainer(configFile); - containerNetwork.ifPresent(network -> addNetwork(tesseraContainer, containerName, network)); - tesseraContainer.start(); - isRunning = true; - - try { - final String host = "http://" + tesseraContainer.getHost(); - nodeURI = new URI(host + ":" + tesseraContainer.getMappedPort(p2pPort)); - LOG.info("Tessera node URI: {}", nodeURI); - q2TUri = new URI(host + ':' + tesseraContainer.getMappedPort(q2TPort)); - LOG.info("Tessera client URI: {}", q2TUri); - thirdPartyUri = new URI(host + ':' + tesseraContainer.getMappedPort(thirdPartyPort)); - LOG.info("Tessera thirdParty URI: {}", thirdPartyUri); - } catch (final URISyntaxException e) { - throw new RuntimeException(e); - } - } - } - - @Override - public void stop() { - if (isRunning) { - tesseraContainer.stop(); - isRunning = false; - } - } - - @Override - public void close() { - stop(); - } - - @Override - public List getPublicKeyPaths() { - return Arrays.asList(enclaveConfiguration.getPublicKeys()); - } - - @Override - public String getDefaultPublicKey() { - return readFile(enclaveConfiguration.getPublicKeys()[0]); - } - - @Override - public List getPublicKeys() { - return Arrays.stream(enclaveConfiguration.getPublicKeys()) - .map(TesseraTestHarness::readFile) - .collect(Collectors.toList()); - } - - private static String readFile(final Path path) { - try { - return readLines(path.toFile(), Charsets.UTF_8).get(0); - } catch (final IOException e) { - e.printStackTrace(); - return ""; - } - } - - @Override - public URI clientUrl() { - return q2TUri; - } - - @Override - public URI nodeUrl() { - return nodeURI; - } - - @Override - public void addOtherNode(final URI otherNode) { - enclaveConfiguration.addOtherNode(otherNode.toString()); - } - - @Override - public EnclaveType getEnclaveType() { - return EnclaveType.TESSERA; - } - - private String createConfigFile(final String nodeName) { - // create a config file - - // @formatter:off - String confString = - "{\n" - + " \"mode\" : \"orion\",\n" - + enclaveConfiguration.getEnclaveEncryptorType().toTesseraEncryptorConfigJSON() - + " \"useWhiteList\": false,\n" - + " \"jdbc\": {\n" - + " \"username\": \"sa\",\n" - + " \"password\": \"\",\n" - + " \"url\": \"jdbc:h2:/tmp/db;MODE=Oracle;TRACE_LEVEL_SYSTEM_OUT=0\",\n" - + " \"autoCreateTables\": true\n" - + " },\n" - + " \"serverConfigs\":[\n" - + " {\n" - + " \"app\":\"ThirdParty\",\n" - + " \"enabled\": true,\n" - + " \"serverAddress\": \"http://" - + nodeName - + ":" - + thirdPartyPort - + "\",\n" - + " \"cors\" : {\n" - + " \"allowedMethods\" : [\"GET\", \"OPTIONS\"],\n" - + " \"allowedOrigins\" : [\"*\"]\n" - + " },\n" - + " \"communicationType\" : \"REST\"\n" - + " },\n" - + " {\n" - + " \"app\":\"Q2T\",\n" - + " \"enabled\": true,\n" - + " \"serverAddress\":\"http://" - + nodeName - + ":" - + q2TPort - + "\",\n" - + " \"communicationType\" : \"REST\"\n" - + " },\n" - + " {\n" - + " \"app\":\"P2P\",\n" - + " \"enabled\": true,\n" - + " \"serverAddress\":\"http://" - + nodeName - + ":" - + p2pPort - + "\",\n" - + " \"communicationType\" : \"REST\"\n" - + " }\n" - + " ],\n" - + " \"keys\": {\n" - + " \"passwords\": [],\n" - + " \"keyData\": " - + buildKeyConfig() - + "\n" - + " },\n" - + " \"alwaysSendTo\": []"; - - if (enclaveConfiguration.getOtherNodes().size() != 0) { - confString += - ",\n" - + " \"peer\": [\n" - + " {\n" - + " \"url\": \"" - + enclaveConfiguration.getOtherNodes().get(0) - + "\"\n" - + " }\n" - + " ]"; - } else { - confString += ",\n" + " \"peer\": []"; - } - - confString += "\n}"; - - final File configFile = Files.newTemporaryFile(); - try { - final FileWriter fw = new FileWriter(configFile, StandardCharsets.UTF_8); - fw.write(confString); - fw.close(); - } catch (final IOException e) { - throw new RuntimeException(e); - } - - return configFile.getAbsolutePath(); - } - - private String buildKeyConfig() { - final JsonArray keyArray = new JsonArray(); - final List pubKeysPaths = Arrays.asList(enclaveConfiguration.getPublicKeys()); - final List privKeyPaths = Arrays.asList(enclaveConfiguration.getPrivateKeys()); - - for (int count = 0; count < pubKeysPaths.size(); count++) { - final HashMap stringStringHashMap = new HashMap<>(); - stringStringHashMap.put( - "publicKeyPath", containerKeyDir + pubKeysPaths.get(count).getFileName()); - stringStringHashMap.put( - "privateKeyPath", containerKeyDir + privKeyPaths.get(count).getFileName()); - keyArray.add(stringStringHashMap); - } - - return keyArray.toString(); - } - - @SuppressWarnings("rawtypes") - private GenericContainer buildTesseraContainer(final String configFilePath) { - final String containerConfigFilePath = "/tmp/config.json"; - final String keyDir = enclaveConfiguration.getTempDir().toString(); - return new GenericContainer<>("quorumengineering/tessera:" + TESSERA_VERSION) - .withCopyFileToContainer(MountableFile.forHostPath(configFilePath), containerConfigFilePath) - .withFileSystemBind(keyDir, containerKeyDir) - .withCommand("--configfile " + containerConfigFilePath) - .withExposedPorts(p2pPort, q2TPort, thirdPartyPort) - .waitingFor(Wait.forHttp("/upcheck").withMethod("GET").forStatusCode(200)); - } - - @SuppressWarnings("rawtypes") - private void addNetwork( - final GenericContainer container, final String containerName, final Network network) { - container.withNetwork(network).withNetworkAliases(containerName); - } -} diff --git a/testutil/src/main/java/org/hyperledger/enclave/testutil/TesseraTestHarnessFactory.java b/testutil/src/main/java/org/hyperledger/enclave/testutil/TesseraTestHarnessFactory.java deleted file mode 100644 index 0cfe8b76c9..0000000000 --- a/testutil/src/main/java/org/hyperledger/enclave/testutil/TesseraTestHarnessFactory.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright ConsenSys AG. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - */ -package org.hyperledger.enclave.testutil; - -import static org.apache.tuweni.io.file.Files.copyResource; - -import java.io.IOException; -import java.nio.file.Path; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import javax.annotation.Nonnull; - -import org.testcontainers.containers.Network; - -/** The Tessera test harness factory. */ -public class TesseraTestHarnessFactory { - private static final String storage = "memory"; - - /** Default constructor */ - private TesseraTestHarnessFactory() {} - - /** - * Create tessera test harness. - * - * @param name the name - * @param tempDir the temp dir - * @param enclaveConfig the enclave config - * @param containerNetwork the container network - * @return the tessera test harness - */ - public static TesseraTestHarness create( - final String name, - final Path tempDir, - final EnclaveKeyConfiguration enclaveConfig, - final Optional containerNetwork) { - return create( - name, - tempDir, - enclaveConfig.getPubKeyPaths(), - enclaveConfig.getPrivKeyPaths(), - enclaveConfig.getEnclaveEncryptorType(), - Collections.emptyList(), - containerNetwork); - } - - /** - * Create tessera test harness. - * - * @param name the name - * @param tempDir the temp dir - * @param pubKeyPaths the pub key paths - * @param privKeyPaths the priv key paths - * @param enclaveEncryptorType the enclave encryptor type - * @param othernodes the othernodes - * @param containerNetwork the container network - * @return the tessera test harness - */ - public static TesseraTestHarness create( - final String name, - final Path tempDir, - final String[] pubKeyPaths, - final String[] privKeyPaths, - final EnclaveEncryptorType enclaveEncryptorType, - final List othernodes, - final Optional containerNetwork) { - final Path[] pubKeys = stringArrayToPathArray(tempDir, pubKeyPaths); - final Path[] privKeys = stringArrayToPathArray(tempDir, privKeyPaths); - - return create( - name, tempDir, pubKeys, privKeys, enclaveEncryptorType, othernodes, containerNetwork); - } - - /** - * Create tessera test harness. - * - * @param name the name - * @param tempDir the temp dir - * @param key1pubs the key 1 pubs - * @param key1keys the key 1 keys - * @param enclaveEncryptorType the enclave encryptor type - * @param othernodes the othernodes - * @param containerNetwork the container network - * @return the tessera test harness - */ - public static TesseraTestHarness create( - final String name, - final Path tempDir, - final Path[] key1pubs, - final Path[] key1keys, - final EnclaveEncryptorType enclaveEncryptorType, - final List othernodes, - final Optional containerNetwork) { - return new TesseraTestHarness( - new EnclaveConfiguration( - name, key1pubs, key1keys, enclaveEncryptorType, tempDir, othernodes, false, storage), - containerNetwork); - } - - @Nonnull - private static Path[] stringArrayToPathArray(final Path tempDir, final String[] privKeyPaths) { - return Arrays.stream(privKeyPaths) - .map( - (pk) -> { - try { - return copyResource(pk, tempDir.resolve(pk)); - } catch (final IOException e) { - throw new RuntimeException(e); - } - }) - .toArray(Path[]::new); - } -}