From 0f2046d4b0eee238d858d7604ad57b4eaa5ac9b8 Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Tue, 25 Jun 2024 08:36:42 -0600 Subject: [PATCH 001/259] Temporary CancunEOF fork for EOF testing. (#7227) Add Genesis ("CancunEOFTime") and reference test ("CancunEOF") support for a temporary Cancun+EOF fork, in anticipation of potential devnets. Signed-off-by: Danno Ferrin --- .../org/hyperledger/besu/cli/BesuCommand.java | 1 + .../besu/config/GenesisConfigOptions.java | 7 ++ .../besu/config/JsonGenesisConfigOptions.java | 7 ++ .../besu/config/StubGenesisConfigOptions.java | 21 +++++- .../besu/config/GenesisConfigOptionsTest.java | 8 ++ .../besu/ethereum/chain/GenesisState.java | 10 ++- .../mainnet/MainnetProtocolSpecFactory.java | 5 ++ .../mainnet/MainnetProtocolSpecs.java | 29 ++++++- .../mainnet/ProtocolScheduleBuilder.java | 2 + .../evmtool/MainnetGenesisFileModule.java | 3 + .../evmtool/benchmarks/BenchmarkExecutor.java | 18 +++-- .../besu/evmtool/state-test/create-eof.json | 4 +- .../besu/evmtool/trace/create-eof.json | 2 +- .../ReferenceTestProtocolSchedules.java | 1 + .../hyperledger/besu/evm/EvmSpecVersion.java | 6 ++ .../org/hyperledger/besu/evm/MainnetEVMs.java | 75 +++++++++++++++++++ .../besu/evm/fluent/EVMExecutor.java | 16 ++++ .../besu/evm/fluent/EVMExecutorTest.java | 4 + .../operations/EofCreateOperationTest.java | 4 +- 19 files changed, 207 insertions(+), 16 deletions(-) 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 4262ff9644..7e1be15fb6 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java @@ -1514,6 +1514,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { } if (genesisConfigOptionsSupplier.get().getCancunTime().isPresent() + || genesisConfigOptionsSupplier.get().getCancunEOFTime().isPresent() || genesisConfigOptionsSupplier.get().getPragueTime().isPresent() || genesisConfigOptionsSupplier.get().getPragueEOFTime().isPresent()) { if (kzgTrustedSetupFile != null) { 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 8e47af3b75..849b121186 100644 --- a/config/src/main/java/org/hyperledger/besu/config/GenesisConfigOptions.java +++ b/config/src/main/java/org/hyperledger/besu/config/GenesisConfigOptions.java @@ -242,6 +242,13 @@ public interface GenesisConfigOptions { */ OptionalLong getCancunTime(); + /** + * Gets cancun EOF time. + * + * @return the cancun EOF time + */ + OptionalLong getCancunEOFTime(); + /** * Gets prague 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 d5635d9ae3..b418a67851 100644 --- a/config/src/main/java/org/hyperledger/besu/config/JsonGenesisConfigOptions.java +++ b/config/src/main/java/org/hyperledger/besu/config/JsonGenesisConfigOptions.java @@ -288,6 +288,11 @@ public class JsonGenesisConfigOptions implements GenesisConfigOptions { return getOptionalLong("shanghaitime"); } + @Override + public OptionalLong getCancunEOFTime() { + return getOptionalLong("cancuneoftime"); + } + @Override public OptionalLong getCancunTime() { return getOptionalLong("cancuntime"); @@ -461,6 +466,7 @@ public class JsonGenesisConfigOptions implements GenesisConfigOptions { getMergeNetSplitBlockNumber().ifPresent(l -> builder.put("mergeNetSplitBlock", l)); getShanghaiTime().ifPresent(l -> builder.put("shanghaiTime", l)); 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)); getTerminalBlockNumber().ifPresent(l -> builder.put("terminalBlockNumber", l)); @@ -610,6 +616,7 @@ public class JsonGenesisConfigOptions implements GenesisConfigOptions { Stream.of( getShanghaiTime(), getCancunTime(), + getCancunEOFTime(), getPragueTime(), getPragueEOFTime(), getFutureEipsTime(), 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 32800f58a1..24f3331029 100644 --- a/config/src/main/java/org/hyperledger/besu/config/StubGenesisConfigOptions.java +++ b/config/src/main/java/org/hyperledger/besu/config/StubGenesisConfigOptions.java @@ -48,6 +48,7 @@ public class StubGenesisConfigOptions implements GenesisConfigOptions, Cloneable private OptionalLong mergeNetSplitBlockNumber = OptionalLong.empty(); private OptionalLong shanghaiTime = OptionalLong.empty(); private OptionalLong cancunTime = OptionalLong.empty(); + private OptionalLong cancunEOFTime = OptionalLong.empty(); private OptionalLong pragueTime = OptionalLong.empty(); private OptionalLong pragueEOFTime = OptionalLong.empty(); private OptionalLong futureEipsTime = OptionalLong.empty(); @@ -82,7 +83,9 @@ public class StubGenesisConfigOptions implements GenesisConfigOptions, Cloneable private boolean fixedBaseFee = false; /** Default constructor. */ - public StubGenesisConfigOptions() {} + public StubGenesisConfigOptions() { + // Explicit default constructor because of JavaDoc linting + } @Override public StubGenesisConfigOptions clone() { @@ -238,6 +241,11 @@ public class StubGenesisConfigOptions implements GenesisConfigOptions, Cloneable return cancunTime; } + @Override + public OptionalLong getCancunEOFTime() { + return cancunEOFTime; + } + @Override public OptionalLong getPragueTime() { return pragueTime; @@ -630,6 +638,17 @@ public class StubGenesisConfigOptions implements GenesisConfigOptions, Cloneable return this; } + /** + * Cancun EOF time. + * + * @param timestamp the timestamp + * @return the stub genesis config options + */ + public StubGenesisConfigOptions cancunEOFTime(final long timestamp) { + cancunEOFTime = OptionalLong.of(timestamp); + return this; + } + /** * Prague time. * 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 0e8138e1bc..ed313ad6cf 100644 --- a/config/src/test/java/org/hyperledger/besu/config/GenesisConfigOptionsTest.java +++ b/config/src/test/java/org/hyperledger/besu/config/GenesisConfigOptionsTest.java @@ -193,6 +193,13 @@ class GenesisConfigOptionsTest { assertThat(config.getCancunTime()).hasValue(1670470142); } + @Test + void shouldGetCancunEOFTime() { + final GenesisConfigOptions config = + fromConfigOptions(singletonMap("cancunEOFTime", 1670470142)); + assertThat(config.getCancunEOFTime()).hasValue(1670470142); + } + @Test void shouldGetPragueTime() { final GenesisConfigOptions config = fromConfigOptions(singletonMap("pragueTime", 1670470143)); @@ -238,6 +245,7 @@ class GenesisConfigOptionsTest { assertThat(config.getMergeNetSplitBlockNumber()).isEmpty(); assertThat(config.getShanghaiTime()).isEmpty(); assertThat(config.getCancunTime()).isEmpty(); + assertThat(config.getCancunEOFTime()).isEmpty(); assertThat(config.getPragueTime()).isEmpty(); assertThat(config.getPragueEOFTime()).isEmpty(); assertThat(config.getFutureEipsTime()).isEmpty(); 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 e975a01f8f..00b20a0170 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 @@ -304,7 +304,15 @@ public final class GenesisState { if (cancunTimestamp.isPresent()) { return genesis.getTimestamp() >= cancunTimestamp.getAsLong(); } - return isPragueAtGenesis(genesis); + return isPragueAtGenesis(genesis) || isCancunEOFAtGenesis(genesis); + } + + private static boolean isCancunEOFAtGenesis(final GenesisConfigFile genesis) { + final OptionalLong cancunEOFTimestamp = genesis.getConfigOptions().getCancunEOFTime(); + if (cancunEOFTimestamp.isPresent()) { + return genesis.getTimestamp() >= cancunEOFTimestamp.getAsLong(); + } + return isPragueEOFAtGenesis(genesis); } private static boolean isPragueAtGenesis(final GenesisConfigFile genesis) { 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 a902d9faa7..aa9bae6c7e 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 @@ -128,6 +128,11 @@ public class MainnetProtocolSpecFactory { chainId, isRevertReasonEnabled, genesisConfigOptions, evmConfiguration, miningParameters); } + public ProtocolSpecBuilder cancunEOFDefinition(final GenesisConfigOptions genesisConfigOptions) { + return MainnetProtocolSpecs.cancunEOFDefinition( + chainId, isRevertReasonEnabled, genesisConfigOptions, evmConfiguration, miningParameters); + } + public ProtocolSpecBuilder pragueDefinition(final GenesisConfigOptions genesisConfigOptions) { return MainnetProtocolSpecs.pragueDefinition( chainId, isRevertReasonEnabled, genesisConfigOptions, evmConfiguration, miningParameters); 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 763c751e4f..b4a75c49c2 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 @@ -617,6 +617,19 @@ public abstract class MainnetProtocolSpecs { .name("Cancun"); } + static ProtocolSpecBuilder cancunEOFDefinition( + final Optional chainId, + final boolean enableRevertReason, + final GenesisConfigOptions genesisConfigOptions, + final EvmConfiguration evmConfiguration, + final MiningParameters miningParameters) { + + ProtocolSpecBuilder protocolSpecBuilder = + cancunDefinition( + chainId, enableRevertReason, genesisConfigOptions, evmConfiguration, miningParameters); + return addEOF(chainId, evmConfiguration, protocolSpecBuilder).name("CancunEOF"); + } + static ProtocolSpecBuilder pragueDefinition( final Optional chainId, final boolean enableRevertReason, @@ -657,8 +670,17 @@ public abstract class MainnetProtocolSpecs { final EvmConfiguration evmConfiguration, final MiningParameters miningParameters) { - return pragueDefinition( - chainId, enableRevertReason, genesisConfigOptions, evmConfiguration, miningParameters) + ProtocolSpecBuilder protocolSpecBuilder = + pragueDefinition( + chainId, enableRevertReason, genesisConfigOptions, evmConfiguration, miningParameters); + return addEOF(chainId, evmConfiguration, protocolSpecBuilder).name("PragueEOF"); + } + + private static ProtocolSpecBuilder addEOF( + final Optional chainId, + final EvmConfiguration evmConfiguration, + final ProtocolSpecBuilder protocolSpecBuilder) { + return protocolSpecBuilder // EIP-7692 EOF v1 Gas calculator .gasCalculator(PragueEOFGasCalculator::new) // EIP-7692 EOF v1 EVM and opcodes @@ -674,8 +696,7 @@ public abstract class MainnetProtocolSpecs { true, List.of(MaxCodeSizeRule.from(evm), EOFValidationCodeRule.from(evm)), 1, - SPURIOUS_DRAGON_FORCE_DELETE_WHEN_EMPTY_ADDRESSES)) - .name("PragueEOF"); + SPURIOUS_DRAGON_FORCE_DELETE_WHEN_EMPTY_ADDRESSES)); } static ProtocolSpecBuilder futureEipsDefinition( 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 100a4425cd..649442f88c 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 @@ -246,6 +246,7 @@ public class ProtocolScheduleBuilder { // Begin timestamp forks lastForkBlock = validateForkOrder("Shanghai", config.getShanghaiTime(), lastForkBlock); 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("FutureEips", config.getFutureEipsTime(), lastForkBlock); @@ -326,6 +327,7 @@ public class ProtocolScheduleBuilder { // Timestamp Forks timestampMilestone(config.getShanghaiTime(), specFactory.shanghaiDefinition(config)), timestampMilestone(config.getCancunTime(), specFactory.cancunDefinition(config)), + timestampMilestone(config.getCancunEOFTime(), specFactory.cancunEOFDefinition(config)), timestampMilestone(config.getPragueTime(), specFactory.pragueDefinition(config)), timestampMilestone(config.getPragueEOFTime(), specFactory.pragueEOFDefinition(config)), timestampMilestone(config.getFutureEipsTime(), specFactory.futureEipsDefinition(config)), 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 dc6b6dce00..db70ccf41f 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 @@ -117,6 +117,9 @@ class MainnetGenesisFileModule extends GenesisFileModule { Map.entry( "cancun", createSchedule(new StubGenesisConfigOptions().cancunTime(0).baseFeePerGas(0x0a))), + Map.entry( + "cancuneof", + createSchedule(new StubGenesisConfigOptions().cancunEOFTime(0).baseFeePerGas(0x0a))), Map.entry( "prague", createSchedule(new StubGenesisConfigOptions().pragueTime(0).baseFeePerGas(0x0a))), 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 50a6df67d4..082fae7f69 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 @@ -113,12 +113,12 @@ public abstract class BenchmarkExecutor { } timer.stop(); - if (executions < 1) { + if (executions > 0) { + final double elapsed = timer.elapsed(TimeUnit.NANOSECONDS) / 1.0e9D; + return elapsed / executions; + } else { return Double.NaN; } - - final double elapsed = timer.elapsed(TimeUnit.NANOSECONDS) / 1.0e9D; - return elapsed / executions; } /** @@ -143,7 +143,15 @@ public abstract class BenchmarkExecutor { case SHANGHAI -> new ShanghaiGasCalculator(); case CANCUN -> new CancunGasCalculator(); case PRAGUE -> new PragueGasCalculator(); - case PRAGUE_EOF, OSAKA, AMSTERDAM, BOGOTA, POLIS, BANGKOK, FUTURE_EIPS, EXPERIMENTAL_EIPS -> + case CANCUN_EOF, + PRAGUE_EOF, + OSAKA, + AMSTERDAM, + BOGOTA, + POLIS, + BANGKOK, + FUTURE_EIPS, + EXPERIMENTAL_EIPS -> new PragueEOFGasCalculator(); }; } 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 4e8529872d..e924043042 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": { - "Prague": [ + "CancunEOF": [ { "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":"Prague","d":0,"g":0,"v":0,"postHash":"0x1a8642a04dae90535f00f53d3a30284c4db051d508a653db89eb100ba9aecbf3","postLogsHash":"0xf48b954a6a6f4ce6b28e4950b7027413f4bdc8f459df6003b6e8d7a1567c8940","pass":true}, + {"output":"","gasUsed":"0xe433","test":"create-eof","fork":"CancunEOF","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/trace/create-eof.json b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/create-eof.json index bba2c85103..b0699f1b3c 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", - "pragueeof" + "CancunEOF" ], "stdin": "", "stdout": [ 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 0976b92421..4d62c314ae 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 @@ -84,6 +84,7 @@ public class ReferenceTestProtocolSchedules { "ShanghaiToCancunAtTime15k", createSchedule(genesisStub.clone().shanghaiTime(0).cancunTime(15000))); builder.put("Cancun", createSchedule(genesisStub.clone().cancunTime(0))); + builder.put("CancunEOF", createSchedule(genesisStub.clone().cancunEOFTime(0))); // also load KZG file for mainnet KZGPointEvalPrecompiledContract.init(); builder.put( 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 9bf370d031..8dc536c7bf 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/EvmSpecVersion.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/EvmSpecVersion.java @@ -55,6 +55,8 @@ public enum EvmSpecVersion { SHANGHAI(0x6000, 0xc000, 0, true, "Shanghai", "Finalized"), /** Cancun evm spec version. */ CANCUN(0x6000, 0xc000, 0, true, "Cancun", "Finalized"), + /** Cancun evm spec version. */ + CANCUN_EOF(0x6000, 0xc000, 1, false, "CancunEOF", "For Testing"), /** Prague evm spec version. */ PRAGUE(0x6000, 0xc000, 0, false, "Prague", "In Development"), /** PragueEOF evm spec version. */ @@ -201,6 +203,10 @@ public enum EvmSpecVersion { if ("prague".equalsIgnoreCase(name)) { return EvmSpecVersion.PRAGUE_EOF; } + // TODO remove once PragueEOF settles + if ("cancuneof".equalsIgnoreCase(name)) { + return EvmSpecVersion.CANCUN_EOF; + } for (var version : EvmSpecVersion.values()) { if (version.name().equalsIgnoreCase(name)) { return version; 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 11ce3546a8..2d9be8d312 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/MainnetEVMs.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/MainnetEVMs.java @@ -897,6 +897,76 @@ public class MainnetEVMs { registry.put(new BlobBaseFeeOperation(gasCalculator)); } + /** + * CancunEOF evm. + * + * @param evmConfiguration the evm configuration + * @return the evm + */ + public static EVM cancunEOF(final EvmConfiguration evmConfiguration) { + return cancunEOF(DEV_NET_CHAIN_ID, evmConfiguration); + } + + /** + * CancunEOF evm. + * + * @param chainId the chain id + * @param evmConfiguration the evm configuration + * @return the evm + */ + public static EVM cancunEOF(final BigInteger chainId, final EvmConfiguration evmConfiguration) { + return cancunEOF(new CancunGasCalculator(), chainId, evmConfiguration); + } + + /** + * CancunEOF evm. + * + * @param gasCalculator the gas calculator + * @param chainId the chain id + * @param evmConfiguration the evm configuration + * @return the evm + */ + public static EVM cancunEOF( + final GasCalculator gasCalculator, + final BigInteger chainId, + final EvmConfiguration evmConfiguration) { + return new EVM( + cancunEOFOperations(gasCalculator, chainId), + gasCalculator, + evmConfiguration, + EvmSpecVersion.CANCUN_EOF); + } + + /** + * Operation registry for PragueEOF's operations. + * + * @param gasCalculator the gas calculator + * @param chainId the chain id + * @return the operation registry + */ + public static OperationRegistry cancunEOFOperations( + final GasCalculator gasCalculator, final BigInteger chainId) { + OperationRegistry operationRegistry = new OperationRegistry(); + registerCancunEOFOperations(operationRegistry, gasCalculator, chainId); + return operationRegistry; + } + + /** + * Register CancunEOF's operations. + * + * @param registry the registry + * @param gasCalculator the gas calculator + * @param chainID the chain id + */ + public static void registerCancunEOFOperations( + final OperationRegistry registry, + final GasCalculator gasCalculator, + final BigInteger chainID) { + registerCancunOperations(registry, gasCalculator, chainID); + + registerEOFOperations(registry, gasCalculator); + } + /** * Prague evm. * @@ -1034,6 +1104,11 @@ public class MainnetEVMs { final BigInteger chainID) { registerPragueOperations(registry, gasCalculator, chainID); + registerEOFOperations(registry, gasCalculator); + } + + private static void registerEOFOperations( + final OperationRegistry registry, final GasCalculator gasCalculator) { // EIP-663 Unlimited Swap and Dup registry.put(new DupNOperation(gasCalculator)); registry.put(new SwapNOperation(gasCalculator)); 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 a65bd034d5..08b7a067a1 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 @@ -160,6 +160,7 @@ public class EVMExecutor { case PARIS -> paris(chainId, evmConfiguration); case SHANGHAI -> shanghai(chainId, evmConfiguration); 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); @@ -493,6 +494,21 @@ public class EVMExecutor { return executor; } + /** + * Instantiate Cancun EOF evm executor. + * + * @param chainId the chain ID + * @param evmConfiguration the evm configuration + * @return the evm executor + */ + public static EVMExecutor cancunEOF( + final BigInteger chainId, final EvmConfiguration evmConfiguration) { + final EVMExecutor executor = new EVMExecutor(MainnetEVMs.cancunEOF(chainId, evmConfiguration)); + executor.precompileContractRegistry = + MainnetPrecompiledContracts.cancun(executor.evm.getGasCalculator()); + return executor; + } + /** * Instantiate Prague evm executor. * 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 a080f649c9..aa9dcdb23f 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 @@ -126,6 +126,10 @@ class EVMExecutorTest { EVMExecutor cancunEVM = EVMExecutor.cancun(EvmConfiguration.DEFAULT); assertThat(cancunEVM.getChainId()).contains(defaultChainId); + EVMExecutor cancunEOFEVM = + EVMExecutor.cancunEOF(defaultChainId.toBigInteger(), EvmConfiguration.DEFAULT); + assertThat(cancunEOFEVM.getChainId()).contains(defaultChainId); + EVMExecutor pragueEVM = EVMExecutor.pragueEOF(defaultChainId.toBigInteger(), EvmConfiguration.DEFAULT); assertThat(pragueEVM.getChainId()).contains(defaultChainId); diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operations/EofCreateOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operations/EofCreateOperationTest.java index c0a7f2bcc4..86a0f8cce1 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operations/EofCreateOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operations/EofCreateOperationTest.java @@ -62,7 +62,7 @@ class EofCreateOperationTest { @Test void innerContractIsCorrect() { - final EVM evm = MainnetEVMs.pragueEOF(EvmConfiguration.DEFAULT); + final EVM evm = MainnetEVMs.cancunEOF(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.pragueEOF(EvmConfiguration.DEFAULT); + final EVM evm = MainnetEVMs.cancunEOF(EvmConfiguration.DEFAULT); Code code = evm.getCodeUncached(outerContract); if (!code.isValid()) { From 47f341edf5c80022349ab6be10d186adb3c50810 Mon Sep 17 00:00:00 2001 From: Jason Frame Date: Wed, 26 Jun 2024 15:50:45 +1000 Subject: [PATCH 002/259] Snapserver responses to return at least one response (#7190) Signed-off-by: Jason Frame --- .../ethereum/eth/manager/snap/SnapServer.java | 19 ++- .../eth/manager/snap/SnapServerTest.java | 154 ++++++++++++++++++ 2 files changed, 167 insertions(+), 6 deletions(-) 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 bfccede676..8d0add16f9 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 @@ -456,8 +456,9 @@ class SnapServer implements BesuEvents.InitialSyncCompletionListener { } else { Optional optCode = worldStateStorageCoordinator.getCode(Hash.wrap(codeHash), null); if (optCode.isPresent()) { - if (sumListBytes(codeBytes) + optCode.get().size() > maxResponseBytes - || stopWatch.getTime() > StatefulPredicate.MAX_MILLIS_PER_REQUEST) { + if (!codeBytes.isEmpty() + && (sumListBytes(codeBytes) + optCode.get().size() > maxResponseBytes + || stopWatch.getTime() > StatefulPredicate.MAX_MILLIS_PER_REQUEST)) { break; } codeBytes.add(optCode.get()); @@ -511,8 +512,9 @@ class SnapServer implements BesuEvents.InitialSyncCompletionListener { var optStorage = storage.getTrieNodeUnsafe(CompactEncoding.decode(triePath.get(0))); if (optStorage.isPresent()) { - if (sumListBytes(trieNodes) + optStorage.get().size() > maxResponseBytes - || stopWatch.getTime() > StatefulPredicate.MAX_MILLIS_PER_REQUEST) { + if (!trieNodes.isEmpty() + && (sumListBytes(trieNodes) + optStorage.get().size() > maxResponseBytes + || stopWatch.getTime() > StatefulPredicate.MAX_MILLIS_PER_REQUEST)) { break; } trieNodes.add(optStorage.get()); @@ -536,7 +538,9 @@ class SnapServer implements BesuEvents.InitialSyncCompletionListener { storage.getTrieNodeUnsafe( Bytes.concatenate(accountPrefix, CompactEncoding.decode(path))); if (optStorage.isPresent()) { - if (sumListBytes(trieNodes) + optStorage.get().size() > maxResponseBytes) { + if (!trieNodes.isEmpty() + && sumListBytes(trieNodes) + optStorage.get().size() + > maxResponseBytes) { break; } trieNodes.add(optStorage.get()); @@ -614,11 +618,14 @@ class SnapServer implements BesuEvents.InitialSyncCompletionListener { return false; } + var hasNoRecords = recordLimit.get() == 0; var underRecordLimit = recordLimit.addAndGet(1) <= MAX_ENTRIES_PER_REQUEST; var underByteLimit = byteLimit.accumulateAndGet(0, (cur, __) -> cur + encodingSizeAccumulator.apply(pair)) < maxResponseBytesFudgeFactor; - if (underRecordLimit && underByteLimit) { + // Only enforce limits when we have at least 1 record as the snapsync spec + // requires at least 1 record must be returned + if (hasNoRecords || (underRecordLimit && underByteLimit)) { return true; } else { shouldContinue.set(false); 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 d7d3fc5275..1b4cc0618c 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 @@ -221,6 +221,37 @@ public class SnapServerTest { assertThat(assertIsValidAccountRangeProof(Hash.ZERO, rangeData)).isTrue(); } + @Test + public void assertAccountLimitRangeResponse_atLeastOneAccount() { + List randomLoad = IntStream.range(1, 4096).boxed().collect(Collectors.toList()); + Collections.shuffle(randomLoad); + randomLoad.stream() + .forEach( + i -> + insertTestAccounts( + createTestAccount( + Bytes.concatenate( + Bytes.fromHexString("0x40"), + Bytes.fromHexStringLenient(Integer.toHexString(i * 256))) + .toHexString()))); + + final BytesValueRLPOutput tmp = new BytesValueRLPOutput(); + tmp.startList(); + tmp.writeBytes(storageTrie.getRootHash()); + tmp.writeBytes(Hash.ZERO); + tmp.writeBytes(HASH_LAST); + tmp.writeBigIntegerScalar(BigInteger.ZERO); + tmp.endList(); + var tinyRangeLimit = new GetAccountRangeMessage(tmp.encoded()).wrapMessageData(BigInteger.ZERO); + + var rangeData = + getAndVerifyAccountRangeData( + (AccountRangeMessage) snapServer.constructGetAccountRangeResponse(tinyRangeLimit), 1); + + // assert proofs are valid for the requested range + assertThat(assertIsValidAccountRangeProof(Hash.ZERO, rangeData)).isTrue(); + } + @Test public void assertLastEmptyRange() { // When our final range request is empty, no next account is possible, @@ -353,6 +384,42 @@ public class SnapServerTest { .isTrue(); } + @Test + public void assertStorageLimitRangeResponse_atLeastOneSlot() { + insertTestAccounts(acct1, acct2, acct3, acct4); + + final BytesValueRLPOutput tmp = new BytesValueRLPOutput(); + tmp.startList(); + tmp.writeBigIntegerScalar(BigInteger.ONE); + tmp.writeBytes(storageTrie.getRootHash()); + tmp.writeList( + List.of(acct3.addressHash, acct4.addressHash), + (hash, rlpOutput) -> rlpOutput.writeBytes(hash)); + tmp.writeBytes(Hash.ZERO); + tmp.writeBytes(HASH_LAST); + tmp.writeBigIntegerScalar(BigInteger.ZERO); + tmp.endList(); + var tinyRangeLimit = new GetStorageRangeMessage(tmp.encoded()); + + var rangeData = + (StorageRangeMessage) snapServer.constructGetStorageRangeResponse(tinyRangeLimit); + + // assert proofs are valid for the requested range + assertThat(rangeData).isNotNull(); + var slotsData = rangeData.slotsData(false); + assertThat(slotsData).isNotNull(); + assertThat(slotsData.slots()).isNotNull(); + assertThat(slotsData.slots().size()).isEqualTo(1); + var firstAccountStorages = slotsData.slots().first(); + // expecting to see complete 10 slot storage for acct3 + assertThat(firstAccountStorages.size()).isEqualTo(1); + assertThat(slotsData.proofs().size()).isNotEqualTo(0); + + assertThat( + assertIsValidStorageProof(acct4, Hash.ZERO, firstAccountStorages, slotsData.proofs())) + .isTrue(); + } + @Test public void assertAccountTriePathRequest() { insertTestAccounts(acct1, acct2, acct3, acct4); @@ -416,6 +483,39 @@ public class SnapServerTest { assertThat(trieNodes.size()).isEqualTo(accountNodeLimit * 90 / 100); } + @Test + public void assertAccountTrieLimitRequest_atLeastOneTrieNode() { + insertTestAccounts(acct1, acct2, acct3, acct4); + + var partialPathToAcct1 = Bytes.fromHexString("0x01"); // first nibble is 1 + var partialPathToAcct2 = CompactEncoding.bytesToPath(acct2.addressHash).slice(0, 1); + var partialPathToAcct3 = Bytes.fromHexString("0x03"); // first nibble is 1 + var partialPathToAcct4 = Bytes.fromHexString("0x04"); // first nibble is 1 + final BytesValueRLPOutput tmp = new BytesValueRLPOutput(); + tmp.startList(); + tmp.writeBigIntegerScalar(BigInteger.ONE); + tmp.writeBytes(storageTrie.getRootHash()); + tmp.writeList( + List.of( + List.of(partialPathToAcct4), + List.of(partialPathToAcct3), + List.of(partialPathToAcct2), + List.of(partialPathToAcct1)), + (path, rlpOutput) -> + rlpOutput.writeList(path, (b, subRlpOutput) -> subRlpOutput.writeBytes(b))); + tmp.writeBigIntegerScalar(BigInteger.ZERO); + tmp.endList(); + + var trieNodeRequest = + (TrieNodesMessage) + snapServer.constructGetTrieNodesResponse(new GetTrieNodesMessage(tmp.encoded())); + + assertThat(trieNodeRequest).isNotNull(); + List trieNodes = trieNodeRequest.nodes(false); + assertThat(trieNodes).isNotNull(); + assertThat(trieNodes.size()).isEqualTo(1); + } + @Test public void assertStorageTriePathRequest() { insertTestAccounts(acct1, acct2, acct3, acct4); @@ -468,6 +568,37 @@ public class SnapServerTest { assertThat(trieNodes.size()).isEqualTo(trieNodeLimit * 90 / 100); } + @Test + public void assertStorageTrieLimitRequest_atLeastOneTrieNode() { + insertTestAccounts(acct1, acct2, acct3, acct4); + + var pathToSlot11 = CompactEncoding.encode(Bytes.fromHexStringLenient("0x0101")); + var pathToSlot12 = CompactEncoding.encode(Bytes.fromHexStringLenient("0x0102")); + var pathToSlot1a = CompactEncoding.encode(Bytes.fromHexStringLenient("0x010A")); // not present + + final BytesValueRLPOutput tmp = new BytesValueRLPOutput(); + tmp.startList(); + tmp.writeBigIntegerScalar(BigInteger.ONE); + tmp.writeBytes(storageTrie.getRootHash()); + tmp.writeList( + List.of( + List.of(acct3.addressHash, pathToSlot11, pathToSlot12, pathToSlot1a), + List.of(acct4.addressHash, pathToSlot11, pathToSlot12, pathToSlot1a)), + (path, rlpOutput) -> + rlpOutput.writeList(path, (b, subRlpOutput) -> subRlpOutput.writeBytes(b))); + tmp.writeBigIntegerScalar(BigInteger.ZERO); + tmp.endList(); + + var trieNodeRequest = + (TrieNodesMessage) + snapServer.constructGetTrieNodesResponse(new GetTrieNodesMessage(tmp.encoded())); + + assertThat(trieNodeRequest).isNotNull(); + List trieNodes = trieNodeRequest.nodes(false); + assertThat(trieNodes).isNotNull(); + assertThat(trieNodes.size()).isEqualTo(1); + } + @Test public void assertCodePresent() { insertTestAccounts(acct1, acct2, acct3, acct4); @@ -506,6 +637,29 @@ public class SnapServerTest { assertThat(codes.codes().size()).isEqualTo(codeLimit * 90 / 100); } + @Test + public void assertCodeLimitRequest_atLeastOneByteCode() { + insertTestAccounts(acct1, acct2, acct3, acct4); + + final BytesValueRLPOutput tmp = new BytesValueRLPOutput(); + tmp.startList(); + tmp.writeBigIntegerScalar(BigInteger.ONE); + tmp.writeList( + List.of(acct3.accountValue.getCodeHash(), acct4.accountValue.getCodeHash()), + (hash, rlpOutput) -> rlpOutput.writeBytes(hash)); + tmp.writeBigIntegerScalar(BigInteger.ZERO); + tmp.endList(); + + var codeRequest = + (ByteCodesMessage) + snapServer.constructGetBytecodesResponse(new GetByteCodesMessage(tmp.encoded())); + + assertThat(codeRequest).isNotNull(); + ByteCodesMessage.ByteCodes codes = codeRequest.bytecodes(false); + assertThat(codes).isNotNull(); + assertThat(codes.codes().size()).isEqualTo(1); + } + static SnapTestAccount createTestAccount(final String hexAddr) { return new SnapTestAccount( Hash.wrap(Bytes32.rightPad(Bytes.fromHexString(hexAddr))), From 67637fa3f0a23671394d5a552376944088007ccc Mon Sep 17 00:00:00 2001 From: Jason Frame Date: Thu, 27 Jun 2024 09:35:31 +1000 Subject: [PATCH 003/259] Snapserver GetTrieNodes request to handle short hash for storage (#7264) Signed-off-by: Jason Frame --- .../ethereum/eth/manager/snap/SnapServer.java | 2 +- .../eth/manager/snap/SnapServerTest.java | 25 ++++++++++++++++++- 2 files changed, 25 insertions(+), 2 deletions(-) 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 8d0add16f9..49f725d825 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 @@ -530,7 +530,7 @@ class SnapServer implements BesuEvents.InitialSyncCompletionListener { // otherwise the first element should be account hash, and subsequent paths // are compact encoded account storage paths - final Bytes accountPrefix = triePath.get(0); + final Bytes accountPrefix = Bytes32.leftPad(triePath.getFirst()); List storagePaths = triePath.subList(1, triePath.size()); for (var path : storagePaths) { 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 1b4cc0618c..2103af4124 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 @@ -534,6 +534,24 @@ public class SnapServerTest { assertThat(trieNodes.size()).isEqualTo(4); } + @Test + public void assertStorageTrieShortAccountHashPathRequest() { + Bytes accountShortHash = Bytes.fromHexStringLenient("0x40"); + Hash accountFullHash = Hash.wrap(Bytes32.leftPad(accountShortHash)); + SnapTestAccount testAccount = createTestContractAccount(accountFullHash, inMemoryStorage); + insertTestAccounts(testAccount); + var pathToSlot11 = CompactEncoding.encode(Bytes.fromHexStringLenient("0x0101")); + var pathToSlot12 = CompactEncoding.encode(Bytes.fromHexStringLenient("0x0102")); + var trieNodeRequest = + requestTrieNodes( + storageTrie.getRootHash(), + List.of(List.of(accountShortHash, pathToSlot11, pathToSlot12))); + assertThat(trieNodeRequest).isNotNull(); + List trieNodes = trieNodeRequest.nodes(false); + assertThat(trieNodes).isNotNull(); + assertThat(trieNodes.size()).isEqualTo(2); + } + @Test public void assertStorageTrieLimitRequest() { insertTestAccounts(acct1, acct2, acct3, acct4); @@ -671,7 +689,12 @@ public class SnapServerTest { static SnapTestAccount createTestContractAccount( final String hexAddr, final BonsaiWorldStateKeyValueStorage storage) { - Hash acctHash = Hash.wrap(Bytes32.rightPad(Bytes.fromHexString(hexAddr))); + final Hash acctHash = Hash.wrap(Bytes32.rightPad(Bytes.fromHexString(hexAddr))); + return createTestContractAccount(acctHash, storage); + } + + static SnapTestAccount createTestContractAccount( + final Hash acctHash, final BonsaiWorldStateKeyValueStorage storage) { MerkleTrie trie = new StoredMerklePatriciaTrie<>( (loc, hash) -> storage.getAccountStorageTrieNode(acctHash, loc, hash), From 77183f6d600cfdc17d2f309aac507a8d038a56b5 Mon Sep 17 00:00:00 2001 From: Usman Saleem Date: Thu, 27 Jun 2024 13:09:00 +1000 Subject: [PATCH 004/259] javadoc: Adding javadoc for ethstats module (#7269) * javadoc: Adding javadoc for ethstats module --------- Signed-off-by: Usman Saleem --- .../logging/XmlExtensionConfiguration.java | 2 +- build.gradle | 1 - .../besu/ethstats/EthStatsService.java | 14 ++-- .../authentication/AuthenticationData.java | 19 +++++ .../ethstats/authentication/NodeInfo.java | 60 ++++++++++++++ .../besu/ethstats/report/BlockReport.java | 14 ++++ .../besu/ethstats/report/HistoryReport.java | 14 ++++ .../besu/ethstats/report/LatencyReport.java | 14 ++++ .../besu/ethstats/report/NodeStatsReport.java | 50 ++++++++++++ .../report/PendingTransactionsReport.java | 20 +++++ .../besu/ethstats/report/PingReport.java | 14 ++++ .../ethstats/request/EthStatsRequest.java | 65 +++++++++++++++ .../ethstats/util/EthStatsConnectOptions.java | 47 +++++++++++ .../ethstats/util/PrimusHeartBeatsHelper.java | 15 ++++ .../evmtool/src/main/resources/log4j2.xml | 2 +- util/build.gradle | 2 + .../log4j/plugin/BesuLogMessageConverter.java | 80 +++++++++++++++++++ .../plugin/BesuLogMessageConverterTest.java | 39 +++++++++ 18 files changed, 462 insertions(+), 10 deletions(-) create mode 100644 util/src/main/java/org/hyperledger/besu/util/log4j/plugin/BesuLogMessageConverter.java create mode 100644 util/src/test/java/org/hyperledger/besu/util/log4j/plugin/BesuLogMessageConverterTest.java diff --git a/besu/src/main/java/org/hyperledger/besu/cli/logging/XmlExtensionConfiguration.java b/besu/src/main/java/org/hyperledger/besu/cli/logging/XmlExtensionConfiguration.java index d2ae7071bd..1e87327655 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/logging/XmlExtensionConfiguration.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/logging/XmlExtensionConfiguration.java @@ -102,7 +102,7 @@ public class XmlExtensionConfiguration extends XmlConfiguration { dim("%t"), colorize("%-5level"), dim("%c{1}"), - colorize("%msg%n%throwable"))) + colorize("%msgc%n%throwable"))) .build(); final ConsoleAppender consoleAppender = ConsoleAppender.newBuilder().setName("Console").setLayout(patternLayout).build(); diff --git a/build.gradle b/build.gradle index 3db0da35ce..d869daf5e6 100644 --- a/build.gradle +++ b/build.gradle @@ -368,7 +368,6 @@ allprojects { // TODO: these are temporary disabled (ethereum and sub modules), it should be removed in a future PR. '-org.hyperledger.besu.ethereum,' + '-org.hyperledger.besu.ethereum.*,' + - '-org.hyperledger.besu.ethstats.*,' + '-org.hyperledger.besu.evmtool', true) options.addStringOption('Xmaxerrs','65535') diff --git a/ethereum/ethstats/src/main/java/org/hyperledger/besu/ethstats/EthStatsService.java b/ethereum/ethstats/src/main/java/org/hyperledger/besu/ethstats/EthStatsService.java index 0fa93e1b68..b96a48dc5e 100644 --- a/ethereum/ethstats/src/main/java/org/hyperledger/besu/ethstats/EthStatsService.java +++ b/ethereum/ethstats/src/main/java/org/hyperledger/besu/ethstats/EthStatsService.java @@ -80,8 +80,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * This class describes the behaviour of the EthStats service. This class is used to report pending - * transactions, blocks, and several node-related information to a netstats server. + * This class describes the behaviour of the EthStatsService. This class is used to report pending + * transactions, blocks, and several node-related information to an ethstats server. */ public class EthStatsService { @@ -112,18 +112,18 @@ public class EthStatsService { private long pingTimestamp; /** - * Instantiates a new EthStats service. + * Instantiates a new EthStatsService. * - * @param ethStatsConnectOptions the netstats url + * @param ethStatsConnectOptions the ethstats options * @param blockchainQueries the blockchain queries * @param protocolManager the protocol manager * @param transactionPool the transaction pool * @param miningCoordinator the mining coordinator - * @param syncState the sync state - * @param vertx the vertx + * @param syncState the SyncState + * @param vertx the vertx instance * @param clientVersion the client version * @param genesisConfigOptions the genesis config options - * @param p2PNetwork the p 2 p network + * @param p2PNetwork the p2p network */ public EthStatsService( final EthStatsConnectOptions ethStatsConnectOptions, diff --git a/ethereum/ethstats/src/main/java/org/hyperledger/besu/ethstats/authentication/AuthenticationData.java b/ethereum/ethstats/src/main/java/org/hyperledger/besu/ethstats/authentication/AuthenticationData.java index 2e222f08b0..cb68ebc7d1 100644 --- a/ethereum/ethstats/src/main/java/org/hyperledger/besu/ethstats/authentication/AuthenticationData.java +++ b/ethereum/ethstats/src/main/java/org/hyperledger/besu/ethstats/authentication/AuthenticationData.java @@ -19,18 +19,37 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import org.immutables.value.Value; +/** + * This interface represents the authentication data. It provides methods to get the id, info, and + * secret of the authentication data. + */ @Value.Immutable @JsonSerialize(as = ImmutableAuthenticationData.class) @JsonDeserialize(as = ImmutableAuthenticationData.class) @Value.Style(allParameters = true) public interface AuthenticationData { + /** + * Gets the id of the authentication data. + * + * @return the id of the authentication data. + */ @JsonProperty("id") String getId(); + /** + * Gets the info of the authentication data. + * + * @return the info of the authentication data. + */ @JsonProperty("info") NodeInfo getInfo(); + /** + * Gets the secret of the authentication data. + * + * @return the secret of the authentication data. + */ @JsonProperty("secret") String getSecret(); } diff --git a/ethereum/ethstats/src/main/java/org/hyperledger/besu/ethstats/authentication/NodeInfo.java b/ethereum/ethstats/src/main/java/org/hyperledger/besu/ethstats/authentication/NodeInfo.java index 19c34db4b3..b54fd9fa39 100644 --- a/ethereum/ethstats/src/main/java/org/hyperledger/besu/ethstats/authentication/NodeInfo.java +++ b/ethereum/ethstats/src/main/java/org/hyperledger/besu/ethstats/authentication/NodeInfo.java @@ -19,42 +19,102 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import org.immutables.value.Value; +/** + * This interface represents the information of a node. It provides methods to get the name, node, + * port, network, protocol, api, os, os version, client, update history capability, and contact of + * the node. + */ @Value.Immutable @JsonSerialize(as = ImmutableNodeInfo.class) @JsonDeserialize(as = ImmutableNodeInfo.class) @Value.Style(allParameters = true) public interface NodeInfo { + /** + * Gets the name of the node. + * + * @return the name of the node. + */ @JsonProperty("name") String getName(); + /** + * Gets the node. + * + * @return the node. + */ @JsonProperty("node") String getNode(); + /** + * Gets the port of the node. + * + * @return the port of the node. + */ @JsonProperty("port") String getPort(); + /** + * Gets the network of the node. + * + * @return the network of the node. + */ @JsonProperty("net") String getNetwork(); + /** + * Gets the protocol of the node. + * + * @return the protocol of the node. + */ @JsonProperty("protocol") String getProtocol(); + /** + * Gets the api of the node. + * + * @return the api of the node. + */ @JsonProperty("api") String getApi(); + /** + * Gets the operating system of the node. + * + * @return the operating system of the node. + */ @JsonProperty("os") String getOs(); + /** + * Gets the operating system version of the node. + * + * @return the operating system version of the node. + */ @JsonProperty("os_v") String getOsVer(); + /** + * Gets the client of the node. + * + * @return the client of the node. + */ @JsonProperty("client") String getClient(); + /** + * Gets the update history capability of the node. + * + * @return the update history capability of the node. + */ @JsonProperty("canUpdateHistory") Boolean getCanUpdateHistory(); + /** + * Gets the contact of the node. + * + * @return the contact of the node. + */ @JsonProperty("contact") String getContact(); } diff --git a/ethereum/ethstats/src/main/java/org/hyperledger/besu/ethstats/report/BlockReport.java b/ethereum/ethstats/src/main/java/org/hyperledger/besu/ethstats/report/BlockReport.java index ccedbb0395..c4816d6486 100644 --- a/ethereum/ethstats/src/main/java/org/hyperledger/besu/ethstats/report/BlockReport.java +++ b/ethereum/ethstats/src/main/java/org/hyperledger/besu/ethstats/report/BlockReport.java @@ -21,15 +21,29 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import org.immutables.value.Value; +/** + * This interface represents a block report. It provides methods to get the id and block result of + * the block report. + */ @Value.Immutable @Value.Style(allParameters = true) @JsonSerialize(as = ImmutableBlockReport.class) @JsonDeserialize(as = ImmutableBlockReport.class) public interface BlockReport { + /** + * Gets the id of the block report. + * + * @return the id of the block report. + */ @JsonProperty("id") String getId(); + /** + * Gets the block result of the block report. + * + * @return the block result of the block report. + */ @JsonProperty("block") BlockResult getBlock(); } diff --git a/ethereum/ethstats/src/main/java/org/hyperledger/besu/ethstats/report/HistoryReport.java b/ethereum/ethstats/src/main/java/org/hyperledger/besu/ethstats/report/HistoryReport.java index 3aafa6200b..5df2c848ca 100644 --- a/ethereum/ethstats/src/main/java/org/hyperledger/besu/ethstats/report/HistoryReport.java +++ b/ethereum/ethstats/src/main/java/org/hyperledger/besu/ethstats/report/HistoryReport.java @@ -23,15 +23,29 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import org.immutables.value.Value; +/** + * This interface represents a history report. It provides methods to get the id and history of the + * history report. + */ @Value.Immutable @Value.Style(allParameters = true) @JsonSerialize(as = ImmutableHistoryReport.class) @JsonDeserialize(as = ImmutableHistoryReport.class) public interface HistoryReport { + /** + * Gets the id of the history report. + * + * @return the id of the history report. + */ @JsonProperty(value = "id") String getId(); + /** + * Gets the block results of the history report. + * + * @return the list of block results of the history report. + */ @JsonProperty("history") List getHistory(); } diff --git a/ethereum/ethstats/src/main/java/org/hyperledger/besu/ethstats/report/LatencyReport.java b/ethereum/ethstats/src/main/java/org/hyperledger/besu/ethstats/report/LatencyReport.java index 58201332b9..5c58842724 100644 --- a/ethereum/ethstats/src/main/java/org/hyperledger/besu/ethstats/report/LatencyReport.java +++ b/ethereum/ethstats/src/main/java/org/hyperledger/besu/ethstats/report/LatencyReport.java @@ -19,15 +19,29 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import org.immutables.value.Value; +/** + * This interface represents a latency report. It provides methods to get the id and latency of the + * latency report. + */ @Value.Immutable @Value.Style(allParameters = true) @JsonSerialize(as = ImmutableLatencyReport.class) @JsonDeserialize(as = ImmutableLatencyReport.class) public interface LatencyReport { + /** + * Gets the id of the latency report. + * + * @return the id of the latency report. + */ @JsonProperty("id") String getId(); + /** + * Gets the latency of the latency report. + * + * @return the latency of the latency report. + */ @JsonProperty("latency") String getLatency(); } diff --git a/ethereum/ethstats/src/main/java/org/hyperledger/besu/ethstats/report/NodeStatsReport.java b/ethereum/ethstats/src/main/java/org/hyperledger/besu/ethstats/report/NodeStatsReport.java index 67bc977a19..af95de720a 100644 --- a/ethereum/ethstats/src/main/java/org/hyperledger/besu/ethstats/report/NodeStatsReport.java +++ b/ethereum/ethstats/src/main/java/org/hyperledger/besu/ethstats/report/NodeStatsReport.java @@ -19,42 +19,92 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import org.immutables.value.Value; +/** + * This interface represents a node stats report. It provides methods to get the id and stats of the + * node stats report. + */ @Value.Immutable @Value.Style(deepImmutablesDetection = true, depluralize = true) @JsonSerialize(as = ImmutableNodeStatsReport.class) @JsonDeserialize(as = ImmutableNodeStatsReport.class) public interface NodeStatsReport { + /** + * Gets the id of the node stats report. + * + * @return the id of the node stats report. + */ @JsonProperty("id") String getId(); + /** + * Gets the stats of the node stats report. + * + * @return the stats of the node stats report. + */ @JsonProperty("stats") NStats getStats(); + /** This interface represents the stats of a node. */ @Value.Immutable @Value.Style(allParameters = true) @JsonSerialize(as = ImmutableNStats.class) @JsonDeserialize(as = ImmutableNStats.class) interface NStats { + /** + * Checks if the node is active. + * + * @return true if the node is active, false otherwise. + */ @JsonProperty("active") boolean isActive(); + /** + * Checks if the node is mining. + * + * @return true if the node is mining, false otherwise. + */ @JsonProperty("mining") boolean isMining(); + /** + * Gets the hashrate of the node. + * + * @return the hashrate of the node. + */ @JsonProperty("hashrate") long getHashrate(); + /** + * Gets the number of peers of the node. + * + * @return the number of peers of the node. + */ @JsonProperty("peers") int getPeers(); + /** + * Gets the gas price of the node. + * + * @return the gas price of the node. + */ @JsonProperty("gasPrice") long getGasPrice(); + /** + * Checks if the node is syncing. + * + * @return true if the node is syncing, false otherwise. + */ @JsonProperty("syncing") boolean isSyncing(); + /** + * Gets the uptime of the node. + * + * @return the uptime of the node. + */ @JsonProperty("uptime") int getUpTime(); } diff --git a/ethereum/ethstats/src/main/java/org/hyperledger/besu/ethstats/report/PendingTransactionsReport.java b/ethereum/ethstats/src/main/java/org/hyperledger/besu/ethstats/report/PendingTransactionsReport.java index 5c168e2907..dbb19ac34b 100644 --- a/ethereum/ethstats/src/main/java/org/hyperledger/besu/ethstats/report/PendingTransactionsReport.java +++ b/ethereum/ethstats/src/main/java/org/hyperledger/besu/ethstats/report/PendingTransactionsReport.java @@ -19,24 +19,44 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import org.immutables.value.Value; +/** + * This interface represents a pending transactions report. It provides methods to get the id and + * stats of the pending transactions report. + */ @Value.Immutable @Value.Style(deepImmutablesDetection = true, depluralize = true) @JsonSerialize(as = ImmutablePendingTransactionsReport.class) @JsonDeserialize(as = ImmutablePendingTransactionsReport.class) public interface PendingTransactionsReport { + /** + * Gets the id of the pending transactions report. + * + * @return the id of the pending transactions report. + */ @JsonProperty("id") String getId(); + /** + * Gets the stats of the pending transactions report. + * + * @return the stats of the pending transactions report. + */ @JsonProperty("stats") PStats getStats(); + /** This interface represents the stats of a pending transactions report. */ @Value.Immutable @Value.Style(allParameters = true) @JsonSerialize(as = ImmutablePStats.class) @JsonDeserialize(as = ImmutablePStats.class) interface PStats { + /** + * Gets the number of pending transactions. + * + * @return the number of pending transactions. + */ @JsonProperty("pending") int getPending(); } diff --git a/ethereum/ethstats/src/main/java/org/hyperledger/besu/ethstats/report/PingReport.java b/ethereum/ethstats/src/main/java/org/hyperledger/besu/ethstats/report/PingReport.java index 945f35530b..d7470a65cf 100644 --- a/ethereum/ethstats/src/main/java/org/hyperledger/besu/ethstats/report/PingReport.java +++ b/ethereum/ethstats/src/main/java/org/hyperledger/besu/ethstats/report/PingReport.java @@ -19,15 +19,29 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import org.immutables.value.Value; +/** + * This interface represents a ping report. It provides methods to get the id and current time of + * the ping report. + */ @Value.Immutable @Value.Style(allParameters = true) @JsonSerialize(as = ImmutablePingReport.class) @JsonDeserialize(as = ImmutablePingReport.class) public interface PingReport { + /** + * Gets the id of the ping report. + * + * @return the id of the ping report. + */ @JsonProperty("id") String getId(); + /** + * Gets the current time of the ping report. + * + * @return the current time of the ping report. + */ @JsonProperty("clientTime") String getCurrentTime(); } diff --git a/ethereum/ethstats/src/main/java/org/hyperledger/besu/ethstats/request/EthStatsRequest.java b/ethereum/ethstats/src/main/java/org/hyperledger/besu/ethstats/request/EthStatsRequest.java index dbd8b9ccf6..8d2acf3a05 100644 --- a/ethereum/ethstats/src/main/java/org/hyperledger/besu/ethstats/request/EthStatsRequest.java +++ b/ethereum/ethstats/src/main/java/org/hyperledger/besu/ethstats/request/EthStatsRequest.java @@ -23,10 +23,16 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +/** + * This class represents an Ethereum statistics request. It provides methods to get the type of the + * request and the parameters associated with it. + */ public class EthStatsRequest { + /** The constant MAPPER. */ public static final ObjectMapper MAPPER = new ObjectMapper(); + /** The constant EMIT_FIELD. */ public static final String EMIT_FIELD = "emit"; @JsonProperty(EMIT_FIELD) @@ -34,11 +40,22 @@ public class EthStatsRequest { private EthStatsRequest() {} + /** + * Constructs a new EthStatsRequest with the given type and parameters. + * + * @param type the type of the request + * @param parameters the parameters of the request + */ public EthStatsRequest(final Type type, final Object... parameters) { this.emit = Stream.concat(Stream.of(type.value), Stream.of(parameters)).collect(Collectors.toList()); } + /** + * Gets the type of the request. + * + * @return the type of the request + */ @JsonIgnore public Type getType() { return getEmit().stream() @@ -49,14 +66,31 @@ public class EthStatsRequest { .orElse(Type.UNKNOWN); } + /** + * Gets the parameters of the request. + * + * @return the parameters of the request + */ public List getEmit() { return emit; } + /** + * Generates a command string from the request. + * + * @return the command string + * @throws JsonProcessingException if there is an error processing the JSON + */ public String generateCommand() throws JsonProcessingException { return MAPPER.writeValueAsString(this); } + /** + * Creates an EthStatsRequest from a response string. + * + * @param value the response string + * @return the EthStatsRequest + */ public static EthStatsRequest fromResponse(final String value) { try { return MAPPER.readValue(value, EthStatsRequest.class); @@ -65,16 +99,36 @@ public class EthStatsRequest { } } + /** The enum Type represents the type of the request. */ public enum Type { + /** Represents the 'hello' type of the request. */ HELLO("hello"), + + /** Represents the 'ready' type of the request. */ READY("ready"), + + /** Represents the 'node-ping' type of the request. */ NODE_PING("node-ping"), + + /** Represents the 'node-pong' type of the request. */ NODE_PONG("node-pong"), + + /** Represents the 'latency' type of the request. */ LATENCY("latency"), + + /** Represents the 'block' type of the request. */ BLOCK("block"), + + /** Represents the 'history' type of the request. */ HISTORY("history"), + + /** Represents the 'pending' type of the request. */ PENDING("pending"), + + /** Represents the 'stats' type of the request. */ STATS("stats"), + + /** Represents an unknown type of the request. */ UNKNOWN(""); String value; @@ -83,10 +137,21 @@ public class EthStatsRequest { this.value = value; } + /** + * Gets the value of the type. + * + * @return the value of the type + */ public String getValue() { return value; } + /** + * Gets the type from a value string. + * + * @param value the value string + * @return the type + */ public static Type fromValue(final String value) { for (Type type : values()) { if (type.value.equalsIgnoreCase(value)) { diff --git a/ethereum/ethstats/src/main/java/org/hyperledger/besu/ethstats/util/EthStatsConnectOptions.java b/ethereum/ethstats/src/main/java/org/hyperledger/besu/ethstats/util/EthStatsConnectOptions.java index 7f020adf45..1db7473523 100644 --- a/ethereum/ethstats/src/main/java/org/hyperledger/besu/ethstats/util/EthStatsConnectOptions.java +++ b/ethereum/ethstats/src/main/java/org/hyperledger/besu/ethstats/util/EthStatsConnectOptions.java @@ -23,24 +23,71 @@ import javax.annotation.Nullable; import org.immutables.value.Value; import org.slf4j.LoggerFactory; +/** + * This interface represents the connection options for Ethereum statistics. It provides methods to + * get the scheme, node name, secret, host, port, contact, and CA certificate. + */ @Value.Immutable public interface EthStatsConnectOptions { + /** + * Gets the scheme of the connection. + * + * @return the scheme of the connection. + */ @Nullable String getScheme(); + /** + * Gets the node name of the connection. + * + * @return the node name of the connection. + */ String getNodeName(); + /** + * Gets the secret of the connection. + * + * @return the secret of the connection. + */ String getSecret(); + /** + * Gets the host of the connection. + * + * @return the host of the connection. + */ String getHost(); + /** + * Gets the port of the connection. + * + * @return the port of the connection. + */ Integer getPort(); + /** + * Gets the contact of the connection. + * + * @return the contact of the connection. + */ String getContact(); + /** + * Gets the CA certificate of the connection. + * + * @return the CA certificate of the connection. + */ @Nullable Path getCaCert(); + /** + * Creates an EthStatsConnectOptions from the given parameters. + * + * @param url the url of the connection + * @param contact the contact of the connection + * @param caCert the CA certificate of the connection + * @return the EthStatsConnectOptions + */ static EthStatsConnectOptions fromParams( final String url, final String contact, final Path caCert) { try { diff --git a/ethereum/ethstats/src/main/java/org/hyperledger/besu/ethstats/util/PrimusHeartBeatsHelper.java b/ethereum/ethstats/src/main/java/org/hyperledger/besu/ethstats/util/PrimusHeartBeatsHelper.java index e96019ef81..03b6634af1 100644 --- a/ethereum/ethstats/src/main/java/org/hyperledger/besu/ethstats/util/PrimusHeartBeatsHelper.java +++ b/ethereum/ethstats/src/main/java/org/hyperledger/besu/ethstats/util/PrimusHeartBeatsHelper.java @@ -18,14 +18,29 @@ import java.util.regex.Pattern; import io.vertx.core.http.WebSocket; +/** This class provides helper methods for handling Primus heartbeats. */ public final class PrimusHeartBeatsHelper { + /** The constant PRIMUS_PING_REGEX. */ public static final Pattern PRIMUS_PING_REGEX = Pattern.compile("primus::ping::([\\d]+)"); + private PrimusHeartBeatsHelper() {} + + /** + * Checks if the given request is a heartbeat request. + * + * @param request the request to check + * @return true if the request is a heartbeat request, false otherwise + */ public static boolean isHeartBeatsRequest(final String request) { return PRIMUS_PING_REGEX.matcher(request).find(); } + /** + * Sends a heartbeat response through the given WebSocket. + * + * @param webSocket the WebSocket to send the response through + */ public static void sendHeartBeatsResponse(final WebSocket webSocket) { if (webSocket != null) { webSocket.writeTextMessage(String.format("\"primus::pong::%d\"", System.currentTimeMillis())); diff --git a/ethereum/evmtool/src/main/resources/log4j2.xml b/ethereum/evmtool/src/main/resources/log4j2.xml index 0d3a7de136..8e70c35eea 100644 --- a/ethereum/evmtool/src/main/resources/log4j2.xml +++ b/ethereum/evmtool/src/main/resources/log4j2.xml @@ -6,7 +6,7 @@ - + diff --git a/util/build.gradle b/util/build.gradle index b2a93b1c78..41e4badb33 100644 --- a/util/build.gradle +++ b/util/build.gradle @@ -31,6 +31,8 @@ jar { dependencies { api 'org.slf4j:slf4j-api' + annotationProcessor 'org.apache.logging.log4j:log4j-core' + implementation 'com.google.guava:guava' implementation 'net.java.dev.jna:jna' implementation 'org.apache.commons:commons-lang3' diff --git a/util/src/main/java/org/hyperledger/besu/util/log4j/plugin/BesuLogMessageConverter.java b/util/src/main/java/org/hyperledger/besu/util/log4j/plugin/BesuLogMessageConverter.java new file mode 100644 index 0000000000..5598f92f9d --- /dev/null +++ b/util/src/main/java/org/hyperledger/besu/util/log4j/plugin/BesuLogMessageConverter.java @@ -0,0 +1,80 @@ +/* + * 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.log4j.plugin; + +import org.apache.logging.log4j.core.LogEvent; +import org.apache.logging.log4j.core.config.plugins.Plugin; +import org.apache.logging.log4j.core.pattern.ConverterKeys; +import org.apache.logging.log4j.core.pattern.LogEventPatternConverter; +import org.apache.logging.log4j.core.pattern.PatternConverter; + +/** + * Besu Log4j2 plugin for cleaner message logging. + * + *

Usage: In the pattern layout configuration, replace {@code %msg} with {@code %msgc}. + */ +@Plugin(name = "BesuLogMessageConverter", category = PatternConverter.CATEGORY) +@ConverterKeys({"msgc"}) +public class BesuLogMessageConverter extends LogEventPatternConverter { + + private BesuLogMessageConverter() { + super("BesuLogMessageConverter", null); + } + + /** + * Creates new instance of this class. Required by Log4j2. + * + * @param options Array of options + * @return instance of this class + */ + @SuppressWarnings("unused") // used by Log4j2 + public static BesuLogMessageConverter newInstance(final String[] options) { + return new BesuLogMessageConverter(); + } + + @Override + public void format(final LogEvent event, final StringBuilder toAppendTo) { + final String filteredString = formatBesuLogMessage(event.getMessage().getFormattedMessage()); + toAppendTo.append(filteredString); + } + + /** + * Format Besu log message. + * + * @param input The log message + * @return The formatted log message + */ + public static String formatBesuLogMessage(final String input) { + final StringBuilder builder = new StringBuilder(input.length()); + char prevChar = 0; + + for (int i = 0; i < input.length(); i++) { + final char c = input.charAt(i); + + if (c == 0x0A) { + if (prevChar == 0x0D) { + builder.append(prevChar); + } + builder.append(c); + } else if (c == 0x09 || !Character.isISOControl(c)) { + builder.append(c); + } + + prevChar = c; + } + + return builder.toString(); + } +} diff --git a/util/src/test/java/org/hyperledger/besu/util/log4j/plugin/BesuLogMessageConverterTest.java b/util/src/test/java/org/hyperledger/besu/util/log4j/plugin/BesuLogMessageConverterTest.java new file mode 100644 index 0000000000..777e5c31a3 --- /dev/null +++ b/util/src/test/java/org/hyperledger/besu/util/log4j/plugin/BesuLogMessageConverterTest.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.util.log4j.plugin; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; + +public class BesuLogMessageConverterTest { + + @Test + public void logCleanup() { + final StringBuilder testDataBuilder = new StringBuilder("log "); + for (int i = 0; i <= 0x001F; i++) { + testDataBuilder.append((char) i); + } + for (int i = 0x007F; i <= 0x009F; i++) { + testDataBuilder.append((char) i); + } + testDataBuilder.append((char) 0x0D).append((char) 0x0A).append("message"); + + String testData = testDataBuilder.toString(); + String cleanedData = BesuLogMessageConverter.formatBesuLogMessage(testData); + String expectedData = String.format("log %c%c%c%cmessage", 0x09, 0x0A, 0x0D, 0x0A); + assertThat(cleanedData).isEqualTo(expectedData); + } +} From bcacbab467d296825e99e98916fd96b5ee37b424 Mon Sep 17 00:00:00 2001 From: Usman Saleem Date: Thu, 27 Jun 2024 14:03:25 +1000 Subject: [PATCH 005/259] Fix javadoc for ethereum:core top level package (#7270) * javadoc - Apply javadoc to ethereum core top level package --------- Signed-off-by: Usman Saleem --- build.gradle | 1 - .../besu/ethereum/BlockProcessingOutputs.java | 29 +++++++++ .../besu/ethereum/BlockProcessingResult.java | 52 ++++++++++++++++ .../besu/ethereum/BlockValidationResult.java | 40 +++++++++++++ .../besu/ethereum/BlockValidator.java | 49 +++++++++++++++ .../besu/ethereum/ConsensusContext.java | 12 ++++ .../ethereum/ConsensusContextFactory.java | 10 ++++ .../besu/ethereum/GasLimitCalculator.java | 23 +++++++- .../besu/ethereum/MainnetBlockValidator.java | 22 +++++++ .../besu/ethereum/ProtocolContext.java | 59 +++++++++++++++++++ 10 files changed, 295 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index d869daf5e6..a8e02a8835 100644 --- a/build.gradle +++ b/build.gradle @@ -366,7 +366,6 @@ allprojects { '-org.hyperledger.besu.tests.acceptance.*,' + '-org.hyperledger.besu.tests.web3j.generated,' + // TODO: these are temporary disabled (ethereum and sub modules), it should be removed in a future PR. - '-org.hyperledger.besu.ethereum,' + '-org.hyperledger.besu.ethereum.*,' + '-org.hyperledger.besu.evmtool', true) diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/BlockProcessingOutputs.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/BlockProcessingOutputs.java index 4064b1ef11..92d9769768 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/BlockProcessingOutputs.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/BlockProcessingOutputs.java @@ -21,17 +21,31 @@ import org.hyperledger.besu.ethereum.core.TransactionReceipt; import java.util.List; import java.util.Optional; +/** Contains the outputs of processing a block. */ public class BlockProcessingOutputs { private final MutableWorldState worldState; private final List receipts; private final Optional> maybeRequests; + /** + * Creates a new instance. + * + * @param worldState the world state after processing the block + * @param receipts the receipts produced by processing the block + */ public BlockProcessingOutputs( final MutableWorldState worldState, final List receipts) { this(worldState, receipts, Optional.empty()); } + /** + * Creates a new instance. + * + * @param worldState the world state after processing the block + * @param receipts the receipts produced by processing the block + * @param maybeRequests the requests produced by processing the block + */ public BlockProcessingOutputs( final MutableWorldState worldState, final List receipts, @@ -41,14 +55,29 @@ public class BlockProcessingOutputs { this.maybeRequests = maybeRequests; } + /** + * Returns the world state after processing the block. + * + * @return the world state after processing the block + */ public MutableWorldState getWorldState() { return worldState; } + /** + * Returns the receipts produced by processing the block. + * + * @return the receipts produced by processing the block + */ public List getReceipts() { return receipts; } + /** + * Returns the requests produced by processing the block. + * + * @return the requests produced by processing the block + */ public Optional> getRequests() { return maybeRequests; } 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 be8b2dd3d4..926dd13abd 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 @@ -20,24 +20,43 @@ import java.util.ArrayList; import java.util.List; import java.util.Optional; +/** Contains the outputs of processing a block. */ public class BlockProcessingResult extends BlockValidationResult { private final Optional yield; private final boolean isPartial; + /** A result indicating that processing failed. */ public static final BlockProcessingResult FAILED = new BlockProcessingResult("processing failed"); + /** + * A result indicating that processing was successful but incomplete. + * + * @param yield the outputs of processing a block + */ public BlockProcessingResult(final Optional yield) { this.yield = yield; this.isPartial = false; } + /** + * A result indicating that processing was successful but incomplete. + * + * @param yield the outputs of processing a block + * @param isPartial whether the processing was incomplete + */ public BlockProcessingResult( final Optional yield, final boolean isPartial) { this.yield = yield; this.isPartial = isPartial; } + /** + * A result indicating that processing was successful but incomplete. + * + * @param yield the outputs of processing a block + * @param errorMessage the error message if any + */ public BlockProcessingResult( final Optional yield, final String errorMessage) { super(errorMessage); @@ -45,6 +64,12 @@ public class BlockProcessingResult extends BlockValidationResult { this.isPartial = false; } + /** + * A result indicating that processing was successful but incomplete. + * + * @param yield the outputs of processing a block + * @param cause the cause of the error if any + */ public BlockProcessingResult( final Optional yield, final Throwable cause) { super(cause.getLocalizedMessage(), cause); @@ -52,6 +77,13 @@ public class BlockProcessingResult extends BlockValidationResult { this.isPartial = false; } + /** + * A result indicating that processing was successful but incomplete. + * + * @param yield the outputs of processing a block + * @param errorMessage the error message if any + * @param isPartial whether the processing was incomplete + */ public BlockProcessingResult( final Optional yield, final String errorMessage, @@ -61,20 +93,40 @@ public class BlockProcessingResult extends BlockValidationResult { this.isPartial = isPartial; } + /** + * A result indicating that processing failed. + * + * @param errorMessage the error message + */ public BlockProcessingResult(final String errorMessage) { super(errorMessage); this.isPartial = false; this.yield = Optional.empty(); } + /** + * Gets the block processing outputs of the result. + * + * @return the block processing outputs of the result + */ public Optional getYield() { return yield; } + /** + * Checks if the processing was incomplete. + * + * @return true if the processing was incomplete, false otherwise + */ public boolean isPartial() { return isPartial; } + /** + * Gets the transaction receipts of the result. + * + * @return the transaction receipts of the result + */ public List getReceipts() { if (yield.isEmpty()) { return new ArrayList<>(); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/BlockValidationResult.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/BlockValidationResult.java index 68a13c7d98..83734e29c0 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/BlockValidationResult.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/BlockValidationResult.java @@ -16,38 +16,78 @@ package org.hyperledger.besu.ethereum; import java.util.Optional; +/** + * Represents the result of a block validation. This class holds the success status, error message, + * and cause of the validation. + */ public class BlockValidationResult { + /** The error message of the failed validation, if any. */ public final Optional errorMessage; + + /** The cause of the failed validation, if any. */ public final Optional cause; + + /** + * The success status of the validation. True if the validation was successful, false otherwise. + */ public final boolean success; + /** Constructs a new BlockValidationResult indicating a successful validation. */ public BlockValidationResult() { this.success = true; this.errorMessage = Optional.empty(); this.cause = Optional.empty(); } + /** + * Constructs a new BlockValidationResult indicating a failed validation with the given error + * message. + * + * @param errorMessage the error message of the failed validation + */ public BlockValidationResult(final String errorMessage) { this.success = false; this.errorMessage = Optional.of(errorMessage); this.cause = Optional.empty(); } + /** + * Constructs a new BlockValidationResult indicating a failed validation with the given error + * message and cause. + * + * @param errorMessage the error message of the failed validation + * @param cause the cause of the failed validation + */ public BlockValidationResult(final String errorMessage, final Throwable cause) { this.success = false; this.errorMessage = Optional.of(errorMessage); this.cause = Optional.of(cause); } + /** + * Checks if the validation was successful. + * + * @return true if the validation was successful, false otherwise + */ public boolean isSuccessful() { return this.success; } + /** + * Checks if the validation failed. + * + * @return true if the validation failed, false otherwise + */ public boolean isFailed() { return !isSuccessful(); } + /** + * Gets the cause of the failed validation. + * + * @return the cause of the failed validation + */ public Optional causedBy() { return cause; } 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 dc4c071ec1..e8136062bb 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 @@ -22,14 +22,39 @@ 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 + * Ethereum protocol. + */ public interface BlockValidator { + /** + * Validates and processes a block with the given context, block, header validation mode, and + * ommer validation mode. + * + * @param context the protocol context + * @param block the block to validate and process + * @param headerValidationMode the header validation mode + * @param ommerValidationMode the ommer validation mode + * @return the result of the block processing + */ BlockProcessingResult validateAndProcessBlock( final ProtocolContext context, final Block block, final HeaderValidationMode headerValidationMode, final HeaderValidationMode ommerValidationMode); + /** + * Validates and processes a block with the given context, block, header validation mode, ommer + * validation mode, and persistence flag. + * + * @param context the protocol context + * @param block the block to validate and process + * @param headerValidationMode the header validation mode + * @param ommerValidationMode the ommer validation mode + * @param shouldPersist flag indicating whether the block should be persisted + * @return the result of the block processing + */ BlockProcessingResult validateAndProcessBlock( final ProtocolContext context, final Block block, @@ -37,6 +62,18 @@ public interface BlockValidator { final HeaderValidationMode ommerValidationMode, final boolean shouldPersist); + /** + * Validates and processes a block with the given context, block, header validation mode, ommer + * validation mode, persistence flag, and bad block recording flag. + * + * @param context the protocol context + * @param block the block to validate and process + * @param headerValidationMode the header validation mode + * @param ommerValidationMode the ommer validation mode + * @param shouldPersist flag indicating whether the block should be persisted + * @param shouldRecordBadBlock flag indicating whether bad blocks should be recorded + * @return the result of the block processing + */ BlockProcessingResult validateAndProcessBlock( final ProtocolContext context, final Block block, @@ -45,6 +82,18 @@ public interface BlockValidator { final boolean shouldPersist, final boolean shouldRecordBadBlock); + /** + * Performs fast block validation with the given context, block, transaction receipts, requests, + * header validation mode, and ommer validation mode. + * + * @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 + * @return true if the block is valid, false otherwise + */ boolean fastBlockValidation( final ProtocolContext context, final Block block, diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/ConsensusContext.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/ConsensusContext.java index dc1c117ae8..33ade39ab3 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/ConsensusContext.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/ConsensusContext.java @@ -14,7 +14,19 @@ */ package org.hyperledger.besu.ethereum; +/** + * The ConsensusContext interface defines a method for casting the consensus context to a specific + * class. + */ @FunctionalInterface public interface ConsensusContext { + + /** + * Casts the consensus context to the specified class. + * + * @param the type of the class to cast the consensus context to + * @param klass the class to cast the consensus context to + * @return the consensus context cast to the specified class + */ C as(final Class klass); } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/ConsensusContextFactory.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/ConsensusContextFactory.java index 848d861197..a9381fa199 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/ConsensusContextFactory.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/ConsensusContextFactory.java @@ -18,9 +18,19 @@ import org.hyperledger.besu.ethereum.chain.Blockchain; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; +/** The ConsensusContextFactory interface defines a method for creating a consensus context. */ @FunctionalInterface public interface ConsensusContextFactory { + /** + * Creates a consensus context with the given blockchain, world state archive, and protocol + * schedule. + * + * @param blockchain the blockchain + * @param worldStateArchive the world state archive + * @param protocolSchedule the protocol schedule + * @return the created consensus context + */ ConsensusContext create( Blockchain blockchain, WorldStateArchive worldStateArchive, diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/GasLimitCalculator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/GasLimitCalculator.java index 3d5375c401..7c15d6229c 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/GasLimitCalculator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/GasLimitCalculator.java @@ -14,16 +14,37 @@ */ package org.hyperledger.besu.ethereum; +/** The GasLimitCalculator interface defines methods for calculating the gas limit. */ public interface GasLimitCalculator { - static final long BLOB_GAS_LIMIT = 786432; + /** The constant BLOB_GAS_LIMIT represents the gas limit for blob data. */ + long BLOB_GAS_LIMIT = 786432; + /** + * Calculates the next gas limit based on the current gas limit, target gas limit, and new block + * number. + * + * @param currentGasLimit the current gas limit + * @param targetGasLimit the target gas limit + * @param newBlockNumber the new block number + * @return the calculated next gas limit + */ long nextGasLimit(long currentGasLimit, long targetGasLimit, long newBlockNumber); + /** + * Returns a GasLimitCalculator that always returns the current gas limit. + * + * @return a GasLimitCalculator that always returns the current gas limit + */ static GasLimitCalculator constant() { return (currentGasLimit, targetGasLimit, newBlockNumber) -> currentGasLimit; } + /** + * Returns the current blob gas limit. + * + * @return the current blob gas limit + */ default long currentBlobGasLimit() { return BLOB_GAS_LIMIT; } 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 1b2847d08c..5d80a95150 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 @@ -36,14 +36,36 @@ import java.util.Optional; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +/** + * The MainnetBlockValidator class implements the BlockValidator interface for the Mainnet Ethereum + * network. It validates and processes blocks according to the rules of the Mainnet Ethereum + * network. + */ public class MainnetBlockValidator implements BlockValidator { private static final Logger LOG = LoggerFactory.getLogger(MainnetBlockValidator.class); + + /** The BlockHeaderValidator used to validate block headers. */ protected final BlockHeaderValidator blockHeaderValidator; + + /** The BlockBodyValidator used to validate block bodies. */ protected final BlockBodyValidator blockBodyValidator; + + /** The BlockProcessor used to process blocks. */ protected final BlockProcessor blockProcessor; + + /** The BadBlockManager used to manage bad blocks. */ protected final BadBlockManager badBlockManager; + /** + * Constructs a new MainnetBlockValidator with the given BlockHeaderValidator, BlockBodyValidator, + * BlockProcessor, and BadBlockManager. + * + * @param blockHeaderValidator the BlockHeaderValidator used to validate block headers + * @param blockBodyValidator the BlockBodyValidator used to validate block bodies + * @param blockProcessor the BlockProcessor used to process blocks + * @param badBlockManager the BadBlockManager used to manage bad blocks + */ public MainnetBlockValidator( final BlockHeaderValidator blockHeaderValidator, final BlockBodyValidator blockBodyValidator, 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 1468c62102..e5ec5ae092 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 @@ -35,6 +35,15 @@ public class ProtocolContext { private Optional synchronizer; + /** + * Constructs a new ProtocolContext with the given blockchain, world state archive, consensus + * context, and bad block manager. + * + * @param blockchain the blockchain of the protocol context + * @param worldStateArchive the world state archive of the protocol context + * @param consensusContext the consensus context of the protocol context + * @param badBlockManager the bad block manager of the protocol context + */ public ProtocolContext( final MutableBlockchain blockchain, final WorldStateArchive worldStateArchive, @@ -47,6 +56,17 @@ public class ProtocolContext { this.badBlockManager = badBlockManager; } + /** + * Initializes a new ProtocolContext with the given blockchain, world state archive, protocol + * schedule, consensus context factory, and bad block manager. + * + * @param blockchain the blockchain of the protocol context + * @param worldStateArchive the world state archive of the protocol context + * @param protocolSchedule the protocol schedule of the protocol context + * @param consensusContextFactory the consensus context factory of the protocol context + * @param badBlockManager the bad block manager of the protocol context + * @return the initialized ProtocolContext + */ public static ProtocolContext init( final MutableBlockchain blockchain, final WorldStateArchive worldStateArchive, @@ -60,30 +80,69 @@ public class ProtocolContext { badBlockManager); } + /** + * Gets the synchronizer of the protocol context. + * + * @return the synchronizer of the protocol context + */ public Optional getSynchronizer() { return synchronizer; } + /** + * Sets the synchronizer of the protocol context. + * + * @param synchronizer the synchronizer to set + */ public void setSynchronizer(final Optional synchronizer) { this.synchronizer = synchronizer; } + /** + * Gets the blockchain of the protocol context. + * + * @return the blockchain of the protocol context + */ public MutableBlockchain getBlockchain() { return blockchain; } + /** + * Gets the world state archive of the protocol context. + * + * @return the world state archive of the protocol context + */ public WorldStateArchive getWorldStateArchive() { return worldStateArchive; } + /** + * Gets the bad block manager of the protocol context. + * + * @return the bad block manager of the protocol context + */ public BadBlockManager getBadBlockManager() { return badBlockManager; } + /** + * Gets the consensus context of the protocol context. + * + * @param the type of the consensus context + * @param klass the klass + * @return the consensus context of the protocol context + */ public C getConsensusContext(final Class klass) { return consensusContext.as(klass); } + /** + * Gets the safe consensus context of the protocol context. + * + * @param the type of the consensus context + * @param klass the klass + * @return the consensus context of the protocol context + */ public Optional safeConsensusContext(final Class klass) { return Optional.ofNullable(consensusContext) .filter(c -> klass.isAssignableFrom(c.getClass())) From 571e03096dec1e5dbd8d6d9295e015b772b2bd08 Mon Sep 17 00:00:00 2001 From: Sally MacFarlane Date: Thu, 27 Jun 2024 15:10:19 +1000 Subject: [PATCH 006/259] Disable Flaky tests - permissioning (#7256) * disable some flaky tests Signed-off-by: Sally MacFarlane * correct name for test Signed-off-by: Sally MacFarlane * formatting Signed-off-by: Sally MacFarlane * disable some flaky tests Signed-off-by: Sally MacFarlane --------- Signed-off-by: Sally MacFarlane Co-authored-by: Usman Saleem --- .../NodeSmartContractPermissioningAcceptanceTest.java | 2 ++ .../NodeSmartContractPermissioningV2AcceptanceTest.java | 2 ++ ...NodeSmartContractPermissioningV2DNSAcceptanceTest.java | 8 ++------ .../api/jsonrpc/internal/methods/EthEstimateGasTest.java | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeSmartContractPermissioningAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeSmartContractPermissioningAcceptanceTest.java index 8f17c78add..903919c800 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeSmartContractPermissioningAcceptanceTest.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeSmartContractPermissioningAcceptanceTest.java @@ -17,6 +17,7 @@ package org.hyperledger.besu.tests.acceptance.permissioning; import org.hyperledger.besu.tests.acceptance.dsl.node.Node; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; public class NodeSmartContractPermissioningAcceptanceTest @@ -57,6 +58,7 @@ public class NodeSmartContractPermissioningAcceptanceTest } @Test + @Disabled("test is flaky") public void permissionedNodeShouldPeerOnlyWithAllowedNodes() { bootnode.verify(net.awaitPeerCount(3)); allowedNode.verify(net.awaitPeerCount(3)); diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeSmartContractPermissioningV2AcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeSmartContractPermissioningV2AcceptanceTest.java index 843d14004f..efb88178d6 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeSmartContractPermissioningV2AcceptanceTest.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeSmartContractPermissioningV2AcceptanceTest.java @@ -17,6 +17,7 @@ package org.hyperledger.besu.tests.acceptance.permissioning; import org.hyperledger.besu.tests.acceptance.dsl.node.Node; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; public class NodeSmartContractPermissioningV2AcceptanceTest @@ -51,6 +52,7 @@ public class NodeSmartContractPermissioningV2AcceptanceTest } @Test + @Disabled("test is flaky") public void permissionedNodeShouldPeerOnlyWithAllowedNodes() { bootnode.verify(net.awaitPeerCount(3)); allowedNode.verify(net.awaitPeerCount(3)); diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeSmartContractPermissioningV2DNSAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeSmartContractPermissioningV2DNSAcceptanceTest.java index 7a55283e4f..435333a776 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeSmartContractPermissioningV2DNSAcceptanceTest.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeSmartContractPermissioningV2DNSAcceptanceTest.java @@ -25,8 +25,10 @@ import java.net.UnknownHostException; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; +@Disabled("test is flaky #7191") public class NodeSmartContractPermissioningV2DNSAcceptanceTest extends NodeSmartContractPermissioningV2AcceptanceTestBase { @@ -57,12 +59,6 @@ public class NodeSmartContractPermissioningV2DNSAcceptanceTest permissionedNode.execute(allowNode(permissionedNode)); permissionedNode.verify(connectionIsAllowed(permissionedNode)); - - // Verify initial configuration - bootnode.verify(net.awaitPeerCount(3)); - allowedNode.verify(net.awaitPeerCount(3)); - forbiddenNode.verify(net.awaitPeerCount(2)); - permissionedNode.verify(net.awaitPeerCount(2)); } @Test diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthEstimateGasTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthEstimateGasTest.java index 98b9226404..aa52a31c1f 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthEstimateGasTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthEstimateGasTest.java @@ -361,7 +361,7 @@ public class EthEstimateGasTest { } @Test - public void shouldNotIgnoreSenderBalanceAccountWhenStrictModeDisabled() { + public void shouldNotIgnoreSenderBalanceAccountWhenStrictModeEnabled() { final JsonRpcRequestContext request = ethEstimateGasRequest(legacyTransactionCallParameter(Wei.ZERO, true)); mockTransientProcessorResultGasEstimate(1L, false, true); From d7f851071ccadd88149ebc6eda382c06c706a05e Mon Sep 17 00:00:00 2001 From: Matt Whitehead Date: Thu, 27 Jun 2024 11:34:44 +0100 Subject: [PATCH 007/259] Add bootnodes to the maintained peer list (#7257) * Add bootnodes to the maintained peer list Signed-off-by: Matthew Whitehead * Update unit tests Signed-off-by: Matthew Whitehead * Add entry in changelog Signed-off-by: Matthew Whitehead * Tweak unit test Signed-off-by: Matthew Whitehead * Refactor to keep common steps the same for both cases Signed-off-by: Matthew Whitehead * Add debug log, call sanitizePeers() only once Signed-off-by: Matthew Whitehead --------- Signed-off-by: Matthew Whitehead --- CHANGELOG.md | 1 + ...eSmartContractPermissioningAcceptanceTest.java | 4 ++-- ...martContractPermissioningV2AcceptanceTest.java | 6 +++--- .../java/org/hyperledger/besu/RunnerBuilder.java | 15 ++++++++++++++- 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 07cdf58634..4eb0b5166d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ - Update Docker base image to Ubuntu 24.04 [#7251](https://github.com/hyperledger/besu/pull/7251) - Add LUKSO as predefined network name [#7223](https://github.com/hyperledger/besu/pull/7223) - Refactored how code, initcode, and max stack size are configured in forks. [#7245](https://github.com/hyperledger/besu/pull/7245) +- Nodes in a permissioned chain maintain (and retry) connections to bootnodes [#7257](https://github.com/hyperledger/besu/pull/7257) ### Bug fixes - Validation errors ignored in accounts-allowlist and empty list [#7138](https://github.com/hyperledger/besu/issues/7138) diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeSmartContractPermissioningAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeSmartContractPermissioningAcceptanceTest.java index 903919c800..f1ed4e1490 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeSmartContractPermissioningAcceptanceTest.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeSmartContractPermissioningAcceptanceTest.java @@ -38,9 +38,10 @@ public class NodeSmartContractPermissioningAcceptanceTest permissionedCluster.start(bootnode, forbiddenNode, allowedNode, permissionedNode); // updating permissioning smart contract with allowed nodes - + permissionedNode.verify(nodeIsForbidden(bootnode)); permissionedNode.execute(allowNode(bootnode)); permissionedNode.verify(nodeIsAllowed(bootnode)); + permissionedNode.verify(admin.hasPeer(bootnode)); permissionedNode.execute(allowNode(allowedNode)); permissionedNode.verify(nodeIsAllowed(allowedNode)); @@ -48,7 +49,6 @@ public class NodeSmartContractPermissioningAcceptanceTest permissionedNode.execute(allowNode(permissionedNode)); permissionedNode.verify(nodeIsAllowed(permissionedNode)); - permissionedNode.verify(admin.addPeer(bootnode)); permissionedNode.verify(admin.addPeer(allowedNode)); allowedNode.verify(eth.syncingStatus(false)); diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeSmartContractPermissioningV2AcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeSmartContractPermissioningV2AcceptanceTest.java index efb88178d6..1f2cc682c6 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeSmartContractPermissioningV2AcceptanceTest.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeSmartContractPermissioningV2AcceptanceTest.java @@ -62,7 +62,7 @@ public class NodeSmartContractPermissioningV2AcceptanceTest @Test public void permissionedNodeShouldDisconnectFromNodeNotPermittedAnymore() { - permissionedNode.verify(admin.addPeer(bootnode)); + permissionedNode.verify(admin.hasPeer(bootnode)); permissionedNode.verify(admin.addPeer(allowedNode)); permissionedNode.verify(net.awaitPeerCount(2)); @@ -74,7 +74,7 @@ public class NodeSmartContractPermissioningV2AcceptanceTest @Test public void permissionedNodeShouldConnectToNewlyPermittedNode() { - permissionedNode.verify(admin.addPeer(bootnode)); + permissionedNode.verify(admin.hasPeer(bootnode)); permissionedNode.verify(admin.addPeer(allowedNode)); permissionedNode.verify(net.awaitPeerCount(2)); @@ -89,7 +89,7 @@ public class NodeSmartContractPermissioningV2AcceptanceTest @Test public void permissioningUpdatesPropagateThroughNetwork() { - permissionedNode.verify(admin.addPeer(bootnode)); + permissionedNode.verify(admin.hasPeer(bootnode)); permissionedNode.verify(admin.addPeer(allowedNode)); permissionedNode.verify(net.awaitPeerCount(2)); diff --git a/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java b/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java index 1f9c48cccc..e9f9ef6268 100644 --- a/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java @@ -790,7 +790,20 @@ public class RunnerBuilder { LOG.debug("added ethash observer: {}", stratumServer.get()); } - sanitizePeers(network, staticNodes) + final Stream maintainedPeers; + if (besuController.getGenesisConfigOptions().isPoa()) { + // In a permissioned chain Besu should maintain connections to both static nodes and + // bootnodes, which includes retries periodically + maintainedPeers = + sanitizePeers( + network, + Stream.concat(staticNodes.stream(), bootnodes.stream()).collect(Collectors.toList())); + LOG.debug("Added bootnodes to the maintained peer list"); + } else { + // In a public chain only maintain connections to static nodes + maintainedPeers = sanitizePeers(network, staticNodes); + } + maintainedPeers .map(DefaultPeer::fromEnodeURL) .forEach(peerNetwork::addMaintainedConnectionPeer); From 3c5ce8bb897b47ddd32f9984f3e767aa2f2105bd Mon Sep 17 00:00:00 2001 From: Usman Saleem Date: Fri, 28 Jun 2024 10:40:55 +1000 Subject: [PATCH 008/259] Fix javadoc for ethereum api module, graphql package (#7272) * javadoc - Adding missing javadocs ethereum:api graphql package Signed-off-by: Usman Saleem --- build.gradle | 62 ++++- .../besu/ethereum/api/ApiConfiguration.java | 67 +++++ .../api/graphql/GraphQLConfiguration.java | 78 +++++- .../api/graphql/GraphQLContextType.java | 21 +- .../graphql/GraphQLDataFetcherContext.java | 38 +++ .../GraphQLDataFetcherContextImpl.java | 33 +++ .../api/graphql/GraphQLDataFetchers.java | 89 ++++++ .../api/graphql/GraphQLHttpService.java | 43 +++ .../ethereum/api/graphql/GraphQLProvider.java | 18 ++ .../api/graphql/internal/Scalars.java | 47 ++++ .../pojoadapter/AccessListEntryAdapter.java | 21 ++ .../internal/pojoadapter/AccountAdapter.java | 55 ++++ .../pojoadapter/BlockAdapterBase.java | 158 +++++++++++ .../internal/pojoadapter/CallResult.java | 29 ++ .../pojoadapter/EmptyAccountAdapter.java | 13 + .../internal/pojoadapter/LogAdapter.java | 41 +++ .../pojoadapter/NormalBlockAdapter.java | 59 ++++ .../pojoadapter/PendingStateAdapter.java | 65 ++++- .../pojoadapter/SyncStateAdapter.java | 30 +++ .../pojoadapter/TransactionAdapter.java | 253 ++++++++++++++++++ .../pojoadapter/WithdrawalAdapter.java | 34 +++ .../internal/response/GraphQLError.java | 133 ++++++--- .../response/GraphQLErrorResponse.java | 14 + .../internal/response/GraphQLJsonRequest.java | 41 +++ .../internal/response/GraphQLNoResponse.java | 12 + .../internal/response/GraphQLResponse.java | 22 +- .../response/GraphQLResponseType.java | 7 + .../response/GraphQLSuccessResponse.java | 21 ++ .../ethereum/p2p/testing/MockNetwork.java | 5 + 29 files changed, 1465 insertions(+), 44 deletions(-) diff --git a/build.gradle b/build.gradle index a8e02a8835..1adc3b992c 100644 --- a/build.gradle +++ b/build.gradle @@ -365,9 +365,65 @@ allprojects { options.addBooleanOption('Xdoclint/package:-org.hyperledger.besu.privacy.contracts.generated,' + '-org.hyperledger.besu.tests.acceptance.*,' + '-org.hyperledger.besu.tests.web3j.generated,' + - // TODO: these are temporary disabled (ethereum and sub modules), it should be removed in a future PR. - '-org.hyperledger.besu.ethereum.*,' + - '-org.hyperledger.besu.evmtool', + // TODO: these are temporary excluded from lint (ethereum sub modules), it should be removed in a future PR. + // ethereum api module + '-org.hyperledger.besu.ethereum.api.handlers,' + + '-org.hyperledger.besu.ethereum.api.jsonrpc,' + + '-org.hyperledger.besu.ethereum.api.jsonrpc.*,' + + '-org.hyperledger.besu.ethereum.api.query,' + + '-org.hyperledger.besu.ethereum.api.query.*,' + + '-org.hyperledger.besu.ethereum.api.tls,' + + '-org.hyperledger.besu.ethereum.api.util,' + + // ethereum blockcreation module + '-org.hyperledger.besu.ethereum.blockcreation,' + + '-org.hyperledger.besu.ethereum.blockcreation.*,' + + // ethereum core module + '-org.hyperledger.besu.ethereum.chain,' + + '-org.hyperledger.besu.ethereum.core,' + + '-org.hyperledger.besu.ethereum.core.*,' + + '-org.hyperledger.besu.ethereum.debug,' + + '-org.hyperledger.besu.ethereum.difficulty.fixed,' + + '-org.hyperledger.besu.ethereum.forkid,' + + '-org.hyperledger.besu.ethereum.mainnet,' + + '-org.hyperledger.besu.ethereum.mainnet.*,' + + '-org.hyperledger.besu.ethereum.privacy,' + + '-org.hyperledger.besu.ethereum.privacy.*,' + + '-org.hyperledger.besu.ethereum.processing,' + + '-org.hyperledger.besu.ethereum.proof,' + + '-org.hyperledger.besu.ethereum.storage,' + + '-org.hyperledger.besu.ethereum.storage.*,' + + '-org.hyperledger.besu.ethereum.transaction,' + + '-org.hyperledger.besu.ethereum.trie.*,' + + '-org.hyperledger.besu.ethereum.util,' + + '-org.hyperledger.besu.ethereum.vm,' + + '-org.hyperledger.besu.ethereum.worldstate,' + + // ethereum eth module + '-org.hyperledger.besu.ethereum.eth.*,' + + '-org.hyperledger.besu.ethereum.eth,' + + '-org.hyperledger.besu.consensus.merge,' + + // evmtool module + '-org.hyperledger.besu.evmtool,' + + // p2p module + '-org.hyperledger.besu.ethereum.p2p,' + + '-org.hyperledger.besu.ethereum.p2p.*,' + + // permissioning module + '-org.hyperledger.besu.ethereum.permissioning,' + + '-org.hyperledger.besu.ethereum.permissioning.*,' + + // referencetests module + '-org.hyperledger.besu.ethereum.referencetests,' + + // retesteth module + '-org.hyperledger.besu.ethereum.retesteth.methods,' + + '-org.hyperledger.besu.ethereum.retesteth,' + + //rlp module + '-org.hyperledger.besu.ethereum.rlp,' + + // stratum module + '-org.hyperledger.besu.ethereum.stratum,' + + // trie module + '-org.hyperledger.besu.ethereum.trie.*,' + + '-org.hyperledger.besu.ethereum.trie,' + + // verkle trie module + '-org.hyperledger.besu.ethereum.verkletrie,' + + '-org.hyperledger.besu.ethereum.verkletrie.*', true) options.addStringOption('Xmaxerrs','65535') options.addStringOption('Xmaxwarns','65535') diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/ApiConfiguration.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/ApiConfiguration.java index 334b716900..e317845f84 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/ApiConfiguration.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/ApiConfiguration.java @@ -18,58 +18,125 @@ import org.hyperledger.besu.datatypes.Wei; import org.immutables.value.Value; +/** + * The ApiConfiguration class provides configuration for the API. It includes default values for gas + * price, max logs range, gas cap, and other parameters. + */ @Value.Immutable @Value.Style(allParameters = true) public abstract class ApiConfiguration { + /** + * The default lower bound coefficient for gas and priority fee. This value is used as the default + * lower bound when calculating the gas and priority fee. + */ public static final long DEFAULT_LOWER_BOUND_GAS_AND_PRIORITY_FEE_COEFFICIENT = 0L; + + /** + * The default upper bound coefficient for gas and priority fee. This value is used as the default + * upper bound when calculating the gas and priority fee. + */ public static final long DEFAULT_UPPER_BOUND_GAS_AND_PRIORITY_FEE_COEFFICIENT = Long.MAX_VALUE; + /** Constructs a new ApiConfiguration with default values. */ + protected ApiConfiguration() {} + + /** + * Returns the number of blocks to consider for gas price calculations. Default value is 100. + * + * @return the number of blocks for gas price calculations + */ @Value.Default public long getGasPriceBlocks() { return 100; } + /** + * Returns the percentile to use for gas price calculations. Default value is 50.0. + * + * @return the percentile for gas price calculations + */ @Value.Default public double getGasPricePercentile() { return 50.0d; } + /** + * Returns the maximum gas price. Default value is 500 GWei. + * + * @return the maximum gas price + */ @Value.Default public Wei getGasPriceMax() { return Wei.of(500_000_000_000L); // 500 GWei } + /** + * Returns the fraction to use for gas price calculations. This is derived from the gas price + * percentile. + * + * @return the fraction for gas price calculations + */ @Value.Derived public double getGasPriceFraction() { return getGasPricePercentile() / 100.0; } + /** + * Returns the maximum range for logs. Default value is 5000. + * + * @return the maximum range for logs + */ @Value.Default public Long getMaxLogsRange() { return 5000L; } + /** + * Returns the gas cap. Default value is 0. + * + * @return the gas cap + */ @Value.Default public Long getGasCap() { return 0L; } + /** + * Returns whether gas and priority fee limiting is enabled. Default value is false. + * + * @return true if gas and priority fee limiting is enabled, false otherwise + */ @Value.Default public boolean isGasAndPriorityFeeLimitingEnabled() { return false; } + /** + * Returns the lower bound coefficient for gas and priority fee. Default value is 0. + * + * @return the lower bound coefficient for gas and priority fee + */ @Value.Default public Long getLowerBoundGasAndPriorityFeeCoefficient() { return DEFAULT_LOWER_BOUND_GAS_AND_PRIORITY_FEE_COEFFICIENT; } + /** + * Returns the upper bound coefficient for gas and priority fee. Default value is Long.MAX_VALUE. + * + * @return the upper bound coefficient for gas and priority fee + */ @Value.Default public Long getUpperBoundGasAndPriorityFeeCoefficient() { return DEFAULT_UPPER_BOUND_GAS_AND_PRIORITY_FEE_COEFFICIENT; } + /** + * Returns the maximum range for trace filter. Default value is 1000. + * + * @return the maximum range for trace filter + */ @Value.Default public Long getMaxTraceFilterRange() { return 1000L; diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/GraphQLConfiguration.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/GraphQLConfiguration.java index 8c32b55288..a2829edb07 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/GraphQLConfiguration.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/GraphQLConfiguration.java @@ -26,17 +26,33 @@ import java.util.Objects; import com.google.common.base.MoreObjects; +/** + * Represents the configuration for GraphQL. This class is used to set and get the configuration + * details for GraphQL such as enabling GraphQL, setting the port and host, setting the allowed + * domains for CORS, setting the hosts allowlist, and setting the HTTP timeout. + */ public class GraphQLConfiguration { private static final String DEFAULT_GRAPHQL_HTTP_HOST = "127.0.0.1"; + + /** The default port number for the GraphQL HTTP server. */ public static final int DEFAULT_GRAPHQL_HTTP_PORT = 8547; private boolean enabled; private int port; private String host; private List corsAllowedDomains = Collections.emptyList(); - private List hostsAllowlist = Arrays.asList("localhost", "127.0.0.1"); + private List hostsAllowlist = Arrays.asList("localhost", DEFAULT_GRAPHQL_HTTP_HOST); private long httpTimeoutSec = TimeoutOptions.defaultOptions().getTimeoutSeconds(); + /** + * Creates a default configuration for GraphQL. + * + *

This method initializes a new GraphQLConfiguration object with default settings. The default + * settings are: - GraphQL is not enabled - The port is set to the default GraphQL HTTP port - The + * host is set to the default GraphQL HTTP host - The HTTP timeout is set to the default timeout + * + * @return a GraphQLConfiguration object with default settings + */ public static GraphQLConfiguration createDefault() { final GraphQLConfiguration config = new GraphQLConfiguration(); config.setEnabled(false); @@ -48,52 +64,112 @@ public class GraphQLConfiguration { private GraphQLConfiguration() {} + /** + * Checks if GraphQL is enabled. + * + * @return true if GraphQL is enabled, false otherwise + */ public boolean isEnabled() { return enabled; } + /** + * Sets the enabled status of GraphQL. + * + * @param enabled the status to set. true to enable GraphQL, false to disable it + */ public void setEnabled(final boolean enabled) { this.enabled = enabled; } + /** + * Retrieves the port number for the GraphQL HTTP server. + * + * @return the port number + */ public int getPort() { return port; } + /** + * Sets the port number for the GraphQL HTTP server. + * + * @param port the port number to set + */ public void setPort(final int port) { this.port = port; } + /** + * Retrieves the host for the GraphQL HTTP server. + * + * @return the host + */ public String getHost() { return host; } + /** + * Sets the host for the GraphQL HTTP server. + * + * @param host the host to set + */ public void setHost(final String host) { this.host = host; } + /** + * Retrieves the allowed domains for CORS. + * + * @return a collection of allowed domains for CORS + */ Collection getCorsAllowedDomains() { return corsAllowedDomains; } + /** + * Sets the allowed domains for CORS. + * + * @param corsAllowedDomains a list of allowed domains for CORS + */ public void setCorsAllowedDomains(final List corsAllowedDomains) { checkNotNull(corsAllowedDomains); this.corsAllowedDomains = corsAllowedDomains; } + /** + * Retrieves the hosts allowlist. + * + * @return a collection of hosts in the allowlist + */ Collection getHostsAllowlist() { return Collections.unmodifiableCollection(this.hostsAllowlist); } + /** + * Sets the hosts allowlist. + * + * @param hostsAllowlist a list of hosts to be added to the allowlist + */ public void setHostsAllowlist(final List hostsAllowlist) { checkNotNull(hostsAllowlist); this.hostsAllowlist = hostsAllowlist; } + /** + * Retrieves the HTTP timeout in seconds. + * + * @return the HTTP timeout in seconds + */ public Long getHttpTimeoutSec() { return httpTimeoutSec; } + /** + * Sets the HTTP timeout in seconds. + * + * @param httpTimeoutSec the HTTP timeout to set in seconds + */ public void setHttpTimeoutSec(final long httpTimeoutSec) { this.httpTimeoutSec = httpTimeoutSec; } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/GraphQLContextType.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/GraphQLContextType.java index 05752f813b..c12f7578c6 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/GraphQLContextType.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/GraphQLContextType.java @@ -14,14 +14,33 @@ */ package org.hyperledger.besu.ethereum.api.graphql; -/** Internal GraphQL Context */ +/** + * Enum representing various context types for GraphQL. + * + *

These context types are used internally by GraphQL to manage different aspects of the system. + */ public enum GraphQLContextType { + /** Represents blockchain queries context. */ BLOCKCHAIN_QUERIES, + + /** Represents protocol schedule context. */ PROTOCOL_SCHEDULE, + + /** Represents transaction pool context. */ TRANSACTION_POOL, + + /** Represents mining coordinator context. */ MINING_COORDINATOR, + + /** Represents synchronizer context. */ SYNCHRONIZER, + + /** Represents is alive handler context. */ IS_ALIVE_HANDLER, + + /** Represents chain ID context. */ CHAIN_ID, + + /** Represents gas cap context. */ GAS_CAP } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/GraphQLDataFetcherContext.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/GraphQLDataFetcherContext.java index 0ccd8d2b1e..acebe95d11 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/GraphQLDataFetcherContext.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/GraphQLDataFetcherContext.java @@ -21,18 +21,56 @@ import org.hyperledger.besu.ethereum.core.Synchronizer; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; +/** + * Interface representing the context for a GraphQL data fetcher. + * + *

This context provides access to various components of the system such as the transaction pool, + * blockchain queries, mining coordinator, synchronizer, and protocol schedule. + */ public interface GraphQLDataFetcherContext { + /** + * Retrieves the transaction pool. + * + * @return the transaction pool + */ TransactionPool getTransactionPool(); + /** + * Retrieves the blockchain queries. + * + * @return the blockchain queries + */ BlockchainQueries getBlockchainQueries(); + /** + * Retrieves the mining coordinator. + * + * @return the mining coordinator + */ MiningCoordinator getMiningCoordinator(); + /** + * Retrieves the synchronizer. + * + * @return the synchronizer + */ Synchronizer getSynchronizer(); + /** + * Retrieves the protocol schedule. + * + * @return the protocol schedule + */ ProtocolSchedule getProtocolSchedule(); + /** + * Retrieves the is alive handler. + * + *

By default, this method returns a new IsAliveHandler instance with a status of true. + * + * @return the is alive handler + */ default IsAliveHandler getIsAliveHandler() { return new IsAliveHandler(true); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/GraphQLDataFetcherContextImpl.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/GraphQLDataFetcherContextImpl.java index 0e426ebf3a..1f5ed82d74 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/GraphQLDataFetcherContextImpl.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/GraphQLDataFetcherContextImpl.java @@ -21,6 +21,12 @@ import org.hyperledger.besu.ethereum.core.Synchronizer; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; +/** + * Implementation of the GraphQLDataFetcherContext interface. + * + *

This class provides access to various components of the system such as the transaction pool, + * blockchain queries, mining coordinator, synchronizer, and protocol schedule. + */ public class GraphQLDataFetcherContextImpl implements GraphQLDataFetcherContext { private final BlockchainQueries blockchainQueries; @@ -30,6 +36,12 @@ public class GraphQLDataFetcherContextImpl implements GraphQLDataFetcherContext private final TransactionPool transactionPool; private final IsAliveHandler isAliveHandler; + /** + * Constructor that takes a GraphQLDataFetcherContext and an IsAliveHandler. + * + * @param context the GraphQLDataFetcherContext + * @param isAliveHandler the IsAliveHandler + */ public GraphQLDataFetcherContextImpl( final GraphQLDataFetcherContext context, final IsAliveHandler isAliveHandler) { this( @@ -41,6 +53,16 @@ public class GraphQLDataFetcherContextImpl implements GraphQLDataFetcherContext isAliveHandler); } + /** + * Constructor that takes a BlockchainQueries, ProtocolSchedule, TransactionPool, + * MiningCoordinator, and Synchronizer. + * + * @param blockchainQueries the BlockchainQueries + * @param protocolSchedule the ProtocolSchedule + * @param transactionPool the TransactionPool + * @param miningCoordinator the MiningCoordinator + * @param synchronizer the Synchronizer + */ public GraphQLDataFetcherContextImpl( final BlockchainQueries blockchainQueries, final ProtocolSchedule protocolSchedule, @@ -56,6 +78,17 @@ public class GraphQLDataFetcherContextImpl implements GraphQLDataFetcherContext new IsAliveHandler(true)); } + /** + * Constructor that takes a BlockchainQueries, ProtocolSchedule, TransactionPool, + * MiningCoordinator, Synchronizer, and IsAliveHandler. + * + * @param blockchainQueries the BlockchainQueries + * @param protocolSchedule the ProtocolSchedule + * @param transactionPool the TransactionPool + * @param miningCoordinator the MiningCoordinator + * @param synchronizer the Synchronizer + * @param isAliveHandler the IsAliveHandler + */ public GraphQLDataFetcherContextImpl( final BlockchainQueries blockchainQueries, final ProtocolSchedule protocolSchedule, diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/GraphQLDataFetchers.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/GraphQLDataFetchers.java index 312491f5c3..0b97bdb2e9 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/GraphQLDataFetchers.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/GraphQLDataFetchers.java @@ -61,10 +61,34 @@ import graphql.schema.DataFetcher; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; +/** + * This class contains data fetchers for GraphQL queries. + * + *

Data fetchers are responsible for fetching data for a specific field. Each field in the schema + * is associated with a data fetcher. When the field is being processed during a query, the + * associated data fetcher is invoked to get the data for that field. + * + *

This class contains data fetchers for various fields such as protocol version, syncing state, + * pending state, gas price, chain ID, max priority fee per gas, range block, block, account, logs, + * and transaction. + * + *

Each data fetcher is a method that returns a `DataFetcher` object. The `DataFetcher` object + * defines how to fetch the data for the field. It takes a `DataFetchingEnvironment` object as input + * which contains all the context needed to fetch the data. + */ public class GraphQLDataFetchers { private final Integer highestEthVersion; + /** + * Constructs a new GraphQLDataFetchers instance. + * + *

This constructor takes a set of supported capabilities and determines the highest Ethereum + * protocol version supported by these capabilities. This version is then stored and can be + * fetched using the getProtocolVersionDataFetcher method. + * + * @param supportedCapabilities a set of capabilities supported by the Ethereum node + */ public GraphQLDataFetchers(final Set supportedCapabilities) { final OptionalInt version = supportedCapabilities.stream() @@ -74,10 +98,30 @@ public class GraphQLDataFetchers { highestEthVersion = version.isPresent() ? version.getAsInt() : null; } + /** + * Returns a DataFetcher that fetches the highest Ethereum protocol version supported by the node. + * + *

The DataFetcher is a functional interface. It has a single method that takes a + * DataFetchingEnvironment object as input and returns the highest Ethereum protocol version as an + * Optional. + * + * @return a DataFetcher that fetches the highest Ethereum protocol version + */ DataFetcher> getProtocolVersionDataFetcher() { return dataFetchingEnvironment -> Optional.of(highestEthVersion); } + /** + * Returns a DataFetcher that fetches the result of sending a raw transaction. + * + *

The DataFetcher is a functional interface. It has a single method that takes a + * DataFetchingEnvironment object as input and returns the hash of the transaction if it is valid + * and added to the transaction pool. If the transaction is invalid, it throws a GraphQLException + * with the invalid reason. If the raw transaction data cannot be read, it throws a + * GraphQLException with INVALID_PARAMS error. + * + * @return a DataFetcher that fetches the result of sending a raw transaction + */ DataFetcher> getSendRawTransactionDataFetcher() { return dataFetchingEnvironment -> { try { @@ -99,6 +143,19 @@ public class GraphQLDataFetchers { }; } + /** + * Returns a DataFetcher that fetches the syncing state of the Ethereum node. + * + *

The DataFetcher is a functional interface. It has a single method that takes a + * DataFetchingEnvironment object as input and returns the syncing state as an + * Optional. + * + *

The SyncStateAdapter is a wrapper around the SyncStatus of the Ethereum node. It provides + * information about the current syncing state of the node such as the current block, highest + * block, and starting block. + * + * @return a DataFetcher that fetches the syncing state of the Ethereum node + */ DataFetcher> getSyncingDataFetcher() { return dataFetchingEnvironment -> { final Synchronizer synchronizer = @@ -125,6 +182,15 @@ public class GraphQLDataFetchers { }; } + /** + * Returns a DataFetcher that fetches the chain ID of the Ethereum node. + * + *

The DataFetcher is a functional interface. It has a single method that takes a + * DataFetchingEnvironment object as input and returns the chain ID as an {@code + * Optional}. + * + * @return a DataFetcher that fetches the chain ID of the Ethereum node + */ public DataFetcher> getChainIdDataFetcher() { return dataFetchingEnvironment -> { final GraphQLContext graphQLContext = dataFetchingEnvironment.getGraphQlContext(); @@ -132,6 +198,15 @@ public class GraphQLDataFetchers { }; } + /** + * Returns a DataFetcher that fetches the maximum priority fee per gas of the Ethereum node. + * + *

The DataFetcher is a functional interface. It has a single method that takes a + * DataFetchingEnvironment object as input and returns the maximum priority fee per gas as a Wei + * object. If the maximum priority fee per gas is not available, it returns Wei.ZERO. + * + * @return a DataFetcher that fetches the maximum priority fee per gas of the Ethereum node + */ public DataFetcher getMaxPriorityFeePerGasDataFetcher() { return dataFetchingEnvironment -> { final BlockchainQueries blockchainQuery = @@ -167,6 +242,20 @@ public class GraphQLDataFetchers { }; } + /** + * Returns a DataFetcher that fetches a specific block in the Ethereum blockchain. + * + *

The DataFetcher is a functional interface. It has a single method that takes a + * DataFetchingEnvironment object as input. This method fetches a block based on either a block + * number or a block hash. If both a block number and a block hash are provided, it throws a + * GraphQLException with INVALID_PARAMS error. If neither a block number nor a block hash is + * provided, it fetches the latest block. + * + *

The fetched block is then wrapped in a {@link NormalBlockAdapter} and returned as an {@code + * Optional}. + * + * @return a DataFetcher that fetches a specific block in the Ethereum blockchain + */ public DataFetcher> getBlockDataFetcher() { return dataFetchingEnvironment -> { diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/GraphQLHttpService.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/GraphQLHttpService.java index abbcdbf945..fc763a1e3b 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/GraphQLHttpService.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/GraphQLHttpService.java @@ -68,6 +68,15 @@ import io.vertx.ext.web.handler.TimeoutHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +/** + * This class handles the HTTP service for GraphQL. It sets up the server, handles requests and + * responses, and manages the lifecycle of the server. + * + *

It is responsible for processing GraphQL requests, executing them using the provided GraphQL + * engine, and returning the results in the HTTP response. + * + *

It also handles errors and exceptions that may occur during the processing of a request. + */ public class GraphQLHttpService { private static final Logger LOG = LoggerFactory.getLogger(GraphQLHttpService.class); @@ -126,6 +135,15 @@ public class GraphQLHttpService { checkArgument(config.getHost() != null, "Required host is not configured."); } + /** + * Starts the GraphQL HTTP service. + * + *

This method initializes the HTTP server and sets up the necessary routes for handling + * GraphQL requests. It also validates the configuration and sets up the necessary handlers for + * different types of requests. + * + * @return a CompletableFuture that will be completed when the server is successfully started. + */ public CompletableFuture start() { LOG.info("Starting GraphQL HTTP service on {}:{}", config.getHost(), config.getPort()); // Create the HTTP server and a router object. @@ -230,6 +248,14 @@ public class GraphQLHttpService { } } + /** + * Stops the GraphQL HTTP service. + * + *

This method stops the HTTP server that was created and started by the start() method. If the + * server is not running, this method will do nothing. + * + * @return a CompletableFuture that will be completed when the server is successfully stopped. + */ public CompletableFuture stop() { if (httpServer == null) { return CompletableFuture.completedFuture(null); @@ -248,6 +274,15 @@ public class GraphQLHttpService { return resultFuture; } + /** + * Returns the socket address of the GraphQL HTTP service. + * + *

This method returns the socket address that the HTTP server is bound to. If the server is + * not running, it returns an empty socket address. + * + * @return the socket address of the HTTP server, or an empty socket address if the server is not + * running. + */ public InetSocketAddress socketAddress() { if (httpServer == null) { return EMPTY_SOCKET_ADDRESS; @@ -255,6 +290,14 @@ public class GraphQLHttpService { return new InetSocketAddress(config.getHost(), httpServer.actualPort()); } + /** + * Returns the URL of the GraphQL HTTP service. + * + *

This method constructs and returns the URL that the HTTP server is bound to. If the server + * is not running, it returns an empty string. + * + * @return the URL of the HTTP server, or an empty string if the server is not running. + */ @VisibleForTesting public String url() { if (httpServer == null) { diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/GraphQLProvider.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/GraphQLProvider.java index 7e62e39c05..2a3370572b 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/GraphQLProvider.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/GraphQLProvider.java @@ -31,12 +31,30 @@ import graphql.schema.idl.SchemaParser; import graphql.schema.idl.TypeDefinitionRegistry; import graphql.schema.idl.TypeRuntimeWiring; +/** + * This class provides the GraphQL service. + * + *

It contains a method to build the GraphQL service with the provided data fetchers. + */ public class GraphQLProvider { + /** + * The maximum complexity allowed for a GraphQL query. + * + *

This constant is used to prevent overly complex queries from being executed. A query's + * complexity is calculated based on the number and type of fields it contains. + */ public static final int MAX_COMPLEXITY = 200; private GraphQLProvider() {} + /** + * Builds the GraphQL service with the provided data fetchers. + * + * @param graphQLDataFetchers the data fetchers to be used in the GraphQL service. + * @return the built GraphQL service. + * @throws IOException if there is an error reading the schema file. + */ public static GraphQL buildGraphQL(final GraphQLDataFetchers graphQLDataFetchers) throws IOException { final URL url = Resources.getResource("schema.graphqls"); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/Scalars.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/Scalars.java index 5762215bc5..9fbeae5fde 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/Scalars.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/Scalars.java @@ -35,6 +35,13 @@ import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; import org.apache.tuweni.units.bigints.UInt256; +/** + * The Scalars class provides methods for creating GraphQLScalarType objects. These objects + * represent the scalar types used in GraphQL, such as Address, BigInt, Bytes, Bytes32, and Long. + * Each method in this class returns a GraphQLScalarType object that has been configured with a + * specific Coercing implementation. The Coercing implementation defines how that type is + * serialized, deserialized and validated. + */ public class Scalars { private Scalars() {} @@ -366,6 +373,14 @@ public class Scalars { } }; + /** + * Creates a new GraphQLScalarType object for an Address. + * + *

The object is configured with a specific Coercing implementation that defines how the + * Address type is serialized, deserialized and validated. + * + * @return a GraphQLScalarType object for an Address. + */ public static GraphQLScalarType addressScalar() { return GraphQLScalarType.newScalar() .name("Address") @@ -374,6 +389,14 @@ public class Scalars { .build(); } + /** + * Creates a new GraphQLScalarType object for a BigInt. + * + *

The object is configured with a specific Coercing implementation that defines how the BigInt + * type is serialized, deserialized and validated. + * + * @return a GraphQLScalarType object for a BigInt. + */ public static GraphQLScalarType bigIntScalar() { return GraphQLScalarType.newScalar() .name("BigInt") @@ -382,6 +405,14 @@ public class Scalars { .build(); } + /** + * Creates a new GraphQLScalarType object for Bytes. + * + *

The object is configured with a specific Coercing implementation that defines how the Bytes + * type is serialized, deserialized and validated. + * + * @return a GraphQLScalarType object for Bytes. + */ public static GraphQLScalarType bytesScalar() { return GraphQLScalarType.newScalar() .name("Bytes") @@ -390,6 +421,14 @@ public class Scalars { .build(); } + /** + * Creates a new GraphQLScalarType object for Bytes32. + * + *

The object is configured with a specific Coercing implementation that defines how the + * Bytes32 type is serialized, deserialized and validated. + * + * @return a GraphQLScalarType object for Bytes32. + */ public static GraphQLScalarType bytes32Scalar() { return GraphQLScalarType.newScalar() .name("Bytes32") @@ -398,6 +437,14 @@ public class Scalars { .build(); } + /** + * Creates a new GraphQLScalarType object for a Long. + * + *

The object is configured with a specific Coercing implementation that defines how the Long + * type is serialized, deserialized and validated. + * + * @return a GraphQLScalarType object for a Long. + */ public static GraphQLScalarType longScalar() { return GraphQLScalarType.newScalar() .name("Long") diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/AccessListEntryAdapter.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/AccessListEntryAdapter.java index 10451dcc35..a0dc8743c8 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/AccessListEntryAdapter.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/AccessListEntryAdapter.java @@ -23,19 +23,40 @@ import java.util.Optional; import org.apache.tuweni.bytes.Bytes32; +/** + * The AccessListEntryAdapter class extends the AdapterBase class. It provides methods to get the + * storage keys and address from an AccessListEntry. + */ @SuppressWarnings("unused") // reflected by GraphQL public class AccessListEntryAdapter extends AdapterBase { + + /** The AccessListEntry object that this adapter wraps. */ private final AccessListEntry accessListEntry; + /** + * Constructs a new AccessListEntryAdapter with the given AccessListEntry. + * + * @param accessListEntry the AccessListEntry to be adapted + */ public AccessListEntryAdapter(final AccessListEntry accessListEntry) { this.accessListEntry = accessListEntry; } + /** + * Returns the storage keys from the AccessListEntry. + * + * @return a list of storage keys + */ public List getStorageKeys() { final var storage = accessListEntry.storageKeys(); return new ArrayList<>(storage); } + /** + * Returns the address from the AccessListEntry. + * + * @return an Optional containing the address if it exists, otherwise an empty Optional + */ public Optional

getAddress() { return Optional.of(accessListEntry.address()); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/AccountAdapter.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/AccountAdapter.java index faf42aafc8..1b4c8323b6 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/AccountAdapter.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/AccountAdapter.java @@ -28,6 +28,10 @@ import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; import org.apache.tuweni.units.bigints.UInt256; +/** + * The AccountAdapter class extends the AdapterBase class. It provides methods to get the account + * details such as address, balance, transaction count, code, and storage. + */ @SuppressWarnings("unused") // reflected by GraphQL public class AccountAdapter extends AdapterBase { @@ -35,18 +39,42 @@ public class AccountAdapter extends AdapterBase { private final Address address; private final Optional blockNumber; + /** + * Constructs a new AccountAdapter with the given Account. + * + * @param account the Account to be adapted + */ public AccountAdapter(final Account account) { this(account == null ? null : account.getAddress(), account, Optional.empty()); } + /** + * Constructs a new AccountAdapter with the given Account and block number. + * + * @param account the Account to be adapted + * @param blockNumber the block number associated with the account + */ public AccountAdapter(final Account account, final Optional blockNumber) { this(account == null ? null : account.getAddress(), account, blockNumber); } + /** + * Constructs a new AccountAdapter with the given address and Account. + * + * @param address the address of the account + * @param account the Account to be adapted + */ public AccountAdapter(final Address address, final Account account) { this(address, account, Optional.empty()); } + /** + * Constructs a new AccountAdapter with the given address, Account, and block number. + * + * @param address the address of the account + * @param account the Account to be adapted + * @param blockNumber the block number associated with the account + */ public AccountAdapter( final Address address, final Account account, final Optional blockNumber) { this.account = Optional.ofNullable(account); @@ -54,18 +82,39 @@ public class AccountAdapter extends AdapterBase { this.blockNumber = blockNumber; } + /** + * Returns the address of the account. + * + * @return the address of the account + */ public Address getAddress() { return address; } + /** + * Returns the balance of the account. + * + * @return the balance of the account + */ public Wei getBalance() { return account.map(AccountState::getBalance).orElse(Wei.ZERO); } + /** + * Returns the transaction count of the account. + * + * @return the transaction count of the account + */ public Long getTransactionCount() { return account.map(AccountState::getNonce).orElse(0L); } + /** + * Returns the code of the account. + * + * @param environment the DataFetchingEnvironment + * @return the code of the account + */ public Bytes getCode(final DataFetchingEnvironment environment) { if (account.get() instanceof BonsaiAccount) { @@ -80,6 +129,12 @@ public class AccountAdapter extends AdapterBase { } } + /** + * Returns the storage of the account. + * + * @param environment the DataFetchingEnvironment + * @return the storage of the account + */ public Bytes32 getStorage(final DataFetchingEnvironment environment) { final BlockchainQueries query = getBlockchainQueries(environment); final Bytes32 slot = environment.getArgument("slot"); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/BlockAdapterBase.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/BlockAdapterBase.java index 96434ee375..6d5b696353 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/BlockAdapterBase.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/BlockAdapterBase.java @@ -48,15 +48,30 @@ import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; import org.apache.tuweni.units.bigints.UInt256; +/** + * The BlockAdapterBase class extends the AdapterBase class. It provides methods to get and + * manipulate block data. + */ @SuppressWarnings("unused") // reflected by GraphQL public class BlockAdapterBase extends AdapterBase { private final BlockHeader header; + /** + * Constructs a new BlockAdapterBase with the given BlockHeader. + * + * @param header the BlockHeader to be adapted + */ BlockAdapterBase(final BlockHeader header) { this.header = header; } + /** + * Returns the parent block of the current block. + * + * @param environment the DataFetchingEnvironment + * @return an Optional containing the parent block if it exists, otherwise an empty Optional + */ public Optional getParent(final DataFetchingEnvironment environment) { final BlockchainQueries query = getBlockchainQueries(environment); final Hash parentHash = header.getParentHash(); @@ -65,28 +80,59 @@ public class BlockAdapterBase extends AdapterBase { return block.map(NormalBlockAdapter::new); } + /** + * Returns the hash of the current block. + * + * @return the hash of the block + */ public Bytes32 getHash() { return header.getHash(); } + /** + * Returns the nonce of the current block. + * + * @return the nonce of the block + */ public Bytes getNonce() { final long nonce = header.getNonce(); final byte[] bytes = Longs.toByteArray(nonce); return Bytes.wrap(bytes); } + /** + * Returns the transactions root of the current block. + * + * @return the transactions root of the block + */ public Bytes32 getTransactionsRoot() { return header.getTransactionsRoot(); } + /** + * Returns the state root of the current block. + * + * @return the state root of the block + */ public Bytes32 getStateRoot() { return header.getStateRoot(); } + /** + * Returns the receipts root of the current block. + * + * @return the receipts root of the block + */ public Bytes32 getReceiptsRoot() { return header.getReceiptsRoot(); } + /** + * Returns the miner of the current block. + * + * @param environment the DataFetchingEnvironment + * @return an AccountAdapter instance representing the miner of the block + */ public AccountAdapter getMiner(final DataFetchingEnvironment environment) { final BlockchainQueries query = getBlockchainQueries(environment); @@ -102,46 +148,103 @@ public class BlockAdapterBase extends AdapterBase { .orElseGet(() -> new EmptyAccountAdapter(header.getCoinbase())); } + /** + * Returns the extra data of the current block. + * + * @return the extra data of the block + */ public Bytes getExtraData() { return header.getExtraData(); } + /** + * Returns the base fee per gas of the current block. + * + * @return the base fee per gas of the block + */ public Optional getBaseFeePerGas() { return header.getBaseFee(); } + /** + * Returns the gas limit of the current block. + * + * @return the gas limit of the block + */ public Long getGasLimit() { return header.getGasLimit(); } + /** + * Returns the gas used by the current block. + * + * @return the gas used by the block + */ public Long getGasUsed() { return header.getGasUsed(); } + /** + * Returns the timestamp of the current block. + * + * @return the timestamp of the block + */ public Long getTimestamp() { return header.getTimestamp(); } + /** + * Returns the logs bloom of the current block. + * + * @return the logs bloom of the block + */ public Bytes getLogsBloom() { return header.getLogsBloom(); } + /** + * Returns the mix hash of the current block. + * + * @return the mix hash of the block + */ public Bytes32 getMixHash() { return header.getMixHash(); } + /** + * Returns the difficulty of the current block. + * + * @return the difficulty of the block + */ public Difficulty getDifficulty() { return header.getDifficulty(); } + /** + * Returns the ommer hash of the current block. + * + * @return the ommer hash of the block + */ public Bytes32 getOmmerHash() { return header.getOmmersHash(); } + /** + * Returns the number of the current block. + * + * @return the number of the block + */ public Long getNumber() { return header.getNumber(); } + /** + * Returns an AccountAdapter instance for a given address at the current block. + * + * @param environment the DataFetchingEnvironment + * @return an AccountAdapter instance representing the account of the given address at the current + * block + */ public AccountAdapter getAccount(final DataFetchingEnvironment environment) { final BlockchainQueries query = getBlockchainQueries(environment); final long bn = header.getNumber(); @@ -152,6 +255,13 @@ public class BlockAdapterBase extends AdapterBase { .get(); } + /** + * Returns a list of logs for the current block that match a given filter. + * + * @param environment the DataFetchingEnvironment + * @return a list of LogAdapter instances representing the logs of the current block that match + * the filter + */ public List getLogs(final DataFetchingEnvironment environment) { final Map filter = environment.getArgument("filter"); @@ -183,11 +293,24 @@ public class BlockAdapterBase extends AdapterBase { return results; } + /** + * Estimates the gas used for a call execution. + * + * @param environment the DataFetchingEnvironment + * @return the estimated gas used for the call execution + */ public Long getEstimateGas(final DataFetchingEnvironment environment) { final Optional result = executeCall(environment); return result.map(CallResult::getGasUsed).orElse(0L); } + /** + * Executes a call and returns the result. + * + * @param environment the DataFetchingEnvironment + * @return an Optional containing the result of the call execution if it exists, otherwise an + * empty Optional + */ public Optional getCall(final DataFetchingEnvironment environment) { return executeCall(environment); } @@ -259,12 +382,23 @@ public class BlockAdapterBase extends AdapterBase { header); } + /** + * Returns the raw header of the current block. + * + * @return the raw header of the block + */ Bytes getRawHeader() { final BytesValueRLPOutput rlpOutput = new BytesValueRLPOutput(); header.writeTo(rlpOutput); return rlpOutput.encoded(); } + /** + * Returns the raw data of the current block. + * + * @param environment the DataFetchingEnvironment + * @return the raw data of the block + */ Bytes getRaw(final DataFetchingEnvironment environment) { final BlockchainQueries query = getBlockchainQueries(environment); return query @@ -279,10 +413,22 @@ public class BlockAdapterBase extends AdapterBase { .orElse(Bytes.EMPTY); } + /** + * Returns the withdrawals root of the current block. + * + * @return an Optional containing the withdrawals root if it exists, otherwise an empty Optional + */ Optional getWithdrawalsRoot() { return header.getWithdrawalsRoot().map(Function.identity()); } + /** + * Returns a list of withdrawals for the current block. + * + * @param environment the DataFetchingEnvironment + * @return an Optional containing a list of WithdrawalAdapter instances representing the + * withdrawals of the current block if they exist, otherwise an empty Optional + */ Optional> getWithdrawals(final DataFetchingEnvironment environment) { final BlockchainQueries query = getBlockchainQueries(environment); return query @@ -295,10 +441,22 @@ public class BlockAdapterBase extends AdapterBase { .map(wl -> wl.stream().map(WithdrawalAdapter::new).toList())); } + /** + * Returns the blob gas used by the current block. + * + * @return an Optional containing the blob gas used by the current block if it exists, otherwise + * an empty Optional + */ public Optional getBlobGasUsed() { return header.getBlobGasUsed(); } + /** + * Returns the excess blob gas of the current block. + * + * @return an Optional containing the excess blob gas of the current block if it exists, otherwise + * an empty Optional + */ public Optional getExcessBlobGas() { return header.getExcessBlobGas().map(BlobGas::toLong); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/CallResult.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/CallResult.java index 78fa30d874..0a5c9a8f38 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/CallResult.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/CallResult.java @@ -16,26 +16,55 @@ package org.hyperledger.besu.ethereum.api.graphql.internal.pojoadapter; import org.apache.tuweni.bytes.Bytes; +/** + * Represents the result of a call execution. This class is used to encapsulate the status, gas + * used, and data returned by a call execution. It is used in conjunction with the {@link + * org.hyperledger.besu.ethereum.api.graphql.internal.pojoadapter.BlockAdapterBase} class. + * + * @see org.hyperledger.besu.ethereum.api.graphql.internal.pojoadapter.BlockAdapterBase + */ @SuppressWarnings("unused") // reflected by GraphQL public class CallResult { private final Long status; private final Long gasUsed; private final Bytes data; + /** + * Constructs a new CallResult. + * + * @param status the status of the call execution + * @param gasUsed the amount of gas used by the call + * @param data the data returned by the call + */ CallResult(final Long status, final Long gasUsed, final Bytes data) { this.status = status; this.gasUsed = gasUsed; this.data = data; } + /** + * Returns the status of the call execution. + * + * @return the status of the call execution + */ public Long getStatus() { return status; } + /** + * Returns the amount of gas used by the call. + * + * @return the amount of gas used by the call + */ public Long getGasUsed() { return gasUsed; } + /** + * Returns the data returned by the call. + * + * @return the data returned by the call + */ public Bytes getData() { return data; } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/EmptyAccountAdapter.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/EmptyAccountAdapter.java index 4c19b997b6..775934fb1b 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/EmptyAccountAdapter.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/EmptyAccountAdapter.java @@ -21,9 +21,22 @@ import graphql.schema.DataFetchingEnvironment; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; +/** + * Represents an empty account in the Ethereum blockchain. This class is used when an account does + * not exist at a specific address. It provides default values for the account's properties. It + * extends the {@link org.hyperledger.besu.ethereum.api.graphql.internal.pojoadapter.AccountAdapter} + * class. + * + * @see org.hyperledger.besu.ethereum.api.graphql.internal.pojoadapter.AccountAdapter + */ public class EmptyAccountAdapter extends AccountAdapter { private final Address address; + /** + * Constructs a new EmptyAccountAdapter. + * + * @param address the address of the account + */ public EmptyAccountAdapter(final Address address) { super(null); this.address = address; diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/LogAdapter.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/LogAdapter.java index 6beab46fdc..012edbe512 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/LogAdapter.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/LogAdapter.java @@ -28,27 +28,62 @@ import java.util.Optional; import graphql.schema.DataFetchingEnvironment; import org.apache.tuweni.bytes.Bytes; +/** + * This class is an adapter for the LogWithMetadata class. + * + *

It extends the AdapterBase class and provides methods to get the index, topics, data, + * transaction, and account associated with a log. + */ @SuppressWarnings("unused") // reflected by GraphQL public class LogAdapter extends AdapterBase { private final LogWithMetadata logWithMetadata; + /** + * Constructor for LogAdapter. + * + *

It initializes the logWithMetadata field with the provided argument. + * + * @param logWithMetadata the log with metadata to be adapted. + */ public LogAdapter(final LogWithMetadata logWithMetadata) { this.logWithMetadata = logWithMetadata; } + /** + * Returns the index of the log. + * + * @return the index of the log. + */ public Integer getIndex() { return logWithMetadata.getLogIndex(); } + /** + * Returns the topics of the log. + * + * @return a list of topics of the log. + */ public List getTopics() { final List topics = logWithMetadata.getTopics(); return new ArrayList<>(topics); } + /** + * Returns the data of the log. + * + * @return the data of the log. + */ public Bytes getData() { return logWithMetadata.getData(); } + /** + * Returns the transaction associated with the log. + * + * @param environment the data fetching environment. + * @return a TransactionAdapter for the transaction associated with the log. + * @throws java.util.NoSuchElementException if the transaction is not found. + */ public TransactionAdapter getTransaction(final DataFetchingEnvironment environment) { final BlockchainQueries query = getBlockchainQueries(environment); final Hash hash = logWithMetadata.getTransactionHash(); @@ -56,6 +91,12 @@ public class LogAdapter extends AdapterBase { return tran.map(TransactionAdapter::new).orElseThrow(); } + /** + * Returns the account associated with the log. + * + * @param environment the data fetching environment. + * @return an AccountAdapter for the account associated with the log. + */ public AccountAdapter getAccount(final DataFetchingEnvironment environment) { final BlockchainQueries query = getBlockchainQueries(environment); long blockNumber = logWithMetadata.getBlockNumber(); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/NormalBlockAdapter.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/NormalBlockAdapter.java index f54b3f0da0..fa75028a38 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/NormalBlockAdapter.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/NormalBlockAdapter.java @@ -27,9 +27,24 @@ import java.util.Optional; import graphql.schema.DataFetchingEnvironment; +/** + * This class is an adapter for the BlockWithMetadata class. + * + *

It extends the BlockAdapterBase class and provides methods to get the transaction count, total + * difficulty, ommer count, ommers, transactions, and specific ommer and transaction at a given + * index associated with a block. + */ @SuppressWarnings("unused") // reflected by GraphQL public class NormalBlockAdapter extends BlockAdapterBase { + /** + * Constructor for NormalBlockAdapter. + * + *

It initializes the blockWithMetaData field with the provided argument and calls the parent + * constructor with the header of the provided blockWithMetaData. + * + * @param blockWithMetaData the block with metadata to be adapted. + */ public NormalBlockAdapter( final BlockWithMetadata blockWithMetaData) { super(blockWithMetaData.getHeader()); @@ -38,18 +53,39 @@ public class NormalBlockAdapter extends BlockAdapterBase { private final BlockWithMetadata blockWithMetaData; + /** + * Returns the transaction count of the block. + * + * @return the transaction count of the block. + */ public Optional getTransactionCount() { return Optional.of(blockWithMetaData.getTransactions().size()); } + /** + * Returns the total difficulty of the block. + * + * @return the total difficulty of the block. + */ public Difficulty getTotalDifficulty() { return blockWithMetaData.getTotalDifficulty(); } + /** + * Returns the ommer count of the block. + * + * @return the ommer count of the block. + */ public Optional getOmmerCount() { return Optional.of(blockWithMetaData.getOmmers().size()); } + /** + * Returns the ommers of the block. + * + * @param environment the data fetching environment. + * @return a list of UncleBlockAdapter for the ommers of the block. + */ public List getOmmers(final DataFetchingEnvironment environment) { final BlockchainQueries query = getBlockchainQueries(environment); final List ommers = blockWithMetaData.getOmmers(); @@ -63,6 +99,12 @@ public class NormalBlockAdapter extends BlockAdapterBase { return results; } + /** + * Returns the ommer at a given index of the block. + * + * @param environment the data fetching environment. + * @return an UncleBlockAdapter for the ommer at the given index of the block. + */ public Optional getOmmerAt(final DataFetchingEnvironment environment) { final BlockchainQueries query = getBlockchainQueries(environment); final int index = ((Number) environment.getArgument("index")).intValue(); @@ -75,6 +117,13 @@ public class NormalBlockAdapter extends BlockAdapterBase { return Optional.empty(); } + /** + * Returns a list of TransactionAdapter objects for the transactions in the block. + * + *

Each TransactionAdapter object is created by adapting a TransactionWithMetadata object. + * + * @return a list of TransactionAdapter objects for the transactions in the block. + */ public List getTransactions() { final List trans = blockWithMetaData.getTransactions(); final List results = new ArrayList<>(); @@ -84,6 +133,16 @@ public class NormalBlockAdapter extends BlockAdapterBase { return results; } + /** + * Returns a TransactionAdapter object for the transaction at the given index in the block. + * + *

The index is retrieved from the data fetching environment. If there is no transaction at the + * given index, an empty Optional is returned. + * + * @param environment the data fetching environment. + * @return an Optional containing a TransactionAdapter object for the transaction at the given + * index in the block, or an empty Optional if there is no transaction at the given index. + */ public Optional getTransactionAt(final DataFetchingEnvironment environment) { final int index = ((Number) environment.getArgument("index")).intValue(); final List trans = blockWithMetaData.getTransactions(); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/PendingStateAdapter.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/PendingStateAdapter.java index 0202db88f6..49f6bc890f 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/PendingStateAdapter.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/PendingStateAdapter.java @@ -36,19 +36,41 @@ import graphql.schema.DataFetchingEnvironment; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.units.bigints.UInt256; +/** + * This class represents the pending state of transactions in the Ethereum network. + * + *

It extends the AdapterBase class and provides methods to interact with the transaction pool. + */ @SuppressWarnings("unused") // reflected by GraphQL public class PendingStateAdapter extends AdapterBase { private final TransactionPool transactionPool; + /** + * Constructor for PendingStateAdapter. + * + *

It initializes the transactionPool field with the provided argument. + * + * @param transactionPool the transaction pool to be used. + */ public PendingStateAdapter(final TransactionPool transactionPool) { this.transactionPool = transactionPool; } + /** + * Returns the count of transactions in the transaction pool. + * + * @return the count of transactions in the transaction pool. + */ public Integer getTransactionCount() { return transactionPool.count(); } + /** + * Returns a list of TransactionAdapter objects for the transactions in the transaction pool. + * + * @return a list of TransactionAdapter objects for the transactions in the transaction pool. + */ public List getTransactions() { return transactionPool.getPendingTransactions().stream() .map(PendingTransaction::getTransaction) @@ -57,9 +79,17 @@ public class PendingStateAdapter extends AdapterBase { .toList(); } - // until the miner can expose the current "proposed block" we have no - // speculative environment, so estimate against latest. + /** + * Returns an AccountAdapter object for the account associated with the provided address. + * + *

The account state is estimated against the latest block. + * + * @param dataFetchingEnvironment the data fetching environment. + * @return an AccountAdapter object for the account associated with the provided address. + */ public AccountAdapter getAccount(final DataFetchingEnvironment dataFetchingEnvironment) { + // until the miner can expose the current "proposed block" we have no + // speculative environment, so estimate against latest. final BlockchainQueries blockchainQuery = dataFetchingEnvironment.getGraphQlContext().get(GraphQLContextType.BLOCKCHAIN_QUERIES); final Address addr = dataFetchingEnvironment.getArgument("address"); @@ -71,16 +101,39 @@ public class PendingStateAdapter extends AdapterBase { .orElseGet(() -> new AccountAdapter(null)); } - // until the miner can expose the current "proposed block" we have no - // speculative environment, so estimate against latest. + /** + * Estimates the gas required for a transaction. + * + *

This method calls the getCall method to simulate the transaction and then retrieves the gas + * used by the transaction. The gas estimation is done against the latest block as there is + * currently no way to expose the current "proposed block" for a speculative environment. + * + * @param environment the data fetching environment. + * @return an Optional containing the estimated gas for the transaction, or an empty Optional if + * the transaction simulation was not successful. + */ public Optional getEstimateGas(final DataFetchingEnvironment environment) { + // until the miner can expose the current "proposed block" we have no + // speculative environment, so estimate against latest. final Optional result = getCall(environment); return result.map(CallResult::getGasUsed); } - // until the miner can expose the current "proposed block" we have no - // speculative environment, so estimate against latest. + /** + * Simulates the execution of a transaction. + * + *

This method retrieves the transaction parameters from the data fetching environment, creates + * a CallParameter object, and then uses a TransactionSimulator to simulate the execution of the + * transaction. The simulation is done against the latest block as there is currently no way to + * expose the current "proposed block" for a speculative environment. + * + * @param environment the data fetching environment. + * @return an Optional containing the result of the transaction simulation, or an empty Optional + * if the transaction simulation was not successful. + */ public Optional getCall(final DataFetchingEnvironment environment) { + // until the miner can expose the current "proposed block" we have no + // speculative environment, so estimate against latest. final Map callData = environment.getArgument("data"); final Address from = (Address) callData.get("from"); final Address to = (Address) callData.get("to"); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/SyncStateAdapter.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/SyncStateAdapter.java index 0a8dcbbf97..2c3876fe36 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/SyncStateAdapter.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/SyncStateAdapter.java @@ -16,22 +16,52 @@ package org.hyperledger.besu.ethereum.api.graphql.internal.pojoadapter; import org.hyperledger.besu.plugin.data.SyncStatus; +/** + * The SyncStateAdapter class provides methods to retrieve the synchronization status of the + * blockchain. + * + *

This class is used to adapt a SyncStatus object into a format that can be used by GraphQL. The + * SyncStatus object is provided at construction time. + * + *

The class provides methods to retrieve the starting block, current block, and highest block of + * the synchronization status. + */ @SuppressWarnings("unused") // reflected by GraphQL public class SyncStateAdapter { private final SyncStatus syncStatus; + /** + * Constructs a new SyncStateAdapter object. + * + * @param syncStatus the SyncStatus object to adapt. + */ public SyncStateAdapter(final SyncStatus syncStatus) { this.syncStatus = syncStatus; } + /** + * Returns the starting block of the synchronization status. + * + * @return the starting block of the synchronization status. + */ public Long getStartingBlock() { return syncStatus.getStartingBlock(); } + /** + * Returns the current block of the synchronization status. + * + * @return the current block of the synchronization status. + */ public Long getCurrentBlock() { return syncStatus.getCurrentBlock(); } + /** + * Returns the highest block of the synchronization status. + * + * @return the highest block of the synchronization status. + */ public Long getHighestBlock() { return syncStatus.getHighestBlock(); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/TransactionAdapter.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/TransactionAdapter.java index 6e98afc90e..d5eacf8e35 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/TransactionAdapter.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/TransactionAdapter.java @@ -38,11 +38,28 @@ import javax.annotation.Nonnull; import graphql.schema.DataFetchingEnvironment; import org.apache.tuweni.bytes.Bytes; +/** + * The TransactionAdapter class provides methods to retrieve the transaction details. + * + *

This class is used to adapt a TransactionWithMetadata object into a format that can be used by + * GraphQL. The TransactionWithMetadata object is provided at construction time. + * + *

The class provides methods to retrieve the hash, type, nonce, index, from, to, value, gas + * price, max fee per gas, max priority fee per gas, max fee per blob gas, effective tip, gas, input + * data, block, status, gas used, cumulative gas used, effective gas price, blob gas used, blob gas + * price, created contract, logs, R, S, V, Y parity, access list, raw, raw receipt, and blob + * versioned hashes of the transaction. + */ @SuppressWarnings("unused") // reflected by GraphQL public class TransactionAdapter extends AdapterBase { private final TransactionWithMetadata transactionWithMetadata; private Optional transactionReceiptWithMetadata; + /** + * Constructs a new TransactionAdapter object. + * + * @param transactionWithMetadata the TransactionWithMetadata object to adapt. + */ public TransactionAdapter(final @Nonnull TransactionWithMetadata transactionWithMetadata) { this.transactionWithMetadata = transactionWithMetadata; } @@ -65,22 +82,53 @@ public class TransactionAdapter extends AdapterBase { return transactionReceiptWithMetadata; } + /** + * Returns the hash of the transaction. + * + * @return the hash of the transaction. + */ public Hash getHash() { return transactionWithMetadata.getTransaction().getHash(); } + /** + * Returns the type of the transaction. + * + * @return the type of the transaction. + */ public Optional getType() { return Optional.of(transactionWithMetadata.getTransaction().getType().ordinal()); } + /** + * Returns the nonce of the transaction. + * + * @return the nonce of the transaction. + */ public Long getNonce() { return transactionWithMetadata.getTransaction().getNonce(); } + /** + * Returns the index of the transaction. + * + * @return the index of the transaction. + */ public Optional getIndex() { return transactionWithMetadata.getTransactionIndex(); } + /** + * Retrieves the sender of the transaction. + * + *

This method uses the BlockchainQueries to get the block number and then retrieves the sender + * of the transaction. It then uses the getAndMapWorldState method to get the state of the + * sender's account at the given block number. + * + * @param environment the data fetching environment. + * @return an AccountAdapter object representing the sender's account state at the given block + * number. + */ public AccountAdapter getFrom(final DataFetchingEnvironment environment) { final BlockchainQueries query = getBlockchainQueries(environment); final Long blockNumber = @@ -96,6 +144,18 @@ public class TransactionAdapter extends AdapterBase { .orElse(new EmptyAccountAdapter(addr)); } + /** + * Retrieves the recipient of the transaction. + * + *

This method uses the BlockchainQueries to get the block number and then retrieves the + * recipient of the transaction. It then uses the getAndMapWorldState method to get the state of + * the recipient's account at the given block number. + * + * @param environment the data fetching environment. + * @return an Optional containing an AccountAdapter object representing the recipient's account + * state at the given block number, or an empty Optional if the transaction does not have a + * recipient (i.e., it is a contract creation transaction). + */ public Optional getTo(final DataFetchingEnvironment environment) { final BlockchainQueries query = getBlockchainQueries(environment); final Long blockNumber = @@ -115,39 +175,95 @@ public class TransactionAdapter extends AdapterBase { .or(() -> Optional.of(new EmptyAccountAdapter(address)))); } + /** + * Retrieves the value of the transaction. + * + * @return a Wei object representing the value of the transaction. + */ public Wei getValue() { return transactionWithMetadata.getTransaction().getValue(); } + /** + * Retrieves the gas price of the transaction. + * + * @return a Wei object representing the gas price of the transaction. If the transaction does not + * specify a gas price, this method returns zero. + */ public Wei getGasPrice() { return transactionWithMetadata.getTransaction().getGasPrice().orElse(Wei.ZERO); } + /** + * Retrieves the maximum fee per gas of the transaction. + * + * @return an Optional containing a Wei object representing the maximum fee per gas of the + * transaction, or an empty Optional if the transaction does not specify a maximum fee per + * gas. + */ public Optional getMaxFeePerGas() { return transactionWithMetadata.getTransaction().getMaxFeePerGas(); } + /** + * Retrieves the maximum priority fee per gas of the transaction. + * + * @return an Optional containing a Wei object representing the maximum priority fee per gas of + * the transaction, or an empty Optional if the transaction does not specify a maximum + * priority fee per gas. + */ public Optional getMaxPriorityFeePerGas() { return transactionWithMetadata.getTransaction().getMaxPriorityFeePerGas(); } + /** + * Retrieves the maximum fee per blob gas of the transaction. + * + * @return an Optional containing a Wei object representing the maximum fee per blob gas of the + * transaction, or an empty Optional if the transaction does not specify a maximum fee per + * blob gas. + */ public Optional getMaxFeePerBlobGas() { return transactionWithMetadata.getTransaction().getMaxFeePerBlobGas(); } + /** + * Retrieves the effective tip of the transaction. + * + * @param environment the data fetching environment. + * @return an Optional containing a Wei object representing the effective tip of the transaction, + * or an empty Optional if the transaction does not specify an effective tip. + */ public Optional getEffectiveTip(final DataFetchingEnvironment environment) { return getReceipt(environment) .map(rwm -> rwm.getTransaction().getEffectivePriorityFeePerGas(rwm.getBaseFee())); } + /** + * Retrieves the gas limit of the transaction. + * + * @return a Long object representing the gas limit of the transaction. + */ public Long getGas() { return transactionWithMetadata.getTransaction().getGasLimit(); } + /** + * Retrieves the input data of the transaction. + * + * @return a Bytes object representing the input data of the transaction. + */ public Bytes getInputData() { return transactionWithMetadata.getTransaction().getPayload(); } + /** + * Retrieves the block of the transaction. + * + * @param environment the data fetching environment. + * @return an Optional containing a NormalBlockAdapter object representing the block of the + * transaction, or an empty Optional if the transaction does not specify a block. + */ public Optional getBlock(final DataFetchingEnvironment environment) { return transactionWithMetadata .getBlockHash() @@ -155,6 +271,17 @@ public class TransactionAdapter extends AdapterBase { .map(NormalBlockAdapter::new); } + /** + * Retrieves the status of the transaction. + * + *

This method uses the getReceipt method to get the receipt of the transaction. It then checks + * the status of the receipt. If the status is -1, it returns an empty Optional. Otherwise, it + * returns an Optional containing the status of the receipt. + * + * @param environment the data fetching environment. + * @return an Optional containing a Long object representing the status of the transaction, or an + * empty Optional if the status of the receipt is -1. + */ public Optional getStatus(final DataFetchingEnvironment environment) { return getReceipt(environment) .map(TransactionReceiptWithMetadata::getReceipt) @@ -165,27 +292,87 @@ public class TransactionAdapter extends AdapterBase { : Optional.of((long) receipt.getStatus())); } + /** + * Retrieves the gas used by the transaction. + * + *

This method uses the getReceipt method to get the receipt of the transaction. It then + * returns an Optional containing the gas used by the transaction. + * + * @param environment the data fetching environment. + * @return an Optional containing a Long object representing the gas used by the transaction. + */ public Optional getGasUsed(final DataFetchingEnvironment environment) { return getReceipt(environment).map(TransactionReceiptWithMetadata::getGasUsed); } + /** + * Retrieves the cumulative gas used by the transaction. + * + *

This method uses the getReceipt method to get the receipt of the transaction. It then + * returns an Optional containing the cumulative gas used by the transaction. + * + * @param environment the data fetching environment. + * @return an Optional containing a Long object representing the cumulative gas used by the + * transaction. + */ public Optional getCumulativeGasUsed(final DataFetchingEnvironment environment) { return getReceipt(environment).map(rpt -> rpt.getReceipt().getCumulativeGasUsed()); } + /** + * Retrieves the effective gas price of the transaction. + * + *

This method uses the getReceipt method to get the receipt of the transaction. It then + * returns an Optional containing the effective gas price of the transaction. + * + * @param environment the data fetching environment. + * @return an Optional containing a Wei object representing the effective gas price of the + * transaction. + */ public Optional getEffectiveGasPrice(final DataFetchingEnvironment environment) { return getReceipt(environment) .map(rwm -> rwm.getTransaction().getEffectiveGasPrice(rwm.getBaseFee())); } + /** + * Retrieves the blob gas used by the transaction. + * + *

This method uses the getReceipt method to get the receipt of the transaction. It then + * returns an Optional containing the blob gas used by the transaction. + * + * @param environment the data fetching environment. + * @return an Optional containing a Long object representing the blob gas used by the transaction. + */ public Optional getBlobGasUsed(final DataFetchingEnvironment environment) { return getReceipt(environment).flatMap(TransactionReceiptWithMetadata::getBlobGasUsed); } + /** + * Retrieves the blob gas price of the transaction. + * + *

This method uses the getReceipt method to get the receipt of the transaction. It then + * returns an Optional containing the blob gas price of the transaction. + * + * @param environment the data fetching environment. + * @return an Optional containing a Wei object representing the blob gas price of the transaction. + */ public Optional getBlobGasPrice(final DataFetchingEnvironment environment) { return getReceipt(environment).flatMap(TransactionReceiptWithMetadata::getBlobGasPrice); } + /** + * Retrieves the contract created by the transaction. + * + *

This method checks if the transaction is a contract creation transaction. If it is, it + * retrieves the address of the created contract. It then uses the BlockchainQueries to get the + * block number and then retrieves the state of the created contract's account at the given block + * number. + * + * @param environment the data fetching environment. + * @return an Optional containing an AccountAdapter object representing the created contract's + * account state at the given block number, or an empty Optional if the transaction is not a + * contract creation transaction or if the block number is not specified. + */ public Optional getCreatedContract(final DataFetchingEnvironment environment) { final boolean contractCreated = transactionWithMetadata.getTransaction().isContractCreation(); if (contractCreated) { @@ -208,6 +395,17 @@ public class TransactionAdapter extends AdapterBase { return Optional.empty(); } + /** + * Retrieves the logs of the transaction. + * + *

This method uses the BlockchainQueries to get the block header and the receipt of the + * transaction. It then retrieves the logs of the transaction and adapts them into a format that + * can be used by GraphQL. + * + * @param environment the data fetching environment. + * @return a List of LogAdapter objects representing the logs of the transaction. If the + * transaction does not have a receipt, this method returns an empty list. + */ public List getLogs(final DataFetchingEnvironment environment) { final BlockchainQueries query = getBlockchainQueries(environment); final ProtocolSchedule protocolSchedule = @@ -240,14 +438,34 @@ public class TransactionAdapter extends AdapterBase { return results; } + /** + * Retrieves the R component of the transaction's signature. + * + * @return a BigInteger object representing the R component of the transaction's signature. + */ public BigInteger getR() { return transactionWithMetadata.getTransaction().getR(); } + /** + * Retrieves the S component of the transaction's signature. + * + * @return a BigInteger object representing the S component of the transaction's signature. + */ public BigInteger getS() { return transactionWithMetadata.getTransaction().getS(); } + /** + * Retrieves the V component of the transaction's signature. + * + *

If the transaction type is less than the BLOB transaction type and V is null, it returns the + * Y parity of the transaction. Otherwise, it returns V. + * + * @return an Optional containing a BigInteger object representing the V component of the + * transaction's signature, or an Optional containing the Y parity of the transaction if V is + * null and the transaction type is less than the BLOB transaction type. + */ public Optional getV() { BigInteger v = transactionWithMetadata.getTransaction().getV(); return Optional.ofNullable( @@ -258,10 +476,22 @@ public class TransactionAdapter extends AdapterBase { : v); } + /** + * Retrieves the Y parity of the transaction's signature. + * + * @return an Optional containing a BigInteger object representing the Y parity of the + * transaction's signature. + */ public Optional getYParity() { return Optional.ofNullable(transactionWithMetadata.getTransaction().getYParity()); } + /** + * Retrieves the access list of the transaction. + * + * @return a List of AccessListEntryAdapter objects representing the access list of the + * transaction. + */ public List getAccessList() { return transactionWithMetadata .getTransaction() @@ -270,12 +500,30 @@ public class TransactionAdapter extends AdapterBase { .orElse(List.of()); } + /** + * Retrieves the raw transaction data. + * + *

This method uses the writeTo method of the transaction to write the transaction data to a + * BytesValueRLPOutput object. It then encodes the BytesValueRLPOutput object and returns it. + * + * @return an Optional containing a Bytes object representing the raw transaction data. + */ public Optional getRaw() { final BytesValueRLPOutput rlpOutput = new BytesValueRLPOutput(); transactionWithMetadata.getTransaction().writeTo(rlpOutput); return Optional.of(rlpOutput.encoded()); } + /** + * Retrieves the raw receipt of the transaction. + * + *

This method uses the getReceipt method to get the receipt of the transaction. It then writes + * the receipt data to a BytesValueRLPOutput object using the writeToForNetwork method of the + * receipt. It then encodes the BytesValueRLPOutput object and returns it. + * + * @param environment the data fetching environment. + * @return an Optional containing a Bytes object representing the raw receipt of the transaction. + */ public Optional getRawReceipt(final DataFetchingEnvironment environment) { return getReceipt(environment) .map( @@ -286,6 +534,11 @@ public class TransactionAdapter extends AdapterBase { }); } + /** + * Retrieves the versioned hashes of the transaction. + * + * @return a List of VersionedHash objects representing the versioned hashes of the transaction. + */ public List getBlobVersionedHashes() { return transactionWithMetadata.getTransaction().getVersionedHashes().orElse(List.of()); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/WithdrawalAdapter.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/WithdrawalAdapter.java index e8454fcdb5..85ec69b0dd 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/WithdrawalAdapter.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/WithdrawalAdapter.java @@ -17,26 +17,60 @@ package org.hyperledger.besu.ethereum.api.graphql.internal.pojoadapter; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.plugin.data.Withdrawal; +/** + * The WithdrawalAdapter class provides methods to retrieve the withdrawal details. + * + *

This class is used to adapt a Withdrawal object into a format that can be used by GraphQL. The + * Withdrawal object is provided at construction time. + * + *

The class provides methods to retrieve the index, validator, address, and amount of the + * withdrawal. + */ public class WithdrawalAdapter { Withdrawal withdrawal; + /** + * Constructs a new WithdrawalAdapter object. + * + * @param withdrawal the Withdrawal object to adapt. + */ public WithdrawalAdapter(final Withdrawal withdrawal) { this.withdrawal = withdrawal; } + /** + * Returns the index of the withdrawal. + * + * @return the index of the withdrawal. + */ public Long getIndex() { return withdrawal.getIndex().toLong(); } + /** + * Returns the validator of the withdrawal. + * + * @return the validator of the withdrawal. + */ public Long getValidator() { return withdrawal.getValidatorIndex().toLong(); } + /** + * Returns the address of the withdrawal. + * + * @return the address of the withdrawal. + */ public Address getAddress() { return withdrawal.getAddress(); } + /** + * Returns the amount of the withdrawal. + * + * @return the amount of the withdrawal. + */ public Long getAmount() { return withdrawal.getAmount().getAsBigInteger().longValue(); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/response/GraphQLError.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/response/GraphQLError.java index e4aeacd92f..f370df8dcf 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/response/GraphQLError.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/response/GraphQLError.java @@ -19,30 +19,96 @@ import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonGetter; +/** + * Enum representing various types of GraphQL errors. + * + *

Each error is associated with a specific code and message. The code is an integer that + * uniquely identifies the error. The message is a string that provides a human-readable description + * of the error. + * + *

This enum includes standard errors such as INVALID_PARAMS and INTERNAL_ERROR, transaction + * validation failures such as NONCE_TOO_LOW and INVALID_TRANSACTION_SIGNATURE, and private + * transaction errors such as PRIVATE_TRANSACTION_FAILED and PRIVATE_NONCE_TOO_LOW. + * + *

The {@code of} method is used to map a {@code TransactionInvalidReason} to a corresponding + * {@code GraphQLError}. + */ @JsonFormat(shape = JsonFormat.Shape.OBJECT) public enum GraphQLError { // Standard errors + /** Error code -32602. This error occurs when the parameters provided are invalid. */ INVALID_PARAMS(-32602, "Invalid params"), + + /** Error code -32603. This error occurs when there is an internal error. */ INTERNAL_ERROR(-32603, "Internal error"), // Transaction validation failures + /** Error code -32001. This error occurs when the nonce value is too low. */ NONCE_TOO_LOW(-32001, "Nonce too low"), + + /** Error code -32002. This error occurs when the transaction signature is invalid. */ INVALID_TRANSACTION_SIGNATURE(-32002, "Invalid signature"), + + /** Error code -32003. This error occurs when the intrinsic gas exceeds the gas limit. */ INTRINSIC_GAS_EXCEEDS_LIMIT(-32003, "Intrinsic gas exceeds gas limit"), + + /** + * Error code -32004. This error occurs when the upfront cost of the transaction exceeds the + * account balance. + */ TRANSACTION_UPFRONT_COST_EXCEEDS_BALANCE(-32004, "Upfront cost exceeds account balance"), + + /** + * Error code -32005. This error occurs when the transaction gas limit exceeds the block gas + * limit. + */ EXCEEDS_BLOCK_GAS_LIMIT(-32005, "Transaction gas limit exceeds block gas limit"), + + /** Error code -32006. This error occurs when the nonce value is too high. */ INCORRECT_NONCE(-32006, "Nonce too high"), + + /** + * Error code -32007. This error occurs when the sender account is not authorized to send + * transactions. + */ TX_SENDER_NOT_AUTHORIZED(-32007, "Sender account not authorized to send transactions"), + + /** Error code -32008. This error occurs when the initial sync is still in progress. */ CHAIN_HEAD_WORLD_STATE_NOT_AVAILABLE(-32008, "Initial sync is still in progress"), + + /** + * Error code -32009. This error occurs when the gas price is below the configured minimum gas + * price. + */ GAS_PRICE_TOO_LOW(-32009, "Gas price below configured minimum gas price"), + + /** + * Error code -32000. This error occurs when the Chain ID in the transaction signature is wrong. + */ WRONG_CHAIN_ID(-32000, "Wrong Chain ID in transaction signature"), + + /** + * Error code -32000. This error occurs when signatures with replay protection are not supported. + */ REPLAY_PROTECTED_SIGNATURES_NOT_SUPPORTED( -32000, "Signatures with replay protection are not supported"), + + /** Error code -32000. This error occurs when the transaction fee cap is exceeded. */ TX_FEECAP_EXCEEDED(-32000, "Transaction fee cap exceeded"), // Private Transaction Errors + /** Error code -32000. This error occurs when a private transaction fails. */ PRIVATE_TRANSACTION_FAILED(-32000, "Private transaction failed"), + + /** + * Error code -50100. This error occurs when the nonce value for a private transaction is too low. + */ PRIVATE_NONCE_TOO_LOW(-50100, "Private transaction nonce too low"), + + /** + * Error code -50100. This error occurs when the nonce value for a private transaction is + * incorrect. + */ INCORRECT_PRIVATE_NONCE(-50100, "Private transaction nonce is incorrect"); private final int code; @@ -53,49 +119,52 @@ public enum GraphQLError { this.message = message; } + /** + * Returns the error code associated with this GraphQL error. + * + * @return the error code as an integer. + */ @JsonGetter("code") public int getCode() { return code; } + /** + * Returns the error message associated with this GraphQL error. + * + * @return the error message as a string. + */ @JsonGetter("message") public String getMessage() { return message; } + /** + * Maps a {@code TransactionInvalidReason} to a corresponding {@code GraphQLError}. + * + *

This method is used to convert a transaction invalid reason to a GraphQL error, which can be + * used to provide more detailed error information to the client. + * + * @param transactionInvalidReason the transaction invalid reason to be converted. + * @return the corresponding GraphQL error. + */ public static GraphQLError of(final TransactionInvalidReason transactionInvalidReason) { - switch (transactionInvalidReason) { - case WRONG_CHAIN_ID: - return WRONG_CHAIN_ID; - case REPLAY_PROTECTED_SIGNATURES_NOT_SUPPORTED: - return REPLAY_PROTECTED_SIGNATURES_NOT_SUPPORTED; - case INVALID_SIGNATURE: - return INVALID_TRANSACTION_SIGNATURE; - case UPFRONT_COST_EXCEEDS_BALANCE: - return TRANSACTION_UPFRONT_COST_EXCEEDS_BALANCE; - case NONCE_TOO_LOW: - case PRIVATE_NONCE_TOO_LOW: - return NONCE_TOO_LOW; - case NONCE_TOO_HIGH: - case PRIVATE_NONCE_TOO_HIGH: - return INCORRECT_NONCE; - case INTRINSIC_GAS_EXCEEDS_GAS_LIMIT: - return INTRINSIC_GAS_EXCEEDS_LIMIT; - case EXCEEDS_BLOCK_GAS_LIMIT: - return EXCEEDS_BLOCK_GAS_LIMIT; - case TX_SENDER_NOT_AUTHORIZED: - return TX_SENDER_NOT_AUTHORIZED; - case CHAIN_HEAD_WORLD_STATE_NOT_AVAILABLE: - return CHAIN_HEAD_WORLD_STATE_NOT_AVAILABLE; + return switch (transactionInvalidReason) { + case WRONG_CHAIN_ID -> WRONG_CHAIN_ID; + case REPLAY_PROTECTED_SIGNATURES_NOT_SUPPORTED -> REPLAY_PROTECTED_SIGNATURES_NOT_SUPPORTED; + case INVALID_SIGNATURE -> INVALID_TRANSACTION_SIGNATURE; + case UPFRONT_COST_EXCEEDS_BALANCE -> TRANSACTION_UPFRONT_COST_EXCEEDS_BALANCE; + case NONCE_TOO_LOW, PRIVATE_NONCE_TOO_LOW -> NONCE_TOO_LOW; + case NONCE_TOO_HIGH, PRIVATE_NONCE_TOO_HIGH -> INCORRECT_NONCE; + case INTRINSIC_GAS_EXCEEDS_GAS_LIMIT -> INTRINSIC_GAS_EXCEEDS_LIMIT; + case EXCEEDS_BLOCK_GAS_LIMIT -> EXCEEDS_BLOCK_GAS_LIMIT; + case TX_SENDER_NOT_AUTHORIZED -> TX_SENDER_NOT_AUTHORIZED; + case CHAIN_HEAD_WORLD_STATE_NOT_AVAILABLE -> CHAIN_HEAD_WORLD_STATE_NOT_AVAILABLE; // Private Transaction Invalid Reasons - case PRIVATE_TRANSACTION_FAILED: - return PRIVATE_TRANSACTION_FAILED; - case GAS_PRICE_TOO_LOW: - return GAS_PRICE_TOO_LOW; - case TX_FEECAP_EXCEEDED: - return TX_FEECAP_EXCEEDED; - default: - return INTERNAL_ERROR; - } + case PRIVATE_TRANSACTION_FAILED -> PRIVATE_TRANSACTION_FAILED; + case GAS_PRICE_TOO_LOW -> GAS_PRICE_TOO_LOW; + case TX_FEECAP_EXCEEDED -> TX_FEECAP_EXCEEDED; + default -> INTERNAL_ERROR; + }; } } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/response/GraphQLErrorResponse.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/response/GraphQLErrorResponse.java index faf129311c..8204fad075 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/response/GraphQLErrorResponse.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/response/GraphQLErrorResponse.java @@ -16,12 +16,26 @@ package org.hyperledger.besu.ethereum.api.graphql.internal.response; import com.fasterxml.jackson.annotation.JsonIgnore; +/** + * Represents a GraphQL error response. This class extends the GraphQLResponse class and overrides + * the getType method to return ERROR. + */ public class GraphQLErrorResponse extends GraphQLResponse { + /** + * Constructs a new GraphQLErrorResponse with the specified errors. + * + * @param errors the errors to be included in the response. + */ public GraphQLErrorResponse(final Object errors) { super(errors); } + /** + * Returns the type of this GraphQL response. + * + * @return GraphQLResponseType.ERROR, indicating that this is an error response. + */ @Override @JsonIgnore public GraphQLResponseType getType() { diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/response/GraphQLJsonRequest.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/response/GraphQLJsonRequest.java index 4a0755fad3..899e08a7f0 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/response/GraphQLJsonRequest.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/response/GraphQLJsonRequest.java @@ -19,36 +19,77 @@ import java.util.Map; import com.fasterxml.jackson.annotation.JsonGetter; import com.fasterxml.jackson.annotation.JsonSetter; +/** + * This class represents a GraphQL JSON request. + * + *

It contains the query, operation name, and variables for a GraphQL request. The query is a + * string that represents the GraphQL query. The operation name is a string that represents the + * operation to be performed. The variables is a map that contains the variables for the GraphQL + * query. + */ public class GraphQLJsonRequest { private String query; private String operationName; private Map variables; + /** Default constructor for GraphQLJsonRequest. */ + public GraphQLJsonRequest() {} + + /** + * Gets the query of the GraphQL request. + * + * @return the query of the GraphQL request. + */ @JsonGetter public String getQuery() { return query; } + /** + * Sets the query of the GraphQL request. + * + * @param query the query of the GraphQL request. + */ @JsonSetter public void setQuery(final String query) { this.query = query; } + /** + * Gets the operation name of the GraphQL request. + * + * @return the operation name of the GraphQL request. + */ @JsonGetter public String getOperationName() { return operationName; } + /** + * Sets the operation name of the GraphQL request. + * + * @param operationName the operation name of the GraphQL request. + */ @JsonSetter public void setOperationName(final String operationName) { this.operationName = operationName; } + /** + * Gets the variables of the GraphQL request. + * + * @return the variables of the GraphQL request. + */ @JsonGetter public Map getVariables() { return variables; } + /** + * Sets the variables of the GraphQL request. + * + * @param variables the variables of the GraphQL request. + */ @JsonSetter public void setVariables(final Map variables) { this.variables = variables; diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/response/GraphQLNoResponse.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/response/GraphQLNoResponse.java index abc0725107..2891ed1922 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/response/GraphQLNoResponse.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/response/GraphQLNoResponse.java @@ -14,8 +14,20 @@ */ package org.hyperledger.besu.ethereum.api.graphql.internal.response; +/** + * This class represents a GraphQL response with no content. + * + *

It extends the GraphQLResponse class and overrides the getType method to return + * GraphQLResponseType.NONE. + */ public class GraphQLNoResponse extends GraphQLResponse { + /** + * Default constructor for GraphQLNoResponse. + * + *

It calls the parent constructor with null as the argument, indicating no content for this + * response. + */ public GraphQLNoResponse() { super(null); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/response/GraphQLResponse.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/response/GraphQLResponse.java index 21bc17d31a..6612162549 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/response/GraphQLResponse.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/response/GraphQLResponse.java @@ -16,15 +16,35 @@ package org.hyperledger.besu.ethereum.api.graphql.internal.response; import java.util.Objects; +/** + * Represents a GraphQL response. This abstract class provides a structure for different types of + * GraphQL responses. + */ public abstract class GraphQLResponse { - public abstract GraphQLResponseType getType(); private final Object result; + /** + * Constructs a new GraphQLResponse with the specified result. + * + * @param result the result to be included in the response. + */ GraphQLResponse(final Object result) { this.result = result; } + /** + * Returns the type of this GraphQL response. + * + * @return the type of this GraphQL response as a GraphQLResponseType. + */ + public abstract GraphQLResponseType getType(); + + /** + * Returns the result of this GraphQL response. + * + * @return the result of this GraphQL response as an Object. + */ public Object getResult() { return result; } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/response/GraphQLResponseType.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/response/GraphQLResponseType.java index ddd5170c37..655d5bc11a 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/response/GraphQLResponseType.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/response/GraphQLResponseType.java @@ -16,8 +16,15 @@ package org.hyperledger.besu.ethereum.api.graphql.internal.response; /** Various types of responses that the JSON-RPC component may produce. */ public enum GraphQLResponseType { + /** Represents a response type where there is no content. */ NONE, + + /** Represents a successful response type. */ SUCCESS, + + /** Represents an error response type. */ ERROR, + + /** Represents an unauthorized response type. */ UNAUTHORIZED } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/response/GraphQLSuccessResponse.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/response/GraphQLSuccessResponse.java index c5a709c37a..0721f7d276 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/response/GraphQLSuccessResponse.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/response/GraphQLSuccessResponse.java @@ -16,12 +16,33 @@ package org.hyperledger.besu.ethereum.api.graphql.internal.response; import com.fasterxml.jackson.annotation.JsonIgnore; +/** + * This class represents a successful GraphQL response. + * + *

It extends the GraphQLResponse class and overrides the getType method to return + * GraphQLResponseType.SUCCESS. + */ public class GraphQLSuccessResponse extends GraphQLResponse { + /** + * Constructor for GraphQLSuccessResponse. + * + *

It calls the parent constructor with the provided data as the argument. + * + * @param data the data to be included in the successful response. + */ public GraphQLSuccessResponse(final Object data) { super(data); } + /** + * Returns the type of the GraphQL response. + * + *

This method is overridden to return GraphQLResponseType.SUCCESS, indicating a successful + * response. + * + * @return GraphQLResponseType.SUCCESS + */ @Override @JsonIgnore public GraphQLResponseType getType() { diff --git a/ethereum/mock-p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/testing/MockNetwork.java b/ethereum/mock-p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/testing/MockNetwork.java index b443afe9f9..d7a3c2b506 100644 --- a/ethereum/mock-p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/testing/MockNetwork.java +++ b/ethereum/mock-p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/testing/MockNetwork.java @@ -55,6 +55,11 @@ public final class MockNetwork { private final Map nodes = new HashMap<>(); private final List capabilities; + /** + * Constructs a new MockNetwork with the specified capabilities. + * + * @param capabilities a list of capabilities that the mock network should have. + */ public MockNetwork(final List capabilities) { this.capabilities = capabilities; } From 75f565e0c7d8bd2b1716c9d408dbe03dbca183a7 Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Thu, 27 Jun 2024 23:20:51 -0600 Subject: [PATCH 009/259] T8n support for isStateTest and empty accounts (#7275) Update t8n executor to support new isStateTest env flag that will disable extra-transactional processing such as block rewards and beacon root. Also, make sure such extra-transactional commits don't create empty accounts. Signed-off-by: Danno Ferrin Co-authored-by: Usman Saleem --- .../hyperledger/besu/evmtool/T8nExecutor.java | 53 ++++++++++++------- .../BlockchainReferenceTestCaseSpec.java | 3 +- .../referencetests/ReferenceTestEnv.java | 23 ++++++-- 3 files changed, 53 insertions(+), 26 deletions(-) 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 ccabce833a..caa5cb3672 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 @@ -51,6 +51,7 @@ import org.hyperledger.besu.ethereum.referencetests.ReferenceTestWorldState; import org.hyperledger.besu.ethereum.rlp.BytesValueRLPInput; import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; import org.hyperledger.besu.ethereum.rlp.RLP; +import org.hyperledger.besu.ethereum.trie.diffbased.common.DiffBasedAccount; import org.hyperledger.besu.evm.account.Account; import org.hyperledger.besu.evm.gascalculator.GasCalculator; import org.hyperledger.besu.evm.log.Log; @@ -265,9 +266,11 @@ public class T8nExecutor { .blobGasPricePerGas(calculateExcessBlobGasForParent(protocolSpec, blockHeader)); long blobGasLimit = protocolSpec.getGasLimitCalculator().currentBlobGasLimit(); - protocolSpec - .getBlockHashProcessor() - .processBlockHashes(blockchain, worldState, referenceTestEnv); + if (!referenceTestEnv.isStateTest()) { + protocolSpec + .getBlockHashProcessor() + .processBlockHashes(blockchain, worldState, referenceTestEnv); + } final WorldUpdater rootWorldStateUpdater = worldState.updater(); List receipts = new ArrayList<>(); @@ -318,13 +321,12 @@ public class T8nExecutor { timer.stop(); if (shouldClearEmptyAccounts(fork)) { - final Account coinbase = worldStateUpdater.getOrCreate(blockHeader.getCoinbase()); - if (coinbase != null && coinbase.isEmpty()) { - worldStateUpdater.deleteAccount(coinbase.getAddress()); - } - final Account txSender = worldStateUpdater.getAccount(transaction.getSender()); - if (txSender != null && txSender.isEmpty()) { - worldStateUpdater.deleteAccount(txSender.getAddress()); + var entries = new ArrayList<>(worldState.getAccumulator().getAccountsToUpdate().entrySet()); + for (var entry : entries) { + DiffBasedAccount updated = entry.getValue().getUpdated(); + if (updated != null && updated.isEmpty()) { + worldState.getAccumulator().deleteAccount(entry.getKey()); + } } } if (result.isInvalid()) { @@ -397,7 +399,9 @@ public class T8nExecutor { // block reward // The max production reward was 5 Eth, longs can hold over 18 Eth. - if (!validTransactions.isEmpty() && (rewardString == null || Long.decode(rewardString) > 0)) { + if (!referenceTestEnv.isStateTest() + && !validTransactions.isEmpty() + && (rewardString == null || Long.decode(rewardString) > 0)) { Wei reward = (rewardString == null) ? protocolSpec.getBlockReward() @@ -408,15 +412,24 @@ public class T8nExecutor { } rootWorldStateUpdater.commit(); - // Invoke the withdrawal processor to handle CL withdrawals. - if (!referenceTestEnv.getWithdrawals().isEmpty()) { - try { - protocolSpec - .getWithdrawalsProcessor() - .ifPresent( - p -> p.processWithdrawals(referenceTestEnv.getWithdrawals(), worldState.updater())); - } catch (RuntimeException re) { - resultObject.put("exception", re.getMessage()); + + if (referenceTestEnv.isStateTest()) { + if (!referenceTestEnv.getWithdrawals().isEmpty()) { + resultObject.put("exception", "withdrawals are not supported in state tests"); + } + } else { + // Invoke the withdrawal processor to handle CL withdrawals. + if (!referenceTestEnv.getWithdrawals().isEmpty()) { + try { + protocolSpec + .getWithdrawalsProcessor() + .ifPresent( + p -> + p.processWithdrawals( + referenceTestEnv.getWithdrawals(), worldState.updater())); + } catch (RuntimeException re) { + resultObject.put("exception", re.getMessage()); + } } } 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 378637f363..1048f6238a 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 @@ -249,7 +249,8 @@ public class BlockchainReferenceTestCaseSpec { @JsonProperty("uncleHeaders") final Object uncleHeaders, @JsonProperty("withdrawals") final Object withdrawals, @JsonProperty("depositRequests") final Object depositRequests, - @JsonProperty("withdrawalRequests") final Object withdrawalRequests) { + @JsonProperty("withdrawalRequests") final Object withdrawalRequests, + @JsonProperty("consolidationRequests") final Object consolidationRequests) { boolean blockVaid = true; // The BLOCK__WrongCharAtRLP_0 test has an invalid character in its rlp string. Bytes rlpAttempt = null; 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 3cd248e3ae..636e23f878 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 @@ -83,6 +83,8 @@ public class ReferenceTestEnv extends BlockHeader { private final Bytes32 beaconRoot; + private final boolean isStateTest; + /** * Public constructor. * @@ -120,7 +122,8 @@ public class ReferenceTestEnv extends BlockHeader { @JsonProperty("parentGasLimit") final String parentGasLimit, @JsonProperty("parentGasUsed") final String parentGasUsed, @JsonProperty("parentTimestamp") final String parentTimestamp, - @JsonProperty("parentUncleHash") final String _parentUncleHash) { + @JsonProperty("parentUncleHash") final String _parentUncleHash, + @JsonProperty("isStateTest") final String isStateTest) { super( generateTestBlockHash(previousHash, number), Hash.EMPTY_LIST_HASH, // ommersHash @@ -164,10 +167,16 @@ public class ReferenceTestEnv extends BlockHeader { Map.entry( Long.decode(entry.getKey()), Hash.fromHexString(entry.getValue()))) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); - this.beaconRoot = - beaconRoot == null - ? (currentBeaconRoot == null ? null : Hash.fromHexString(currentBeaconRoot)) - : Hash.fromHexString(beaconRoot); + if (beaconRoot == null) { + if (currentBeaconRoot == null) { + this.beaconRoot = null; + } else { + this.beaconRoot = Hash.fromHexString(currentBeaconRoot); + } + } else { + this.beaconRoot = Hash.fromHexString(beaconRoot); + } + this.isStateTest = Boolean.parseBoolean(isStateTest); } @Override @@ -239,6 +248,10 @@ public class ReferenceTestEnv extends BlockHeader { return blockHashes; } + public boolean isStateTest() { + return isStateTest; + } + @Override public boolean equals(final Object o) { if (this == o) return true; From 6d55f91a9c8269cd797fec0954c727c087007b1e Mon Sep 17 00:00:00 2001 From: Simon Dudley Date: Fri, 28 Jun 2024 16:09:52 +1000 Subject: [PATCH 010/259] Promote storage x-trie-log subcommand to trie-log (#7278) Signed-off-by: Simon Dudley --- CHANGELOG.md | 8 ++++++++ .../besu/cli/subcommands/storage/TrieLogSubCommand.java | 3 ++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4eb0b5166d..5ba6b4dc5d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ ## Next Release +### Upcoming Breaking Changes +- Receipt compaction will be enabled by default in a future version of Besu. After this change it will not be possible to downgrade to the previous Besu version. +- PKI-backed QBFT will be removed in a future version of Besu. Other forms of QBFT will remain unchanged. +- --Xbonsai-limit-trie-logs-enabled is deprecated, use --bonsai-limit-trie-logs-enabled instead +- --Xbonsai-trie-logs-pruning-window-size is deprecated, use --bonsai-trie-logs-pruning-window-size instead +- `besu storage x-trie-log` subcommand is deprecated, use `besu storage trie-log` instead + ### Breaking Changes - `Xp2p-peer-lower-bound` has been removed. [#7247](https://github.com/hyperledger/besu/pull/7247) @@ -16,6 +23,7 @@ - Add LUKSO as predefined network name [#7223](https://github.com/hyperledger/besu/pull/7223) - Refactored how code, initcode, and max stack size are configured in forks. [#7245](https://github.com/hyperledger/besu/pull/7245) - Nodes in a permissioned chain maintain (and retry) connections to bootnodes [#7257](https://github.com/hyperledger/besu/pull/7257) +- Promote experimental `besu storage x-trie-log` subcommand to production-ready [#7278](https://github.com/hyperledger/besu/pull/7278) ### Bug fixes - Validation errors ignored in accounts-allowlist and empty list [#7138](https://github.com/hyperledger/besu/issues/7138) 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 6b0507895c..de42616822 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 @@ -49,7 +49,8 @@ import picocli.CommandLine.ParentCommand; /** The Trie Log subcommand. */ @Command( - name = "x-trie-log", + name = "trie-log", + aliases = "x-trie-log", description = "Manipulate trie logs", mixinStandardHelpOptions = true, versionProvider = VersionProvider.class, From c298a9e77e00aa3745a47a155bf5b6448e53bac4 Mon Sep 17 00:00:00 2001 From: Justin Florentine Date: Fri, 28 Jun 2024 08:37:16 -0400 Subject: [PATCH 011/259] Evm tool readme update (#7274) * update paths to binary. update docker build to use java 21 * updated suggested jdk --------- Signed-off-by: Justin Florentine --- ethereum/evmtool/README.md | 71 ++++++--------------- ethereum/evmtool/build.gradle | 41 ------------ ethereum/evmtool/src/main/docker/Dockerfile | 2 +- 3 files changed, 20 insertions(+), 94 deletions(-) diff --git a/ethereum/evmtool/README.md b/ethereum/evmtool/README.md index a1a703f913..50db1066f3 100644 --- a/ethereum/evmtool/README.md +++ b/ethereum/evmtool/README.md @@ -8,13 +8,9 @@ and enclosing data structures. Using EVM Tool in execution-specification-tests ----------------------------------------------- -To use EVM Tool in Execution Spec tests it is recommended that you use -the GraalVM build, as the framework incurs significant startup penalties -for each invocation when run via the Java runtime. - ### Building Execution Tests on macOS -Current as of 24 Jun 2023. +Current as of 26 Jun 2024. MacOS users will typically encounter two problems,one relating to the version of Python used and one relating to zsh. @@ -35,7 +31,7 @@ install python packages needs to escape the brackets pip install -e .\[docs,lint,test\] ``` -An all-in-one script, including homebrew, would look like +An all-in-one script, using homebrew, would look like ```zsh brew install ethereum solidity @@ -43,85 +39,56 @@ git clone https://github.com/ethereum/execution-spec-tests cd execution-spec-tests python3 -m venv ./venv/ source ./venv/bin/activate -pip install -e .[docs,lint,test] +pip install -e .\[docs,lint,test\] ``` -### Building EvmTool with GraalVM on macOS +### Building EvmTool on macOS -First you need a GraalVM JDK installed, if not already installed. +First you need a Java 21+ JDK installed, if not already installed. It is recommended you install [SDKMAN](https://sdkman.io/install) to -manage the graalVM install, homebrew has issues with native attributes -and code signing. +manage the jvm install. ```zsh -sdk install java 22.3.r17-grl -sdk use java 22.3.r17-grl +sdk install java 21.0.3-tem +sdk use java 21.0.3-tem ``` -You can also manually install GraalVM from -the [GraalVM website](https://www.graalvm.org/downloads).. - -Once GraalVM is installed you use the `nativeCompile` target. +Once a JVM is installed you use the gradle target: ```zsh -./gradlew nativeCompile +./gradlew installDist -x test ``` The resulting binary -is `./ethereum/evmtool/build/native/nativeCompile/evmtool` +is `build/install/besu/bin/evmtool` If the testing repository and besu are installed in the same parent directory, the command to run the execution tests is ```zsh -fill -v tests --evm-bin ../besu/ethereum/evmtool/build/install/evmtool/bin/evm +fill -v tests --evm-bin ../besu/build/install/besu/bin/evmtool ``` Assuming homebrew and SDKMan are both installed, the complete script is ```zsh -sdk install java 22.3.r17-grl -sdk use java 22.3.r17-grl +sdk install java 21.0.3-tem +sdk use java 21.0.3-tem git clone https://github.com/hyperledger/besu cd besu -./gradlew nativeCompile +./gradlew installDist -x test cd .. brew install ethereum solidity +solc-select install latest +solc-select use latest git clone https://github.com/ethereum/execution-spec-tests cd execution-spec-tests python3 -m venv ./venv/ source ./venv/bin/activate -pip install -e .[docs,lint,test] +pip install -e .\[docs,lint,test\] -fill -v tests --evm-bin ../besu/ethereum/evmtool/build/install/evmtool/bin/evm +fill -v tests --evm-bin ../besu/build/install/besu/bin/evmtool ``` -If you don't want to use the GraalVM tool the binary that is compatible -is generated by the `ethereum:evmtool:installdist` target and is located -at `./ethereum/evmtool/build/install/evmtool/bin/evm` - -Why not GraalVM for everything? -------------------------------- - -Using GraalVM in execution-spec-tests results in over 20x performance -increase in execution. It will be faster to build GraalVM from scratch -and run the execution-spec-tests than to run just the Java version. - -It is demonstrably faster to run the Java version for a node. -All the test execution gains are the result of reduced startup -penalties. Larger benchmarks will show that performance intensive EVM -code will be slower in GraalVM than the Java version due to the adaptive -compiler. - -For contracts that execute 30 million gas in small operations it is -often faster to run the Java EVMTool than the GraalVM EVMTool, including -startup penalty. The execution tests focus on smaller VM tests that -demonstrate specification conformance. - -We would also need to reconsider some library choices. GraalVM does not -work with Log4J, and we would have to ban that library across Besu and -all dependents. Libraries such as Netty also have some problematic entry -points that interact poorly with how SLF4J needs to initialize. - diff --git a/ethereum/evmtool/build.gradle b/ethereum/evmtool/build.gradle index 0d1700082f..aaddc354d5 100644 --- a/ethereum/evmtool/build.gradle +++ b/ethereum/evmtool/build.gradle @@ -72,16 +72,6 @@ dependencies { mainClassName = 'org.hyperledger.besu.evmtool.EvmTool' -startScripts { - applicationName = 'evm' - defaultJvmOpts = [ - "-Dsecp256k1.randomize=false" - ] - doLast { - unixScript.text = unixScript.text.replace('BESU_HOME', '\$APP_HOME') - windowsScript.text = windowsScript.text.replace('BESU_HOME', '%~dp0..') - } -} // rename the top level dir from besu- to besu and this makes it really // simple for use in docker @@ -148,34 +138,3 @@ tasks.register('dockerUpload', Exec) { executable "sh" args "-c", cmd } - -graalvmNative { - binaries { - main { - sharedLibrary = false - buildArgs.addAll( - "-H:ReflectionConfigurationFiles=${projectDir}/src/main/graal/reflection-config.json", - "-H:AdditionalSecurityProviders=org.bouncycastle.jce.provider.BouncyCastleProvider", - '-H:+TraceSecurityServices' - ) - - - // Netty drags in older versions of bouncy castle, exclude it so there are no conflicts - excludeConfig.put("io.netty:netty-buffer", [".*"]) - } - } -} - - -configurations.nativeImageClasspath { - // netty statically allocates some problematic classes - exclude group: 'io.netty', module: 'netty-buffer' - exclude group: 'io.netty', module: 'netty-common' - exclude group: 'io.netty', module: 'netty-transport' - - // keep log4j from sneaking in. GraalVM has an aleric reaction if it sees even one class - exclude group: 'org.slf4j', module: 'log4j-over-slf4j:1.7.36' - exclude group: "log4j", module: "log4j" - exclude group: "org.apache.logging.log4j" - exclude group: 'org.bouncycastle', module: 'bcprov-jdk18on' -} diff --git a/ethereum/evmtool/src/main/docker/Dockerfile b/ethereum/evmtool/src/main/docker/Dockerfile index 9d9bf4aafa..9d7b48d3cb 100644 --- a/ethereum/evmtool/src/main/docker/Dockerfile +++ b/ethereum/evmtool/src/main/docker/Dockerfile @@ -9,7 +9,7 @@ RUN apt-get update $NO_PROXY_CACHE && \ apt-get -o Acquire::BrokenProxy=true -o Acquire::http::No-Cache=true -o Acquire::http::Pipeline-Depth=0 \ --no-install-recommends -q --assume-yes install ca-certificates-java=20190909* && \ apt-get -o Acquire::BrokenProxy=true -o Acquire::http::No-Cache=true -o Acquire::http::Pipeline-Depth=0 \ - --no-install-recommends -q --assume-yes install openjdk-17-jre-headless=17* && \ + --no-install-recommends -q --assume-yes install openjdk-21-jre-headless=21* && \ # Clean apt cache \ apt-get clean && \ rm -rf /var/cache/apt/archives/* /var/cache/apt/archives/partial/* && \ From fa63fc45b469b309fb6a4c66e438e22f33a198a0 Mon Sep 17 00:00:00 2001 From: Usman Saleem Date: Sat, 29 Jun 2024 02:55:47 +1000 Subject: [PATCH 012/259] javadoc - Add missing javadoc for evmtool module (#7277) Signed-off-by: Usman Saleem --- build.gradle | 2 - .../besu/evmtool/B11rSubCommand.java | 11 ++++ .../besu/evmtool/BenchmarkSubCommand.java | 15 +++++ .../besu/evmtool/BlockchainModule.java | 8 +++ .../besu/evmtool/CodeValidateSubCommand.java | 22 +++++++ .../besu/evmtool/DataStoreModule.java | 11 ++++ .../besu/evmtool/EOFTestSubCommand.java | 15 +++++ .../org/hyperledger/besu/evmtool/EvmTool.java | 9 +++ .../besu/evmtool/EvmToolCommand.java | 43 ++++++++++++ .../evmtool/EvmToolCommandOptionsModule.java | 13 ++++ .../besu/evmtool/EvmToolComponent.java | 47 +++++++++++++ .../besu/evmtool/GenesisFileModule.java | 15 +++++ .../hyperledger/besu/evmtool/JsonUtils.java | 6 ++ .../besu/evmtool/PrettyPrintSubCommand.java | 28 ++++++++ .../besu/evmtool/ProtocolModule.java | 15 +++++ .../besu/evmtool/StateTestSubCommand.java | 21 ++++++ .../hyperledger/besu/evmtool/T8nExecutor.java | 66 ++++++++++++++++++- .../besu/evmtool/T8nServerSubCommand.java | 17 +++++ .../besu/evmtool/T8nSubCommand.java | 23 +++++++ .../besu/evmtool/VersionProvider.java | 18 +++++ 20 files changed, 402 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 1adc3b992c..7d2293b61e 100644 --- a/build.gradle +++ b/build.gradle @@ -401,8 +401,6 @@ allprojects { '-org.hyperledger.besu.ethereum.eth.*,' + '-org.hyperledger.besu.ethereum.eth,' + '-org.hyperledger.besu.consensus.merge,' + - // evmtool module - '-org.hyperledger.besu.evmtool,' + // p2p module '-org.hyperledger.besu.ethereum.p2p,' + '-org.hyperledger.besu.ethereum.p2p.*,' + diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/B11rSubCommand.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/B11rSubCommand.java index 9a27a8a40d..0bb7949754 100644 --- a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/B11rSubCommand.java +++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/B11rSubCommand.java @@ -51,6 +51,11 @@ import picocli.CommandLine.Option; import picocli.CommandLine.Parameters; import picocli.CommandLine.ParentCommand; +/** + * This class implements the Runnable interface and represents the B11rSubCommand. It is responsible + * for handling the block builder subcommand in the EVM tool. It provides methods to read headers, + * move fields, and run the command. + */ @Command( name = COMMAND_NAME, aliases = {COMMAND_ALIAS}, @@ -138,12 +143,18 @@ public class B11rSubCommand implements Runnable { } } + /** Default constructor for the B11rSubCommand class. This is required by PicoCLI. */ @SuppressWarnings("unused") public B11rSubCommand() { // PicoCLI requires this parentCommand = null; } + /** + * Constructs a new B11rSubCommand with the given parent command. + * + * @param parentCommand the parent command of this subcommand + */ @SuppressWarnings("unused") public B11rSubCommand(final EvmToolCommand parentCommand) { // PicoCLI requires this too 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 05d90a7b35..829bf2d58e 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 @@ -33,13 +33,22 @@ import picocli.CommandLine.Option; import picocli.CommandLine.Parameters; import picocli.CommandLine.ParentCommand; +/** + * This class represents the BenchmarkSubCommand. It is responsible for executing an Ethereum State + * Test. + */ @CommandLine.Command( name = COMMAND_NAME, description = "Execute an Ethereum State Test.", mixinStandardHelpOptions = true, versionProvider = VersionProvider.class) public class BenchmarkSubCommand implements Runnable { + /** + * The command name for the BenchmarkSubCommand. This constant is used as the name attribute in + * the {@code CommandLine.Command} annotation. + */ public static final String COMMAND_NAME = "benchmark"; + private final PrintStream output; enum Benchmark { @@ -68,11 +77,17 @@ public class BenchmarkSubCommand implements Runnable { @ParentCommand EvmToolCommand parentCommand; + /** Default constructor for the BenchmarkSubCommand class. This is required by PicoCLI. */ public BenchmarkSubCommand() { // PicoCLI requires this this(System.out); } + /** + * Constructs a new BenchmarkSubCommand with the given output stream. + * + * @param output the output stream to be used + */ public BenchmarkSubCommand(final PrintStream output) { this.output = output; } diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/BlockchainModule.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/BlockchainModule.java index b3a1531133..7b463fe08e 100644 --- a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/BlockchainModule.java +++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/BlockchainModule.java @@ -39,10 +39,18 @@ import dagger.Module; import dagger.Provides; import org.apache.tuweni.bytes.Bytes32; +/** + * This class is a Dagger module that provides dependencies related to the blockchain. It includes + * the GenesisFileModule and DataStoreModule for providing the genesis block and data store + * respectively. The class is annotated with {@code @Module} to indicate that it is a Dagger module. + */ @SuppressWarnings("WeakerAccess") @Module(includes = {GenesisFileModule.class, DataStoreModule.class}) public class BlockchainModule { + /** Default constructor for the BlockchainModule class. */ + public BlockchainModule() {} + @Singleton @Provides Blockchain provideBlockchain( 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 10e167f406..e16d4014f0 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 @@ -40,6 +40,11 @@ import org.apache.tuweni.bytes.Bytes; import picocli.CommandLine; import picocli.CommandLine.ParentCommand; +/** + * This class represents the CodeValidateSubCommand. It is responsible for validating EVM code for + * fuzzing. It implements the Runnable interface and is annotated with the {@code + * CommandLine.Command} annotation. + */ @SuppressWarnings({"ConstantValue", "DataFlowIssue"}) @CommandLine.Command( name = COMMAND_NAME, @@ -47,6 +52,10 @@ import picocli.CommandLine.ParentCommand; mixinStandardHelpOptions = true, versionProvider = VersionProvider.class) public class CodeValidateSubCommand implements Runnable { + /** + * The command name for the CodeValidateSubCommand. This constant is used as the name attribute in + * the CommandLine.Command annotation. + */ public static final String COMMAND_NAME = "code-validate"; @ParentCommand EvmToolCommand parentCommand; @@ -62,6 +71,7 @@ public class CodeValidateSubCommand implements Runnable { @CommandLine.Parameters private final List cliCode = new ArrayList<>(); + /** Default constructor for the CodeValidateSubCommand class. This is required by PicoCLI. */ @SuppressWarnings("unused") public CodeValidateSubCommand() { // PicoCLI requires this @@ -111,6 +121,18 @@ public class CodeValidateSubCommand implements Runnable { } } + /** + * This method is responsible for validating the EVM code. It takes a hexadecimal string + * representation of the EVM code as input. The method first converts the hexadecimal string to + * Bytes. It then checks if the code follows the EOF layout. If the layout is valid, it retrieves + * the code from the EVM. If the code is invalid, it returns an error message with the reason for + * the invalidity. If the code is valid, it returns a string with "OK" followed by the hexadecimal + * string representation of each code section. + * + * @param hexCode the hexadecimal string representation of the EVM code + * @return a string indicating whether the code is valid or not, and in case of validity, the + * hexadecimal string representation of each code section + */ public String considerCode(final String hexCode) { Bytes codeBytes; try { diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/DataStoreModule.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/DataStoreModule.java index 28b212024c..7629b31847 100644 --- a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/DataStoreModule.java +++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/DataStoreModule.java @@ -38,6 +38,14 @@ import com.google.common.base.Suppliers; import dagger.Module; import dagger.Provides; +/** + * This class is a Dagger module that provides dependencies related to the data store. It includes + * the GenesisFileModule for providing the genesis block. The class is annotated with + * {@code @Module} to indicate that it is a Dagger module. It provides various key-value storages + * such as variables, blockchain, world state, world state preimage, and pruning. The type of + * key-value storage (e.g., rocksdb, memory) can be specified. The class also provides a + * BlockchainStorage which is a prefixed key blockchain storage. + */ @SuppressWarnings({"CloseableProvides"}) @Module(includes = GenesisFileModule.class) public class DataStoreModule { @@ -50,6 +58,9 @@ public class DataStoreModule { List.of(KeyValueSegmentIdentifier.values()), RocksDBMetricsFactory.PUBLIC_ROCKS_DB_METRICS)); + /** Default constructor for the DataStoreModule class. */ + public DataStoreModule() {} + @Provides @Singleton @Named("variables") 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 ab53b41e1d..bfa873e61c 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 @@ -45,13 +45,16 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.tuweni.bytes.Bytes; import picocli.CommandLine; +/** A PicoCli annotated command for running EOF validation reference tests. */ @CommandLine.Command( name = COMMAND_NAME, description = "Runs EOF validation reference tests", mixinStandardHelpOptions = true, versionProvider = VersionProvider.class) public class EOFTestSubCommand implements Runnable { + /** The name of the EOF validation reference test command. */ public static final String COMMAND_NAME = "eof-test"; + @CommandLine.ParentCommand private final EvmToolCommand parentCommand; // picocli does it magically @@ -65,10 +68,16 @@ public class EOFTestSubCommand implements Runnable { EVM evm; String fork = null; + /** Default constructor for the EOFTestSubCommand class. Sets the parent command to null. */ public EOFTestSubCommand() { this(null); } + /** + * Constructor for the EOFTestSubCommand class with a parent command. + * + * @param parentCommand The parent command for this sub command. + */ public EOFTestSubCommand(final EvmToolCommand parentCommand) { this.parentCommand = parentCommand; } @@ -199,6 +208,12 @@ public class EOFTestSubCommand implements Runnable { } } + /** + * Considers the given hexadecimal code string for EOF validation. + * + * @param hexCode The hexadecimal string representation of the code to be considered. + * @return The result of the EOF validation test. + */ public TestResult considerCode(final String hexCode) { Bytes codeBytes; try { diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EvmTool.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EvmTool.java index 43c1a666d6..dec0555640 100644 --- a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EvmTool.java +++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EvmTool.java @@ -16,8 +16,17 @@ package org.hyperledger.besu.evmtool; import org.hyperledger.besu.util.LogConfigurator; +/** The main entry point for the EVM (Ethereum Virtual Machine) tool. */ public final class EvmTool { + /** Default constructor for the EvmTool class. */ + public EvmTool() {} + + /** + * The main entry point for the EVM (Ethereum Virtual Machine) tool. + * + * @param args The command line arguments. + */ public static void main(final String... args) { LogConfigurator.setLevel("", "DEBUG"); final EvmToolCommand evmToolCommand = new EvmToolCommand(); 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 90afdcdebb..a3bed6b54b 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 @@ -70,6 +70,21 @@ import picocli.CommandLine; import picocli.CommandLine.Command; import picocli.CommandLine.Option; +/** + * This class, EvmToolCommand, serves as the main command for the EVM (Ethereum Virtual Machine) + * tool. The EVM tool is used to execute Ethereum transactions and contracts in a local environment. + * + *

EvmToolCommand implements the Runnable interface, making it the entrypoint for PicoCLI to + * execute this command. + * + *

The class provides various options for setting up and executing EVM transactions. These + * options include, but are not limited to, setting the gas price, sender address, receiver address, + * and the data to be sent with the transaction. + * + *

Key methods in this class include 'run()' for executing the command, 'execute()' for setting + * up and running the EVM transaction, and 'dumpWorldState()' for outputting the current state of + * the Ethereum world state. + */ @Command( description = "This command evaluates EVM transactions.", abbreviateSynopsis = true, @@ -247,12 +262,22 @@ public class EvmToolCommand implements Runnable { PrintWriter out; InputStream in; + /** + * Default constructor for the EvmToolCommand class. It initializes the input stream with an empty + * byte array and the output stream with the standard output. + */ public EvmToolCommand() { this( new ByteArrayInputStream(new byte[0]), new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out, UTF_8)), true)); } + /** + * Constructor for the EvmToolCommand class with custom input and output streams. + * + * @param in The input stream to be used. + * @param out The output stream to be used. + */ public EvmToolCommand(final InputStream in, final PrintWriter out) { this.in = in; this.out = out; @@ -322,10 +347,21 @@ public class EvmToolCommand implements Runnable { subCommandLine.setHelpSectionKeys(keys); } + /** + * Returns the fork name provided by the Dagger options. If no fork is provided, it returns the + * name of the default EVM specification version. + * + * @return The fork name. + */ public String getFork() { return daggerOptions.provideFork().orElse(EvmSpecVersion.defaultVersion().getName()); } + /** + * Checks if a fork is provided in the Dagger options. + * + * @return True if a fork is provided, false otherwise. + */ public boolean hasFork() { return daggerOptions.provideFork().isPresent(); } @@ -506,6 +542,13 @@ public class EvmToolCommand implements Runnable { } } + /** + * Dumps the current state of the Ethereum world state to the provided PrintWriter. The state + * includes account balances, nonces, codes, and storage. The output is in JSON format. + * + * @param worldState The Ethereum world state to be dumped. + * @param out The PrintWriter to which the state is dumped. + */ public static void dumpWorldState(final MutableWorldState worldState, final PrintWriter out) { out.println("{"); worldState diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EvmToolCommandOptionsModule.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EvmToolCommandOptionsModule.java index fe229dc3cf..820b11442e 100644 --- a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EvmToolCommandOptionsModule.java +++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EvmToolCommandOptionsModule.java @@ -32,6 +32,16 @@ import dagger.Provides; import picocli.CommandLine; import picocli.CommandLine.Option; +/** + * This class, EvmToolCommandOptionsModule, is a Dagger module that provides dependencies for the + * EvmToolCommand. It contains options for setting up the EVM tool, such as whether revert reasons + * should be persisted, the fork to evaluate, the key-value storage to be used, the data path, the + * block number to evaluate against, and the world state update mode. + * + *

The class uses PicoCLI annotations to define these options, which can be provided via the + * command line when running the EVM tool. Each option has a corresponding provider method that + * Dagger uses to inject the option's value where needed. + */ @SuppressWarnings("WeakerAccess") @Module public class EvmToolCommandOptionsModule { @@ -133,4 +143,7 @@ public class EvmToolCommandOptionsModule { EvmConfiguration provideEvmConfiguration() { return new EvmConfiguration(jumpDestCacheWeightKilobytes, worldstateUpdateMode); } + + /** Default constructor for the EvmToolCommandOptionsModule class. */ + public EvmToolCommandOptionsModule() {} } diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EvmToolComponent.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EvmToolComponent.java index 176700ee8e..cc84b59480 100644 --- a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EvmToolComponent.java +++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EvmToolComponent.java @@ -26,6 +26,22 @@ import javax.inject.Singleton; import dagger.Component; +/** + * This is a Dagger component interface for the EVM (Ethereum Virtual Machine) tool. It is annotated + * with @Singleton to ensure that only a single instance of this component exists within the Dagger + * component graph. + * + *

The component is composed of several modules that provide the necessary dependencies for the + * EVM tool: - ProtocolModule: Provides the protocol specification. - GenesisFileModule: Provides + * the genesis file for the blockchain. - DataStoreModule: Provides the data store for blockchain + * data. - BlockchainModule: Provides the blockchain instance. - EvmToolCommandOptionsModule: + * Provides the command options for the EVM tool. - MetricsConfigurationModule and + * MetricsSystemModule: Provide the metrics system and its configuration. + * + *

The interface defines methods to get instances of key classes like ProtocolSpec, EVM, + * WorldUpdater, MutableWorldState, and Blockchain. These methods are used by Dagger to inject the + * returned instances where needed. + */ @Singleton @Component( modules = { @@ -39,13 +55,44 @@ import dagger.Component; }) public interface EvmToolComponent { + /** + * Retrieves the ProtocolSpec instance. ProtocolSpec defines the Ethereum protocol specifications, + * which includes the precompiled contracts, the gas calculator, the EVM, and the private nonce + * calculator. + * + * @return The ProtocolSpec instance. + */ ProtocolSpec getProtocolSpec(); + /** + * Retrieves the EVM instance. EVM (Ethereum Virtual Machine) is responsible for executing the + * bytecode of smart contracts in Ethereum. + * + * @return The EVM instance. + */ EVM getEVM(); + /** + * Retrieves the WorldUpdater instance. WorldUpdater is used to modify the world state, which + * includes the accounts and their associated storage and code. + * + * @return The WorldUpdater instance. + */ WorldUpdater getWorldUpdater(); + /** + * Retrieves the MutableWorldState instance. MutableWorldState represents the world state of + * Ethereum, which includes all accounts, their balances, nonces, codes, and storage. + * + * @return The MutableWorldState instance. + */ MutableWorldState getWorldState(); + /** + * Retrieves the Blockchain instance. Blockchain represents the Ethereum blockchain, which + * includes blocks, transactions, and the world state. + * + * @return The Blockchain instance. + */ Blockchain getBlockchain(); } diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/GenesisFileModule.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/GenesisFileModule.java index 506c3911d8..1283ec039f 100644 --- a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/GenesisFileModule.java +++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/GenesisFileModule.java @@ -36,11 +36,26 @@ import dagger.Module; import dagger.Provides; import io.vertx.core.json.JsonObject; +/** + * This class, GenesisFileModule, is a Dagger module that provides dependencies for the GenesisFile. + * It contains options for setting up the GenesisFile, such as the genesis configuration, genesis + * state, block header functions, and the genesis block. + * + *

The class uses Dagger annotations to define these options, which can be provided via the + * command line when running the EVM tool. Each option has a corresponding provider method that + * Dagger uses to inject the option's value where needed. + */ @Module public class GenesisFileModule { private final String genesisConfig; + /** + * Constructs a new GenesisFileModule with the specified genesis configuration. + * + * @param genesisConfig The configuration for the genesis file. This is typically a JSON string + * that specifies various parameters for the genesis block of the blockchain. + */ protected GenesisFileModule(final String genesisConfig) { this.genesisConfig = genesisConfig; } diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/JsonUtils.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/JsonUtils.java index 42da8fd950..7af31054a6 100644 --- a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/JsonUtils.java +++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/JsonUtils.java @@ -24,6 +24,12 @@ import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import org.apache.tuweni.bytes.Bytes; +/** + * Utility class for JSON related operations. This class provides a method to create an ObjectMapper + * with standard configurations needed for evmtool. The ObjectMapper is configured to match the + * standard JSON output of Go, and it does not auto close the source. It also registers serializers + * for Address and Bytes classes. This class is not meant to be instantiated. + */ public class JsonUtils { private JsonUtils() {} 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 10d31960a8..465f2c4895 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 @@ -30,13 +30,31 @@ import java.util.List; import org.apache.tuweni.bytes.Bytes; import picocli.CommandLine; +/** + * This class, PrettyPrintSubCommand, is a command-line interface (CLI) command that pretty prints + * EOF (Ethereum Object Format) code. It implements the Runnable interface, meaning it can be used + * in a thread of execution. + * + *

The class is annotated with {@code @CommandLine.Command}, which is a PicoCLI annotation that + * designates this class as a command-line command. The annotation parameters define the command's + * name, description, whether it includes standard help options, and the version provider. + * + *

The command's functionality is defined in the run() method, which is overridden from the + * Runnable interface. + */ @CommandLine.Command( name = COMMAND_NAME, description = "Pretty Prints EOF Code", mixinStandardHelpOptions = true, versionProvider = VersionProvider.class) public class PrettyPrintSubCommand implements Runnable { + /** + * The name of the command for the PrettyPrintSubCommand. This constant is used as the name + * parameter in the @CommandLine.Command annotation. It defines the command name that users should + * enter on the command line to invoke this command. + */ public static final String COMMAND_NAME = "pretty-print"; + @CommandLine.ParentCommand private final EvmToolCommand parentCommand; @CommandLine.Option( @@ -48,10 +66,20 @@ public class PrettyPrintSubCommand implements Runnable { // picocli does it magically @CommandLine.Parameters private final List codeList = new ArrayList<>(); + /** + * Default constructor for the PrettyPrintSubCommand class. This constructor initializes the + * parentCommand to null. + */ public PrettyPrintSubCommand() { this(null); } + /** + * Constructs a new PrettyPrintSubCommand with the specified parent command. + * + * @param parentCommand The parent command for this subcommand. This is typically an instance of + * EvmToolCommand. + */ public PrettyPrintSubCommand(final EvmToolCommand parentCommand) { this.parentCommand = parentCommand; } diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/ProtocolModule.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/ProtocolModule.java index 1b8f557b3b..a196a35f5b 100644 --- a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/ProtocolModule.java +++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/ProtocolModule.java @@ -24,10 +24,25 @@ import javax.inject.Singleton; import dagger.Module; import dagger.Provides; +/** + * This class, ProtocolModule, is a Dagger module that provides dependencies for the ProtocolSpec + * and EVM. It includes the GenesisFileModule, which provides the genesis configuration for the + * blockchain. + * + *

The class uses Dagger annotations to define these dependencies, which can be provided via the + * command line when running the EVM tool. Each dependency has a corresponding provider method that + * Dagger uses to inject the dependency's value where needed. + */ @SuppressWarnings("WeakerAccess") @Module(includes = GenesisFileModule.class) public class ProtocolModule { + /** + * Default constructor for the ProtocolModule class. This constructor doesn't take any arguments + * and doesn't perform any initialization. + */ + public ProtocolModule() {} + @Provides @Singleton ProtocolSpec getProtocolSpec(final ProtocolSchedule protocolSchedule) { diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/StateTestSubCommand.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/StateTestSubCommand.java index 60a09b26e8..064a093e84 100644 --- a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/StateTestSubCommand.java +++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/StateTestSubCommand.java @@ -65,12 +65,29 @@ import picocli.CommandLine.Option; import picocli.CommandLine.Parameters; import picocli.CommandLine.ParentCommand; +/** + * This class, StateTestSubCommand, is a command-line interface (CLI) command that executes an + * Ethereum State Test. It implements the Runnable interface, meaning it can be used in a thread of + * execution. + * + *

The class is annotated with @CommandLine.Command, which is a PicoCLI annotation that + * designates this class as a command-line command. The annotation parameters define the command's + * name, description, whether it includes standard help options, and the version provider. + * + *

The command's functionality is defined in the run() method, which is overridden from the + * Runnable interface. + */ @Command( name = COMMAND_NAME, description = "Execute an Ethereum State Test.", mixinStandardHelpOptions = true, versionProvider = VersionProvider.class) public class StateTestSubCommand implements Runnable { + /** + * The name of the command for the StateTestSubCommand. This constant is used as the name + * parameter in the @CommandLine.Command annotation. It defines the command name that users should + * enter on the command line to invoke this command. + */ public static final String COMMAND_NAME = "state-test"; static final Supplier referenceTestProtocolSchedules = @@ -112,6 +129,10 @@ public class StateTestSubCommand implements Runnable { // picocli does it magically @Parameters private final List stateTestFiles = new ArrayList<>(); + /** + * Default constructor for the StateTestSubCommand class. This constructor doesn't take any + * arguments and initializes the parentCommand to null. PicoCLI requires this constructor. + */ @SuppressWarnings("unused") public StateTestSubCommand() { // PicoCLI requires this 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 caa5cb3672..40c73e383f 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 @@ -86,12 +86,43 @@ import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; import org.apache.tuweni.units.bigints.UInt256; +/** + * The T8nExecutor class is responsible for executing transactions in the context of the Ethereum + * Virtual Machine (EVM). It extracts transactions from a given input, runs tests on them, and + * generates results including stateRoot, txRoot, receiptsRoot, and logsHash. It also handles block + * rewards and withdrawal processing. This class is part of the EVM tooling within the Hyperledger + * Besu project. + */ public class T8nExecutor { private static final Set

EMPTY_ADDRESS_SET = Set.of(); + /** + * A record that represents a transaction that has been rejected. It contains the index of the + * transaction and the error message explaining why it was rejected. + * + * @param index The index of the rejected transaction. + * @param error The error message explaining why the transaction was rejected. + */ public record RejectedTransaction(int index, String error) {} + /** + * Default constructor for the T8nExecutor class. This constructor does not perform any + * operations. + */ + public T8nExecutor() {} + + /** + * Extracts transactions from a given JSON iterator and adds them to the provided transactions + * list. If a transaction cannot be parsed or is invalid, it is added to the rejections list with + * its index and error message. + * + * @param out PrintWriter used for outputting information or errors. + * @param it Iterator over JSON nodes, each representing a transaction. + * @param transactions List of transactions to which parsed transactions are added. + * @param rejections List of RejectedTransaction records to which rejected transactions are added. + * @return The updated list of transactions after parsing and validation. + */ protected static List extractTransactions( final PrintWriter out, final Iterator it, @@ -547,12 +578,45 @@ public class T8nExecutor { return new T8nResult(allocObject, bodyBytes, resultObject); } - interface TracerManager { + /** + * The TracerManager interface provides methods for managing OperationTracer instances. It is used + * in the context of Ethereum Virtual Machine (EVM) execution to trace operations. + * + *

The interface defines two methods: - getManagedTracer: This method is used to get a managed + * OperationTracer instance for a specific transaction. - disposeTracer: This method is used to + * dispose of an OperationTracer instance when it is no longer needed. + */ + public interface TracerManager { + + /** + * Retrieves a managed OperationTracer instance for a specific transaction. + * + * @param txIndex The index of the transaction for which the tracer is to be retrieved. + * @param txHash The hash of the transaction for which the tracer is to be retrieved. + * @return The managed OperationTracer instance. + * @throws Exception If an error occurs while retrieving the tracer. + */ OperationTracer getManagedTracer(int txIndex, Hash txHash) throws Exception; + /** + * Disposes of an OperationTracer instance when it is no longer needed. + * + * @param tracer The OperationTracer instance to be disposed. + * @throws IOException If an error occurs while disposing the tracer. + */ void disposeTracer(OperationTracer tracer) throws IOException; } + /** + * A record that represents the result of a transaction test run in the Ethereum Virtual Machine + * (EVM). It contains the final state of the accounts (allocObject), the raw bytes of the + * transactions (bodyBytes), and the result of the test run (resultObject). + * + * @param allocObject The final state of the accounts after the test run. + * @param bodyBytes The raw bytes of the transactions that were run. + * @param resultObject The result of the test run, including stateRoot, txRoot, receiptsRoot, + * logsHash, and other details. + */ @SuppressWarnings("unused") record T8nResult(ObjectNode allocObject, TextNode bodyBytes, ObjectNode resultObject) {} } diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/T8nServerSubCommand.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/T8nServerSubCommand.java index 1c0a49438e..ffa6e67b72 100644 --- a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/T8nServerSubCommand.java +++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/T8nServerSubCommand.java @@ -55,6 +55,19 @@ import io.vertx.core.http.HttpServerRequest; import picocli.CommandLine; import picocli.CommandLine.ParentCommand; +/** + * The T8nServerSubCommand class is responsible for running an Ethereum State Test server. It reads + * the initial state, transactions, and environment from input files or stdin, executes the + * transactions in the Ethereum Virtual Machine (EVM), and writes the final state, transaction + * results, and traces to output files or stdout. + * + *

The class uses the Vert.x library for handling HTTP requests and the picocli library for + * command line argument parsing. It includes options for specifying the host and port to bind to, + * and the base directory for output. + * + *

The class also includes a TracerManager for managing OperationTracer instances, which are used + * to trace EVM operations when the --json flag is specified. + */ @SuppressWarnings("java:S106") // using standard output is the point of this class @CommandLine.Command( name = "t8n-server", @@ -80,6 +93,10 @@ public class T8nServerSubCommand implements Runnable { @ParentCommand private final EvmToolCommand parentCommand; + /** + * Default constructor for the T8nServerSubCommand class. This constructor is required by PicoCLI + * and assigns null to parentCommand. + */ @SuppressWarnings("unused") public T8nServerSubCommand() { // PicoCLI requires this diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/T8nSubCommand.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/T8nSubCommand.java index 95dabb3183..d6db1a1e8d 100644 --- a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/T8nSubCommand.java +++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/T8nSubCommand.java @@ -59,6 +59,19 @@ import picocli.CommandLine.ParameterException; import picocli.CommandLine.Parameters; import picocli.CommandLine.ParentCommand; +/** + * The T8nSubCommand class is responsible for executing an Ethereum State Test. It reads the initial + * state, transactions, and environment from input files or stdin, executes the transactions in the + * Ethereum Virtual Machine (EVM), and writes the final state, transaction results, and traces to + * output files or stdout. + * + *

The class uses the picocli library for command line argument parsing and includes options for + * specifying the input and output files, the fork to run the transition against, the chain ID, and + * the block reward. + * + *

The class also includes a TracerManager for managing OperationTracer instances, which are used + * to trace EVM operations when the --json flag is specified. + */ @Command( name = COMMAND_NAME, aliases = COMMAND_ALIAS, @@ -154,12 +167,22 @@ public class T8nSubCommand implements Runnable { } } + /** + * Default constructor for the T8nSubCommand class. This constructor is required by PicoCLI and + * assigns parent command to 'null'. + */ @SuppressWarnings("unused") public T8nSubCommand() { // PicoCLI requires this parentCommand = null; } + /** + * Constructor for the T8nSubCommand class with a parent command. This constructor is required by + * PicoCLI. + * + * @param parentCommand The parent command for this sub command. + */ @SuppressWarnings("unused") public T8nSubCommand(final EvmToolCommand parentCommand) { // PicoCLI requires this too diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/VersionProvider.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/VersionProvider.java index d97fded882..6f3ff33071 100644 --- a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/VersionProvider.java +++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/VersionProvider.java @@ -18,8 +18,26 @@ import org.hyperledger.besu.BesuInfo; import picocli.CommandLine; +/** + * The VersionProvider class is responsible for providing the version of the Hyperledger Besu EVM + * tool. It implements the IVersionProvider interface from the picocli library. + * + *

The getVersion method returns a string array containing the version of the Hyperledger Besu + * EVM tool. + */ public class VersionProvider implements CommandLine.IVersionProvider { + /** + * Default constructor for the VersionProvider class. This constructor does not perform any + * operations. + */ + public VersionProvider() {} + + /** + * This method returns the version of the Hyperledger Besu EVM tool. + * + * @return A string array containing the version of the Hyperledger Besu EVM tool. + */ @Override public String[] getVersion() { return new String[] {"Hyperledger Besu evm " + BesuInfo.shortVersion()}; From 20b82a40c9be873cd8ace5f1ae76ae564b00d789 Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Fri, 28 Jun 2024 17:07:26 -0600 Subject: [PATCH 013/259] Rename ValidatorPublicKey to ValidatorPubKey (#7280) Adapt to EIP-7002 name change for validator public key in all places. Signed-off-by: Danno Ferrin --- .../WithdrawalRequestParameter.java | 2 +- .../besu/ethereum/core/WithdrawalRequest.java | 18 ++++---- .../encoding/WithdrawalRequestDecoder.java | 4 +- .../encoding/WithdrawalRequestEncoder.java | 2 +- .../WithdrawalRequestContractHelper.java | 4 +- .../WithdrawalRequestContractHelperTest.java | 22 +++++----- .../hyperledger/besu/evmtool/T8nExecutor.java | 6 ++- .../besu/evmtool/t8n/prague-deposit.json | 8 +--- .../besu/evmtool/t8n/prague-withdrawal.json | 42 +++++++++++-------- plugin-api/build.gradle | 2 +- .../besu/plugin/data/WithdrawalRequest.java | 2 +- 11 files changed, 56 insertions(+), 56 deletions(-) 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 index 67fa13f3f8..3561da37a8 100644 --- 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 @@ -45,7 +45,7 @@ public class WithdrawalRequestParameter { final WithdrawalRequest withdrawalRequest) { return new WithdrawalRequestParameter( withdrawalRequest.getSourceAddress().toHexString(), - withdrawalRequest.getValidatorPublicKey().toHexString(), + withdrawalRequest.getValidatorPubkey().toHexString(), withdrawalRequest.getAmount().toShortHexString()); } 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 index decdf22c73..0e7afc1595 100644 --- 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 @@ -26,13 +26,13 @@ public class WithdrawalRequest extends Request implements org.hyperledger.besu.plugin.data.WithdrawalRequest { private final Address sourceAddress; - private final BLSPublicKey validatorPublicKey; + private final BLSPublicKey validatorPubkey; private final GWei amount; public WithdrawalRequest( - final Address sourceAddress, final BLSPublicKey validatorPublicKey, final GWei amount) { + final Address sourceAddress, final BLSPublicKey validatorPubkey, final GWei amount) { this.sourceAddress = sourceAddress; - this.validatorPublicKey = validatorPublicKey; + this.validatorPubkey = validatorPubkey; this.amount = amount; } @@ -47,8 +47,8 @@ public class WithdrawalRequest extends Request } @Override - public PublicKey getValidatorPublicKey() { - return validatorPublicKey; + public PublicKey getValidatorPubkey() { + return validatorPubkey; } @Override @@ -61,8 +61,8 @@ public class WithdrawalRequest extends Request return "WithdrawalRequest{" + "sourceAddress=" + sourceAddress - + " validatorPublicKey=" - + validatorPublicKey + + " validatorPubkey=" + + validatorPubkey + " amount=" + amount + '}'; @@ -78,12 +78,12 @@ public class WithdrawalRequest extends Request } final WithdrawalRequest that = (WithdrawalRequest) o; return Objects.equals(sourceAddress, that.sourceAddress) - && Objects.equals(validatorPublicKey, that.validatorPublicKey) + && Objects.equals(validatorPubkey, that.validatorPubkey) && Objects.equals(amount, that.amount); } @Override public int hashCode() { - return Objects.hash(sourceAddress, validatorPublicKey, amount); + return Objects.hash(sourceAddress, validatorPubkey, amount); } } 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 index 7ade9947b4..031209284e 100644 --- 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 @@ -28,11 +28,11 @@ public class WithdrawalRequestDecoder { public static WithdrawalRequest decode(final RLPInput rlpInput) { rlpInput.enterList(); final Address sourceAddress = Address.readFrom(rlpInput); - final BLSPublicKey validatorPublicKey = BLSPublicKey.readFrom(rlpInput); + final BLSPublicKey validatorPubkey = BLSPublicKey.readFrom(rlpInput); final GWei amount = GWei.of(rlpInput.readUInt64Scalar()); rlpInput.leaveList(); - return new WithdrawalRequest(sourceAddress, validatorPublicKey, amount); + return new WithdrawalRequest(sourceAddress, validatorPubkey, amount); } public static WithdrawalRequest decodeOpaqueBytes(final Bytes 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 index 26be22d488..c9fdb37fce 100644 --- 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 @@ -48,7 +48,7 @@ public class WithdrawalRequestEncoder { final WithdrawalRequest withdrawalRequest, final RLPOutput rlpOutput) { rlpOutput.startList(); rlpOutput.writeBytes(withdrawalRequest.getSourceAddress()); - rlpOutput.writeBytes(withdrawalRequest.getValidatorPublicKey()); + rlpOutput.writeBytes(withdrawalRequest.getValidatorPubkey()); rlpOutput.writeUInt64Scalar(withdrawalRequest.getAmount()); rlpOutput.endList(); } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/WithdrawalRequestContractHelper.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/WithdrawalRequestContractHelper.java index 6bb0e81a75..c0b7302e86 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/WithdrawalRequestContractHelper.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/WithdrawalRequestContractHelper.java @@ -153,7 +153,7 @@ public class WithdrawalRequestContractHelper { queueHeadIndex.plus(i).multiply(WITHDRAWAL_REQUEST_STORAGE_SLOT_SIZE)); final Address sourceAddress = Address.wrap(account.getStorageValue(queueStorageSlot).toBytes().slice(12, 20)); - final BLSPublicKey validatorPublicKey = + final BLSPublicKey validatorPubkey = BLSPublicKey.wrap( Bytes.concatenate( account @@ -165,7 +165,7 @@ public class WithdrawalRequestContractHelper { UInt64.fromBytes(account.getStorageValue(queueStorageSlot.plus(2)).slice(16, 8)); withdrawalRequests.add( - new WithdrawalRequest(sourceAddress, validatorPublicKey, GWei.of(amount))); + new WithdrawalRequest(sourceAddress, validatorPubkey, GWei.of(amount))); } return withdrawalRequests; diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/WithdrawalRequestContractHelperTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/WithdrawalRequestContractHelperTest.java index 6d21744e7b..7e1e857135 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/WithdrawalRequestContractHelperTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/WithdrawalRequestContractHelperTest.java @@ -31,7 +31,6 @@ import org.hyperledger.besu.evm.account.MutableAccount; import org.hyperledger.besu.evm.worldstate.WorldUpdater; import java.util.List; -import java.util.stream.Collectors; import java.util.stream.IntStream; import org.apache.tuweni.bytes.Bytes; @@ -47,12 +46,12 @@ class WithdrawalRequestContractHelperTest { private MutableAccount contract; @BeforeEach - public void setUp() { + void setUp() { worldState = createInMemoryWorldStateArchive().getMutable(); } @Test - public void popWithdrawalRequestsFromQueue_ReadWithdrawalRequestsCorrectly() { + void popWithdrawalRequestsFromQueue_ReadWithdrawalRequestsCorrectly() { final List validatorWithdrawalRequests = List.of(createExit(), createExit(), createExit()); loadContractStorage(worldState, validatorWithdrawalRequests); @@ -64,7 +63,7 @@ class WithdrawalRequestContractHelperTest { } @Test - public void + void popWithdrawalRequestsFromQueue_whenContractCodeIsEmpty_ReturnsEmptyListOfWithdrawalRequests() { // Create account with empty code final WorldUpdater updater = worldState.updater(); @@ -76,10 +75,10 @@ class WithdrawalRequestContractHelperTest { } @Test - public void popWithdrawalRequestsFromQueue_WhenMoreWithdrawalRequests_UpdatesQueuePointers() { + void popWithdrawalRequestsFromQueue_WhenMoreWithdrawalRequests_UpdatesQueuePointers() { // Loading contract with more than 16 WithdrawalRequests final List validatorWithdrawalRequests = - IntStream.range(0, 30).mapToObj(__ -> createExit()).collect(Collectors.toList()); + IntStream.range(0, 30).mapToObj(__ -> createExit()).toList(); loadContractStorage(worldState, validatorWithdrawalRequests); // After loading the contract, the WithdrawalRequests count since last block should match the // size of the list @@ -102,7 +101,7 @@ class WithdrawalRequestContractHelperTest { } @Test - public void popWithdrawalRequestsFromQueue_WhenNoMoreWithdrawalRequests_ZeroQueuePointers() { + void popWithdrawalRequestsFromQueue_WhenNoMoreWithdrawalRequests_ZeroQueuePointers() { final List withdrawalRequests = List.of(createExit(), createExit(), createExit()); loadContractStorage(worldState, withdrawalRequests); @@ -126,7 +125,7 @@ class WithdrawalRequestContractHelperTest { } @Test - public void popWithdrawalRequestsFromQueue_WhenNoWithdrawalRequests_DoesNothing() { + void popWithdrawalRequestsFromQueue_WhenNoWithdrawalRequests_DoesNothing() { // Loading contract with 0 WithdrawalRequests loadContractStorage(worldState, List.of()); // After loading storage, we have the WithdrawalRequests count as zero because no @@ -135,7 +134,7 @@ class WithdrawalRequestContractHelperTest { final List poppedWithdrawalRequests = WithdrawalRequestContractHelper.popWithdrawalRequestsFromQueue(worldState); - assertThat(poppedWithdrawalRequests).hasSize(0); + assertThat(poppedWithdrawalRequests).isEmpty(); // Check that queue pointers are correct (head and tail are zero) assertContractStorageValue(WITHDRAWAL_REQUEST_QUEUE_HEAD_STORAGE_SLOT, 0); @@ -186,14 +185,13 @@ class WithdrawalRequestContractHelperTest { Bytes.fromHexString("0x000000000000000000000000"), request.getSourceAddress()))); // validator_pubkey contract.setStorageValue( - UInt256.valueOf(offset++), - UInt256.fromBytes(request.getValidatorPublicKey().slice(0, 32))); + UInt256.valueOf(offset++), UInt256.fromBytes(request.getValidatorPubkey().slice(0, 32))); contract.setStorageValue( // set public key to slot, with 16 bytes padding on the right UInt256.valueOf(offset++), UInt256.fromBytes( Bytes.concatenate( - request.getValidatorPublicKey().slice(32, 16), + request.getValidatorPubkey().slice(32, 16), request.getAmount().toBytes(), // 8 bytes for amount Bytes.fromHexString("0x0000000000000000")))); } 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 40c73e383f..d523984882 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 @@ -110,7 +110,9 @@ public class T8nExecutor { * Default constructor for the T8nExecutor class. This constructor does not perform any * operations. */ - public T8nExecutor() {} + public T8nExecutor() { + // Default constructor required for Javadoc linting + } /** * Extracts transactions from a given JSON iterator and adds them to the provided transactions @@ -531,7 +533,7 @@ public class T8nExecutor { wr -> { var obj = withdrawlRequests.addObject(); obj.put("sourceAddress", wr.getSourceAddress().toHexString()); - obj.put("validatorPublicKey", wr.getValidatorPublicKey().toHexString()); + obj.put("validatorPubkey", wr.getValidatorPubkey().toHexString()); obj.put("amount", wr.getAmount().toHexString()); }); } 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 80e415b3fc..034325fbe8 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 @@ -180,12 +180,6 @@ "balance": "0x0", "nonce": "0x1" }, - "0x25a219378dad9b3503c8268c9ca836a52427a4fb": { - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0xe4fb5d47f70d54b4f36777ea4c882cf767f93d8f8170285d97a1b8275dfe4dbb" - }, - "balance": "0x0" - }, "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": { "balance": "0xaa00be18c288efd690", "nonce": "0x2" @@ -193,7 +187,7 @@ }, "body": "0xf90404f901ff8007830f42409400000000219ab540356cbb839cbe05303d7705fa8901bc16d674ec800000b9019422895118000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000d0000000000000000000000000000000000000000000000000000000000000011085acb6376c2707b118225da41825974c12b5924a05c6a53b988c9cbc33c55b05000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000325a0ffeb1d6e7ef8e9ee9b64dcdc3b056f9a1d2b94c1572f1949954e712364604575a03d0f42bad795205de84db8d4ab10b9abd0d081ffe560cbf45f6c281768112a69f901ff0107830f42409400000000219ab540356cbb839cbe05303d7705fa8901bc16d674ec800000b9019422895118000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000d0000000000000000000000000000000000000000000000000000000000000011085acb6376c2707b118225da41825974c12b5924a05c6a53b988c9cbc33c55b05000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000326a05bb08e348c9c4b0a2e15d04f4a89d1a210d013205de8d3d93e38e5c1b0c8d8aba04300c0f575d9908d2cbc3413ab82895678bb8f3ef356224dd1e7cb972f2c4855", "result": { - "stateRoot": "0x0dd3e32e0081ff7ca5a0236b257676f277999ec2b8da5b31e19400715de907f1", + "stateRoot": "0x83bc620ec3d5ff77109b241f561e233a5c4f35bfc3337594c12958f51ff2c1c8", "txRoot": "0x2b790bf82ef7259a0e4513d1b89a77d81e99672ba68758ef2ba3fde32851d023", "receiptsRoot": "0x9c8d7a917ecb3ff2566f264abbf39131e51b08b07eb2b69cb46989d79d985593", "logsHash": "0x43e31613bfefc1f55d8b3ca2b61f933f3838d523dc11cb5d7ffdd2ecf0ab5d49", 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 85ad0d7e9a..cf593cbb76 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 @@ -64,6 +64,12 @@ "code": "0x3373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500", "storage": {} }, + "0x25a219378dad9b3503c8268c9ca836a52427a4fb": { + "nonce": "0x00", + "balance": "0x1", + "code": "0x", + "storage": {} + }, "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": { "nonce": "0x00", "balance": "0xad78ebc5ac62000000", @@ -213,7 +219,7 @@ "storage": { "0x0000000000000000000000000000000000000000000000000000000000000000": "0x10715cfbefdb8a0cb2f7d7ca5ee6d1ea65515ecb41cff0a22d1e11716a9d27fb" }, - "balance": "0x0" + "balance": "0x1" }, "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": { "balance": "0xad78ebc5ac619bbcea", @@ -222,7 +228,7 @@ }, "body": "0xf903e5f903e28007830f424094000000000000000000000000000000000000020080b90380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001fffffffffffffffe0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fffffffffffffffe0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005fffffffffffffffe0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007fffffffffffffffe0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009fffffffffffffffe00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bfffffffffffffffe00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000dfffffffffffffffe00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffe000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000026a0963cb6620fe5828cbc93bb7139d3f4501067d76275dff648bf48c3c100ca8dd4a04ac396104a5be4643406718f59a6e74d62a32777f5f6135e55e805e87612013c", "result": { - "stateRoot": "0xf682e4f8f820f44fb43a20c3db274bc3c9fcb9e52cc1af3c3ea7cb21fdb2250b", + "stateRoot": "0x69dc2041a0a7e71f9e5f916c26cb6b2d7d1e255509af793337d4010d19b4b87c", "txRoot": "0x8521df63211790726b6f1a437bb0fd4b27c00e13e7678d324c4cfddb8d834ad2", "receiptsRoot": "0x4bd8bd5580caf4ed45f873794ad7ff9d6fd2363ae529269b17b891b68d349d75", "logsHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", @@ -252,82 +258,82 @@ "withdrawalRequests": [ { "sourceAddress": "0x0000000000000000000000000000000000000200", - "validatorPublicKey": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", + "validatorPubkey": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", "amount": "0xfffffffffffffffe" }, { "sourceAddress": "0x0000000000000000000000000000000000000200", - "validatorPublicKey": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002", + "validatorPubkey": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002", "amount": "0x0000000000000000" }, { "sourceAddress": "0x0000000000000000000000000000000000000200", - "validatorPublicKey": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003", + "validatorPubkey": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003", "amount": "0xfffffffffffffffe" }, { "sourceAddress": "0x0000000000000000000000000000000000000200", - "validatorPublicKey": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004", + "validatorPubkey": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004", "amount": "0x0000000000000000" }, { "sourceAddress": "0x0000000000000000000000000000000000000200", - "validatorPublicKey": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005", + "validatorPubkey": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005", "amount": "0xfffffffffffffffe" }, { "sourceAddress": "0x0000000000000000000000000000000000000200", - "validatorPublicKey": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006", + "validatorPubkey": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006", "amount": "0x0000000000000000" }, { "sourceAddress": "0x0000000000000000000000000000000000000200", - "validatorPublicKey": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007", + "validatorPubkey": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007", "amount": "0xfffffffffffffffe" }, { "sourceAddress": "0x0000000000000000000000000000000000000200", - "validatorPublicKey": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008", + "validatorPubkey": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008", "amount": "0x0000000000000000" }, { "sourceAddress": "0x0000000000000000000000000000000000000200", - "validatorPublicKey": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009", + "validatorPubkey": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009", "amount": "0xfffffffffffffffe" }, { "sourceAddress": "0x0000000000000000000000000000000000000200", - "validatorPublicKey": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a", + "validatorPubkey": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a", "amount": "0x0000000000000000" }, { "sourceAddress": "0x0000000000000000000000000000000000000200", - "validatorPublicKey": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b", + "validatorPubkey": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b", "amount": "0xfffffffffffffffe" }, { "sourceAddress": "0x0000000000000000000000000000000000000200", - "validatorPublicKey": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c", + "validatorPubkey": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c", "amount": "0x0000000000000000" }, { "sourceAddress": "0x0000000000000000000000000000000000000200", - "validatorPublicKey": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d", + "validatorPubkey": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d", "amount": "0xfffffffffffffffe" }, { "sourceAddress": "0x0000000000000000000000000000000000000200", - "validatorPublicKey": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e", + "validatorPubkey": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e", "amount": "0x0000000000000000" }, { "sourceAddress": "0x0000000000000000000000000000000000000200", - "validatorPublicKey": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f", + "validatorPubkey": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f", "amount": "0xfffffffffffffffe" }, { "sourceAddress": "0x0000000000000000000000000000000000000200", - "validatorPublicKey": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010", + "validatorPubkey": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010", "amount": "0x0000000000000000" } ] diff --git a/plugin-api/build.gradle b/plugin-api/build.gradle index fd7f3291b3..dbbb5e4f2b 100644 --- a/plugin-api/build.gradle +++ b/plugin-api/build.gradle @@ -70,7 +70,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 = 'p8jZoKgvi9o8JpVLXTlwh9HoIot4A62hKFHwSOaTF+k=' + knownHash = 'Q6EK5By3BNKNa/JYqYjFw43VXWL0KVBUV3dGEQBjZ70=' } check.dependsOn('checkAPIChanges') 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 index eeadd80418..f07d0d08d0 100644 --- 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 @@ -38,7 +38,7 @@ public interface WithdrawalRequest { * * @return public key of validator */ - PublicKey getValidatorPublicKey(); + PublicKey getValidatorPubkey(); /** * The amount for withdrawal From 08772b466ef4681bd91503805789b4af311ed9cd Mon Sep 17 00:00:00 2001 From: Matt Whitehead Date: Mon, 1 Jul 2024 08:48:21 +0100 Subject: [PATCH 014/259] Add info-level diagnostic logs to aid with resolving stalled BFT chains (#7271) * Add info-level diagnostic logs to aid with resolving stalled BFT chains Signed-off-by: Matthew Whitehead * Add javadoc Signed-off-by: Matthew Whitehead --------- Signed-off-by: Matthew Whitehead Signed-off-by: Matt Whitehead --- CHANGELOG.md | 1 + .../besu/consensus/common/bft/RoundTimer.java | 16 +++++++++ .../statemachine/QbftBlockHeightManager.java | 13 +++++-- .../QbftBlockHeightManagerFactory.java | 3 +- .../qbft/statemachine/RoundChangeManager.java | 34 ++++++++++++++++++- 5 files changed, 63 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ba6b4dc5d..819bb05a7c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ - Refactored how code, initcode, and max stack size are configured in forks. [#7245](https://github.com/hyperledger/besu/pull/7245) - Nodes in a permissioned chain maintain (and retry) connections to bootnodes [#7257](https://github.com/hyperledger/besu/pull/7257) - Promote experimental `besu storage x-trie-log` subcommand to production-ready [#7278](https://github.com/hyperledger/besu/pull/7278) +- Enhanced BFT round-change diagnostics [#7271](https://github.com/hyperledger/besu/pull/7271) ### Bug fixes - Validation errors ignored in accounts-allowlist and empty list [#7138](https://github.com/hyperledger/besu/issues/7138) diff --git a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/RoundTimer.java b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/RoundTimer.java index a500a1ad7e..6a8b02991d 100644 --- a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/RoundTimer.java +++ b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/RoundTimer.java @@ -20,8 +20,14 @@ import java.util.Optional; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** Class for starting and keeping organised round timers */ public class RoundTimer { + + private static final Logger LOG = LoggerFactory.getLogger(RoundTimer.class); + private final BftExecutors bftExecutors; private Optional> currentTimerTask; private final BftEventQueue queue; @@ -71,6 +77,16 @@ public class RoundTimer { final ScheduledFuture newTimerTask = bftExecutors.scheduleTask(newTimerRunnable, expiryTime, TimeUnit.MILLISECONDS); + + // Once we are up to round 2 start logging round expiries + if (round.getRoundNumber() >= 2) { + LOG.info( + "QBFT round {} expired. Moved to round {} which will expire in {} seconds", + round.getRoundNumber() - 1, + round.getRoundNumber(), + (expiryTime / 1000)); + } + currentTimerTask = Optional.of(newTimerTask); } } diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftBlockHeightManager.java b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftBlockHeightManager.java index 0940d35df6..f79537cc0f 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftBlockHeightManager.java +++ b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftBlockHeightManager.java @@ -274,17 +274,26 @@ public class QbftBlockHeightManager implements BaseQbftBlockHeightManager { @Override public void handleRoundChangePayload(final RoundChange message) { final ConsensusRoundIdentifier targetRound = message.getRoundIdentifier(); - LOG.trace("Received a RoundChange Payload for {}", targetRound); + + LOG.debug( + "Round change from {}: block {}, round {}", + message.getAuthor(), + message.getRoundIdentifier().getSequenceNumber(), + message.getRoundIdentifier().getRoundNumber()); + + // Diagnostic logging (only logs anything if the chain has stalled) + roundChangeManager.storeAndLogRoundChangeSummary(message); final MessageAge messageAge = determineAgeOfPayload(message.getRoundIdentifier().getRoundNumber()); if (messageAge == MessageAge.PRIOR_ROUND) { - LOG.trace("Received RoundChange Payload for a prior round. targetRound={}", targetRound); + LOG.debug("Received RoundChange Payload for a prior round. targetRound={}", targetRound); return; } final Optional> result = roundChangeManager.appendRoundChangeMessage(message); + if (result.isPresent()) { LOG.debug( "Received sufficient RoundChange messages to change round to targetRound={}", diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftBlockHeightManagerFactory.java b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftBlockHeightManagerFactory.java index 0d306b1fc9..889f83f98a 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftBlockHeightManagerFactory.java +++ b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftBlockHeightManagerFactory.java @@ -86,7 +86,8 @@ public class QbftBlockHeightManagerFactory { new RoundChangeManager( BftHelpers.calculateRequiredValidatorQuorum(finalState.getValidators().size()), messageValidatorFactory.createRoundChangeMessageValidator( - parentHeader.getNumber() + 1L, parentHeader)), + parentHeader.getNumber() + 1L, parentHeader), + finalState.getLocalAddress()), roundFactory, finalState.getClock(), messageValidatorFactory, diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/RoundChangeManager.java b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/RoundChangeManager.java index ca671a6f52..89e2888395 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/RoundChangeManager.java +++ b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/RoundChangeManager.java @@ -100,19 +100,51 @@ public class RoundChangeManager { @VisibleForTesting final Map roundChangeCache = Maps.newHashMap(); + /** A summary of the latest round each validator is on, for diagnostic purposes only */ + private final Map roundSummary = Maps.newHashMap(); + private final long quorum; private final RoundChangeMessageValidator roundChangeMessageValidator; + private final Address localAddress; /** * Instantiates a new Round change manager. * * @param quorum the quorum * @param roundChangeMessageValidator the round change message validator + * @param localAddress this node's address */ public RoundChangeManager( - final long quorum, final RoundChangeMessageValidator roundChangeMessageValidator) { + final long quorum, + final RoundChangeMessageValidator roundChangeMessageValidator, + final Address localAddress) { this.quorum = quorum; this.roundChangeMessageValidator = roundChangeMessageValidator; + this.localAddress = localAddress; + } + + /** + * Store the latest round for a node, and if chain is stalled log a summary of which round each + * address is on + * + * @param message the round-change message that has just been received + */ + public void storeAndLogRoundChangeSummary(final RoundChange message) { + roundSummary.put(message.getAuthor(), message.getRoundIdentifier()); + if (roundChangeCache.keySet().stream() + .findFirst() + .orElse(new ConsensusRoundIdentifier(0, 0)) + .getRoundNumber() + >= 2) { + LOG.info("BFT round summary (quorum = {})", quorum); + for (Map.Entry nextEntry : roundSummary.entrySet()) { + LOG.info( + "Address: {} Round: {} {}", + nextEntry.getKey(), + nextEntry.getValue().getRoundNumber(), + nextEntry.getKey().equals(localAddress) ? "(Local node)" : ""); + } + } } /** From c0efeef89a1befb23d53323f38f9c3f8b62ea785 Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Mon, 1 Jul 2024 09:58:40 -0600 Subject: [PATCH 015/259] Update EIP-2935 contract (#7281) Use the updated contract and address for EIP-2539. Signed-off-by: Danno Ferrin --- .../blockhash/PragueBlockHashProcessor.java | 2 +- .../besu/ethereum/chain/genesis_prague2.json | 4 ++-- .../besu/evmtool/t8n/prague-deposit.json | 15 ++++++++++++++- .../besu/evmtool/t8n/prague-withdrawal.json | 17 +++++++++-------- 4 files changed, 26 insertions(+), 12 deletions(-) diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/blockhash/PragueBlockHashProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/blockhash/PragueBlockHashProcessor.java index 634a744159..b6b38b37d5 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/blockhash/PragueBlockHashProcessor.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/blockhash/PragueBlockHashProcessor.java @@ -36,7 +36,7 @@ public class PragueBlockHashProcessor extends CancunBlockHashProcessor { private static final Logger LOG = LoggerFactory.getLogger(PragueBlockHashProcessor.class); public static final Address HISTORY_STORAGE_ADDRESS = - Address.fromHexString("0x25a219378dad9b3503c8268c9ca836a52427a4fb"); + Address.fromHexString("0x0aae40965e6800cd9b1f4b05ff21581047e3f91e"); /** The HISTORY_SERVE_WINDOW */ public static final long HISTORY_SERVE_WINDOW = 8192; diff --git a/ethereum/core/src/test/resources/org/hyperledger/besu/ethereum/chain/genesis_prague2.json b/ethereum/core/src/test/resources/org/hyperledger/besu/ethereum/chain/genesis_prague2.json index e7bccadac0..cdb755ace1 100644 --- a/ethereum/core/src/test/resources/org/hyperledger/besu/ethereum/chain/genesis_prague2.json +++ b/ethereum/core/src/test/resources/org/hyperledger/besu/ethereum/chain/genesis_prague2.json @@ -73,8 +73,8 @@ "balance": "0x0", "nonce": "0x1" }, - "25a219378dad9b3503c8268c9ca836a52427a4fb": { - "code": "0x60203611603157600143035f35116029575f356120000143116029576120005f3506545f5260205ff35b5f5f5260205ff35b5f5ffd00", + "0x0aae40965e6800cd9b1f4b05ff21581047e3f91e": { + "code": "0x3373fffffffffffffffffffffffffffffffffffffffe1460575767ffffffffffffffff5f3511605357600143035f3511604b575f35612000014311604b57611fff5f3516545f5260205ff35b5f5f5260205ff35b5f5ffd5b5f35611fff60014303165500", "balance": "0x0", "nonce": "0x1" }, 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 034325fbe8..d48fc66c70 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 @@ -63,6 +63,11 @@ "code": "0x3373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500", "storage": {} }, + "0x0aae40965e6800cd9b1f4b05ff21581047e3f91e": { + "code": "0x3373fffffffffffffffffffffffffffffffffffffffe1460575767ffffffffffffffff5f3511605357600143035f3511604b575f35612000014311604b57611fff5f3516545f5260205ff35b5f5f5260205ff35b5f5ffd5b5f35611fff60014303165500", + "balance": "0x0", + "nonce": "0x1" + }, "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": { "nonce": "0x00", "balance": "0xad78ebc5ac62000000", @@ -180,6 +185,14 @@ "balance": "0x0", "nonce": "0x1" }, + "0x0aae40965e6800cd9b1f4b05ff21581047e3f91e": { + "code": "0x3373fffffffffffffffffffffffffffffffffffffffe1460575767ffffffffffffffff5f3511605357600143035f3511604b575f35612000014311604b57611fff5f3516545f5260205ff35b5f5f5260205ff35b5f5ffd5b5f35611fff60014303165500", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000000": "0xe4fb5d47f70d54b4f36777ea4c882cf767f93d8f8170285d97a1b8275dfe4dbb" + }, + "balance": "0x0", + "nonce": "0x1" + }, "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": { "balance": "0xaa00be18c288efd690", "nonce": "0x2" @@ -187,7 +200,7 @@ }, "body": "0xf90404f901ff8007830f42409400000000219ab540356cbb839cbe05303d7705fa8901bc16d674ec800000b9019422895118000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000d0000000000000000000000000000000000000000000000000000000000000011085acb6376c2707b118225da41825974c12b5924a05c6a53b988c9cbc33c55b05000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000325a0ffeb1d6e7ef8e9ee9b64dcdc3b056f9a1d2b94c1572f1949954e712364604575a03d0f42bad795205de84db8d4ab10b9abd0d081ffe560cbf45f6c281768112a69f901ff0107830f42409400000000219ab540356cbb839cbe05303d7705fa8901bc16d674ec800000b9019422895118000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000d0000000000000000000000000000000000000000000000000000000000000011085acb6376c2707b118225da41825974c12b5924a05c6a53b988c9cbc33c55b05000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000326a05bb08e348c9c4b0a2e15d04f4a89d1a210d013205de8d3d93e38e5c1b0c8d8aba04300c0f575d9908d2cbc3413ab82895678bb8f3ef356224dd1e7cb972f2c4855", "result": { - "stateRoot": "0x83bc620ec3d5ff77109b241f561e233a5c4f35bfc3337594c12958f51ff2c1c8", + "stateRoot": "0x3aa7839837ee1564276a0a05554e35215353a97c4e255c3aacbcd7c7819daefa", "txRoot": "0x2b790bf82ef7259a0e4513d1b89a77d81e99672ba68758ef2ba3fde32851d023", "receiptsRoot": "0x9c8d7a917ecb3ff2566f264abbf39131e51b08b07eb2b69cb46989d79d985593", "logsHash": "0x43e31613bfefc1f55d8b3ca2b61f933f3838d523dc11cb5d7ffdd2ecf0ab5d49", 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 cf593cbb76..66dcf3e85e 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 @@ -64,11 +64,10 @@ "code": "0x3373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500", "storage": {} }, - "0x25a219378dad9b3503c8268c9ca836a52427a4fb": { - "nonce": "0x00", - "balance": "0x1", - "code": "0x", - "storage": {} + "0x0aae40965e6800cd9b1f4b05ff21581047e3f91e": { + "code": "0x3373fffffffffffffffffffffffffffffffffffffffe1460575767ffffffffffffffff5f3511605357600143035f3511604b575f35612000014311604b57611fff5f3516545f5260205ff35b5f5f5260205ff35b5f5ffd5b5f35611fff60014303165500", + "balance": "0x0", + "nonce": "0x1" }, "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": { "nonce": "0x00", @@ -215,11 +214,13 @@ "balance": "0x10", "nonce": "0x1" }, - "0x25a219378dad9b3503c8268c9ca836a52427a4fb": { + "0x0aae40965e6800cd9b1f4b05ff21581047e3f91e": { + "code": "0x3373fffffffffffffffffffffffffffffffffffffffe1460575767ffffffffffffffff5f3511605357600143035f3511604b575f35612000014311604b57611fff5f3516545f5260205ff35b5f5f5260205ff35b5f5ffd5b5f35611fff60014303165500", "storage": { "0x0000000000000000000000000000000000000000000000000000000000000000": "0x10715cfbefdb8a0cb2f7d7ca5ee6d1ea65515ecb41cff0a22d1e11716a9d27fb" }, - "balance": "0x1" + "balance": "0x0", + "nonce": "0x1" }, "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": { "balance": "0xad78ebc5ac619bbcea", @@ -228,7 +229,7 @@ }, "body": "0xf903e5f903e28007830f424094000000000000000000000000000000000000020080b90380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001fffffffffffffffe0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fffffffffffffffe0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005fffffffffffffffe0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007fffffffffffffffe0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009fffffffffffffffe00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bfffffffffffffffe00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000dfffffffffffffffe00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffe000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000026a0963cb6620fe5828cbc93bb7139d3f4501067d76275dff648bf48c3c100ca8dd4a04ac396104a5be4643406718f59a6e74d62a32777f5f6135e55e805e87612013c", "result": { - "stateRoot": "0x69dc2041a0a7e71f9e5f916c26cb6b2d7d1e255509af793337d4010d19b4b87c", + "stateRoot": "0xdba3aee0733886dac565d2a654d8fac1953fd913261f44b3aa31f153e159e98a", "txRoot": "0x8521df63211790726b6f1a437bb0fd4b27c00e13e7678d324c4cfddb8d834ad2", "receiptsRoot": "0x4bd8bd5580caf4ed45f873794ad7ff9d6fd2363ae529269b17b891b68d349d75", "logsHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", From 264e7d9facffe1c881d6de090ad99e807f4d836b Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Mon, 1 Jul 2024 16:32:12 -0600 Subject: [PATCH 016/259] Deeper tracing of self-destructed accounts (#7284) Consider previously self-destructed accounts when creating accounts. Signed-off-by: Danno Ferrin --- .../evm/worldstate/UpdateTrackingAccount.java | 1 - .../besu/evm/worldstate/WorldUpdater.java | 27 +++++++++++++++++-- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/evm/src/main/java/org/hyperledger/besu/evm/worldstate/UpdateTrackingAccount.java b/evm/src/main/java/org/hyperledger/besu/evm/worldstate/UpdateTrackingAccount.java index f571ff2ff0..9f065aee98 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/worldstate/UpdateTrackingAccount.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/worldstate/UpdateTrackingAccount.java @@ -128,7 +128,6 @@ public class UpdateTrackingAccount implements MutableAccount public void setWrappedAccount(final A account) { if (this.account == null) { this.account = account; - storageWasCleared = false; } else { throw new IllegalStateException("Already tracking a wrapped account"); } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/worldstate/WorldUpdater.java b/evm/src/main/java/org/hyperledger/besu/evm/worldstate/WorldUpdater.java index 9b57b6ab9e..4cbda73279 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/worldstate/WorldUpdater.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/worldstate/WorldUpdater.java @@ -24,6 +24,8 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Optional; +import org.apache.tuweni.bytes.Bytes; + /** * An object that buffers updates made over a particular {@link WorldView}. * @@ -73,8 +75,29 @@ public interface WorldUpdater extends MutableWorldView { * #createAccount(Address)} (and thus all his fields will be zero/empty). */ default MutableAccount getOrCreate(final Address address) { - final MutableAccount account = getAccount(address); - return account == null ? createAccount(address) : account; + MutableAccount account = getAccount(address); + if (account == null) { + account = createAccount(address); + if (parentUpdater().isPresent() && parentUpdater().get().isDeleted(address)) { + account.clearStorage(); + account.setCode(Bytes.EMPTY); + } + } + return account; + } + + /** + * Check this and parent updaters to see if an address has been deleted since the last persist + * + * @param address address to check + * @return true if any updaters have marked the address as deleted. + */ + default boolean isDeleted(final Address address) { + if (getDeletedAccountAddresses().contains(address)) { + return true; + } else { + return parentUpdater().map(wu -> wu.isDeleted(address)).orElse(false); + } } /** From 3a73dccd619ed5ab1caf1548ec3a84aeb30a2d58 Mon Sep 17 00:00:00 2001 From: garyschulte Date: Mon, 1 Jul 2024 16:06:55 -0700 Subject: [PATCH 017/259] next release version after 24.7.0 (#7285) Signed-off-by: garyschulte --- CHANGELOG.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 819bb05a7c..d14b3e0fc8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,14 @@ # Changelog -## Next Release +## Next release + +### Breaking Changes + +### Additions and Improvements + +### Bug fixes + +## 24.7.0 ### Upcoming Breaking Changes - Receipt compaction will be enabled by default in a future version of Besu. After this change it will not be possible to downgrade to the previous Besu version. @@ -32,6 +40,8 @@ - Fix "Could not confirm best peer had pivot block" [#7109](https://github.com/hyperledger/besu/issues/7109) - Fix "Chain Download Halt" [#6884](https://github.com/hyperledger/besu/issues/6884) + + ## 24.6.0 ### Breaking Changes From 8ca7129b0be3ba26b60ceb8920c01f717d5f5aca Mon Sep 17 00:00:00 2001 From: Matt Whitehead Date: Tue, 2 Jul 2024 09:39:59 +0100 Subject: [PATCH 018/259] Add experimental `--Xsnapsync-bft-enabled` which enables snap sync for BFT chains (#7140) * Create a BFT-specific pivot block handler Signed-off-by: Matthew Whitehead * Change visibility Signed-off-by: Matthew Whitehead * Refactor sync-peer-count internal variable to match name, add experimental flag to enabled snap + BFT Signed-off-by: Matthew Whitehead * Merge with main Signed-off-by: Matthew Whitehead * Fix uppercase Signed-off-by: Matthew Whitehead * Address synchronization issue with trie pruning. Create BFT-specific account range handler. Add pipeline name and logs Signed-off-by: Matthew Whitehead * Remove debug log Signed-off-by: Matthew Whitehead * fixing snapsync for empty state Signed-off-by: Karim Taam * Don't queue up events we can't handle Signed-off-by: Matthew Whitehead * Fix timing window where a validator with an empty data dir sometimes falls back to full sync if peer status isn't received quickly enough Signed-off-by: Matthew Whitehead * Remove BFT-specific account request class. Not needed Signed-off-by: Matthew Whitehead * Refactor some more 'fast' sync variables that are common to all pivot-based sync types Signed-off-by: Matthew Whitehead * In FULL sync mode, disable bonsai-limit-trie-logs-enabled instead of failing to start Signed-off-by: Matthew Whitehead * Add javadoc comments, clarify overriding bonsai-limit-trie-logs-enabled Signed-off-by: Matthew Whitehead * Add BFT pivot block selector tests Signed-off-by: Matthew Whitehead * Fix failure error message Signed-off-by: Matthew Whitehead * Remove the unnamed Pipe constructor and update tests to set a pipe name Signed-off-by: Matthew Whitehead * Revert some info logs back to debug given the feedback on noise in the logs syncing with holesky Signed-off-by: Matthew Whitehead * Refactor fastSyncPivotDistance to syncPivotDistance Signed-off-by: Matthew Whitehead * Incomplete refactoring Signed-off-by: Matthew Whitehead * Update BFT event queueing tests Signed-off-by: Matthew Whitehead * Event queue test fixes Signed-off-by: Matthew Whitehead * Remove automatic setting of bonsai-limit-trie-logs-enabled to false if sync-mode = FULL (moving to another PR) Signed-off-by: Matthew Whitehead --------- Signed-off-by: Matthew Whitehead Signed-off-by: Karim Taam Signed-off-by: Matt Whitehead Co-authored-by: Karim Taam --- CHANGELOG.md | 1 + .../org/hyperledger/besu/cli/BesuCommand.java | 16 +- .../cli/ConfigurationOverviewBuilder.java | 16 ++ .../options/unstable/SynchronizerOptions.java | 29 +++- .../controller/BesuControllerBuilder.java | 21 ++- .../java/org/hyperledger/besu/RunnerTest.java | 4 +- .../hyperledger/besu/cli/BesuCommandTest.java | 8 +- .../cli/CascadingDefaultProviderTest.java | 4 +- .../cli/options/SynchronizerOptionsTest.java | 6 +- .../consensus/common/bft/BftEventQueue.java | 27 ++- .../consensus/common/bft/BftProcessor.java | 3 + .../common/validator/ValidatorProvider.java | 12 ++ .../common/bft/BftEventQueueTest.java | 69 +++++++- .../common/bft/BftProcessorTest.java | 1 + .../consensus/common/bft/RoundTimerTest.java | 1 + .../BftMiningCoordinatorTest.java | 1 + .../qbft/BFTPivotSelectorFromPeers.java | 160 ++++++++++++++++++ .../qbft/sync/QbftPivotSelectorTest.java | 159 +++++++++++++++++ .../common/trielog/TrieLogPruner.java | 4 +- .../ethereum/eth/manager/snap/SnapServer.java | 18 +- .../eth/sync/DefaultSynchronizer.java | 29 ++-- .../eth/sync/SynchronizerConfiguration.java | 44 ++--- .../eth/sync/fastsync/FastSyncActions.java | 4 +- .../eth/sync/fastsync/FastSyncDownloader.java | 10 +- .../fastsync/NoSyncRequiredException.java | 17 ++ .../sync/fastsync/NoSyncRequiredState.java | 17 ++ .../sync/fastsync/PivotSelectorFromPeers.java | 16 +- .../sync/snapsync/SnapSyncConfiguration.java | 7 + .../request/AccountRangeDataRequest.java | 16 +- .../sync/fastsync/FastSyncActionsTest.java | 42 ++--- .../worldstate/LoadLocalDataStepTest.java | 2 +- .../sync/snapsync/LoadLocalDataStepTest.java | 2 +- .../trie/patricia/TrieNodeDecoder.java | 4 + .../pipeline/AsyncOperationProcessor.java | 2 +- .../besu/services/pipeline/Pipe.java | 19 ++- .../besu/services/pipeline/Pipeline.java | 13 ++ .../services/pipeline/PipelineBuilder.java | 3 +- .../pipeline/BatchingReadPipeTest.java | 3 +- .../services/pipeline/CompleterStageTest.java | 3 +- .../pipeline/FlatMapProcessorTest.java | 6 +- .../pipeline/IteratorSourceStageTest.java | 3 +- .../services/pipeline/MapProcessorTest.java | 6 +- .../besu/services/pipeline/PipeTest.java | 3 +- .../pipeline/ProcessingStageTest.java | 4 +- 44 files changed, 708 insertions(+), 127 deletions(-) create mode 100644 consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/BFTPivotSelectorFromPeers.java create mode 100644 consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/sync/QbftPivotSelectorTest.java create mode 100644 ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/NoSyncRequiredException.java create mode 100644 ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/NoSyncRequiredState.java diff --git a/CHANGELOG.md b/CHANGELOG.md index d14b3e0fc8..4d29b8f8af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,7 @@ - Nodes in a permissioned chain maintain (and retry) connections to bootnodes [#7257](https://github.com/hyperledger/besu/pull/7257) - Promote experimental `besu storage x-trie-log` subcommand to production-ready [#7278](https://github.com/hyperledger/besu/pull/7278) - Enhanced BFT round-change diagnostics [#7271](https://github.com/hyperledger/besu/pull/7271) +- `--Xsnapsync-bft-enabled` option enables experimental support for snap sync with IBFT/QBFT permissioned Bonsai-DB chains [#7140](https://github.com/hyperledger/besu/pull/7140) ### Bug fixes - Validation errors ignored in accounts-allowlist and empty list [#7138](https://github.com/hyperledger/besu/issues/7138) 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 7e1be15fb6..12752f2e9a 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java @@ -1552,10 +1552,11 @@ public class BesuCommand implements DefaultCommandValues, Runnable { } private void validateConsensusSyncCompatibilityOptions() { - // snap and checkpoint can't be used with BFT but can for clique - if (genesisConfigOptionsSupplier.get().isIbftLegacy() - || genesisConfigOptionsSupplier.get().isIbft2() - || genesisConfigOptionsSupplier.get().isQbft()) { + // snap and checkpoint are experimental for BFT + if ((genesisConfigOptionsSupplier.get().isIbftLegacy() + || genesisConfigOptionsSupplier.get().isIbft2() + || genesisConfigOptionsSupplier.get().isQbft()) + && !unstableSynchronizerOptions.isSnapSyncBftEnabled()) { final String errorSuffix = "can't be used with BFT networks"; if (SyncMode.CHECKPOINT.equals(syncMode) || SyncMode.X_CHECKPOINT.equals(syncMode)) { throw new ParameterException( @@ -2181,7 +2182,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { return unstableSynchronizerOptions .toDomainObject() .syncMode(syncMode) - .fastSyncMinimumPeerCount(syncMinPeerCount) + .syncMinimumPeerCount(syncMinPeerCount) .build(); } @@ -2194,14 +2195,14 @@ public class BesuCommand implements DefaultCommandValues, Runnable { .saveFile((dataPath.resolve(txPoolConf.getSaveFile().getPath()).toFile())); if (genesisConfigOptionsSupplier.get().isZeroBaseFee()) { - logger.info( + logger.warn( "Forcing price bump for transaction replacement to 0, since we are on a zero basefee network"); txPoolConfBuilder.priceBump(Percentage.ZERO); } if (miningParametersSupplier.get().getMinTransactionGasPrice().equals(Wei.ZERO) && !transactionPoolOptions.isPriceBumpSet(commandLine)) { - logger.info( + logger.warn( "Forcing price bump for transaction replacement to 0, since min-gas-price is set to 0"); txPoolConfBuilder.priceBump(Percentage.ZERO); } @@ -2810,6 +2811,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { } builder.setSnapServerEnabled(this.unstableSynchronizerOptions.isSnapsyncServerEnabled()); + builder.setSnapSyncBftEnabled(this.unstableSynchronizerOptions.isSnapSyncBftEnabled()); builder.setTxPoolImplementation(buildTransactionPoolConfiguration().getTxPoolImplementation()); builder.setWorldStateUpdateMode(unstableEvmOptions.toDomainObject().worldUpdaterMode()); 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 2d74ae8d26..b2f89a349e 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/ConfigurationOverviewBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/ConfigurationOverviewBuilder.java @@ -56,6 +56,7 @@ public class ConfigurationOverviewBuilder { private long trieLogRetentionLimit = 0; private Integer trieLogsPruningWindowSize = null; private boolean isSnapServerEnabled = false; + private boolean isSnapSyncBftEnabled = false; private TransactionPoolConfiguration.Implementation txPoolImplementation; private EvmConfiguration.WorldUpdaterMode worldStateUpdateMode; private Map environment; @@ -233,6 +234,17 @@ public class ConfigurationOverviewBuilder { return this; } + /** + * Sets snap sync BFT enabled/disabled + * + * @param snapSyncBftEnabled bool to indicate if snap sync for BFT is enabled + * @return the builder + */ + public ConfigurationOverviewBuilder setSnapSyncBftEnabled(final boolean snapSyncBftEnabled) { + isSnapSyncBftEnabled = snapSyncBftEnabled; + return this; + } + /** * Sets trie logs pruning window size * @@ -357,6 +369,10 @@ public class ConfigurationOverviewBuilder { lines.add("Experimental Snap Sync server enabled"); } + if (isSnapSyncBftEnabled) { + lines.add("Experimental Snap Sync for BFT enabled"); + } + if (isBonsaiLimitTrieLogsEnabled) { final StringBuilder trieLogPruningString = new StringBuilder(); trieLogPruningString diff --git a/besu/src/main/java/org/hyperledger/besu/cli/options/unstable/SynchronizerOptions.java b/besu/src/main/java/org/hyperledger/besu/cli/options/unstable/SynchronizerOptions.java index e52839cceb..95bbe0a2b1 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/options/unstable/SynchronizerOptions.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/options/unstable/SynchronizerOptions.java @@ -85,6 +85,8 @@ public class SynchronizerOptions implements CLIOptions

validatorList = new ArrayList<>(); + validatorList.add(Address.ZERO); + validatorList.add(Address.ZERO); + validatorList.add(Address.ZERO); + + when(ethContext.getEthPeers()).thenReturn(ethPeers); + when(validatorProvider.nodeIsValidator(any())).thenReturn(true); + when(validatorProvider.getValidatorsAtHead()).thenReturn(validatorList); + BFTPivotSelectorFromPeers pivotSelector = + new BFTPivotSelectorFromPeers( + ethContext, + syncConfig, + syncState, + metricsSystem, + protocolContext, + nodeKey, + blockHeader); + Optional pivotState = pivotSelector.selectNewPivotBlock(); + assertThat(pivotState.isEmpty()).isTrue(); + } + + @Test + @SuppressWarnings("unused") + public void returnNoSyncRequiredIfOnlyValidatorAndNoPeers() { + + // We're the only validator so just put us in the list + List
validatorList = new ArrayList<>(); + validatorList.add(Address.ZERO); + + when(ethContext.getEthPeers()).thenReturn(ethPeers); + when(validatorProvider.nodeIsValidator(any())).thenReturn(true); + when(validatorProvider.getValidatorsAtHead()).thenReturn(validatorList); + BFTPivotSelectorFromPeers pivotSelector = + new BFTPivotSelectorFromPeers( + ethContext, + syncConfig, + syncState, + metricsSystem, + protocolContext, + nodeKey, + blockHeader); + + try { + Optional pivotState = pivotSelector.selectNewPivotBlock(); + fail("Expected NoSyncRequiredException but none thrown"); + } catch (NoSyncRequiredException e) { + // Ignore - just make sure we get here + } + } + + @Test + public void returnEmptySyncStateIfNonValidatorWithNoBestPeer() { + when(ethContext.getEthPeers()).thenReturn(ethPeers); + when(validatorProvider.nodeIsValidator(any())).thenReturn(false); + BFTPivotSelectorFromPeers pivotSelector = + new BFTPivotSelectorFromPeers( + ethContext, + syncConfig, + syncState, + metricsSystem, + protocolContext, + nodeKey, + blockHeader); + + Optional pivotState = pivotSelector.selectNewPivotBlock(); + assertThat(pivotState.isEmpty()).isTrue(); + } + + @Test + public void returnEmptySyncStateIfValidatorAndNotAtGenesisAndOtherValidators() { + when(ethContext.getEthPeers()).thenReturn(ethPeers); + when(validatorProvider.nodeIsValidator(any())).thenReturn(false); + when(blockHeader.getNumber()).thenReturn(10L); + BFTPivotSelectorFromPeers pivotSelector = + new BFTPivotSelectorFromPeers( + ethContext, + syncConfig, + syncState, + metricsSystem, + protocolContext, + nodeKey, + blockHeader); + + Optional pivotState = pivotSelector.selectNewPivotBlock(); + assertThat(pivotState.isEmpty()).isTrue(); + } +} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/trielog/TrieLogPruner.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/trielog/TrieLogPruner.java index 4a5cc87511..6f347be033 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/trielog/TrieLogPruner.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/trielog/TrieLogPruner.java @@ -99,7 +99,7 @@ public class TrieLogPruner implements TrieLogEvent.TrieLogObserver { } } - public void addToPruneQueue(final long blockNumber, final Hash blockHash) { + public synchronized void addToPruneQueue(final long blockNumber, final Hash blockHash) { LOG.atTrace() .setMessage("adding trie log to queue for later pruning blockNumber {}; blockHash {}") .addArgument(blockNumber) @@ -108,7 +108,7 @@ public class TrieLogPruner implements TrieLogEvent.TrieLogObserver { trieLogBlocksAndForksByDescendingBlockNumber.put(blockNumber, blockHash); } - public int pruneFromQueue() { + public synchronized int pruneFromQueue() { final long retainAboveThisBlock = blockchain.getChainHeadBlockNumber() - numBlocksToRetain; final Optional finalized = blockchain.getFinalized(); if (requireFinalizedBlock && finalized.isEmpty()) { 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 49f725d825..d6bfe900d9 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 @@ -32,6 +32,7 @@ import org.hyperledger.besu.ethereum.p2p.rlpx.wire.MessageData; import org.hyperledger.besu.ethereum.proof.WorldStateProofProvider; import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; import org.hyperledger.besu.ethereum.trie.CompactEncoding; +import org.hyperledger.besu.ethereum.trie.MerkleTrie; import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.BonsaiWorldStateProvider; import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.BonsaiWorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.worldstate.FlatDbMode; @@ -225,6 +226,9 @@ class SnapServer implements BesuEvents.InitialSyncCompletionListener { .addArgument(() -> asLogHash(range.endKeyHash())) .log(); try { + if (range.worldStateRootHash().equals(Hash.EMPTY_TRIE_HASH)) { + return AccountRangeMessage.create(new HashMap<>(), List.of(MerkleTrie.EMPTY_TRIE_NODE)); + } return worldStateStorageProvider .apply(range.worldStateRootHash()) .map( @@ -509,8 +513,11 @@ class SnapServer implements BesuEvents.InitialSyncCompletionListener { // first element in paths is account if (triePath.size() == 1) { // if there is only one path, presume it should be compact encoded account path - var optStorage = - storage.getTrieNodeUnsafe(CompactEncoding.decode(triePath.get(0))); + final Bytes location = CompactEncoding.decode(triePath.get(0)); + var optStorage = storage.getTrieNodeUnsafe(location); + if (optStorage.isEmpty() && location.isEmpty()) { + optStorage = Optional.of(MerkleTrie.EMPTY_TRIE_NODE); + } if (optStorage.isPresent()) { if (!trieNodes.isEmpty() && (sumListBytes(trieNodes) + optStorage.get().size() > maxResponseBytes @@ -534,9 +541,12 @@ class SnapServer implements BesuEvents.InitialSyncCompletionListener { List storagePaths = triePath.subList(1, triePath.size()); for (var path : storagePaths) { + final Bytes location = CompactEncoding.decode(path); var optStorage = - storage.getTrieNodeUnsafe( - Bytes.concatenate(accountPrefix, CompactEncoding.decode(path))); + storage.getTrieNodeUnsafe(Bytes.concatenate(accountPrefix, location)); + if (optStorage.isEmpty() && location.isEmpty()) { + optStorage = Optional.of(MerkleTrie.EMPTY_TRIE_NODE); + } if (optStorage.isPresent()) { if (!trieNodes.isEmpty() && sumListBytes(trieNodes) + optStorage.get().size() 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 af35898ac2..5e596576aa 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 @@ -25,6 +25,7 @@ import org.hyperledger.besu.ethereum.eth.manager.EthContext; import org.hyperledger.besu.ethereum.eth.sync.checkpointsync.CheckpointDownloaderFactory; import org.hyperledger.besu.ethereum.eth.sync.fastsync.FastSyncDownloader; import org.hyperledger.besu.ethereum.eth.sync.fastsync.FastSyncState; +import org.hyperledger.besu.ethereum.eth.sync.fastsync.NoSyncRequiredState; import org.hyperledger.besu.ethereum.eth.sync.fastsync.worldstate.FastDownloaderFactory; import org.hyperledger.besu.ethereum.eth.sync.fullsync.FullSyncDownloader; import org.hyperledger.besu.ethereum.eth.sync.fullsync.SyncTerminationCondition; @@ -242,16 +243,24 @@ public class DefaultSynchronizer implements Synchronizer, UnverifiedForkchoiceLi // We've been shutdown which will have triggered the fast sync future to complete return CompletableFuture.completedFuture(null); } - fastSyncDownloader.ifPresent(FastSyncDownloader::deleteFastSyncState); - result - .getPivotBlockHeader() - .ifPresent( - blockHeader -> protocolContext.getWorldStateArchive().resetArchiveStateTo(blockHeader)); - LOG.info( - "Sync completed successfully with pivot block {}", - result.getPivotBlockNumber().getAsLong()); - pivotBlockSelector.close(); - syncState.markInitialSyncPhaseAsDone(); + + if (result instanceof NoSyncRequiredState) { + LOG.info("Sync ended (no sync required)"); + syncState.markInitialSyncPhaseAsDone(); + } else { + fastSyncDownloader.ifPresent(FastSyncDownloader::deleteFastSyncState); + result + .getPivotBlockHeader() + .ifPresent( + blockHeader -> + protocolContext.getWorldStateArchive().resetArchiveStateTo(blockHeader)); + if (result.hasPivotBlockHash()) + LOG.info( + "Sync completed successfully with pivot block {}", + result.getPivotBlockNumber().getAsLong()); + pivotBlockSelector.close(); + syncState.markInitialSyncPhaseAsDone(); + } if (terminationCondition.shouldContinueDownload()) { return startFullSync(); diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/SynchronizerConfiguration.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/SynchronizerConfiguration.java index 28f8bee6db..d46da85dc4 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/SynchronizerConfiguration.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/SynchronizerConfiguration.java @@ -29,7 +29,7 @@ public class SynchronizerConfiguration { public static final int DEFAULT_PIVOT_DISTANCE_FROM_HEAD = 50; public static final float DEFAULT_FULL_VALIDATION_RATE = .1f; - public static final int DEFAULT_FAST_SYNC_MINIMUM_PEERS = 5; + public static final int DEFAULT_SYNC_MINIMUM_PEERS = 5; public static final int DEFAULT_WORLD_STATE_HASH_COUNT_PER_REQUEST = 384; public static final int DEFAULT_WORLD_STATE_REQUEST_PARALLELISM = 10; public static final int DEFAULT_WORLD_STATE_MAX_REQUESTS_WITHOUT_PROGRESS = 1000; @@ -53,9 +53,9 @@ public class SynchronizerConfiguration { public static final boolean DEFAULT_CHECKPOINT_POST_MERGE_ENABLED = false; // Fast sync config - private final int fastSyncPivotDistance; + private final int syncPivotDistance; private final float fastSyncFullValidationRate; - private final int fastSyncMinimumPeerCount; + private final int syncMinimumPeerCount; private final int worldStateHashCountPerRequest; private final int worldStateRequestParallelism; private final int worldStateMaxRequestsWithoutProgress; @@ -87,9 +87,9 @@ public class SynchronizerConfiguration { private final long propagationManagerGetBlockTimeoutMillis; private SynchronizerConfiguration( - final int fastSyncPivotDistance, + final int syncPivotDistance, final float fastSyncFullValidationRate, - final int fastSyncMinimumPeerCount, + final int syncMinimumPeerCount, final int worldStateHashCountPerRequest, final int worldStateRequestParallelism, final int worldStateMaxRequestsWithoutProgress, @@ -109,9 +109,9 @@ public class SynchronizerConfiguration { final int maxTrailingPeers, final long propagationManagerGetBlockTimeoutMillis, final boolean checkpointPostMergeEnabled) { - this.fastSyncPivotDistance = fastSyncPivotDistance; + this.syncPivotDistance = syncPivotDistance; this.fastSyncFullValidationRate = fastSyncFullValidationRate; - this.fastSyncMinimumPeerCount = fastSyncMinimumPeerCount; + this.syncMinimumPeerCount = syncMinimumPeerCount; this.worldStateHashCountPerRequest = worldStateHashCountPerRequest; this.worldStateRequestParallelism = worldStateRequestParallelism; this.worldStateMaxRequestsWithoutProgress = worldStateMaxRequestsWithoutProgress; @@ -171,12 +171,14 @@ public class SynchronizerConfiguration { } /** - * The distance from the chain head at which we should switch from fast sync to full sync. + * The distance from the chain head at which we should switch from fast, snap, or checkpoint sync + * to full sync. * - * @return distance from the chain head at which we should switch from fast sync to full sync. + * @return distance from the chain head at which we should switch from fast, snap or checkpoint + * sync to full sync. */ - public int getFastSyncPivotDistance() { - return fastSyncPivotDistance; + public int getSyncPivotDistance() { + return syncPivotDistance; } public long getDownloaderChangeTargetThresholdByHeight() { @@ -222,8 +224,8 @@ public class SynchronizerConfiguration { return fastSyncFullValidationRate; } - public int getFastSyncMinimumPeerCount() { - return fastSyncMinimumPeerCount; + public int getSyncMinimumPeerCount() { + return syncMinimumPeerCount; } public int getWorldStateHashCountPerRequest() { @@ -256,7 +258,7 @@ public class SynchronizerConfiguration { public static class Builder { private SyncMode syncMode = SyncMode.FULL; - private int fastSyncMinimumPeerCount = DEFAULT_FAST_SYNC_MINIMUM_PEERS; + private int syncMinimumPeerCount = DEFAULT_SYNC_MINIMUM_PEERS; private int maxTrailingPeers = Integer.MAX_VALUE; private Range blockPropagationRange = DEFAULT_BLOCK_PROPAGATION_RANGE; private long downloaderChangeTargetThresholdByHeight = @@ -270,7 +272,7 @@ public class SynchronizerConfiguration { private int downloaderParallelism = DEFAULT_DOWNLOADER_PARALLELISM; private int transactionsParallelism = DEFAULT_TRANSACTIONS_PARALLELISM; private int computationParallelism = DEFAULT_COMPUTATION_PARALLELISM; - private int fastSyncPivotDistance = DEFAULT_PIVOT_DISTANCE_FROM_HEAD; + private int syncPivotDistance = DEFAULT_PIVOT_DISTANCE_FROM_HEAD; private float fastSyncFullValidationRate = DEFAULT_FULL_VALIDATION_RATE; private int worldStateHashCountPerRequest = DEFAULT_WORLD_STATE_HASH_COUNT_PER_REQUEST; private int worldStateRequestParallelism = DEFAULT_WORLD_STATE_REQUEST_PARALLELISM; @@ -283,8 +285,8 @@ public class SynchronizerConfiguration { DEFAULT_PROPAGATION_MANAGER_GET_BLOCK_TIMEOUT_MILLIS; private boolean checkpointPostMergeEnabled = DEFAULT_CHECKPOINT_POST_MERGE_ENABLED; - public Builder fastSyncPivotDistance(final int distance) { - fastSyncPivotDistance = distance; + public Builder syncPivotDistance(final int distance) { + syncPivotDistance = distance; return this; } @@ -357,8 +359,8 @@ public class SynchronizerConfiguration { return this; } - public Builder fastSyncMinimumPeerCount(final int fastSyncMinimumPeerCount) { - this.fastSyncMinimumPeerCount = fastSyncMinimumPeerCount; + public Builder syncMinimumPeerCount(final int syncMinimumPeerCount) { + this.syncMinimumPeerCount = syncMinimumPeerCount; return this; } @@ -406,9 +408,9 @@ public class SynchronizerConfiguration { public SynchronizerConfiguration build() { return new SynchronizerConfiguration( - fastSyncPivotDistance, + syncPivotDistance, fastSyncFullValidationRate, - fastSyncMinimumPeerCount, + syncMinimumPeerCount, worldStateHashCountPerRequest, worldStateRequestParallelism, worldStateMaxRequestsWithoutProgress, diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncActions.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncActions.java index 52d384acf6..06bf8aace6 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncActions.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncActions.java @@ -142,8 +142,8 @@ public class FastSyncActions { ethContext, metricsSystem, currentState.getPivotBlockNumber().getAsLong(), - syncConfig.getFastSyncMinimumPeerCount(), - syncConfig.getFastSyncPivotDistance()) + syncConfig.getSyncMinimumPeerCount(), + syncConfig.getSyncPivotDistance()) .downloadPivotBlockHeader())); } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncDownloader.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncDownloader.java index 7b64f885c2..565824a780 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncDownloader.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncDownloader.java @@ -1,5 +1,5 @@ /* - * Copyright ConsenSys AG. + * 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 @@ -80,7 +80,7 @@ public class FastSyncDownloader { if (!running.compareAndSet(false, true)) { throw new IllegalStateException("SyncDownloader already running"); } - LOG.info("Starting sync"); + LOG.info("Starting pivot-based sync"); return start(initialFastSyncState); } @@ -94,7 +94,7 @@ public class FastSyncDownloader { onBonsai.clearFlatDatabase(); onBonsai.clearTrieLog(); }); - LOG.debug("Start sync with initial sync state {}", fastSyncState); + LOG.debug("Start fast sync with initial sync state {}", fastSyncState); return findPivotBlock(fastSyncState, fss -> downloadChainAndWorldState(fastSyncActions, fss)); } @@ -114,7 +114,9 @@ public class FastSyncDownloader { protected CompletableFuture handleFailure(final Throwable error) { trailingPeerRequirements = Optional.empty(); Throwable rootCause = ExceptionUtils.rootCause(error); - if (rootCause instanceof SyncException) { + if (rootCause instanceof NoSyncRequiredException) { + return CompletableFuture.completedFuture(new NoSyncRequiredState()); + } else if (rootCause instanceof SyncException) { return CompletableFuture.failedFuture(error); } else if (rootCause instanceof StalledDownloadException) { LOG.debug("Stalled sync re-pivoting to newer block."); diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/NoSyncRequiredException.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/NoSyncRequiredException.java new file mode 100644 index 0000000000..caa45abdc1 --- /dev/null +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/NoSyncRequiredException.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.sync.fastsync; + +public class NoSyncRequiredException extends RuntimeException {} diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/NoSyncRequiredState.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/NoSyncRequiredState.java new file mode 100644 index 0000000000..9cefe78ed1 --- /dev/null +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/NoSyncRequiredState.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.sync.fastsync; + +public class NoSyncRequiredState extends FastSyncState {} diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/PivotSelectorFromPeers.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/PivotSelectorFromPeers.java index 6402b58d1f..16f7e09d6d 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/PivotSelectorFromPeers.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/PivotSelectorFromPeers.java @@ -35,8 +35,8 @@ public class PivotSelectorFromPeers implements PivotBlockSelector { private static final Logger LOG = LoggerFactory.getLogger(PivotSelectorFromPeers.class); - private final EthContext ethContext; - private final SynchronizerConfiguration syncConfig; + protected final EthContext ethContext; + protected final SynchronizerConfiguration syncConfig; private final SyncState syncState; private final MetricsSystem metricsSystem; @@ -66,7 +66,7 @@ public class PivotSelectorFromPeers implements PivotBlockSelector { conservativelyEstimatedPivotBlock(), syncConfig.getMaxTrailingPeers())); trailingPeerLimiter.enforceTrailingPeerLimit(); - return waitForPeers(syncConfig.getFastSyncMinimumPeerCount()); + return waitForPeers(syncConfig.getSyncMinimumPeerCount()); } @Override @@ -74,9 +74,9 @@ public class PivotSelectorFromPeers implements PivotBlockSelector { return syncState.bestChainHeight(); } - private Optional fromBestPeer(final EthPeer peer) { + protected Optional fromBestPeer(final EthPeer peer) { final long pivotBlockNumber = - peer.chainState().getEstimatedHeight() - syncConfig.getFastSyncPivotDistance(); + peer.chainState().getEstimatedHeight() - syncConfig.getSyncPivotDistance(); if (pivotBlockNumber <= BlockHeader.GENESIS_BLOCK_NUMBER) { // Peer's chain isn't long enough, return an empty value, so we can try again. LOG.info("Waiting for peers with sufficient chain height"); @@ -86,7 +86,7 @@ public class PivotSelectorFromPeers implements PivotBlockSelector { return Optional.of(new FastSyncState(pivotBlockNumber)); } - private Optional selectBestPeer() { + protected Optional selectBestPeer() { return ethContext .getEthPeers() .bestPeerMatchingCriteria(this::canPeerDeterminePivotBlock) @@ -96,7 +96,7 @@ public class PivotSelectorFromPeers implements PivotBlockSelector { private boolean enoughFastSyncPeersArePresent() { final long peerCount = countPeersThatCanDeterminePivotBlock(); - final int minPeerCount = syncConfig.getFastSyncMinimumPeerCount(); + final int minPeerCount = syncConfig.getSyncMinimumPeerCount(); if (peerCount < minPeerCount) { LOG.info( "Waiting for valid peers with chain height information. {} / {} required peers currently available.", @@ -126,7 +126,7 @@ public class PivotSelectorFromPeers implements PivotBlockSelector { private long conservativelyEstimatedPivotBlock() { final long estimatedNextPivot = - syncState.getLocalChainHeight() + syncConfig.getFastSyncPivotDistance(); + syncState.getLocalChainHeight() + syncConfig.getSyncPivotDistance(); return Math.min(syncState.bestChainHeight(), estimatedNextPivot); } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/SnapSyncConfiguration.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/SnapSyncConfiguration.java index 669287cfef..dbe043b92a 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/SnapSyncConfiguration.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/SnapSyncConfiguration.java @@ -38,6 +38,8 @@ public class SnapSyncConfiguration { public static final Boolean DEFAULT_SNAP_SERVER_ENABLED = Boolean.FALSE; + public static final Boolean DEFAULT_SNAP_SYNC_BFT_ENABLED = Boolean.FALSE; + public static SnapSyncConfiguration getDefault() { return ImmutableSnapSyncConfiguration.builder().build(); } @@ -81,4 +83,9 @@ public class SnapSyncConfiguration { public Boolean isSnapServerEnabled() { return DEFAULT_SNAP_SERVER_ENABLED; } + + @Value.Default + public Boolean isSnapSyncBftEnabled() { + return DEFAULT_SNAP_SYNC_BFT_ENABLED; + } } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/request/AccountRangeDataRequest.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/request/AccountRangeDataRequest.java index 213912a1ac..21a707e9a6 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/request/AccountRangeDataRequest.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/request/AccountRangeDataRequest.java @@ -58,12 +58,12 @@ public class AccountRangeDataRequest extends SnapDataRequest { private static final Logger LOG = LoggerFactory.getLogger(AccountRangeDataRequest.class); - private final Bytes32 startKeyHash; - private final Bytes32 endKeyHash; - private final Optional startStorageRange; - private final Optional endStorageRange; + protected final Bytes32 startKeyHash; + protected final Bytes32 endKeyHash; + protected final Optional startStorageRange; + protected final Optional endStorageRange; - private final StackTrie stackTrie; + protected final StackTrie stackTrie; private Optional isProofValid; protected AccountRangeDataRequest( @@ -170,6 +170,12 @@ public class AccountRangeDataRequest extends SnapDataRequest { } else { stackTrie.addElement(startKeyHash, proofs, accounts); isProofValid = Optional.of(true); + LOG.atDebug() + .setMessage("{} accounts received during sync for account range {} {}") + .addArgument(accounts.size()) + .addArgument(startKeyHash) + .addArgument(endKeyHash) + .log(); } } } diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncActionsTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncActionsTest.java index e060bab6fb..d29bb7260e 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncActionsTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncActionsTest.java @@ -62,7 +62,7 @@ import org.junit.jupiter.params.provider.ArgumentsSource; public class FastSyncActionsTest { private final SynchronizerConfiguration.Builder syncConfigBuilder = - new SynchronizerConfiguration.Builder().syncMode(SyncMode.FAST).fastSyncPivotDistance(1000); + new SynchronizerConfiguration.Builder().syncMode(SyncMode.FAST).syncPivotDistance(1000); private final WorldStateStorageCoordinator worldStateStorageCoordinator = mock(WorldStateStorageCoordinator.class); @@ -113,9 +113,9 @@ public class FastSyncActionsTest { public void waitForPeersShouldSucceedIfEnoughPeersAreFound( final DataStorageFormat storageFormat) { setUp(storageFormat); - for (int i = 0; i < syncConfig.getFastSyncMinimumPeerCount(); i++) { + for (int i = 0; i < syncConfig.getSyncMinimumPeerCount(); i++) { EthProtocolManagerTestUtil.createPeer( - ethProtocolManager, syncConfig.getFastSyncPivotDistance() + i + 1); + ethProtocolManager, syncConfig.getSyncPivotDistance() + i + 1); } final CompletableFuture result = fastSyncActions.selectPivotBlock(FastSyncState.EMPTY_SYNC_STATE); @@ -153,7 +153,7 @@ public class FastSyncActionsTest { final DataStorageFormat storageFormat) { setUp(storageFormat); final int minPeers = 1; - syncConfigBuilder.fastSyncMinimumPeerCount(minPeers); + syncConfigBuilder.syncMinimumPeerCount(minPeers); syncConfig = syncConfigBuilder.build(); fastSyncActions = createFastSyncActions( @@ -174,7 +174,7 @@ public class FastSyncActionsTest { final DataStorageFormat storageFormat) { setUp(storageFormat); final int minPeers = 1; - syncConfigBuilder.fastSyncMinimumPeerCount(minPeers); + syncConfigBuilder.syncMinimumPeerCount(minPeers); syncConfig = syncConfigBuilder.build(); fastSyncActions = createFastSyncActions( @@ -197,7 +197,7 @@ public class FastSyncActionsTest { setUp(storageFormat); EthProtocolManagerTestUtil.disableEthSchedulerAutoRun(ethProtocolManager); final int minPeers = 2; - syncConfigBuilder.fastSyncMinimumPeerCount(minPeers); + syncConfigBuilder.syncMinimumPeerCount(minPeers); syncConfig = syncConfigBuilder.build(); fastSyncActions = createFastSyncActions( @@ -228,13 +228,13 @@ public class FastSyncActionsTest { final DataStorageFormat storageFormat) { setUp(storageFormat); final int minPeers = 3; - syncConfigBuilder.fastSyncMinimumPeerCount(minPeers); + syncConfigBuilder.syncMinimumPeerCount(minPeers); syncConfig = syncConfigBuilder.build(); fastSyncActions = createFastSyncActions( syncConfig, new PivotSelectorFromPeers(ethContext, syncConfig, syncState, metricsSystem)); - final long minPivotHeight = syncConfig.getFastSyncPivotDistance() + 1L; + final long minPivotHeight = syncConfig.getSyncPivotDistance() + 1L; EthProtocolManagerTestUtil.disableEthSchedulerAutoRun(ethProtocolManager); // Create peers without chain height estimates @@ -267,7 +267,7 @@ public class FastSyncActionsTest { final long bestPeerHeight = minPivotHeight + 1; peers.get(minPeers - 1).getEthPeer().chainState().updateHeightEstimate(bestPeerHeight); final FastSyncState expected = - new FastSyncState(bestPeerHeight - syncConfig.getFastSyncPivotDistance()); + new FastSyncState(bestPeerHeight - syncConfig.getSyncPivotDistance()); EthProtocolManagerTestUtil.runPendingFutures(ethProtocolManager); assertThat(result).isCompletedWithValue(expected); } @@ -279,13 +279,13 @@ public class FastSyncActionsTest { setUp(storageFormat); final int minPeers = 3; final PeerValidator validator = mock(PeerValidator.class); - syncConfigBuilder.fastSyncMinimumPeerCount(minPeers); + syncConfigBuilder.syncMinimumPeerCount(minPeers); syncConfig = syncConfigBuilder.build(); fastSyncActions = createFastSyncActions( syncConfig, new PivotSelectorFromPeers(ethContext, syncConfig, syncState, metricsSystem)); - final long minPivotHeight = syncConfig.getFastSyncPivotDistance() + 1L; + final long minPivotHeight = syncConfig.getSyncPivotDistance() + 1L; EthProtocolManagerTestUtil.disableEthSchedulerAutoRun(ethProtocolManager); // Create peers that are not validated @@ -319,7 +319,7 @@ public class FastSyncActionsTest { bestPeer.chainState().updateHeightEstimate(bestPeerHeight); bestPeer.markValidated(validator); final FastSyncState expected = - new FastSyncState(bestPeerHeight - syncConfig.getFastSyncPivotDistance()); + new FastSyncState(bestPeerHeight - syncConfig.getSyncPivotDistance()); EthProtocolManagerTestUtil.runPendingFutures(ethProtocolManager); assertThat(result).isCompletedWithValue(expected); } @@ -351,13 +351,13 @@ public class FastSyncActionsTest { final boolean bestMissingHeight, final boolean bestNotValidated) { final int minPeers = 3; final int peerCount = minPeers + 1; - syncConfigBuilder.fastSyncMinimumPeerCount(minPeers); + syncConfigBuilder.syncMinimumPeerCount(minPeers); syncConfig = syncConfigBuilder.build(); fastSyncActions = createFastSyncActions( syncConfig, new PivotSelectorFromPeers(ethContext, syncConfig, syncState, metricsSystem)); - final long minPivotHeight = syncConfig.getFastSyncPivotDistance() + 1L; + final long minPivotHeight = syncConfig.getSyncPivotDistance() + 1L; EthProtocolManagerTestUtil.disableEthSchedulerAutoRun(ethProtocolManager); // Create peers without chain height estimates @@ -392,7 +392,7 @@ public class FastSyncActionsTest { final long expectedBestChainHeight = peers.get(1).getEthPeer().chainState().getEstimatedHeight(); final FastSyncState expected = - new FastSyncState(expectedBestChainHeight - syncConfig.getFastSyncPivotDistance()); + new FastSyncState(expectedBestChainHeight - syncConfig.getSyncPivotDistance()); EthProtocolManagerTestUtil.runPendingFutures(ethProtocolManager); assertThat(result).isCompletedWithValue(expected); } @@ -403,13 +403,13 @@ public class FastSyncActionsTest { final DataStorageFormat storageFormat) { setUp(storageFormat); final int minPeers = 1; - syncConfigBuilder.fastSyncMinimumPeerCount(minPeers); + syncConfigBuilder.syncMinimumPeerCount(minPeers); syncConfig = syncConfigBuilder.build(); fastSyncActions = createFastSyncActions( syncConfig, new PivotSelectorFromPeers(ethContext, syncConfig, syncState, metricsSystem)); - final long pivotDistance = syncConfig.getFastSyncPivotDistance(); + final long pivotDistance = syncConfig.getSyncPivotDistance(); EthProtocolManagerTestUtil.disableEthSchedulerAutoRun(ethProtocolManager); EthProtocolManagerTestUtil.createPeer(ethProtocolManager, pivotDistance - 1); @@ -432,10 +432,10 @@ public class FastSyncActionsTest { public void selectPivotBlockShouldRetryIfBestPeerChainIsEqualToPivotDistance( final DataStorageFormat storageFormat) { setUp(storageFormat); - final long pivotDistance = syncConfig.getFastSyncPivotDistance(); + final long pivotDistance = syncConfig.getSyncPivotDistance(); EthProtocolManagerTestUtil.disableEthSchedulerAutoRun(ethProtocolManager); // Create peers with chains that are too short - for (int i = 0; i < syncConfig.getFastSyncMinimumPeerCount(); i++) { + for (int i = 0; i < syncConfig.getSyncMinimumPeerCount(); i++) { EthProtocolManagerTestUtil.createPeer(ethProtocolManager, pivotDistance); } @@ -467,7 +467,7 @@ public class FastSyncActionsTest { public void downloadPivotBlockHeaderShouldRetrievePivotBlockHeader( final DataStorageFormat storageFormat) { setUp(storageFormat); - syncConfig = SynchronizerConfiguration.builder().fastSyncMinimumPeerCount(1).build(); + syncConfig = SynchronizerConfiguration.builder().syncMinimumPeerCount(1).build(); fastSyncActions = createFastSyncActions( syncConfig, @@ -489,7 +489,7 @@ public class FastSyncActionsTest { public void downloadPivotBlockHeaderShouldRetrievePivotBlockHash( final DataStorageFormat storageFormat) { setUp(storageFormat); - syncConfig = SynchronizerConfiguration.builder().fastSyncMinimumPeerCount(1).build(); + syncConfig = SynchronizerConfiguration.builder().syncMinimumPeerCount(1).build(); GenesisConfigOptions genesisConfig = mock(GenesisConfigOptions.class); when(genesisConfig.getTerminalBlockNumber()).thenReturn(OptionalLong.of(10L)); diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/worldstate/LoadLocalDataStepTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/worldstate/LoadLocalDataStepTest.java index 6707ed9705..582bdff633 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/worldstate/LoadLocalDataStepTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/worldstate/LoadLocalDataStepTest.java @@ -51,7 +51,7 @@ public class LoadLocalDataStepTest { private final Task task = new StubTask(request); private final Pipe> completedTasks = - new Pipe<>(10, NO_OP_COUNTER, NO_OP_COUNTER, NO_OP_COUNTER); + new Pipe<>(10, NO_OP_COUNTER, NO_OP_COUNTER, NO_OP_COUNTER, "test_pipe"); private final LoadLocalDataStep loadLocalDataStep = new LoadLocalDataStep( new WorldStateStorageCoordinator(worldStateKeyValueStorage), new NoOpMetricsSystem()); diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/LoadLocalDataStepTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/LoadLocalDataStepTest.java index 9027538ce5..06f92460c2 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/LoadLocalDataStepTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/LoadLocalDataStepTest.java @@ -55,7 +55,7 @@ public class LoadLocalDataStepTest { private final Task task = new StubTask(request); private final Pipe> completedTasks = - new Pipe<>(10, NO_OP_COUNTER, NO_OP_COUNTER, NO_OP_COUNTER); + new Pipe<>(10, NO_OP_COUNTER, NO_OP_COUNTER, NO_OP_COUNTER, "test_pipe"); private final SnapSyncProcessState snapSyncState = mock(SnapSyncProcessState.class); private final SnapWorldDownloadState downloadState = mock(SnapWorldDownloadState.class); diff --git a/ethereum/trie/src/main/java/org/hyperledger/besu/ethereum/trie/patricia/TrieNodeDecoder.java b/ethereum/trie/src/main/java/org/hyperledger/besu/ethereum/trie/patricia/TrieNodeDecoder.java index b3476337a7..6179f45fc0 100644 --- a/ethereum/trie/src/main/java/org/hyperledger/besu/ethereum/trie/patricia/TrieNodeDecoder.java +++ b/ethereum/trie/src/main/java/org/hyperledger/besu/ethereum/trie/patricia/TrieNodeDecoder.java @@ -16,6 +16,7 @@ package org.hyperledger.besu.ethereum.trie.patricia; import static com.google.common.base.Preconditions.checkArgument; +import org.hyperledger.besu.ethereum.trie.MerkleTrie; import org.hyperledger.besu.ethereum.trie.Node; import org.hyperledger.besu.ethereum.trie.NodeLoader; import org.hyperledger.besu.ethereum.trie.NullNode; @@ -59,6 +60,9 @@ public class TrieNodeDecoder { * @return A list of nodes and node references embedded in the given rlp. */ public static List> decodeNodes(final Bytes location, final Bytes nodeRlp) { + if (nodeRlp.equals(MerkleTrie.EMPTY_TRIE_NODE)) { + return new ArrayList<>(); + } final Node node = decode(location, nodeRlp); final List> nodes = new ArrayList<>(); nodes.add(node); diff --git a/services/pipeline/src/main/java/org/hyperledger/besu/services/pipeline/AsyncOperationProcessor.java b/services/pipeline/src/main/java/org/hyperledger/besu/services/pipeline/AsyncOperationProcessor.java index f64454fa9f..c8c7e5905d 100644 --- a/services/pipeline/src/main/java/org/hyperledger/besu/services/pipeline/AsyncOperationProcessor.java +++ b/services/pipeline/src/main/java/org/hyperledger/besu/services/pipeline/AsyncOperationProcessor.java @@ -83,7 +83,7 @@ class AsyncOperationProcessor implements Processor { waitForAnyFutureToComplete(); outputCompletedTasks(outputPipe); } catch (final InterruptedException e) { - LOG.trace("Interrupted while waiting for processing to complete", e); + LOG.trace("Interrupted while waiting for processing to complete", e.getMessage()); } catch (final ExecutionException e) { throw new AsyncOperationException("Async operation failed. " + e.getMessage(), e); } catch (final TimeoutException e) { diff --git a/services/pipeline/src/main/java/org/hyperledger/besu/services/pipeline/Pipe.java b/services/pipeline/src/main/java/org/hyperledger/besu/services/pipeline/Pipe.java index 3697e0e3ba..63fb01bad1 100644 --- a/services/pipeline/src/main/java/org/hyperledger/besu/services/pipeline/Pipe.java +++ b/services/pipeline/src/main/java/org/hyperledger/besu/services/pipeline/Pipe.java @@ -44,6 +44,7 @@ public class Pipe implements ReadPipe, WritePipe { private final Counter abortedItemCounter; private final AtomicBoolean closed = new AtomicBoolean(); private final AtomicBoolean aborted = new AtomicBoolean(); + private String pipeName = ""; /** * Instantiates a new Pipe. @@ -52,16 +53,28 @@ public class Pipe implements ReadPipe, WritePipe { * @param inputCounter the input counter * @param outputCounter the output counter * @param abortedItemCounter the aborted item counter + * @param pipeName the name of the pipe */ public Pipe( final int capacity, final Counter inputCounter, final Counter outputCounter, - final Counter abortedItemCounter) { + final Counter abortedItemCounter, + final String pipeName) { queue = new ArrayBlockingQueue<>(capacity); this.inputCounter = inputCounter; this.outputCounter = outputCounter; this.abortedItemCounter = abortedItemCounter; + this.pipeName = pipeName; + } + + /** + * Get the name of this pipe + * + * @return the name of the pipe + */ + public String getPipeName() { + return pipeName; } @Override @@ -110,7 +123,7 @@ public class Pipe implements ReadPipe, WritePipe { } } } catch (final InterruptedException e) { - LOG.trace("Interrupted while waiting for next item", e); + LOG.trace("Interrupted while waiting for next item from pipe {}", pipeName); } return null; } @@ -140,7 +153,7 @@ public class Pipe implements ReadPipe, WritePipe { return; } } catch (final InterruptedException e) { - LOG.trace("Interrupted while waiting to add to output", e); + LOG.trace("Interrupted while waiting to add to output to pipe {}", pipeName); } } } diff --git a/services/pipeline/src/main/java/org/hyperledger/besu/services/pipeline/Pipeline.java b/services/pipeline/src/main/java/org/hyperledger/besu/services/pipeline/Pipeline.java index 7f37a4bac9..507e87a8c0 100644 --- a/services/pipeline/src/main/java/org/hyperledger/besu/services/pipeline/Pipeline.java +++ b/services/pipeline/src/main/java/org/hyperledger/besu/services/pipeline/Pipeline.java @@ -89,6 +89,19 @@ public class Pipeline { this.stages = stages; this.pipes = pipes; this.completerStage = completerStage; + + if (LOG.isTraceEnabled()) { + StringBuilder sb = new StringBuilder(); + sb.append("Building pipeline "); + sb.append(name); + sb.append(". Stages: "); + for (Stage nextStage : stages) { + sb.append(nextStage.getName()); + sb.append(" -> "); + } + sb.append("END"); + LOG.trace("{}", sb.toString()); + } } /** diff --git a/services/pipeline/src/main/java/org/hyperledger/besu/services/pipeline/PipelineBuilder.java b/services/pipeline/src/main/java/org/hyperledger/besu/services/pipeline/PipelineBuilder.java index 3bc6656e70..aaf68f5e3f 100644 --- a/services/pipeline/src/main/java/org/hyperledger/besu/services/pipeline/PipelineBuilder.java +++ b/services/pipeline/src/main/java/org/hyperledger/besu/services/pipeline/PipelineBuilder.java @@ -421,6 +421,7 @@ public class PipelineBuilder { newBufferSize, outputCounter.labels(labelName, "added"), outputCounter.labels(labelName, "removed"), - outputCounter.labels(labelName, "aborted")); + outputCounter.labels(labelName, "aborted"), + stageName); } } diff --git a/services/pipeline/src/test/java/org/hyperledger/besu/services/pipeline/BatchingReadPipeTest.java b/services/pipeline/src/test/java/org/hyperledger/besu/services/pipeline/BatchingReadPipeTest.java index fb90128fbb..da0908e814 100644 --- a/services/pipeline/src/test/java/org/hyperledger/besu/services/pipeline/BatchingReadPipeTest.java +++ b/services/pipeline/src/test/java/org/hyperledger/besu/services/pipeline/BatchingReadPipeTest.java @@ -31,7 +31,8 @@ import org.junit.jupiter.api.Test; public class BatchingReadPipeTest { - private final Pipe source = new Pipe<>(10, NO_OP_COUNTER, NO_OP_COUNTER, NO_OP_COUNTER); + private final Pipe source = + new Pipe<>(10, NO_OP_COUNTER, NO_OP_COUNTER, NO_OP_COUNTER, "source_pipe"); private final Counter batchCounter = mock(Counter.class); private final BatchingReadPipe batchingPipe = new BatchingReadPipe<>(source, 3, batchCounter); diff --git a/services/pipeline/src/test/java/org/hyperledger/besu/services/pipeline/CompleterStageTest.java b/services/pipeline/src/test/java/org/hyperledger/besu/services/pipeline/CompleterStageTest.java index ef3e29afeb..ea4a81a9d9 100644 --- a/services/pipeline/src/test/java/org/hyperledger/besu/services/pipeline/CompleterStageTest.java +++ b/services/pipeline/src/test/java/org/hyperledger/besu/services/pipeline/CompleterStageTest.java @@ -24,7 +24,8 @@ import org.junit.jupiter.api.Test; public class CompleterStageTest { - private final Pipe pipe = new Pipe<>(10, NO_OP_COUNTER, NO_OP_COUNTER, NO_OP_COUNTER); + private final Pipe pipe = + new Pipe<>(10, NO_OP_COUNTER, NO_OP_COUNTER, NO_OP_COUNTER, "test_pipe"); private final List output = new ArrayList<>(); private final CompleterStage stage = new CompleterStage<>("name", pipe, output::add); diff --git a/services/pipeline/src/test/java/org/hyperledger/besu/services/pipeline/FlatMapProcessorTest.java b/services/pipeline/src/test/java/org/hyperledger/besu/services/pipeline/FlatMapProcessorTest.java index 1012d3b012..4e3b8cfa51 100644 --- a/services/pipeline/src/test/java/org/hyperledger/besu/services/pipeline/FlatMapProcessorTest.java +++ b/services/pipeline/src/test/java/org/hyperledger/besu/services/pipeline/FlatMapProcessorTest.java @@ -28,8 +28,10 @@ import org.junit.jupiter.api.Test; public class FlatMapProcessorTest { - private final Pipe input = new Pipe<>(10, NO_OP_COUNTER, NO_OP_COUNTER, NO_OP_COUNTER); - private final Pipe output = new Pipe<>(10, NO_OP_COUNTER, NO_OP_COUNTER, NO_OP_COUNTER); + private final Pipe input = + new Pipe<>(10, NO_OP_COUNTER, NO_OP_COUNTER, NO_OP_COUNTER, "input_pipe"); + private final Pipe output = + new Pipe<>(10, NO_OP_COUNTER, NO_OP_COUNTER, NO_OP_COUNTER, "output_pipe"); @SuppressWarnings("unchecked") private final Function> mapper = mock(Function.class); diff --git a/services/pipeline/src/test/java/org/hyperledger/besu/services/pipeline/IteratorSourceStageTest.java b/services/pipeline/src/test/java/org/hyperledger/besu/services/pipeline/IteratorSourceStageTest.java index 02052615b7..915a90b1fd 100644 --- a/services/pipeline/src/test/java/org/hyperledger/besu/services/pipeline/IteratorSourceStageTest.java +++ b/services/pipeline/src/test/java/org/hyperledger/besu/services/pipeline/IteratorSourceStageTest.java @@ -22,7 +22,8 @@ import org.junit.jupiter.api.Test; public class IteratorSourceStageTest { - private final Pipe output = new Pipe<>(10, NO_OP_COUNTER, NO_OP_COUNTER, NO_OP_COUNTER); + private final Pipe output = + new Pipe<>(10, NO_OP_COUNTER, NO_OP_COUNTER, NO_OP_COUNTER, "output_pipe"); private final IteratorSourceStage stage = new IteratorSourceStage<>("name", Iterators.forArray("a", "b", "c", "d"), output); diff --git a/services/pipeline/src/test/java/org/hyperledger/besu/services/pipeline/MapProcessorTest.java b/services/pipeline/src/test/java/org/hyperledger/besu/services/pipeline/MapProcessorTest.java index 0d7a913c3e..7698e8d327 100644 --- a/services/pipeline/src/test/java/org/hyperledger/besu/services/pipeline/MapProcessorTest.java +++ b/services/pipeline/src/test/java/org/hyperledger/besu/services/pipeline/MapProcessorTest.java @@ -27,8 +27,10 @@ import org.junit.jupiter.api.Test; public class MapProcessorTest { - private final Pipe input = new Pipe<>(10, NO_OP_COUNTER, NO_OP_COUNTER, NO_OP_COUNTER); - private final Pipe output = new Pipe<>(10, NO_OP_COUNTER, NO_OP_COUNTER, NO_OP_COUNTER); + private final Pipe input = + new Pipe<>(10, NO_OP_COUNTER, NO_OP_COUNTER, NO_OP_COUNTER, "intput_pipe"); + private final Pipe output = + new Pipe<>(10, NO_OP_COUNTER, NO_OP_COUNTER, NO_OP_COUNTER, "output_pipe"); @SuppressWarnings("unchecked") private final Function processor = mock(Function.class); diff --git a/services/pipeline/src/test/java/org/hyperledger/besu/services/pipeline/PipeTest.java b/services/pipeline/src/test/java/org/hyperledger/besu/services/pipeline/PipeTest.java index c838bc887a..c4a7a88b52 100644 --- a/services/pipeline/src/test/java/org/hyperledger/besu/services/pipeline/PipeTest.java +++ b/services/pipeline/src/test/java/org/hyperledger/besu/services/pipeline/PipeTest.java @@ -30,7 +30,8 @@ public class PipeTest { private final Counter inputCounter = mock(Counter.class); private final Counter outputCounter = mock(Counter.class); private final Counter abortedItemCounter = mock(Counter.class); - private final Pipe pipe = new Pipe<>(5, inputCounter, outputCounter, abortedItemCounter); + private final Pipe pipe = + new Pipe<>(5, inputCounter, outputCounter, abortedItemCounter, "test_pipe"); @Test public void shouldNotHaveMoreWhenEmptyAndClosed() { diff --git a/services/pipeline/src/test/java/org/hyperledger/besu/services/pipeline/ProcessingStageTest.java b/services/pipeline/src/test/java/org/hyperledger/besu/services/pipeline/ProcessingStageTest.java index efbe16da66..a07530f549 100644 --- a/services/pipeline/src/test/java/org/hyperledger/besu/services/pipeline/ProcessingStageTest.java +++ b/services/pipeline/src/test/java/org/hyperledger/besu/services/pipeline/ProcessingStageTest.java @@ -34,9 +34,9 @@ import org.mockito.junit.jupiter.MockitoExtension; public class ProcessingStageTest { private final Pipe inputPipe = - new Pipe<>(10, NO_OP_COUNTER, NO_OP_COUNTER, NO_OP_COUNTER); + new Pipe<>(10, NO_OP_COUNTER, NO_OP_COUNTER, NO_OP_COUNTER, "input_pipe"); private final Pipe outputPipe = - new Pipe<>(10, NO_OP_COUNTER, NO_OP_COUNTER, NO_OP_COUNTER); + new Pipe<>(10, NO_OP_COUNTER, NO_OP_COUNTER, NO_OP_COUNTER, "output_pipe"); @Mock private Processor singleStep; private ProcessingStage stage; From 8d8dbf05b51ed4c3b1a18a4956ac9bdeb2fa2325 Mon Sep 17 00:00:00 2001 From: Chaminda Divitotawela Date: Wed, 3 Jul 2024 11:49:26 +1000 Subject: [PATCH 019/259] Turn off CicleCI for Besu (#7291) All the CI jobs run in GitHub actions and Circle CI it no longer needed in Besu project Signed-off-by: Chaminda Divitotawela --- .circleci/config.yml | 502 ------------------------------------------- 1 file changed, 502 deletions(-) delete mode 100644 .circleci/config.yml diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index 45aa3beb28..0000000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,502 +0,0 @@ ---- -version: 2.1 -orbs: - win: circleci/windows@5.0 - -executors: - besu_executor_med: # 2cpu, 4G ram - docker: - - image: cimg/openjdk:21.0 - resource_class: medium - working_directory: ~/project - environment: - architecture: "amd64" - GRADLE_OPTS: -Dorg.gradle.daemon=false -Dorg.gradle.parallel=true -Dorg.gradle.workers.max=2 - - besu_arm64_executor_med: # 2cpu, 8G ram - machine: #https://circleci.com/developer/machine/image/ubuntu-2204 - image: ubuntu-2204:2022.10.2 - resource_class: arm.medium - working_directory: ~/project - environment: - architecture: "arm64" - GRADLE_OPTS: -Dorg.gradle.daemon=false -Dorg.gradle.parallel=true -Dorg.gradle.workers.max=2 - - besu_executor_xl: # 8cpu, 16G ram - docker: - - image: cimg/openjdk:21.0 - resource_class: xlarge - working_directory: ~/project - environment: - GRADLE_OPTS: -Dorg.gradle.daemon=false -Dorg.gradle.parallel=true -Dorg.gradle.workers.max=4 - - xl_machine_executor: - machine: #https://circleci.com/developer/machine/image/ubuntu-2204 - image: ubuntu-2204:2022.10.2 - resource_class: xlarge - - trivy_executor: - docker: - - image: docker:stable-git - resource_class: small - working_directory: ~/project - -commands: - prepare: - description: "Prepare" - steps: - - checkout - - run: - name: Install Packages - LibSodium, nssdb - command: | - sudo apt-get update - sudo apt-get install -y libsodium23 libsodium-dev libjemalloc-dev apt-transport-https haveged libnss3-tools - sudo service haveged restart - java --version - - restore_gradle_cache - restore_gradle_cache: - description: "Restore Gradle cache" - steps: - - restore_cache: - name: Restore cached gradle dependencies - keys: - - deps-{{ checksum "gradle/versions.gradle" }}-{{ .Branch }}-{{ .Revision }} - - deps-{{ checksum "gradle/versions.gradle" }} - - deps- - - capture_test_results: - description: "Capture test results" - steps: - - run: - name: Jacoco - command: | - ./gradlew --no-daemon jacocoTestReport - - run: - name: Gather test results - when: always - command: | - FILES=`find . -name test-results` - for FILE in $FILES - do - MODULE=`echo "$FILE" | sed -e 's@./\(.*\)/build/test-results@\1@'` - TARGET="build/test-results/$MODULE" - mkdir -p "$TARGET" - cp -rf ${FILE}/*/* "$TARGET" - done - - store_test_results: - path: build/test-results - - store_artifacts: - path: besu/build/reports/jacoco - - capture_test_logs: - description: "Capture test logs" - steps: - - store_artifacts: - path: acceptance-tests/tests/build/acceptanceTestLogs - destination: acceptance-tests-logs - - store_artifacts: - path: acceptance-tests/tests/build/jvmErrorLogs - -jobs: - assemble: - executor: besu_executor_xl - steps: - - prepare - - run: - name: Assemble - command: | - ./gradlew --no-daemon clean compileJava compileTestJava assemble - - save_cache: - name: Caching gradle dependencies - key: deps-{{ checksum "gradle/versions.gradle" }}-{{ .Branch }}-{{ .Revision }} - paths: - - .gradle - - ~/.gradle - - persist_to_workspace: - root: ~/project - paths: - - ./ - - store_artifacts: - name: Distribution artifacts - path: build/distributions - destination: distributions - when: always - - testWindows: - executor: win/default - steps: - - attach_workspace: - at: ~/project - - run: - name: Unzip Windows build - no_output_timeout: 20m - command: | - cd build/distributions - unzip besu-*.zip -d besu-tmp - cd besu-tmp - mv besu-* ../besu - - run: - name: Test Besu Windows executable - no_output_timeout: 10m - command: | - build\distributions\besu\bin\besu.bat --help - build\distributions\besu\bin\besu.bat --version - - dockerScan: - executor: trivy_executor - steps: - - checkout - - restore_gradle_cache - - setup_remote_docker: - docker_layer_caching: true - - run: - name: Install trivy - command: | - apk add --update-cache --upgrade curl bash - curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin - - run: - name: Scan with trivy - shell: /bin/sh - command: | - for FILE in $(ls docker) - do - if [[ $FILE == "test.sh" || $FILE == "tests" ]]; then - continue - fi - docker pull -q "hyperledger/besu:develop-$FILE" - trivy -q image --exit-code 1 --no-progress --severity HIGH,CRITICAL "hyperledger/besu:develop-$FILE" - done - - unitTests: - executor: besu_executor_xl - steps: - - prepare - - attach_workspace: - at: ~/project - - run: - name: Build - no_output_timeout: 20m - command: | - ./gradlew --no-daemon build - - capture_test_results - - integrationTests: - executor: xl_machine_executor # needs the machine executor since privacy test uses container tests (docker) - steps: - - prepare - - attach_workspace: - at: ~/project - - run: - name: IntegrationTests - command: | - ./gradlew --no-daemon integrationTest - - run: - name: CompileJmh - command: | - ./gradlew --no-daemon compileJmh - - capture_test_results - - referenceTests: - executor: besu_executor_xl - steps: - - prepare - - attach_workspace: - at: ~/project - - run: - name: ReferenceTests - no_output_timeout: 40m - command: | - git submodule update --init --recursive - ./gradlew --no-daemon referenceTest - - capture_test_results - - acceptanceTests: - parallelism: 4 - executor: xl_machine_executor # needs the machine executor since privacy test uses container tests (docker) - steps: - - prepare - - attach_workspace: - at: ~/project - - run: - name: AcceptanceTests (Mainnet) - no_output_timeout: 20m - command: | - CLASSNAMES=$(circleci tests glob "acceptance-tests/tests/src/test/java/**/*.java" \ - | sed 's@.*/src/test/java/@@' \ - | sed 's@/@.@g' \ - | sed 's/.\{5\}$//' \ - | circleci tests split --split-by=timings --timings-type=classname) - # Format the arguments to "./gradlew test" - GRADLE_ARGS=$(echo $CLASSNAMES | awk '{for (i=1; i<=NF; i++) print "--tests",$i}') - ./gradlew --no-daemon acceptanceTestMainnet $GRADLE_ARGS - - capture_test_results - - capture_test_logs - - acceptanceTestsCliqueBft: - executor: besu_executor_med - steps: - - prepare - - attach_workspace: - at: ~/project - - run: - name: AcceptanceTests (Non-Mainnet) - no_output_timeout: 30m - command: | - ./gradlew --no-daemon --max-workers=1 acceptanceTestCliqueBft - - capture_test_results - - capture_test_logs - - acceptanceTestsPrivacy: - parallelism: 4 - executor: xl_machine_executor # needs the machine executor since it uses container tests (docker) - steps: - - prepare - - attach_workspace: - at: ~/project - - run: - name: AcceptanceTests (Non-Mainnet) - no_output_timeout: 20m - command: | - CLASSNAMES=$(circleci tests glob "acceptance-tests/tests/src/test/java/**/*.java" \ - | sed 's@.*/src/test/java/@@' \ - | sed 's@/@.@g' \ - | sed 's/.\{5\}$//' \ - | circleci tests split --split-by=timings --timings-type=classname) - # Format the arguments to "./gradlew test" - GRADLE_ARGS=$(echo $CLASSNAMES | awk '{for (i=1; i<=NF; i++) print "--tests",$i}') - ./gradlew --no-daemon acceptanceTestPrivacy $GRADLE_ARGS - - capture_test_results - - capture_test_logs - - acceptanceTestsPermissioning: - executor: besu_executor_med - steps: - - prepare - - attach_workspace: - at: ~/project - - run: - name: AcceptanceTests (Non-Mainnet) - no_output_timeout: 20m - command: | - ./gradlew --no-daemon --max-workers=1 acceptanceTestPermissioning - - capture_test_results - - capture_test_logs - - buildDocker: - executor: besu_executor_med - steps: - - prepare - - attach_workspace: - at: ~/project - - setup_remote_docker - - run: - name: hadoLint_openjdk_17 - command: | - docker run --rm -i hadolint/hadolint < docker/openjdk-17/Dockerfile - - run: - name: hadoLint_openjdk_17_debug - command: | - docker run --rm -i hadolint/hadolint < docker/openjdk-17-debug/Dockerfile - - run: - name: hadoLint_openjdk_latest - command: | - docker run --rm -i hadolint/hadolint < docker/openjdk-latest/Dockerfile - - run: - name: hadoLint_graalvm - command: | - docker run --rm -i hadolint/hadolint < docker/graalvm/Dockerfile - - run: - name: build image - command: | - ./gradlew --no-daemon distDocker - - run: - name: test image - command: | - mkdir -p docker/reports - curl -L https://github.com/aelsabbahy/goss/releases/download/v0.3.9/goss-linux-amd64 -o ./docker/tests/goss-linux-amd64 - ./gradlew --no-daemon testDocker - - buildArm64Docker: - executor: besu_arm64_executor_med - steps: - - prepare - - attach_workspace: - at: ~/project - - run: - name: hadoLint_openjdk_17 - command: | - docker run --rm -i hadolint/hadolint < docker/openjdk-17/Dockerfile - - run: - name: hadoLint_openjdk_latest - command: | - docker run --rm -i hadolint/hadolint < docker/openjdk-latest/Dockerfile - - run: - name: hadoLint_graalvm - command: | - docker run --rm -i hadolint/hadolint < docker/graalvm/Dockerfile - - run: - name: Java_17 - command: | - sudo apt install -q --assume-yes openjdk-17-jre-headless openjdk-17-jdk-headless - sudo update-java-alternatives -a - - run: - name: build image - command: | - ./gradlew --no-daemon distDocker - - run: - name: test image - command: | - mkdir -p docker/reports - curl -L https://github.com/aelsabbahy/goss/releases/download/v0.3.9/goss-linux-arm -o ./docker/tests/goss-linux-arm64 - ./gradlew --no-daemon testDocker - - publish: - executor: besu_executor_med - steps: - - prepare - - attach_workspace: - at: ~/project - - run: - name: Publish - command: | - ./gradlew --no-daemon artifactoryPublish - - publishDocker: - executor: besu_executor_med - steps: - - prepare - - attach_workspace: - at: ~/project - - setup_remote_docker - - run: - name: Publish Docker - command: | - docker login --username "${DOCKER_USER_RW}" --password "${DOCKER_PASSWORD_RW}" - ./gradlew --no-daemon "-Pbranch=${CIRCLE_BRANCH}" dockerUpload - - publishArm64Docker: - executor: besu_arm64_executor_med - steps: - - prepare - - attach_workspace: - at: ~/project - - run: - name: Java_17 - command: | - sudo apt install -q --assume-yes openjdk-17-jre-headless openjdk-17-jdk-headless - sudo update-java-alternatives -a - - run: - name: Publish Docker - command: | - docker login --username "${DOCKER_USER_RW}" --password "${DOCKER_PASSWORD_RW}" - ./gradlew --no-daemon "-Pbranch=${CIRCLE_BRANCH}" dockerUpload - manifestDocker: - executor: besu_executor_med - steps: - - prepare - - setup_remote_docker - - run: - name: Create and publish docker manifest - command: | - docker login --username "${DOCKER_USER_RW}" --password "${DOCKER_PASSWORD_RW}" - ./gradlew --no-daemon "-Pbranch=${CIRCLE_BRANCH}" --parallel manifestDocker - -workflows: - version: 2 - default: - jobs: - - assemble - - unitTests: - requires: - - assemble - - testWindows: - requires: - - assemble - - referenceTests: - requires: - - assemble - - integrationTests: - requires: - - assemble - - acceptanceTests: - requires: - - assemble - - acceptanceTestsCliqueBft: - requires: - - assemble - - acceptanceTests - - acceptanceTestsPermissioning: - requires: - - assemble - - buildDocker: - requires: - - assemble - - buildArm64Docker: - requires: - - buildDocker - - assemble - - publish: - filters: - branches: - only: - - main - - /^release-.*/ - requires: - - assemble - - integrationTests - - unitTests - - acceptanceTests - - referenceTests - - buildDocker - - publishDocker: - filters: - branches: - only: - - main - - /^release-.*/ - requires: - - assemble - - integrationTests - - unitTests - - acceptanceTests - - referenceTests - - buildDocker - context: - - besu-dockerhub-rw - - publishArm64Docker: - filters: - branches: - only: - - main - - /^release-.*/ - requires: - - integrationTests - - unitTests - - acceptanceTests - - referenceTests - - buildArm64Docker - context: - - besu-dockerhub-rw - - manifestDocker: - filters: - branches: - only: - - main - - /^release-.*/ - requires: - - publishDocker - - publishArm64Docker - context: - - besu-dockerhub-rw - - nightly: - triggers: - - schedule: - cron: "0 19 * * *" - filters: - branches: - only: - - main - jobs: - - assemble - - dockerScan From 8a9a84ad58fa5930208ec8da63c3f0f25f858d98 Mon Sep 17 00:00:00 2001 From: Stefan Pingel <16143240+pinges@users.noreply.github.com> Date: Wed, 3 Jul 2024 15:17:13 +1000 Subject: [PATCH 020/259] Check for snap server (#6609) * EthPeer add isServingSnap to be able to make sure that we have enough snap servers connected when we are snap syncing Signed-off-by: stefan.pingel@consensys.net Signed-off-by: Sally MacFarlane Co-authored-by: Sally MacFarlane --- .../org/hyperledger/besu/RunnerBuilder.java | 10 +- .../controller/BesuControllerBuilder.java | 36 +- ...onsensusScheduleBesuControllerBuilder.java | 7 +- .../MergeBesuControllerBuilder.java | 7 +- .../TransitionBesuControllerBuilder.java | 27 +- .../bft/protocol/BftProtocolManager.java | 6 - .../besu/ethereum/forkid/ForkIdManager.java | 6 +- .../besu/ethereum/eth/manager/EthPeer.java | 20 +- .../besu/ethereum/eth/manager/EthPeers.java | 375 +++++++++++++----- .../eth/manager/EthProtocolManager.java | 63 +-- .../ethereum/eth/manager/PeerRequest.java | 4 + .../eth/manager/PendingPeerRequest.java | 1 + .../snap/GetAccountRangeFromPeerTask.java | 39 +- .../manager/snap/GetBytecodeFromPeerTask.java | 32 +- .../snap/GetStorageRangeFromPeerTask.java | 41 +- .../manager/snap/GetTrieNodeFromPeerTask.java | 31 +- .../RetryingGetAccountRangeFromPeerTask.java | 6 + .../snap/RetryingGetBytecodeFromPeerTask.java | 5 + .../RetryingGetStorageRangeFromPeerTask.java | 5 + .../snap/RetryingGetTrieNodeFromPeerTask.java | 5 + .../eth/manager/snap/SnapProtocolManager.java | 6 - .../task/AbstractRetryingPeerTask.java | 20 +- .../AbstractRetryingSwitchingPeerTask.java | 17 +- .../ethereum/eth/sync/ChainHeadTracker.java | 75 ++-- .../eth/sync/DefaultSynchronizer.java | 7 +- .../ethereum/eth/sync/SnapServerChecker.java | 86 ++++ .../besu/ethereum/eth/sync/SyncMode.java | 4 + .../eth/sync/fastsync/SyncTargetManager.java | 9 +- .../ethereum/eth/manager/EthPeersTest.java | 89 ++++- .../eth/manager/EthProtocolManagerTest.java | 9 +- .../manager/EthProtocolManagerTestUtil.java | 69 +++- .../eth/manager/RespondingEthPeer.java | 36 +- .../ethtaskutils/AbstractMessageTaskTest.java | 7 +- .../AbstractBlockPropagationManagerTest.java | 11 +- .../eth/sync/ChainHeadTrackerTest.java | 6 +- .../fastsync/PivotBlockRetrieverTest.java | 6 +- .../ethereum/eth/transactions/TestNode.java | 28 +- .../TransactionPoolFactoryTest.java | 9 +- .../ethereum/p2p/network/NetworkRunner.java | 19 +- .../ethereum/p2p/network/ProtocolManager.java | 10 - .../rlpx/wire/messages/DisconnectMessage.java | 4 +- .../ethereum/retesteth/RetestethContext.java | 7 +- 42 files changed, 942 insertions(+), 318 deletions(-) create mode 100644 ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/SnapServerChecker.java diff --git a/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java b/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java index e9f9ef6268..7ed627cfc1 100644 --- a/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java @@ -688,13 +688,14 @@ public class RunnerBuilder { .map(nodePerms -> PeerPermissions.combine(nodePerms, defaultPeerPermissions)) .orElse(defaultPeerPermissions); + final EthPeers ethPeers = besuController.getEthPeers(); + LOG.info("Detecting NAT service."); final boolean fallbackEnabled = natMethod == NatMethod.AUTO || natMethodFallbackEnabled; final NatService natService = new NatService(buildNatManager(natMethod), fallbackEnabled); final NetworkBuilder inactiveNetwork = caps -> new NoopP2PNetwork(); final NetworkBuilder activeNetwork = caps -> { - final EthPeers ethPeers = besuController.getEthPeers(); return DefaultP2PNetwork.builder() .vertx(vertx) .nodeKey(nodeKey) @@ -709,8 +710,8 @@ public class RunnerBuilder { .blockchain(context.getBlockchain()) .blockNumberForks(besuController.getGenesisConfigOptions().getForkBlockNumbers()) .timestampForks(besuController.getGenesisConfigOptions().getForkBlockTimestamps()) - .allConnectionsSupplier(ethPeers::getAllConnections) - .allActiveConnectionsSupplier(ethPeers::getAllActiveConnections) + .allConnectionsSupplier(ethPeers::streamAllConnections) + .allActiveConnectionsSupplier(ethPeers::streamAllActiveConnections) .maxPeers(ethPeers.getMaxPeers()) .build(); }; @@ -721,9 +722,10 @@ public class RunnerBuilder { .subProtocols(subProtocols) .network(p2pEnabled ? activeNetwork : inactiveNetwork) .metricsSystem(metricsSystem) + .ethPeersShouldConnect(ethPeers::shouldTryToConnect) .build(); - besuController.getEthPeers().setRlpxAgent(networkRunner.getRlpxAgent()); + ethPeers.setRlpxAgent(networkRunner.getRlpxAgent()); final P2PNetwork network = networkRunner.getNetwork(); // ForkId in Ethereum Node Record needs updating when we transition to a new protocol spec 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 ac0fa25fd3..6123535f63 100644 --- a/besu/src/main/java/org/hyperledger/besu/controller/BesuControllerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/controller/BesuControllerBuilder.java @@ -46,7 +46,6 @@ import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.Difficulty; import org.hyperledger.besu.ethereum.core.MiningParameters; import org.hyperledger.besu.ethereum.core.PrivacyParameters; -import org.hyperledger.besu.ethereum.core.Synchronizer; import org.hyperledger.besu.ethereum.eth.EthProtocol; import org.hyperledger.besu.ethereum.eth.EthProtocolConfiguration; import org.hyperledger.besu.ethereum.eth.SnapProtocol; @@ -77,6 +76,7 @@ import org.hyperledger.besu.ethereum.eth.transactions.BlobCache; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolFactory; +import org.hyperledger.besu.ethereum.forkid.ForkIdManager; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; import org.hyperledger.besu.ethereum.p2p.config.NetworkingConfiguration; @@ -604,6 +604,12 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides final int maxMessageSize = ethereumWireProtocolConfiguration.getMaxMessageSize(); final Supplier currentProtocolSpecSupplier = () -> protocolSchedule.getByBlockHeader(blockchain.getChainHeadHeader()); + final ForkIdManager forkIdManager = + new ForkIdManager( + blockchain, + genesisConfigOptions.getForkBlockNumbers(), + genesisConfigOptions.getForkBlockTimestamps(), + ethereumWireProtocolConfiguration.isLegacyEth64ForkIdEnabled()); final EthPeers ethPeers = new EthPeers( getSupportedProtocol(), @@ -615,7 +621,9 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides nodeKey.getPublicKey().getEncodedBytes(), maxPeers, maxRemotelyInitiatedPeers, - randomPeerPriority); + randomPeerPriority, + syncConfig.getSyncMode(), + forkIdManager); final EthMessages ethMessages = new EthMessages(); final EthMessages snapMessages = new EthMessages(); @@ -681,13 +689,14 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides ethMessages, scheduler, peerValidators, - Optional.empty()); + Optional.empty(), + forkIdManager); final PivotBlockSelector pivotBlockSelector = createPivotSelector( protocolSchedule, protocolContext, ethContext, syncState, metricsSystem, blockchain); - final Synchronizer synchronizer = + final DefaultSynchronizer synchronizer = createSynchronizer( protocolSchedule, worldStateStorageCoordinator, @@ -697,6 +706,16 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides ethProtocolManager, pivotBlockSelector); + ethPeers.setTrailingPeerRequirementsSupplier(synchronizer::calculateTrailingPeerRequirements); + + if (SyncMode.isSnapSync(syncConfig.getSyncMode()) + || SyncMode.isCheckpointSync(syncConfig.getSyncMode())) { + synchronizer.subscribeInSync((b) -> ethPeers.snapServerPeersNeeded(!b)); + ethPeers.snapServerPeersNeeded(true); + } else { + ethPeers.snapServerPeersNeeded(false); + } + protocolContext.setSynchronizer(Optional.of(synchronizer)); final Optional maybeSnapProtocolManager = @@ -809,7 +828,7 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides * @param pivotBlockSelector the pivot block selector * @return the synchronizer */ - protected Synchronizer createSynchronizer( + protected DefaultSynchronizer createSynchronizer( final ProtocolSchedule protocolSchedule, final WorldStateStorageCoordinator worldStateStorageCoordinator, final ProtocolContext protocolContext, @@ -1000,6 +1019,7 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides * @param scheduler the scheduler * @param peerValidators the peer validators * @param mergePeerFilter the merge peer filter + * @param forkIdManager the fork id manager * @return the eth protocol manager */ protected EthProtocolManager createEthProtocolManager( @@ -1012,7 +1032,8 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides final EthMessages ethMessages, final EthScheduler scheduler, final List peerValidators, - final Optional mergePeerFilter) { + final Optional mergePeerFilter, + final ForkIdManager forkIdManager) { return new EthProtocolManager( protocolContext.getBlockchain(), networkId, @@ -1026,8 +1047,7 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides mergePeerFilter, synchronizerConfiguration, scheduler, - genesisConfigOptions.getForkBlockNumbers(), - genesisConfigOptions.getForkBlockTimestamps()); + forkIdManager); } /** diff --git a/besu/src/main/java/org/hyperledger/besu/controller/ConsensusScheduleBesuControllerBuilder.java b/besu/src/main/java/org/hyperledger/besu/controller/ConsensusScheduleBesuControllerBuilder.java index d138c96a24..af59a7625d 100644 --- a/besu/src/main/java/org/hyperledger/besu/controller/ConsensusScheduleBesuControllerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/controller/ConsensusScheduleBesuControllerBuilder.java @@ -49,6 +49,7 @@ import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration; import org.hyperledger.besu.ethereum.eth.sync.state.SyncState; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration; +import org.hyperledger.besu.ethereum.forkid.ForkIdManager; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.p2p.config.SubProtocolConfiguration; import org.hyperledger.besu.ethereum.storage.StorageProvider; @@ -242,7 +243,8 @@ public class ConsensusScheduleBesuControllerBuilder extends BesuControllerBuilde final EthMessages ethMessages, final EthScheduler scheduler, final List peerValidators, - final Optional mergePeerFilter) { + final Optional mergePeerFilter, + final ForkIdManager forkIdManager) { return besuControllerBuilderSchedule .get(0L) .createEthProtocolManager( @@ -255,7 +257,8 @@ public class ConsensusScheduleBesuControllerBuilder extends BesuControllerBuilde ethMessages, scheduler, peerValidators, - mergePeerFilter); + mergePeerFilter, + forkIdManager); } @Override diff --git a/besu/src/main/java/org/hyperledger/besu/controller/MergeBesuControllerBuilder.java b/besu/src/main/java/org/hyperledger/besu/controller/MergeBesuControllerBuilder.java index 1e8da674a5..cdd46ea5b9 100644 --- a/besu/src/main/java/org/hyperledger/besu/controller/MergeBesuControllerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/controller/MergeBesuControllerBuilder.java @@ -41,6 +41,7 @@ import org.hyperledger.besu.ethereum.eth.sync.backwardsync.BackwardChain; import org.hyperledger.besu.ethereum.eth.sync.backwardsync.BackwardSyncContext; import org.hyperledger.besu.ethereum.eth.sync.state.SyncState; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool; +import org.hyperledger.besu.ethereum.forkid.ForkIdManager; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ScheduleBasedBlockHeaderFunctions; import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; @@ -97,7 +98,8 @@ public class MergeBesuControllerBuilder extends BesuControllerBuilder { final EthMessages ethMessages, final EthScheduler scheduler, final List peerValidators, - final Optional mergePeerFilter) { + final Optional mergePeerFilter, + final ForkIdManager forkIdManager) { var mergeContext = protocolContext.getConsensusContext(MergeContext.class); @@ -126,7 +128,8 @@ public class MergeBesuControllerBuilder extends BesuControllerBuilder { ethMessages, scheduler, peerValidators, - filterToUse); + filterToUse, + forkIdManager); return ethProtocolManager; } diff --git a/besu/src/main/java/org/hyperledger/besu/controller/TransitionBesuControllerBuilder.java b/besu/src/main/java/org/hyperledger/besu/controller/TransitionBesuControllerBuilder.java index a2f52c90ee..4f084f3c13 100644 --- a/besu/src/main/java/org/hyperledger/besu/controller/TransitionBesuControllerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/controller/TransitionBesuControllerBuilder.java @@ -33,7 +33,6 @@ import org.hyperledger.besu.ethereum.chain.Blockchain; import org.hyperledger.besu.ethereum.chain.MutableBlockchain; import org.hyperledger.besu.ethereum.core.MiningParameters; import org.hyperledger.besu.ethereum.core.PrivacyParameters; -import org.hyperledger.besu.ethereum.core.Synchronizer; import org.hyperledger.besu.ethereum.eth.EthProtocolConfiguration; import org.hyperledger.besu.ethereum.eth.manager.EthContext; import org.hyperledger.besu.ethereum.eth.manager.EthMessages; @@ -49,6 +48,7 @@ import org.hyperledger.besu.ethereum.eth.sync.backwardsync.BackwardSyncContext; import org.hyperledger.besu.ethereum.eth.sync.state.SyncState; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration; +import org.hyperledger.besu.ethereum.forkid.ForkIdManager; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.storage.StorageProvider; import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; @@ -156,7 +156,8 @@ public class TransitionBesuControllerBuilder extends BesuControllerBuilder { final EthMessages ethMessages, final EthScheduler scheduler, final List peerValidators, - final Optional mergePeerFilter) { + final Optional mergePeerFilter, + final ForkIdManager forkIdManager) { return mergeBesuControllerBuilder.createEthProtocolManager( protocolContext, synchronizerConfiguration, @@ -167,7 +168,8 @@ public class TransitionBesuControllerBuilder extends BesuControllerBuilder { ethMessages, scheduler, peerValidators, - mergePeerFilter); + mergePeerFilter, + forkIdManager); } @Override @@ -212,7 +214,7 @@ public class TransitionBesuControllerBuilder extends BesuControllerBuilder { } @Override - protected Synchronizer createSynchronizer( + protected DefaultSynchronizer createSynchronizer( final ProtocolSchedule protocolSchedule, final WorldStateStorageCoordinator worldStateStorageCoordinator, final ProtocolContext protocolContext, @@ -222,15 +224,14 @@ public class TransitionBesuControllerBuilder extends BesuControllerBuilder { final PivotBlockSelector pivotBlockSelector) { DefaultSynchronizer sync = - (DefaultSynchronizer) - super.createSynchronizer( - protocolSchedule, - worldStateStorageCoordinator, - protocolContext, - ethContext, - syncState, - ethProtocolManager, - pivotBlockSelector); + super.createSynchronizer( + protocolSchedule, + worldStateStorageCoordinator, + protocolContext, + ethContext, + syncState, + ethProtocolManager, + pivotBlockSelector); if (genesisConfigOptions.getTerminalTotalDifficulty().isPresent()) { LOG.info( diff --git a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/protocol/BftProtocolManager.java b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/protocol/BftProtocolManager.java index 0ef72f95ed..0c0dd5f67d 100644 --- a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/protocol/BftProtocolManager.java +++ b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/protocol/BftProtocolManager.java @@ -20,7 +20,6 @@ import org.hyperledger.besu.consensus.common.bft.events.BftEvents; import org.hyperledger.besu.consensus.common.bft.network.PeerConnectionTracker; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.ethereum.p2p.network.ProtocolManager; -import org.hyperledger.besu.ethereum.p2p.peers.Peer; import org.hyperledger.besu.ethereum.p2p.rlpx.connections.PeerConnection; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.Capability; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.Message; @@ -108,11 +107,6 @@ public class BftProtocolManager implements ProtocolManager { peers.add(peerConnection); } - @Override - public boolean shouldConnect(final Peer peer, final boolean incoming) { - return false; // for now the EthProtocolManager takes care of this - } - @Override public void handleDisconnect( final PeerConnection peerConnection, diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/forkid/ForkIdManager.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/forkid/ForkIdManager.java index bae8cfc339..859fb918a4 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/forkid/ForkIdManager.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/forkid/ForkIdManager.java @@ -58,7 +58,11 @@ public class ForkIdManager { checkNotNull(blockchain); checkNotNull(blockNumberForks); this.chainHeadSupplier = blockchain::getChainHeadHeader; - this.genesisHash = blockchain.getGenesisBlock().getHash(); + try { + this.genesisHash = blockchain.getGenesisBlock().getHash(); + } catch (Exception e) { + throw new RuntimeException(e); + } this.blockNumbersForkIds = new ArrayList<>(); this.timestampsForkIds = new ArrayList<>(); this.legacyEth64 = legacyEth64; diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/EthPeer.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/EthPeer.java index e0f0517f1e..8cc907d686 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/EthPeer.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/EthPeer.java @@ -103,6 +103,7 @@ public class EthPeer implements Comparable { private final PeerReputation reputation = new PeerReputation(); private final Map validationStatus = new ConcurrentHashMap<>(); private final Bytes id; + private boolean isServingSnap = false; private static final Map roundMessages; @@ -393,6 +394,14 @@ public class EthPeer implements Comparable { requestManagers.get(SnapProtocol.NAME).get(SnapV1.GET_TRIE_NODES), getTrieNodes); } + public void setIsServingSnap(final boolean isServingSnap) { + this.isServingSnap = isServingSnap; + } + + public boolean isServingSnap() { + return isServingSnap; + } + private RequestManager.ResponseStream sendRequest( final RequestManager requestManager, final MessageData messageData) throws PeerNotConnected { lastRequestTimestamp = clock.millis(); @@ -582,9 +591,9 @@ public class EthPeer implements Comparable { } /** - * Return A read-only snapshot of this peer's current {@code chainState} } + * Return A read-only snapshot of this peer's current {@code chainState} * - * @return A read-only snapshot of this peer's current {@code chainState} } + * @return A read-only snapshot of this peer's current {@code chainState} */ public ChainHeadEstimate chainStateSnapshot() { return chainHeadState.getSnapshot(); @@ -629,14 +638,17 @@ public class EthPeer implements Comparable { @Override public String toString() { return String.format( - "PeerId: %s %s, validated? %s, disconnected? %s, client: %s, %s, %s", + "PeerId: %s %s, validated? %s, disconnected? %s, client: %s, %s, %s, isServingSnap %s, has height %s, connected for %s ms", getLoggableId(), reputation, isFullyValidated(), isDisconnected(), connection.getPeerInfo().getClientId(), connection, - connection.getPeer().getEnodeURLString()); + connection.getPeer().getEnodeURLString(), + isServingSnap, + chainHeadState.getEstimatedHeight(), + System.currentTimeMillis() - connection.getInitiatedAt()); } @Nonnull 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 bef7a1a038..851c075290 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 @@ -14,8 +14,16 @@ */ 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.peervalidation.PeerValidator; +import org.hyperledger.besu.ethereum.eth.sync.ChainHeadTracker; +import org.hyperledger.besu.ethereum.eth.sync.SnapServerChecker; +import org.hyperledger.besu.ethereum.eth.sync.SyncMode; +import org.hyperledger.besu.ethereum.eth.sync.TrailingPeerRequirements; +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.rlpx.RlpxAgent; @@ -35,8 +43,10 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.TimeUnit; import java.util.function.Predicate; import java.util.function.Supplier; import java.util.stream.Collectors; @@ -72,7 +82,7 @@ public class EthPeers { public static final int NODE_ID_LENGTH = 64; public static final int USEFULL_PEER_SCORE_THRESHOLD = 102; - private final Map completeConnections = new ConcurrentHashMap<>(); + private final Map activeConnections = new ConcurrentHashMap<>(); private final Cache incompleteConnections = CacheBuilder.newBuilder() @@ -92,12 +102,22 @@ public class EthPeers { private final Boolean randomPeerPriority; private final Bytes nodeIdMask = Bytes.random(NODE_ID_LENGTH); private final Supplier currentProtocolSpecSupplier; + private final SyncMode syncMode; + private final ForkIdManager forkIdManager; + private final int snapServerTargetNumber; + private final boolean shouldLimitRemoteConnections; private Comparator bestPeerComparator; private final Bytes localNodeId; private RlpxAgent rlpxAgent; private final Counter connectedPeersCounter; + // private List protocolManagers; + private ChainHeadTracker tracker; + private SnapServerChecker snapServerChecker; + private boolean snapServerPeersNeeded = false; + private Supplier trailingPeerRequirementsSupplier = + () -> TrailingPeerRequirements.UNRESTRICTED; public EthPeers( final String protocolName, @@ -109,7 +129,9 @@ public class EthPeers { final Bytes localNodeId, final int peerUpperBound, final int maxRemotelyInitiatedConnections, - final Boolean randomPeerPriority) { + final Boolean randomPeerPriority, + final SyncMode syncMode, + final ForkIdManager forkIdManager) { this.protocolName = protocolName; this.currentProtocolSpecSupplier = currentProtocolSpecSupplier; this.clock = clock; @@ -121,11 +143,22 @@ public class EthPeers { this.maxRemotelyInitiatedConnections = maxRemotelyInitiatedConnections; this.randomPeerPriority = randomPeerPriority; LOG.trace("MaxPeers: {}, Max Remote: {}", peerUpperBound, maxRemotelyInitiatedConnections); + this.syncMode = syncMode; + this.forkIdManager = forkIdManager; + this.snapServerTargetNumber = + peerUpperBound / 2; // 50% of peers should be snap servers while snap syncing + this.shouldLimitRemoteConnections = maxRemotelyInitiatedConnections < peerUpperBound; + metricsSystem.createIntegerGauge( BesuMetricCategory.ETHEREUM, "peer_count", "The current number of peers connected", - () -> (int) streamAvailablePeers().filter(p -> p.readyForRequests()).count()); + activeConnections::size); + metricsSystem.createIntegerGauge( + BesuMetricCategory.ETHEREUM, + "peer_count_snap_server", + "The current number of peers connected that serve snap data", + () -> (int) streamAvailablePeers().filter(EthPeer::isServingSnap).count()); metricsSystem.createIntegerGauge( BesuMetricCategory.PEERS, "pending_peer_requests_current", @@ -146,7 +179,7 @@ public class EthPeers { final PeerConnection newConnection, final List peerValidators) { final Bytes id = newConnection.getPeer().getId(); synchronized (this) { - EthPeer ethPeer = completeConnections.get(id); + EthPeer ethPeer = activeConnections.get(id); if (ethPeer == null) { final Optional peerInList = incompleteConnections.asMap().values().stream() @@ -193,12 +226,12 @@ public class EthPeers { if (peer.getConnection().equals(connection)) { final Bytes id = peer.getId(); if (!peerHasIncompleteConnection(id)) { - removed = completeConnections.remove(id, peer); + removed = activeConnections.remove(id, peer); disconnectCallbacks.forEach(callback -> callback.onDisconnect(peer)); peer.handleDisconnect(); abortPendingRequestsAssignedToDisconnectedPeers(); if (peer.getReputation().getScore() > USEFULL_PEER_SCORE_THRESHOLD) { - LOG.atDebug().setMessage("Disconnected USEFULL peer {}").addArgument(peer).log(); + LOG.atDebug().setMessage("Disconnected USEFUL peer {}").addArgument(peer).log(); } else { LOG.atDebug() .setMessage("Disconnected EthPeer {}") @@ -227,7 +260,7 @@ public class EthPeers { public EthPeer peer(final PeerConnection connection) { final EthPeer ethPeer = incompleteConnections.getIfPresent(connection); - return ethPeer != null ? ethPeer : completeConnections.get(connection.getPeer().getId()); + return ethPeer != null ? ethPeer : activeConnections.get(connection.getPeer().getId()); } public PendingPeerRequest executePeerRequest( @@ -265,7 +298,7 @@ public class EthPeers { @VisibleForTesting void reattemptPendingPeerRequests() { synchronized (this) { - final List peers = streamAvailablePeers().collect(Collectors.toList()); + final List peers = streamAvailablePeers().toList(); final Iterator iterator = pendingRequests.iterator(); while (iterator.hasNext() && peers.stream().anyMatch(EthPeer::hasAvailableRequestCapacity)) { final PendingPeerRequest request = iterator.next(); @@ -290,7 +323,7 @@ public class EthPeers { public int peerCount() { removeDisconnectedPeers(); - return completeConnections.size(); + return activeConnections.size(); } public int getMaxPeers() { @@ -298,11 +331,11 @@ public class EthPeers { } public Stream streamAllPeers() { - return completeConnections.values().stream(); + return activeConnections.values().stream(); } private void removeDisconnectedPeers() { - completeConnections + activeConnections .values() .forEach( ep -> { @@ -313,9 +346,7 @@ public class EthPeers { } public Stream streamAvailablePeers() { - return streamAllPeers() - .filter(EthPeer::readyForRequests) - .filter(peer -> !peer.isDisconnected()); + return streamAllPeers().filter(peer -> !peer.isDisconnected()); } public Stream streamBestPeers() { @@ -350,53 +381,59 @@ public class EthPeers { this.rlpxAgent = rlpxAgent; } - public Stream getAllActiveConnections() { - return completeConnections.values().stream() + public Stream streamAllActiveConnections() { + return activeConnections.values().stream() .map(EthPeer::getConnection) .filter(c -> !c.isDisconnected()); } - public Stream getAllConnections() { + public Stream streamAllConnections() { return Stream.concat( - completeConnections.values().stream().map(EthPeer::getConnection), + activeConnections.values().stream().map(EthPeer::getConnection), incompleteConnections.asMap().keySet().stream()) .distinct() .filter(c -> !c.isDisconnected()); } - public boolean shouldConnect(final Peer peer, final boolean inbound) { + public boolean shouldTryToConnect(final Peer peer, final boolean inbound) { + + if (peer.getForkId().isPresent()) { + final ForkId forkId = peer.getForkId().get(); + if (!forkIdManager.peerCheck(forkId)) { + LOG.atDebug() + .setMessage("Wrong fork id, not trying to connect to peer {}") + .addArgument(peer::getId) + .log(); + + return false; + } + } + final Bytes id = peer.getId(); - if (peerCount() >= peerUpperBound && !canExceedPeerLimits(id)) { + if (alreadyConnectedOrConnecting(inbound, id)) { LOG.atTrace() - .setMessage("not connecting to peer {} - too many peers") + .setMessage("not connecting to peer {} - already connected") .addArgument(peer.getLoggableId()) .log(); return false; } - final EthPeer ethPeer = completeConnections.get(id); + + return peerCount() < getMaxPeers() || needMoreSnapServers() || canExceedPeerLimits(id); + } + + private boolean alreadyConnectedOrConnecting(final boolean inbound, final Bytes id) { + final EthPeer ethPeer = activeConnections.get(id); if (ethPeer != null && !ethPeer.isDisconnected()) { - LOG.atTrace() - .setMessage("not connecting to peer {} - already disconnected") - .addArgument(ethPeer.getLoggableId()) - .log(); - return false; + return true; } final List incompleteConnections = getIncompleteConnections(id); - if (!incompleteConnections.isEmpty()) { - if (incompleteConnections.stream() - .anyMatch(c -> !c.isDisconnected() && (!inbound || (inbound && c.inboundInitiated())))) { - LOG.atTrace() - .setMessage("not connecting to peer {} - new connection already in process") - .addArgument(peer.getLoggableId()) - .log(); - return false; - } - } - return true; + return incompleteConnections.stream() + .anyMatch(c -> !c.isDisconnected() && (!inbound || (inbound && c.inboundInitiated()))); } public void disconnectWorstUselessPeer() { streamAvailablePeers() + .filter(p -> !canExceedPeerLimits(p.getId())) .min(getBestPeerComparator()) .ifPresent( peer -> { @@ -411,6 +448,23 @@ public class EthPeers { }); } + public void setChainHeadTracker(final ChainHeadTracker tracker) { + this.tracker = tracker; + } + + public void setSnapServerChecker(final SnapServerChecker checker) { + this.snapServerChecker = checker; + } + + public void snapServerPeersNeeded(final boolean b) { + this.snapServerPeersNeeded = b; + } + + public void setTrailingPeerRequirementsSupplier( + final Supplier tprSupplier) { + this.trailingPeerRequirementsSupplier = tprSupplier; + } + @FunctionalInterface public interface ConnectCallback { void onPeerConnected(EthPeer newPeer); @@ -418,21 +472,108 @@ public class EthPeers { @Override public String toString() { - if (completeConnections.isEmpty()) { + if (activeConnections.isEmpty()) { return "0 EthPeers {}"; } final String connectionsList = - completeConnections.values().stream() + activeConnections.values().stream() .sorted() .map(EthPeer::toString) .collect(Collectors.joining(", \n")); - return completeConnections.size() + " EthPeers {\n" + connectionsList + '}'; + return activeConnections.size() + " EthPeers {\n" + connectionsList + '}'; } private void ethPeerStatusExchanged(final EthPeer peer) { - if (addPeerToEthPeers(peer)) { - connectedPeersCounter.inc(); - connectCallbacks.forEach(cb -> cb.onPeerConnected(peer)); + // We have a connection to a peer that is on the right chain and is willing to connect to us. + // Find out what the EthPeer block height is and whether it can serve snap data (if we are doing + // snap sync) + LOG.debug("Peer {} status exchanged", peer); + assert tracker != null : "ChainHeadTracker must be set before EthPeers can be used"; + CompletableFuture future = tracker.getBestHeaderFromPeer(peer); + + future.whenComplete( + (peerHeadBlockHeader, error) -> { + if (peerHeadBlockHeader == null) { + LOG.debug( + "Failed to retrieve chain head info. Disconnecting {}... {}", + peer.getLoggableId(), + error); + peer.disconnect( + DisconnectMessage.DisconnectReason.USELESS_PEER_FAILED_TO_RETRIEVE_CHAIN_HEAD); + } else { + + // we can check trailing peers now + final TrailingPeerRequirements trailingPeerRequirements = + trailingPeerRequirementsSupplier.get(); + if (trailingPeerRequirements != null) { + if (peer.chainState().getEstimatedHeight() + < trailingPeerRequirements.getMinimumHeightToBeUpToDate()) { + if (!(getNumTrailingPeers(trailingPeerRequirements.getMinimumHeightToBeUpToDate()) + < trailingPeerRequirements.getMaxTrailingPeers())) { + LOG.atTrace() + .setMessage( + "Adding trailing peer {} would exceed max trailing peers {}. Disconnecting...") + .addArgument(peer.getLoggableId()) + .addArgument(trailingPeerRequirements.getMaxTrailingPeers()) + .log(); + peer.disconnect( + DisconnectMessage.DisconnectReason.USELESS_PEER_EXCEEDS_TRAILING_PEERS); + return; + } + } + } + + peer.chainState().updateHeightEstimate(peerHeadBlockHeader.getNumber()); + CompletableFuture isServingSnapFuture; + if (SyncMode.isCheckpointSync(syncMode) || SyncMode.isSnapSync(syncMode)) { + // even if we have finished the snap sync, we still want to know if the peer is a snap + // server + isServingSnapFuture = + CompletableFuture.runAsync( + () -> { + try { + checkIsSnapServer(peer, peerHeadBlockHeader); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + } else { + isServingSnapFuture = CompletableFuture.completedFuture(null); + } + isServingSnapFuture.thenRun( + () -> { + if (!peer.getConnection().isDisconnected() && addPeerToEthPeers(peer)) { + connectedPeersCounter.inc(); + connectCallbacks.forEach(cb -> cb.onPeerConnected(peer)); + } + }); + } + }); + } + + private void checkIsSnapServer(final EthPeer peer, final BlockHeader peersHeadBlockHeader) { + if (peer.getAgreedCapabilities().contains(SnapProtocol.SNAP1)) { + if (snapServerChecker != null) { + // set that peer is a snap server for doing the test + peer.setIsServingSnap(true); + Boolean isServer; + try { + isServer = snapServerChecker.check(peer, peersHeadBlockHeader).get(6L, TimeUnit.SECONDS); + } catch (Exception e) { + LOG.atTrace() + .setMessage("Error checking if peer {} is a snap server. Setting to false.") + .addArgument(peer.getLoggableId()) + .log(); + peer.setIsServingSnap(false); + return; + } + peer.setIsServingSnap(isServer); + LOG.atTrace() + .setMessage("{}: peer {}") + .addArgument(isServer ? "Is a snap server" : "Is NOT a snap server") + .addArgument(peer.getLoggableId()) + .log(); + } } } @@ -468,7 +609,7 @@ public class EthPeers { } private void enforceRemoteConnectionLimits() { - if (!shouldLimitRemoteConnections() || peerCount() < maxRemotelyInitiatedConnections) { + if (!shouldLimitRemoteConnections || peerCount() < maxRemotelyInitiatedConnections) { // Nothing to do return; } @@ -488,7 +629,7 @@ public class EthPeers { } private Stream getActivePrioritizedPeers() { - return completeConnections.values().stream() + return activeConnections.values().stream() .filter(p -> !p.isDisconnected()) .sorted(this::comparePeerPriorities); } @@ -512,19 +653,15 @@ public class EthPeers { }); } - private boolean remoteConnectionLimitReached() { - return shouldLimitRemoteConnections() - && countUntrustedRemotelyInitiatedConnections() >= maxRemotelyInitiatedConnections; - } - - private boolean shouldLimitRemoteConnections() { - return maxRemotelyInitiatedConnections < peerUpperBound; + private boolean inboundInitiatedConnectionLimitExceeded() { + return shouldLimitRemoteConnections + && countUntrustedRemotelyInitiatedConnections() > maxRemotelyInitiatedConnections; } private long countUntrustedRemotelyInitiatedConnections() { - return completeConnections.values().stream() - .map(ep -> ep.getConnection()) - .filter(c -> c.inboundInitiated()) + return activeConnections.values().stream() + .map(EthPeer::getConnection) + .filter(PeerConnection::inboundInitiated) .filter(c -> !c.isDisconnected()) .filter(conn -> !canExceedPeerLimits(conn.getPeer().getId())) .count(); @@ -534,67 +671,123 @@ public class EthPeers { final RemovalNotification removalNotification) { if (removalNotification.wasEvicted()) { final PeerConnection peerConnectionRemoved = removalNotification.getKey(); - final PeerConnection peerConnectionOfEthPeer = removalNotification.getValue().getConnection(); - if (!peerConnectionRemoved.equals(peerConnectionOfEthPeer)) { - // If this connection is not the connection of the EthPeer by now we can disconnect - peerConnectionRemoved.disconnect(DisconnectMessage.DisconnectReason.ALREADY_CONNECTED); + final EthPeer peer = removalNotification.getValue(); + if (peer == null) { + return; + } + final PeerConnection peerConnectionOfEthPeer = peer.getConnection(); + if (peerConnectionRemoved != null) { + if (!peerConnectionRemoved.equals(peerConnectionOfEthPeer)) { + // If this connection is not the connection of the EthPeer by now we can disconnect + peerConnectionRemoved.disconnect(DisconnectMessage.DisconnectReason.ALREADY_CONNECTED); + } } } } - private boolean addPeerToEthPeers(final EthPeer peer) { + boolean addPeerToEthPeers(final EthPeer peer) { // We have a connection to a peer that is on the right chain and is willing to connect to us. - // Figure out whether we want to keep this peer and add it to the EthPeers connections. - if (completeConnections.containsValue(peer)) { + // Figure out whether we want to add it to the active connections. + final PeerConnection connection = peer.getConnection(); + if (activeConnections.containsValue(peer)) { return false; } - final PeerConnection connection = peer.getConnection(); + final Bytes id = peer.getId(); if (!randomPeerPriority) { - // Disconnect if too many peers - if (!canExceedPeerLimits(id) && peerCount() >= peerUpperBound) { - LOG.atTrace() - .setMessage("Too many peers. Disconnect connection: {}, max connections {}") - .addArgument(connection) - .addArgument(peerUpperBound) - .log(); - connection.disconnect(DisconnectMessage.DisconnectReason.TOO_MANY_PEERS); - return false; - } - // Disconnect if too many remotely-initiated connections - if (connection.inboundInitiated() - && !canExceedPeerLimits(id) - && remoteConnectionLimitReached()) { - LOG.atTrace() - .setMessage( - "Too many remotely-initiated connections. Disconnect incoming connection: {}, maxRemote={}") - .addArgument(connection) - .addArgument(maxRemotelyInitiatedConnections) - .log(); - connection.disconnect(DisconnectMessage.DisconnectReason.TOO_MANY_PEERS); - return false; + + if (peerCount() >= peerUpperBound) { + final long numSnapServers = numberOfSnapServers(); + final boolean inboundLimitExceeded = inboundInitiatedConnectionLimitExceeded(); + // three reasons why we would disconnect an existing peer to accommodate the new peer + if (canExceedPeerLimits(id) + || (snapServerPeersNeeded + && numSnapServers < snapServerTargetNumber + && peer.isServingSnap()) + || (inboundLimitExceeded && !peer.getConnection().inboundInitiated())) { + + final boolean filterOutSnapServers = + snapServerPeersNeeded && (numSnapServers <= snapServerTargetNumber); + + // find and disconnect the least useful peer we can disconnect + activeConnections.values().stream() + .filter(p -> !canExceedPeerLimits(p.getId())) + .filter(filterOutSnapServers ? p -> !p.isServingSnap() : p -> true) + .filter(inboundLimitExceeded ? p -> p.getConnection().inboundInitiated() : p -> true) + .min(MOST_USEFUL_PEER) + .ifPresentOrElse( + pe -> { + pe.disconnect(DisconnectMessage.DisconnectReason.TOO_MANY_PEERS); + LOG.atTrace() + .setMessage("Disconnecting peer {} to be replaced by prioritised peer {}") + .addArgument(pe.getLoggableId()) + .addArgument(peer.getLoggableId()) + .log(); + }, + () -> // disconnect the least useful peer + activeConnections.values().stream() + .filter(p -> !canExceedPeerLimits(p.getId())) + .min(MOST_USEFUL_PEER) + .ifPresent( + p -> { + p.disconnect(DisconnectMessage.DisconnectReason.TOO_MANY_PEERS); + LOG.atTrace() + .setMessage( + "Disconnecting peer {} to be replaced by prioritised peer {}") + .addArgument(p.getLoggableId()) + .addArgument(peer.getLoggableId()) + .log(); + })); + } else { + LOG.atTrace() + .setMessage( + "Too many peers. Disconnect peer {} with connection: {}, max connections {}") + .addArgument(peer.getLoggableId()) + .addArgument(connection) + .addArgument(peerUpperBound) + .log(); + connection.disconnect(DisconnectMessage.DisconnectReason.TOO_MANY_PEERS); + return false; + } } - final boolean added = (completeConnections.putIfAbsent(id, peer) == null); + + final boolean added = (activeConnections.putIfAbsent(id, peer) == null); if (added) { LOG.atTrace() - .setMessage("Added peer {} with connection {} to completeConnections") + .setMessage("Added peer {} with connection {} to activeConnections") .addArgument(id) .addArgument(connection) .log(); } else { LOG.atTrace() - .setMessage("Did not add peer {} with connection {} to completeConnections") + .setMessage("Did not add peer {} with connection {} to activeConnections") .addArgument(id) .addArgument(connection) .log(); } return added; + } else { // randomPeerPriority! Add the peer and if there are too many connections fix it - completeConnections.putIfAbsent(id, peer); + // TODO: random peer priority does not care yet about snap server peers -> check later + activeConnections.putIfAbsent(id, peer); enforceRemoteConnectionLimits(); enforceConnectionLimits(); - return completeConnections.containsKey(id); + return activeConnections.containsKey(id); } } + + private long getNumTrailingPeers(final long minimumHeightToBeUpToDate) { + return streamAvailablePeers() + .filter(p -> p.chainState().getEstimatedHeight() < minimumHeightToBeUpToDate) + .count(); + } + + private boolean needMoreSnapServers() { + return snapServerPeersNeeded && numberOfSnapServers() < snapServerTargetNumber; + } + + private long numberOfSnapServers() { + return activeConnections.values().stream().filter(EthPeer::isServingSnap).count(); + } } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/EthProtocolManager.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/EthProtocolManager.java index c8781e73e3..5532bed865 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/EthProtocolManager.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/EthProtocolManager.java @@ -34,7 +34,6 @@ import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool; import org.hyperledger.besu.ethereum.forkid.ForkId; import org.hyperledger.besu.ethereum.forkid.ForkIdManager; import org.hyperledger.besu.ethereum.p2p.network.ProtocolManager; -import org.hyperledger.besu.ethereum.p2p.peers.Peer; import org.hyperledger.besu.ethereum.p2p.rlpx.connections.PeerConnection; import org.hyperledger.besu.ethereum.p2p.rlpx.connections.PeerConnection.PeerNotConnected; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.Capability; @@ -161,41 +160,6 @@ public class EthProtocolManager implements ProtocolManager, MinedBlockObserver { ethereumWireProtocolConfiguration.isLegacyEth64ForkIdEnabled())); } - public EthProtocolManager( - final Blockchain blockchain, - final BigInteger networkId, - final WorldStateArchive worldStateArchive, - final TransactionPool transactionPool, - final EthProtocolConfiguration ethereumWireProtocolConfiguration, - final EthPeers ethPeers, - final EthMessages ethMessages, - final EthContext ethContext, - final List peerValidators, - final Optional mergePeerFilter, - final SynchronizerConfiguration synchronizerConfiguration, - final EthScheduler scheduler, - final List blockNumberForks, - final List timestampForks) { - this( - blockchain, - networkId, - worldStateArchive, - transactionPool, - ethereumWireProtocolConfiguration, - ethPeers, - ethMessages, - ethContext, - peerValidators, - mergePeerFilter, - synchronizerConfiguration, - scheduler, - new ForkIdManager( - blockchain, - blockNumberForks, - timestampForks, - ethereumWireProtocolConfiguration.isLegacyEth64ForkIdEnabled())); - } - public EthContext ethContext() { return ethContext; } @@ -398,28 +362,6 @@ public class EthProtocolManager implements ProtocolManager, MinedBlockObserver { LOG.atTrace().setMessage("{}").addArgument(ethPeers::toString).log(); } - @Override - public boolean shouldConnect(final Peer peer, final boolean incoming) { - if (peer.getForkId().map(forkIdManager::peerCheck).orElse(true)) { - LOG.atDebug() - .setMessage("ForkId OK or not available for peer {}") - .addArgument(peer::getLoggableId) - .log(); - if (ethPeers.shouldConnect(peer, incoming)) { - return true; - } - } else { - LOG.atDebug() - .setMessage("ForkId check failed for peer {} our fork id {} theirs {}") - .addArgument(peer::getLoggableId) - .addArgument(forkIdManager.getForkIdForChainHead()) - .addArgument(peer.getForkId()) - .log(); - return false; - } - return false; - } - @Override public void handleDisconnect( final PeerConnection connection, @@ -427,11 +369,10 @@ public class EthProtocolManager implements ProtocolManager, MinedBlockObserver { final boolean initiatedByPeer) { final boolean wasActiveConnection = ethPeers.registerDisconnect(connection); LOG.atDebug() - .setMessage("Disconnect - active Connection? {} - {} - {} {} - {} {} - {} peers left") + .setMessage("Disconnect - active Connection? {} - {} - {} - {} {} - {} peers left") .addArgument(wasActiveConnection) .addArgument(initiatedByPeer ? "Inbound" : "Outbound") - .addArgument(reason::getValue) - .addArgument(reason::name) + .addArgument(reason::toString) .addArgument(() -> connection.getPeer().getLoggableId()) .addArgument(() -> connection.getPeerInfo().getClientId()) .addArgument(ethPeers::peerCount) diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/PeerRequest.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/PeerRequest.java index 09cbdb969d..5daad56b9b 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/PeerRequest.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/PeerRequest.java @@ -19,4 +19,8 @@ import org.hyperledger.besu.ethereum.p2p.rlpx.connections.PeerConnection.PeerNot public interface PeerRequest { ResponseStream sendRequest(EthPeer peer) throws PeerNotConnected; + + default boolean isEthPeerSuitable(final EthPeer ethPeer) { + return true; + } } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/PendingPeerRequest.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/PendingPeerRequest.java index 120b32bdfe..71da1e4d2d 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/PendingPeerRequest.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/PendingPeerRequest.java @@ -86,6 +86,7 @@ public class PendingPeerRequest { : ethPeers .streamAvailablePeers() .filter(peer -> peer.chainState().getEstimatedHeight() >= minimumBlockNumber) + .filter(request::isEthPeerSuitable) .min(EthPeers.LEAST_TO_MOST_BUSY); } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/GetAccountRangeFromPeerTask.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/GetAccountRangeFromPeerTask.java index 75a6183eb4..8e67ff4aeb 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/GetAccountRangeFromPeerTask.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/GetAccountRangeFromPeerTask.java @@ -17,10 +17,13 @@ package org.hyperledger.besu.ethereum.eth.manager.snap; import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.eth.manager.EthContext; import org.hyperledger.besu.ethereum.eth.manager.EthPeer; +import org.hyperledger.besu.ethereum.eth.manager.PeerRequest; import org.hyperledger.besu.ethereum.eth.manager.PendingPeerRequest; +import org.hyperledger.besu.ethereum.eth.manager.RequestManager; import org.hyperledger.besu.ethereum.eth.manager.task.AbstractPeerRequestTask; import org.hyperledger.besu.ethereum.eth.messages.snap.AccountRangeMessage; import org.hyperledger.besu.ethereum.eth.messages.snap.SnapV1; +import org.hyperledger.besu.ethereum.p2p.rlpx.connections.PeerConnection; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.MessageData; import org.hyperledger.besu.plugin.services.MetricsSystem; @@ -64,14 +67,34 @@ public class GetAccountRangeFromPeerTask @Override protected PendingPeerRequest sendRequest() { return sendRequestToPeer( - peer -> { - LOG.trace( - "Requesting account range [{} ,{}] for state root {} from peer {} .", - startKeyHash, - endKeyHash, - blockHeader.getStateRoot(), - peer); - return peer.getSnapAccountRange(blockHeader.getStateRoot(), startKeyHash, endKeyHash); + new PeerRequest() { + @Override + public RequestManager.ResponseStream sendRequest(final EthPeer peer) + throws PeerConnection.PeerNotConnected { + LOG.atTrace() + .setMessage("Requesting account range [{} ,{}] for state root {} from peer {} .") + .addArgument(startKeyHash) + .addArgument(endKeyHash) + .addArgument(blockHeader) + .addArgument(peer) + .log(); + if (!peer.isServingSnap()) { + LOG.atDebug() + .setMessage("EthPeer that is not serving snap called in {}, peer: {}") + .addArgument(GetAccountRangeFromPeerTask.class) + .addArgument(peer) + .log(); + throw new RuntimeException( + "EthPeer that is not serving snap called in " + + GetAccountRangeFromPeerTask.class); + } + return peer.getSnapAccountRange(blockHeader.getStateRoot(), startKeyHash, endKeyHash); + } + + @Override + public boolean isEthPeerSuitable(final EthPeer ethPeer) { + return ethPeer.isServingSnap(); + } }, blockHeader.getNumber()); } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/GetBytecodeFromPeerTask.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/GetBytecodeFromPeerTask.java index d57acc590c..1c8c1d12d7 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/GetBytecodeFromPeerTask.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/GetBytecodeFromPeerTask.java @@ -21,10 +21,13 @@ import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.eth.manager.EthContext; import org.hyperledger.besu.ethereum.eth.manager.EthPeer; +import org.hyperledger.besu.ethereum.eth.manager.PeerRequest; import org.hyperledger.besu.ethereum.eth.manager.PendingPeerRequest; +import org.hyperledger.besu.ethereum.eth.manager.RequestManager; import org.hyperledger.besu.ethereum.eth.manager.task.AbstractPeerRequestTask; import org.hyperledger.besu.ethereum.eth.messages.snap.ByteCodesMessage; import org.hyperledger.besu.ethereum.eth.messages.snap.SnapV1; +import org.hyperledger.besu.ethereum.p2p.rlpx.connections.PeerConnection; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.MessageData; import org.hyperledger.besu.plugin.services.MetricsSystem; @@ -66,9 +69,32 @@ public class GetBytecodeFromPeerTask extends AbstractPeerRequestTask { - LOG.trace("Requesting {} Bytecodes from {} .", codeHashes.size(), peer); - return peer.getSnapBytecode(blockHeader.getStateRoot(), codeHashes); + new PeerRequest() { + @Override + public RequestManager.ResponseStream sendRequest(final EthPeer peer) + throws PeerConnection.PeerNotConnected { + LOG.atTrace() + .setMessage("Requesting {} Bytecodes from {} .") + .addArgument(codeHashes.size()) + .addArgument(peer) + .log(); + if (!peer.isServingSnap()) { + LOG.atDebug() + .setMessage("EthPeer that is not serving snap called in {}, peer: {}") + .addArgument(GetAccountRangeFromPeerTask.class) + .addArgument(peer) + .log(); + throw new RuntimeException( + "EthPeer that is not serving snap called in " + + GetAccountRangeFromPeerTask.class); + } + return peer.getSnapBytecode(blockHeader.getStateRoot(), codeHashes); + } + + @Override + public boolean isEthPeerSuitable(final EthPeer ethPeer) { + return ethPeer.isServingSnap(); + } }, blockHeader.getNumber()); } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/GetStorageRangeFromPeerTask.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/GetStorageRangeFromPeerTask.java index bcc8f23ebd..cb3e4c83ea 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/GetStorageRangeFromPeerTask.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/GetStorageRangeFromPeerTask.java @@ -17,10 +17,13 @@ package org.hyperledger.besu.ethereum.eth.manager.snap; import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.eth.manager.EthContext; import org.hyperledger.besu.ethereum.eth.manager.EthPeer; +import org.hyperledger.besu.ethereum.eth.manager.PeerRequest; import org.hyperledger.besu.ethereum.eth.manager.PendingPeerRequest; +import org.hyperledger.besu.ethereum.eth.manager.RequestManager; import org.hyperledger.besu.ethereum.eth.manager.task.AbstractPeerRequestTask; import org.hyperledger.besu.ethereum.eth.messages.snap.SnapV1; import org.hyperledger.besu.ethereum.eth.messages.snap.StorageRangeMessage; +import org.hyperledger.besu.ethereum.p2p.rlpx.connections.PeerConnection; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.MessageData; import org.hyperledger.besu.plugin.services.MetricsSystem; @@ -69,15 +72,35 @@ public class GetStorageRangeFromPeerTask @Override protected PendingPeerRequest sendRequest() { return sendRequestToPeer( - peer -> { - LOG.trace( - "Requesting storage range [{} ,{}] for {} accounts from peer {} .", - startKeyHash, - endKeyHash, - accountHashes.size(), - peer); - return peer.getSnapStorageRange( - blockHeader.getStateRoot(), accountHashes, startKeyHash, endKeyHash); + new PeerRequest() { + @Override + public RequestManager.ResponseStream sendRequest(final EthPeer peer) + throws PeerConnection.PeerNotConnected { + LOG.atTrace() + .setMessage("Requesting storage range [{} ,{}] for {} accounts from peer {} .") + .addArgument(startKeyHash) + .addArgument(endKeyHash) + .addArgument(accountHashes.size()) + .addArgument(peer) + .log(); + if (!peer.isServingSnap()) { + LOG.atDebug() + .setMessage("EthPeer that is not serving snap called in {}, peer: {}") + .addArgument(GetAccountRangeFromPeerTask.class) + .addArgument(peer) + .log(); + throw new RuntimeException( + "EthPeer that is not serving snap called in " + + GetAccountRangeFromPeerTask.class); + } + return peer.getSnapStorageRange( + blockHeader.getStateRoot(), accountHashes, startKeyHash, endKeyHash); + } + + @Override + public boolean isEthPeerSuitable(final EthPeer ethPeer) { + return ethPeer.isServingSnap(); + } }, blockHeader.getNumber()); } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/GetTrieNodeFromPeerTask.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/GetTrieNodeFromPeerTask.java index 6b2e8cc6b0..a060ca79d0 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/GetTrieNodeFromPeerTask.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/GetTrieNodeFromPeerTask.java @@ -20,10 +20,13 @@ import static org.slf4j.LoggerFactory.getLogger; import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.eth.manager.EthContext; import org.hyperledger.besu.ethereum.eth.manager.EthPeer; +import org.hyperledger.besu.ethereum.eth.manager.PeerRequest; import org.hyperledger.besu.ethereum.eth.manager.PendingPeerRequest; +import org.hyperledger.besu.ethereum.eth.manager.RequestManager; import org.hyperledger.besu.ethereum.eth.manager.task.AbstractPeerRequestTask; import org.hyperledger.besu.ethereum.eth.messages.snap.SnapV1; import org.hyperledger.besu.ethereum.eth.messages.snap.TrieNodesMessage; +import org.hyperledger.besu.ethereum.p2p.rlpx.connections.PeerConnection; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.MessageData; import org.hyperledger.besu.plugin.services.MetricsSystem; @@ -72,9 +75,31 @@ public class GetTrieNodeFromPeerTask extends AbstractPeerRequestTask { - LOG.trace("Requesting {} trie nodes from peer {}", paths.size(), peer); - return peer.getSnapTrieNode(blockHeader.getStateRoot(), paths); + new PeerRequest() { + @Override + public RequestManager.ResponseStream sendRequest(final EthPeer peer) + throws PeerConnection.PeerNotConnected { + LOG.atTrace() + .setMessage("Requesting {} trie nodes from peer {}") + .addArgument(paths.size()) + .addArgument(peer) + .log(); + if (!peer.isServingSnap()) { + LOG.debug( + "EthPeer that is not serving snap called in {}, {}", + GetAccountRangeFromPeerTask.class, + peer); + throw new RuntimeException( + "EthPeer that is not serving snap called in " + + GetAccountRangeFromPeerTask.class); + } + return peer.getSnapTrieNode(blockHeader.getStateRoot(), paths); + } + + @Override + public boolean isEthPeerSuitable(final EthPeer ethPeer) { + return ethPeer.isServingSnap(); + } }, blockHeader.getNumber()); } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/RetryingGetAccountRangeFromPeerTask.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/RetryingGetAccountRangeFromPeerTask.java index 36d6b75e6e..0624a90589 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/RetryingGetAccountRangeFromPeerTask.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/RetryingGetAccountRangeFromPeerTask.java @@ -31,6 +31,7 @@ public class RetryingGetAccountRangeFromPeerTask extends AbstractRetryingPeerTask { public static final int MAX_RETRIES = 4; + private final EthContext ethContext; private final Bytes32 startKeyHash; private final Bytes32 endKeyHash; @@ -79,4 +80,9 @@ public class RetryingGetAccountRangeFromPeerTask return peerResult.getResult(); }); } + + @Override + protected boolean isSuitablePeer(final EthPeer peer) { + return peer.isServingSnap(); + } } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/RetryingGetBytecodeFromPeerTask.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/RetryingGetBytecodeFromPeerTask.java index 9b340c8cdd..3258298f2c 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/RetryingGetBytecodeFromPeerTask.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/RetryingGetBytecodeFromPeerTask.java @@ -69,4 +69,9 @@ public class RetryingGetBytecodeFromPeerTask extends AbstractRetryingPeerTask extends AbstractEthTask { this.metricsSystem = metricsSystem; } - public void assignPeer(final EthPeer peer) { - assignedPeer = Optional.of(peer); + /** + * Assign the peer to be used for the task. + * + * @param peer The peer to assign to the task. + * @return True if the peer was assigned, false otherwise. + */ + public boolean assignPeer(final EthPeer peer) { + if (isSuitablePeer(peer)) { + assignedPeer = Optional.of(peer); + return true; + } else { + assignedPeer = Optional.empty(); + return false; + } } public Optional getAssignedPeer() { @@ -167,4 +179,8 @@ public abstract class AbstractRetryingPeerTask extends AbstractEthTask { public int getMaxRetries() { return maxRetries; } + + protected boolean isSuitablePeer(final EthPeer peer) { + return true; + } } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/task/AbstractRetryingSwitchingPeerTask.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/task/AbstractRetryingSwitchingPeerTask.java index 88fe3bb6a7..a102128977 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/task/AbstractRetryingSwitchingPeerTask.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/task/AbstractRetryingSwitchingPeerTask.java @@ -49,9 +49,12 @@ public abstract class AbstractRetryingSwitchingPeerTask extends AbstractRetry } @Override - public void assignPeer(final EthPeer peer) { - super.assignPeer(peer); - triedPeers.add(peer); + public boolean assignPeer(final EthPeer peer) { + if (super.assignPeer(peer)) { + triedPeers.add(peer); + return true; + } + return false; } protected abstract CompletableFuture executeTaskOnCurrentPeer(final EthPeer peer); @@ -62,8 +65,7 @@ public abstract class AbstractRetryingSwitchingPeerTask extends AbstractRetry final Optional maybePeer = assignedPeer .filter(u -> getRetryCount() == 1) // first try with the assigned peer if present - .map(Optional::of) - .orElseGet(this::selectNextPeer); // otherwise, select a new one from the pool + .or(this::selectNextPeer); // otherwise select a new one from the pool if (maybePeer.isEmpty()) { LOG.atTrace() @@ -101,7 +103,7 @@ public abstract class AbstractRetryingSwitchingPeerTask extends AbstractRetry @Override protected void handleTaskError(final Throwable error) { if (isPeerFailure(error)) { - getAssignedPeer().ifPresent(peer -> failedPeers.add(peer)); + getAssignedPeer().ifPresent(failedPeers::add); } super.handleTaskError(error); } @@ -124,10 +126,11 @@ public abstract class AbstractRetryingSwitchingPeerTask extends AbstractRetry return maybeNextPeer; } - private Stream remainingPeersToTry() { + protected Stream remainingPeersToTry() { return getEthContext() .getEthPeers() .streamBestPeers() + .filter(this::isSuitablePeer) .filter(peer -> !triedPeers.contains(peer)); } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/ChainHeadTracker.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/ChainHeadTracker.java index 5d563e012d..67681acf6a 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/ChainHeadTracker.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/ChainHeadTracker.java @@ -19,24 +19,25 @@ import org.hyperledger.besu.ethereum.chain.Blockchain; import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.eth.manager.EthContext; import org.hyperledger.besu.ethereum.eth.manager.EthPeer; -import org.hyperledger.besu.ethereum.eth.manager.EthPeers.ConnectCallback; +import org.hyperledger.besu.ethereum.eth.manager.task.AbstractPeerTask; import org.hyperledger.besu.ethereum.eth.manager.task.GetHeadersFromPeerByHashTask; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; -import org.hyperledger.besu.ethereum.p2p.rlpx.wire.messages.DisconnectMessage.DisconnectReason; +import org.hyperledger.besu.ethereum.p2p.rlpx.wire.messages.DisconnectMessage; import org.hyperledger.besu.plugin.services.MetricsSystem; +import java.util.List; +import java.util.concurrent.CompletableFuture; import java.util.function.Supplier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class ChainHeadTracker implements ConnectCallback { +public class ChainHeadTracker { private static final Logger LOG = LoggerFactory.getLogger(ChainHeadTracker.class); private final EthContext ethContext; private final ProtocolSchedule protocolSchedule; - private final TrailingPeerLimiter trailingPeerLimiter; private final MetricsSystem metricsSystem; public ChainHeadTracker( @@ -46,7 +47,6 @@ public class ChainHeadTracker implements ConnectCallback { final MetricsSystem metricsSystem) { this.ethContext = ethContext; this.protocolSchedule = protocolSchedule; - this.trailingPeerLimiter = trailingPeerLimiter; this.metricsSystem = metricsSystem; } @@ -60,48 +60,53 @@ public class ChainHeadTracker implements ConnectCallback { new TrailingPeerLimiter(ethContext.getEthPeers(), trailingPeerRequirementsCalculator); final ChainHeadTracker tracker = new ChainHeadTracker(ethContext, protocolSchedule, trailingPeerLimiter, metricsSystem); - ethContext.getEthPeers().subscribeConnect(tracker); + ethContext.getEthPeers().setChainHeadTracker(tracker); blockchain.observeBlockAdded(trailingPeerLimiter); } - @Override - public void onPeerConnected(final EthPeer peer) { + public CompletableFuture getBestHeaderFromPeer(final EthPeer peer) { LOG.atDebug() .setMessage("Requesting chain head info from {}...") .addArgument(peer::getLoggableId) .log(); - GetHeadersFromPeerByHashTask.forSingleHash( + final CompletableFuture>> + bestHeaderFromPeerCompletableFuture = getBestHeaderFromPeerCompletableFuture(peer); + final CompletableFuture future = new CompletableFuture<>(); + bestHeaderFromPeerCompletableFuture.whenComplete( + (peerResult, error) -> { + if (peerResult != null && !peerResult.getResult().isEmpty()) { + final BlockHeader chainHeadHeader = peerResult.getResult().get(0); + peer.chainState().update(chainHeadHeader); + future.complete(chainHeadHeader); + LOG.atDebug() + .setMessage("Retrieved chain head info {} from {}...") + .addArgument( + () -> chainHeadHeader.getNumber() + " (" + chainHeadHeader.getBlockHash() + ")") + .addArgument(peer::getLoggableId) + .log(); + } else { + LOG.atDebug() + .setMessage("Failed to retrieve chain head info. Disconnecting {}... {}") + .addArgument(peer::getLoggableId) + .addArgument(error != null ? error : "Empty Response") + .log(); + peer.disconnect( + DisconnectMessage.DisconnectReason.USELESS_PEER_FAILED_TO_RETRIEVE_CHAIN_HEAD); + future.complete(null); + } + }); + return future; + } + + public CompletableFuture>> + getBestHeaderFromPeerCompletableFuture(final EthPeer peer) { + return GetHeadersFromPeerByHashTask.forSingleHash( protocolSchedule, ethContext, Hash.wrap(peer.chainState().getBestBlock().getHash()), 0, metricsSystem) .assignPeer(peer) - .run() - .whenComplete( - (peerResult, error) -> { - if (peerResult != null && !peerResult.getResult().isEmpty()) { - final BlockHeader chainHeadHeader = peerResult.getResult().get(0); - peer.chainState().update(chainHeadHeader); - trailingPeerLimiter.enforceTrailingPeerLimit(); - LOG.atDebug() - .setMessage("Retrieved chain head info {} from {}...") - .addArgument( - () -> - chainHeadHeader.getNumber() - + " (" - + chainHeadHeader.getBlockHash() - + ")") - .addArgument(peer::getLoggableId) - .log(); - } else { - LOG.atDebug() - .setMessage("Failed to retrieve chain head info. Disconnecting {}... {}") - .addArgument(peer::getLoggableId) - .addArgument(error) - .log(); - peer.disconnect(DisconnectReason.USELESS_PEER_FAILED_TO_RETRIEVE_CHAIN_STATE); - } - }); + .run(); } } 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 5e596576aa..7605754a65 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 @@ -99,6 +99,11 @@ public class DefaultSynchronizer implements Synchronizer, UnverifiedForkchoiceLi this::calculateTrailingPeerRequirements, metricsSystem); + if (SyncMode.isSnapSync(syncConfig.getSyncMode()) + || SyncMode.isCheckpointSync(syncConfig.getSyncMode())) { + SnapServerChecker.createAndSetSnapServerChecker(ethContext, metricsSystem); + } + this.blockPropagationManager = terminationCondition.shouldStopDownload() ? Optional.empty() @@ -187,7 +192,7 @@ public class DefaultSynchronizer implements Synchronizer, UnverifiedForkchoiceLi () -> getSyncStatus().isPresent() ? 0 : 1); } - private TrailingPeerRequirements calculateTrailingPeerRequirements() { + public TrailingPeerRequirements calculateTrailingPeerRequirements() { return fastSyncDownloader .flatMap(FastSyncDownloader::calculateTrailingPeerRequirements) .orElse( diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/SnapServerChecker.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/SnapServerChecker.java new file mode 100644 index 0000000000..c7fa141837 --- /dev/null +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/SnapServerChecker.java @@ -0,0 +1,86 @@ +/* + * 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.eth.sync; + +import org.hyperledger.besu.datatypes.Hash; +import org.hyperledger.besu.ethereum.core.BlockHeader; +import org.hyperledger.besu.ethereum.eth.manager.EthContext; +import org.hyperledger.besu.ethereum.eth.manager.EthPeer; +import org.hyperledger.besu.ethereum.eth.manager.snap.GetAccountRangeFromPeerTask; +import org.hyperledger.besu.ethereum.eth.manager.task.AbstractPeerTask; +import org.hyperledger.besu.ethereum.eth.messages.snap.AccountRangeMessage; +import org.hyperledger.besu.plugin.services.MetricsSystem; + +import java.util.concurrent.CompletableFuture; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SnapServerChecker { + + private static final Logger LOG = LoggerFactory.getLogger(SnapServerChecker.class); + + private final EthContext ethContext; + private final MetricsSystem metricsSystem; + + public SnapServerChecker(final EthContext ethContext, final MetricsSystem metricsSystem) { + this.ethContext = ethContext; + this.metricsSystem = metricsSystem; + } + + public static void createAndSetSnapServerChecker( + final EthContext ethContext, final MetricsSystem metricsSystem) { + final SnapServerChecker checker = new SnapServerChecker(ethContext, metricsSystem); + ethContext.getEthPeers().setSnapServerChecker(checker); + } + + public CompletableFuture check(final EthPeer peer, final BlockHeader peersHeadHeader) { + LOG.atTrace() + .setMessage("Checking whether peer {} is a snap server ...") + .addArgument(peer::getLoggableId) + .log(); + final CompletableFuture> + snapServerCheckCompletableFuture = getAccountRangeFromPeer(peer, peersHeadHeader); + final CompletableFuture future = new CompletableFuture<>(); + snapServerCheckCompletableFuture.whenComplete( + (peerResult, error) -> { + if (peerResult != null) { + if (!peerResult.getResult().accounts().isEmpty() + || !peerResult.getResult().proofs().isEmpty()) { + LOG.atTrace() + .setMessage("Peer {} is a snap server.") + .addArgument(peer::getLoggableId) + .log(); + future.complete(true); + } else { + LOG.atTrace() + .setMessage("Peer {} is not a snap server.") + .addArgument(peer::getLoggableId) + .log(); + future.complete(false); + } + } + }); + return future; + } + + public CompletableFuture> + getAccountRangeFromPeer(final EthPeer peer, final BlockHeader header) { + return GetAccountRangeFromPeerTask.forAccountRange( + ethContext, Hash.ZERO, Hash.ZERO, header, metricsSystem) + .assignPeer(peer) + .run(); + } +} diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/SyncMode.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/SyncMode.java index b5d0c2570b..4f3affbe55 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/SyncMode.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/SyncMode.java @@ -54,4 +54,8 @@ public enum SyncMode { public static boolean isCheckpointSync(final SyncMode syncMode) { return X_CHECKPOINT.equals(syncMode) || CHECKPOINT.equals(syncMode); } + + public static boolean isSnapSync(final SyncMode syncMode) { + return X_SNAP.equals(syncMode) || SNAP.equals(syncMode); + } } 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 b587b18f26..2acfa54d04 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 @@ -42,6 +42,9 @@ import org.slf4j.LoggerFactory; public class SyncTargetManager extends AbstractSyncTargetManager { private static final Logger LOG = LoggerFactory.getLogger(SyncTargetManager.class); + + private static final int LOG_DEBUG_REPEAT_DELAY = 15; + 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 WorldStateStorageCoordinator worldStateStorageCoordinator; @@ -52,8 +55,6 @@ public class SyncTargetManager extends AbstractSyncTargetManager { private final FastSyncState fastSyncState; private final AtomicBoolean logDebug = new AtomicBoolean(true); private final AtomicBoolean logInfo = new AtomicBoolean(true); - private final int logDebugRepeatDelay = 15; - private final int logInfoRepeatDelay = 120; public SyncTargetManager( final SynchronizerConfiguration config, @@ -84,14 +85,14 @@ public class SyncTargetManager extends AbstractSyncTargetManager { "Unable to find sync target. Currently checking %d peers for usefulness. Pivot block: %d", ethContext.getEthPeers().peerCount(), pivotBlockHeader.getNumber()), logDebug, - logDebugRepeatDelay); + LOG_DEBUG_REPEAT_DELAY); throttledLog( LOG::info, String.format( "Unable to find sync target. Currently checking %d peers for usefulness.", ethContext.getEthPeers().peerCount()), logInfo, - logInfoRepeatDelay); + LOG_INFO_REPEAT_DELAY); return completedFuture(Optional.empty()); } else { final EthPeer bestPeer = maybeBestPeer.get(); diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/EthPeersTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/EthPeersTest.java index 59c0294142..f6c635aa51 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/EthPeersTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/EthPeersTest.java @@ -21,15 +21,18 @@ import static org.assertj.core.api.Assertions.fail; import static org.mockito.ArgumentMatchers.any; 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.verifyNoInteractions; import static org.mockito.Mockito.when; import org.hyperledger.besu.datatypes.Hash; +import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.Difficulty; import org.hyperledger.besu.ethereum.eth.manager.exceptions.NoAvailablePeersException; import org.hyperledger.besu.ethereum.eth.manager.exceptions.PeerDisconnectedException; import org.hyperledger.besu.ethereum.eth.messages.NodeDataMessage; +import org.hyperledger.besu.ethereum.eth.sync.ChainHeadTracker; import org.hyperledger.besu.ethereum.p2p.rlpx.connections.PeerConnection.PeerNotConnected; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.messages.DisconnectMessage.DisconnectReason; @@ -37,6 +40,7 @@ import java.util.Collections; import java.util.Optional; import java.util.OptionalLong; import java.util.concurrent.CancellationException; +import java.util.concurrent.CompletableFuture; import java.util.function.Consumer; import org.junit.jupiter.api.BeforeEach; @@ -56,6 +60,11 @@ public class EthPeersTest { when(peerRequest.sendRequest(any())).thenReturn(responseStream); ethProtocolManager = EthProtocolManagerTestUtil.create(); ethPeers = ethProtocolManager.ethContext().getEthPeers(); + final ChainHeadTracker mock = mock(ChainHeadTracker.class); + final BlockHeader blockHeader = mock(BlockHeader.class); + when(mock.getBestHeaderFromPeer(any())) + .thenReturn(CompletableFuture.completedFuture(blockHeader)); + ethPeers.setChainHeadTracker(mock); } @Test @@ -112,6 +121,9 @@ public class EthPeersTest { @Test public void shouldExecutePeerRequestImmediatelyWhenPeerIsAvailable() throws Exception { final RespondingEthPeer peer = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 1000); + + when(peerRequest.isEthPeerSuitable(peer.getEthPeer())).thenReturn(true); + final PendingPeerRequest pendingRequest = ethPeers.executePeerRequest(peerRequest, 10, Optional.empty()); @@ -127,6 +139,8 @@ public class EthPeersTest { EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 1000); useRequestSlot(workingPeer.getEthPeer()); + when(peerRequest.isEthPeerSuitable(any())).thenReturn(true); + final PendingPeerRequest pendingRequest = ethPeers.executePeerRequest(peerRequest, 10, Optional.empty()); @@ -147,6 +161,8 @@ public class EthPeersTest { assertThat(leastRecentlyUsedPeer.getEthPeer().outstandingRequests()) .isEqualTo(mostRecentlyUsedPeer.getEthPeer().outstandingRequests()); + when(peerRequest.isEthPeerSuitable(any())).thenReturn(true); + final PendingPeerRequest pendingRequest = ethPeers.executePeerRequest(peerRequest, 10, Optional.empty()); @@ -180,10 +196,13 @@ public class EthPeersTest { EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 1000); useAllAvailableCapacity(suitablePeer.getEthPeer()); + when(peerRequest.isEthPeerSuitable(suitablePeer.getEthPeer())).thenReturn(true); + final PendingPeerRequest pendingRequest = ethPeers.executePeerRequest(peerRequest, 200, Optional.empty()); - verifyNoInteractions(peerRequest); + verify(peerRequest, times(0)).sendRequest(suitablePeer.getEthPeer()); + assertNotDone(pendingRequest); suitablePeer.disconnect(DisconnectReason.TOO_MANY_PEERS); @@ -194,6 +213,8 @@ public class EthPeersTest { public void shouldFailWithPeerNotConnectedIfPeerRequestThrows() throws Exception { final RespondingEthPeer peer = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 1000); when(peerRequest.sendRequest(peer.getEthPeer())).thenThrow(new PeerNotConnected("Oh dear")); + when(peerRequest.isEthPeerSuitable(any())).thenReturn(true); + final PendingPeerRequest pendingRequest = ethPeers.executePeerRequest(peerRequest, 100, Optional.empty()); @@ -205,9 +226,11 @@ public class EthPeersTest { final RespondingEthPeer peer = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 1000); useAllAvailableCapacity(peer.getEthPeer()); + when(peerRequest.isEthPeerSuitable(any())).thenReturn(true); + final PendingPeerRequest pendingRequest = ethPeers.executePeerRequest(peerRequest, 100, Optional.empty()); - verifyNoInteractions(peerRequest); + verify(peerRequest, times(0)).sendRequest(peer.getEthPeer()); freeUpCapacity(peer.getEthPeer()); @@ -221,11 +244,12 @@ public class EthPeersTest { EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 10); final RespondingEthPeer peer = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 1000); + when(peerRequest.isEthPeerSuitable(peer.getEthPeer())).thenReturn(true); useAllAvailableCapacity(peer.getEthPeer()); final PendingPeerRequest pendingRequest = ethPeers.executePeerRequest(peerRequest, 100, Optional.empty()); - verifyNoInteractions(peerRequest); + verify(peerRequest, times(0)).sendRequest(peer.getEthPeer()); freeUpCapacity(peer.getEthPeer()); @@ -238,15 +262,17 @@ public class EthPeersTest { final RespondingEthPeer peer = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 1000); useAllAvailableCapacity(peer.getEthPeer()); + when(peerRequest.isEthPeerSuitable(peer.getEthPeer())).thenReturn(true); + final PendingPeerRequest pendingRequest = ethPeers.executePeerRequest(peerRequest, 100, Optional.empty()); - verifyNoInteractions(peerRequest); + verify(peerRequest, times(0)).sendRequest(peer.getEthPeer()); pendingRequest.abort(); freeUpCapacity(peer.getEthPeer()); - verifyNoInteractions(peerRequest); + verify(peerRequest, times(0)).sendRequest(peer.getEthPeer()); assertRequestFailure(pendingRequest, CancellationException.class); } @@ -349,6 +375,59 @@ public class EthPeersTest { assertThat(ethPeers.toString()).contains(peerA.getLoggableId()); } + @Test + public void snapServersPreferredWhileSyncing() { + + ethPeers.snapServerPeersNeeded(true); + + while (ethPeers.peerCount() < ethPeers.getMaxPeers()) { + final EthPeer ethPeer = + EthProtocolManagerTestUtil.createPeer( + ethProtocolManager, Difficulty.of(50), 20, false, false) + .getEthPeer(); + assertThat(ethPeers.addPeerToEthPeers(ethPeer)).isTrue(); + } + + final EthPeer nonSnapServingPeer = + EthProtocolManagerTestUtil.createPeer( + ethProtocolManager, Difficulty.of(50), 20, false, false) + .getEthPeer(); + + assertThat(ethPeers.addPeerToEthPeers(nonSnapServingPeer)).isFalse(); + assertThat(nonSnapServingPeer.getConnection().isDisconnected()).isTrue(); + + final EthPeer snapServingPeer = + EthProtocolManagerTestUtil.createPeer( + ethProtocolManager, Difficulty.of(50), 20, true, false) + .getEthPeer(); + + assertThat(ethPeers.addPeerToEthPeers(snapServingPeer)).isTrue(); + assertThat(ethPeers.peerCount()).isEqualTo(ethPeers.getMaxPeers()); + } + + @Test + public void snapServersNotPreferredWhenInSync() { + + ethPeers.snapServerPeersNeeded(false); + + while (ethPeers.peerCount() < ethPeers.getMaxPeers()) { + final EthPeer ethPeer = + EthProtocolManagerTestUtil.createPeer( + ethProtocolManager, Difficulty.of(50), 20, false, false) + .getEthPeer(); + assertThat(ethPeers.addPeerToEthPeers(ethPeer)).isTrue(); + } + + final EthPeer snapServingPeer = + EthProtocolManagerTestUtil.createPeer( + ethProtocolManager, Difficulty.of(50), 20, true, false) + .getEthPeer(); + + assertThat(ethPeers.addPeerToEthPeers(snapServingPeer)).isFalse(); + assertThat(snapServingPeer.getConnection().isDisconnected()).isTrue(); + assertThat(ethPeers.peerCount()).isEqualTo(ethPeers.getMaxPeers()); + } + private void freeUpCapacity(final EthPeer ethPeer) { ethPeers.dispatchMessage(ethPeer, new EthMessage(ethPeer, NodeDataMessage.create(emptyList()))); } diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/EthProtocolManagerTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/EthProtocolManagerTest.java index ff5d655cc6..93a80be2fd 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/EthProtocolManagerTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/EthProtocolManagerTest.java @@ -528,7 +528,7 @@ public final class EthProtocolManagerTest { private MockPeerConnection setupPeer( final EthProtocolManager ethManager, final PeerSendHandler onSend) { - final MockPeerConnection peer = setupPeerWithoutStatusExchange(ethManager, onSend); + final MockPeerConnection peerConnection = setupPeerWithoutStatusExchange(ethManager, onSend); final StatusMessage statusMessage = StatusMessage.create( EthProtocolVersion.V63, @@ -536,8 +536,11 @@ public final class EthProtocolManagerTest { blockchain.getChainHead().getTotalDifficulty(), blockchain.getChainHeadHash(), blockchain.getBlockHeader(BlockHeader.GENESIS_BLOCK_NUMBER).get().getHash()); - ethManager.processMessage(EthProtocol.ETH63, new DefaultMessage(peer, statusMessage)); - return peer; + ethManager.processMessage(EthProtocol.ETH63, new DefaultMessage(peerConnection, statusMessage)); + final EthPeers ethPeers = ethManager.ethContext().getEthPeers(); + final EthPeer ethPeer = ethPeers.peer(peerConnection); + ethPeers.addPeerToEthPeers(ethPeer); + return peerConnection; } private MockPeerConnection setupPeerWithoutStatusExchange( diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/EthProtocolManagerTestUtil.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/EthProtocolManagerTestUtil.java index 63ada13040..0b0bd1e3eb 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/EthProtocolManagerTestUtil.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/EthProtocolManagerTestUtil.java @@ -16,12 +16,15 @@ package org.hyperledger.besu.ethereum.eth.manager; import static com.google.common.base.Preconditions.checkArgument; import static org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider.createInMemoryBlockchain; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.chain.Blockchain; import org.hyperledger.besu.ethereum.chain.ChainHead; import org.hyperledger.besu.ethereum.chain.GenesisState; +import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.BlockchainSetupUtil; import org.hyperledger.besu.ethereum.core.Difficulty; import org.hyperledger.besu.ethereum.core.ProtocolScheduleFixture; @@ -29,6 +32,8 @@ import org.hyperledger.besu.ethereum.eth.EthProtocol; import org.hyperledger.besu.ethereum.eth.EthProtocolConfiguration; import org.hyperledger.besu.ethereum.eth.manager.snap.SnapProtocolManager; import org.hyperledger.besu.ethereum.eth.peervalidation.PeerValidator; +import org.hyperledger.besu.ethereum.eth.sync.ChainHeadTracker; +import org.hyperledger.besu.ethereum.eth.sync.SyncMode; import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool; import org.hyperledger.besu.ethereum.forkid.ForkIdManager; @@ -46,8 +51,10 @@ import java.math.BigInteger; import java.util.Collections; import java.util.Optional; import java.util.OptionalLong; +import java.util.concurrent.CompletableFuture; import org.apache.tuweni.bytes.Bytes; +import org.mockito.Mockito; public class EthProtocolManagerTestUtil { @@ -86,7 +93,13 @@ public class EthProtocolManagerTestUtil { Bytes.random(64), 25, 25, - false); + false, + SyncMode.FAST, + new ForkIdManager(blockchain, Collections.emptyList(), Collections.emptyList(), false)); + + final ChainHeadTracker chainHeadTrackerMock = getChainHeadTrackerMock(); + peers.setChainHeadTracker(chainHeadTrackerMock); + final EthMessages messages = new EthMessages(); final EthScheduler ethScheduler = new DeterministicEthScheduler(TimeoutPolicy.NEVER_TIMEOUT); final EthContext ethContext = new EthContext(peers, messages, ethScheduler); @@ -139,6 +152,8 @@ public class EthProtocolManagerTestUtil { final EthContext ethContext, final ForkIdManager forkIdManager) { + ethPeers.setChainHeadTracker(getChainHeadTrackerMock()); + final BigInteger networkId = BigInteger.ONE; return new EthProtocolManager( blockchain, @@ -205,9 +220,15 @@ public class EthProtocolManagerTestUtil { Bytes.random(64), 25, 25, - false); + false, + SyncMode.FAST, + new ForkIdManager(blockchain, Collections.emptyList(), Collections.emptyList(), false)); final EthMessages messages = new EthMessages(); + final ChainHeadTracker chtMock = getChainHeadTrackerMock(); + + peers.setChainHeadTracker(chtMock); + return create( blockchain, ethScheduler, @@ -219,6 +240,17 @@ public class EthProtocolManagerTestUtil { new EthContext(peers, messages, ethScheduler)); } + public static ChainHeadTracker getChainHeadTrackerMock() { + final ChainHeadTracker chtMock = mock(ChainHeadTracker.class); + final BlockHeader blockHeaderMock = mock(BlockHeader.class); + Mockito.lenient() + .when(chtMock.getBestHeaderFromPeer(any())) + .thenReturn(CompletableFuture.completedFuture(blockHeaderMock)); + Mockito.lenient().when(blockHeaderMock.getNumber()).thenReturn(0L); + Mockito.lenient().when(blockHeaderMock.getStateRoot()).thenReturn(Hash.ZERO); + return chtMock; + } + public static EthProtocolManager create( final ProtocolSchedule protocolSchedule, final Blockchain blockchain, @@ -239,7 +271,9 @@ public class EthProtocolManagerTestUtil { Bytes.random(64), 25, 25, - false); + false, + SyncMode.FAST, + new ForkIdManager(blockchain, Collections.emptyList(), Collections.emptyList(), false)); final EthMessages messages = new EthMessages(); return create( @@ -258,7 +292,7 @@ public class EthProtocolManagerTestUtil { final ProtocolSchedule protocolSchedule, final Blockchain blockchain, final EthScheduler ethScheduler) { - final EthPeers peers = + final EthPeers ethPeers = new EthPeers( EthProtocol.NAME, () -> protocolSchedule.getByBlockHeader(blockchain.getChainHeadHeader()), @@ -269,7 +303,13 @@ public class EthProtocolManagerTestUtil { Bytes.random(64), 25, 25, - false); + false, + SyncMode.FAST, + new ForkIdManager(blockchain, Collections.emptyList(), Collections.emptyList(), false)); + + final ChainHeadTracker chainHeadTrackerMock = getChainHeadTrackerMock(); + ethPeers.setChainHeadTracker(chainHeadTrackerMock); + final EthMessages messages = new EthMessages(); return create( @@ -278,9 +318,9 @@ public class EthProtocolManagerTestUtil { BlockchainSetupUtil.forTesting(DataStorageFormat.FOREST).getWorldArchive(), mock(TransactionPool.class), EthProtocolConfiguration.defaultConfig(), - peers, + ethPeers, messages, - new EthContext(peers, messages, ethScheduler)); + new EthContext(ethPeers, messages, ethScheduler)); } public static EthProtocolManager create() { @@ -446,4 +486,19 @@ public class EthProtocolManagerTestUtil { .estimatedHeight(blockchain.getChainHeadBlockNumber()) .build(); } + + public static RespondingEthPeer createPeer( + final EthProtocolManager ethProtocolManager, + final Difficulty td, + final int estimatedHeight, + final boolean isServingSnap, + final boolean addToEthPeers) { + return RespondingEthPeer.builder() + .ethProtocolManager(ethProtocolManager) + .totalDifficulty(td) + .estimatedHeight(estimatedHeight) + .isServingSnap(isServingSnap) + .addToEthPeers(addToEthPeers) + .build(); + } } diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/RespondingEthPeer.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/RespondingEthPeer.java index 7427545984..58f4893432 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/RespondingEthPeer.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/RespondingEthPeer.java @@ -121,7 +121,9 @@ public class RespondingEthPeer { final Hash chainHeadHash, final Difficulty totalDifficulty, final OptionalLong estimatedHeight, - final List peerValidators) { + final List peerValidators, + final boolean isServingSnap, + final boolean addToEthPeers) { final EthPeers ethPeers = ethProtocolManager.ethContext().getEthPeers(); final Set caps = new HashSet<>(Collections.singletonList(EthProtocol.ETH63)); @@ -130,10 +132,24 @@ public class RespondingEthPeer { new MockPeerConnection( caps, (cap, msg, conn) -> outgoingMessages.add(new OutgoingMessage(cap, msg))); ethPeers.registerNewConnection(peerConnection, peerValidators); + final int before = ethPeers.peerCount(); final EthPeer peer = ethPeers.peer(peerConnection); peer.registerStatusReceived(chainHeadHash, totalDifficulty, 63, peerConnection); estimatedHeight.ifPresent(height -> peer.chainState().update(chainHeadHash, height)); - peer.registerStatusSent(peerConnection); + if (addToEthPeers) { + peer.registerStatusSent(peerConnection); + ethPeers.addPeerToEthPeers(peer); + while (ethPeers.peerCount() + <= before) { // this is needed to make sure that the peer is added to the active + // connections + try { + Thread.sleep(100L); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + } + peer.setIsServingSnap(isServingSnap); return new RespondingEthPeer( ethProtocolManager, snapProtocolManager, peerConnection, peer, outgoingMessages); @@ -396,6 +412,8 @@ public class RespondingEthPeer { private Difficulty totalDifficulty = Difficulty.of(1000L); private OptionalLong estimatedHeight = OptionalLong.of(1000L); private final List peerValidators = new ArrayList<>(); + private boolean isServingSnap = false; + private boolean addToEthPeers = true; public RespondingEthPeer build() { checkNotNull(ethProtocolManager, "Must configure EthProtocolManager"); @@ -406,7 +424,9 @@ public class RespondingEthPeer { chainHeadHash, totalDifficulty, estimatedHeight, - peerValidators); + peerValidators, + isServingSnap, + addToEthPeers); } public Builder ethProtocolManager(final EthProtocolManager ethProtocolManager) { @@ -444,6 +464,11 @@ public class RespondingEthPeer { return this; } + public Builder isServingSnap(final boolean isServingSnap) { + this.isServingSnap = isServingSnap; + return this; + } + public Builder peerValidators(final List peerValidators) { checkNotNull(peerValidators); this.peerValidators.addAll(peerValidators); @@ -454,6 +479,11 @@ public class RespondingEthPeer { peerValidators(Arrays.asList(peerValidators)); return this; } + + public Builder addToEthPeers(final boolean addToEthPeers) { + this.addToEthPeers = addToEthPeers; + return this; + } } static class OutgoingMessage { diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/ethtaskutils/AbstractMessageTaskTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/ethtaskutils/AbstractMessageTaskTest.java index 2f0657d23d..6dbea259cc 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/ethtaskutils/AbstractMessageTaskTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/ethtaskutils/AbstractMessageTaskTest.java @@ -38,11 +38,13 @@ 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.manager.task.EthTask; +import org.hyperledger.besu.ethereum.eth.sync.SyncMode; import org.hyperledger.besu.ethereum.eth.sync.state.SyncState; import org.hyperledger.besu.ethereum.eth.transactions.BlobCache; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolFactory; +import org.hyperledger.besu.ethereum.forkid.ForkIdManager; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import org.hyperledger.besu.plugin.services.MetricsSystem; @@ -121,7 +123,10 @@ public abstract class AbstractMessageTaskTest { Bytes.random(64), MAX_PEERS, MAX_PEERS, - false)); + false, + SyncMode.FAST, + new ForkIdManager( + blockchain, Collections.emptyList(), Collections.emptyList(), false))); final EthMessages ethMessages = new EthMessages(); final EthScheduler ethScheduler = diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/AbstractBlockPropagationManagerTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/AbstractBlockPropagationManagerTest.java index a91b19c8e9..dcc0239f61 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/AbstractBlockPropagationManagerTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/AbstractBlockPropagationManagerTest.java @@ -55,6 +55,7 @@ import org.hyperledger.besu.ethereum.eth.messages.NewBlockMessage; import org.hyperledger.besu.ethereum.eth.sync.BlockPropagationManager.ProcessingBlocksManager; import org.hyperledger.besu.ethereum.eth.sync.state.PendingBlocksManager; import org.hyperledger.besu.ethereum.eth.sync.state.SyncState; +import org.hyperledger.besu.ethereum.forkid.ForkIdManager; import org.hyperledger.besu.ethereum.mainnet.MainnetBlockHeaderFunctions; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; @@ -629,7 +630,10 @@ public abstract class AbstractBlockPropagationManagerTest { Bytes.random(64), 25, 25, - false), + false, + SyncMode.SNAP, + new ForkIdManager( + blockchain, Collections.emptyList(), Collections.emptyList(), false)), new EthMessages(), ethScheduler); final BlockPropagationManager blockPropagationManager = @@ -767,7 +771,10 @@ public abstract class AbstractBlockPropagationManagerTest { Bytes.random(64), 25, 25, - false), + false, + SyncMode.SNAP, + new ForkIdManager( + blockchain, Collections.emptyList(), Collections.emptyList(), false)), new EthMessages(), ethScheduler); final BlockPropagationManager blockPropagationManager = diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/ChainHeadTrackerTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/ChainHeadTrackerTest.java index 393824af75..b46a109c12 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/ChainHeadTrackerTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/ChainHeadTrackerTest.java @@ -98,7 +98,7 @@ public class ChainHeadTrackerTest { blockchainSetupUtil.getBlockchain(), blockchainSetupUtil.getWorldArchive(), blockchainSetupUtil.getTransactionPool()); - chainHeadTracker.onPeerConnected(respondingPeer.getEthPeer()); + chainHeadTracker.getBestHeaderFromPeer(respondingPeer.getEthPeer()); Assertions.assertThat(chainHeadState().getEstimatedHeight()).isZero(); @@ -118,7 +118,7 @@ public class ChainHeadTrackerTest { blockchainSetupUtil.getBlockchain(), blockchainSetupUtil.getWorldArchive(), blockchainSetupUtil.getTransactionPool()); - chainHeadTracker.onPeerConnected(respondingPeer.getEthPeer()); + chainHeadTracker.getBestHeaderFromPeer(respondingPeer.getEthPeer()); // Change the hash of the current known head respondingPeer.getEthPeer().chainState().statusReceived(Hash.EMPTY_TRIE_HASH, Difficulty.ONE); @@ -137,7 +137,7 @@ public class ChainHeadTrackerTest { blockchainSetupUtil.getBlockchain(), blockchainSetupUtil.getWorldArchive(), blockchainSetupUtil.getTransactionPool()); - chainHeadTracker.onPeerConnected(respondingPeer.getEthPeer()); + chainHeadTracker.getBestHeaderFromPeer(respondingPeer.getEthPeer()); Assertions.assertThat(chainHeadState().getEstimatedHeight()).isZero(); diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/PivotBlockRetrieverTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/PivotBlockRetrieverTest.java index ae96bbf768..41317fdab3 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/PivotBlockRetrieverTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/PivotBlockRetrieverTest.java @@ -288,15 +288,15 @@ public class PivotBlockRetrieverTest { final CompletableFuture future = pivotBlockRetriever.downloadPivotBlockHeader(); peerA.respond(responder); - peerB.respondTimes(emptyResponder, 3); + peerB.respondTimes(emptyResponder, 4); // PeerA should have responded, while peerB is being retried, peerC shouldn't have been queried // yet assertThat(future).isNotCompleted(); assertThat(peerC.hasOutstandingRequests()).isFalse(); - // After exhausting retries for peerB, we should try peerC - peerB.respondTimes(emptyResponder, 2); + // After exhausting retries (max retries is 5) for peerB, we should try peerC + peerB.respondTimes(emptyResponder, 1); peerC.respond(responder); assertThat(future) diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TestNode.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TestNode.java index 743f0b47e2..8e9bda89c0 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TestNode.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TestNode.java @@ -18,6 +18,7 @@ import static java.util.Collections.singletonList; import static java.util.Objects.requireNonNull; import static org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider.createInMemoryBlockchain; import static org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider.createInMemoryWorldStateArchive; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -30,6 +31,7 @@ import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.chain.BadBlockManager; import org.hyperledger.besu.ethereum.chain.GenesisState; import org.hyperledger.besu.ethereum.chain.MutableBlockchain; +import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.BlockHeaderFunctions; import org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider; import org.hyperledger.besu.ethereum.core.MiningParameters; @@ -42,8 +44,11 @@ import org.hyperledger.besu.ethereum.eth.manager.EthMessages; import org.hyperledger.besu.ethereum.eth.manager.EthPeers; import org.hyperledger.besu.ethereum.eth.manager.EthProtocolManager; import org.hyperledger.besu.ethereum.eth.manager.EthScheduler; +import org.hyperledger.besu.ethereum.eth.sync.ChainHeadTracker; +import org.hyperledger.besu.ethereum.eth.sync.SyncMode; import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration; import org.hyperledger.besu.ethereum.eth.sync.state.SyncState; +import org.hyperledger.besu.ethereum.forkid.ForkIdManager; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ScheduleBasedBlockHeaderFunctions; import org.hyperledger.besu.ethereum.p2p.config.DiscoveryConfiguration; @@ -77,6 +82,7 @@ import java.util.concurrent.CompletableFuture; import io.vertx.core.Vertx; import org.apache.tuweni.bytes.Bytes; +import org.mockito.Mockito; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -153,7 +159,12 @@ public class TestNode implements Closeable { Bytes.random(64), 25, 25, - false); + false, + SyncMode.SNAP, + new ForkIdManager(blockchain, Collections.emptyList(), Collections.emptyList(), false)); + + final ChainHeadTracker mockCHT = getChainHeadTracker(); + ethPeers.setChainHeadTracker(mockCHT); final EthScheduler scheduler = new EthScheduler(1, 1, 1, metricsSystem); final EthContext ethContext = new EthContext(ethPeers, ethMessages, scheduler); @@ -189,6 +200,7 @@ public class TestNode implements Closeable { NetworkRunner.builder() .subProtocols(EthProtocol.get()) .protocolManagers(singletonList(ethProtocolManager)) + .ethPeersShouldConnect((p, d) -> true) .network( capabilities -> DefaultP2PNetwork.builder() @@ -201,8 +213,8 @@ public class TestNode implements Closeable { .blockchain(blockchain) .blockNumberForks(Collections.emptyList()) .timestampForks(Collections.emptyList()) - .allConnectionsSupplier(ethPeers::getAllConnections) - .allActiveConnectionsSupplier(ethPeers::getAllActiveConnections) + .allConnectionsSupplier(ethPeers::streamAllConnections) + .allActiveConnectionsSupplier(ethPeers::streamAllActiveConnections) .build()) .metricsSystem(new NoOpMetricsSystem()) .build(); @@ -217,6 +229,16 @@ public class TestNode implements Closeable { selfPeer = DefaultPeer.fromEnodeURL(network.getLocalEnode().get()); } + private static ChainHeadTracker getChainHeadTracker() { + final ChainHeadTracker mockCHT = mock(ChainHeadTracker.class); + final BlockHeader mockBlockHeader = mock(BlockHeader.class); + Mockito.lenient().when(mockBlockHeader.getNumber()).thenReturn(0L); + Mockito.lenient() + .when(mockCHT.getBestHeaderFromPeer(any())) + .thenReturn(CompletableFuture.completedFuture(mockBlockHeader)); + return mockCHT; + } + public Bytes id() { return nodeKey.getPublicKey().getEncodedBytes(); } diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolFactoryTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolFactoryTest.java index d6b1b65381..ef8d070178 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolFactoryTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolFactoryTest.java @@ -34,6 +34,7 @@ import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.chain.BadBlockManager; import org.hyperledger.besu.ethereum.chain.BlockAddedObserver; import org.hyperledger.besu.ethereum.chain.MutableBlockchain; +import org.hyperledger.besu.ethereum.core.Block; import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture; import org.hyperledger.besu.ethereum.core.MiningParameters; import org.hyperledger.besu.ethereum.core.PrivacyParameters; @@ -44,6 +45,7 @@ import org.hyperledger.besu.ethereum.eth.manager.EthMessages; import org.hyperledger.besu.ethereum.eth.manager.EthPeers; import org.hyperledger.besu.ethereum.eth.manager.EthProtocolManager; import org.hyperledger.besu.ethereum.eth.manager.EthScheduler; +import org.hyperledger.besu.ethereum.eth.sync.SyncMode; import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration; import org.hyperledger.besu.ethereum.eth.sync.state.SyncState; import org.hyperledger.besu.ethereum.eth.transactions.layered.LayeredPendingTransactions; @@ -102,6 +104,9 @@ public class TransactionPoolFactoryTest { @BeforeEach public void setup() { when(blockchain.getBlockHashByNumber(anyLong())).thenReturn(Optional.of(mock(Hash.class))); + final Block mockBlock = mock(Block.class); + when(mockBlock.getHash()).thenReturn(Hash.ZERO); + when(blockchain.getGenesisBlock()).thenReturn(mockBlock); when(context.getBlockchain()).thenReturn(blockchain); final NodeMessagePermissioningProvider nmpp = (destinationEnode, code) -> true; @@ -116,7 +121,9 @@ public class TransactionPoolFactoryTest { Bytes.random(64), 25, 25, - false); + false, + SyncMode.SNAP, + new ForkIdManager(blockchain, Collections.emptyList(), Collections.emptyList(), false)); when(ethContext.getEthMessages()).thenReturn(ethMessages); when(ethContext.getEthPeers()).thenReturn(ethPeers); diff --git a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/network/NetworkRunner.java b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/network/NetworkRunner.java index 028d5acd89..77e9903bb8 100644 --- a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/network/NetworkRunner.java +++ b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/network/NetworkRunner.java @@ -14,6 +14,7 @@ */ package org.hyperledger.besu.ethereum.p2p.network; +import org.hyperledger.besu.ethereum.p2p.peers.Peer; import org.hyperledger.besu.ethereum.p2p.rlpx.RlpxAgent; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.Capability; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.SubProtocol; @@ -31,6 +32,7 @@ import java.util.List; import java.util.Map; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.BiFunction; import java.util.stream.Collectors; import org.slf4j.Logger; @@ -47,15 +49,18 @@ public class NetworkRunner implements AutoCloseable { private final Map subProtocols; private final List protocolManagers; private final LabelledMetric inboundMessageCounter; + private final BiFunction ethPeersShouldConnect; private NetworkRunner( final P2PNetwork network, final Map subProtocols, final List protocolManagers, - final MetricsSystem metricsSystem) { + final MetricsSystem metricsSystem, + final BiFunction ethPeersShouldConnect) { this.network = network; this.protocolManagers = protocolManagers; this.subProtocols = subProtocols; + this.ethPeersShouldConnect = ethPeersShouldConnect; inboundMessageCounter = metricsSystem.createLabelledCounter( BesuMetricCategory.NETWORK, @@ -158,8 +163,7 @@ public class NetworkRunner implements AutoCloseable { protocolManager.handleNewConnection(connection); }); - network.subscribeConnectRequest( - (peer, incoming) -> protocolManager.shouldConnect(peer, incoming)); + network.subscribeConnectRequest(ethPeersShouldConnect::apply); network.subscribeDisconnect( (connection, disconnectReason, initiatedByPeer) -> { @@ -186,6 +190,7 @@ public class NetworkRunner implements AutoCloseable { List protocolManagers = new ArrayList<>(); List subProtocols = new ArrayList<>(); MetricsSystem metricsSystem; + private BiFunction ethPeersShouldConnect; public NetworkRunner build() { final Map subProtocolMap = new HashMap<>(); @@ -203,7 +208,8 @@ public class NetworkRunner implements AutoCloseable { } } final P2PNetwork network = networkProvider.build(caps); - return new NetworkRunner(network, subProtocolMap, protocolManagers, metricsSystem); + return new NetworkRunner( + network, subProtocolMap, protocolManagers, metricsSystem, ethPeersShouldConnect); } public Builder protocolManagers(final List protocolManagers) { @@ -230,6 +236,11 @@ public class NetworkRunner implements AutoCloseable { this.metricsSystem = metricsSystem; return this; } + + public Builder ethPeersShouldConnect(final BiFunction shouldConnect) { + this.ethPeersShouldConnect = shouldConnect; + return this; + } } @FunctionalInterface diff --git a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/network/ProtocolManager.java b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/network/ProtocolManager.java index 603464d690..c61e6d907c 100644 --- a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/network/ProtocolManager.java +++ b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/network/ProtocolManager.java @@ -14,7 +14,6 @@ */ package org.hyperledger.besu.ethereum.p2p.network; -import org.hyperledger.besu.ethereum.p2p.peers.Peer; import org.hyperledger.besu.ethereum.p2p.rlpx.connections.PeerConnection; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.Capability; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.Message; @@ -59,15 +58,6 @@ public interface ProtocolManager extends AutoCloseable { */ void handleNewConnection(PeerConnection peerConnection); - /** - * Call this to find out whether we should try to connect to a certain peer - * - * @param peer the peer that we are trying to connect to - * @param incoming true if the connection is incoming - * @return true, if the ProtocolManager wants to connect to the peer, false otherwise - */ - boolean shouldConnect(Peer peer, final boolean incoming); - /** * Handles peer disconnects. * diff --git a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/rlpx/wire/messages/DisconnectMessage.java b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/rlpx/wire/messages/DisconnectMessage.java index 87df88c40e..d951ecc5d9 100644 --- a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/rlpx/wire/messages/DisconnectMessage.java +++ b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/rlpx/wire/messages/DisconnectMessage.java @@ -129,11 +129,11 @@ public final class DisconnectMessage extends AbstractMessageData { USELESS_PEER_NO_SHARED_CAPABILITIES((byte) 0x03, "No shared capabilities"), USELESS_PEER_WORLD_STATE_NOT_AVAILABLE((byte) 0x03, "World state not available"), USELESS_PEER_MISMATCHED_PIVOT_BLOCK((byte) 0x03, "Mismatched pivot block"), - USELESS_PEER_FAILED_TO_RETRIEVE_CHAIN_STATE( - (byte) 0x03, "Failed to retrieve header for chain state"), + USELESS_PEER_FAILED_TO_RETRIEVE_CHAIN_HEAD((byte) 0x03, "Failed to retrieve chain head header"), USELESS_PEER_CANNOT_CONFIRM_PIVOT_BLOCK((byte) 0x03, "Peer failed to confirm pivot block"), USELESS_PEER_BY_REPUTATION((byte) 0x03, "Lowest reputation score"), USELESS_PEER_BY_CHAIN_COMPARATOR((byte) 0x03, "Lowest by chain height comparator"), + USELESS_PEER_EXCEEDS_TRAILING_PEERS((byte) 0x03, "Adding peer would exceed max trailing peers"), TOO_MANY_PEERS((byte) 0x04), ALREADY_CONNECTED((byte) 0x05), INCOMPATIBLE_P2P_PROTOCOL_VERSION((byte) 0x06), diff --git a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/RetestethContext.java b/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/RetestethContext.java index eb43f96dfb..fd39ef7f44 100644 --- a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/RetestethContext.java +++ b/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/RetestethContext.java @@ -42,12 +42,14 @@ import org.hyperledger.besu.ethereum.eth.manager.EthContext; import org.hyperledger.besu.ethereum.eth.manager.EthMessages; import org.hyperledger.besu.ethereum.eth.manager.EthPeers; import org.hyperledger.besu.ethereum.eth.manager.EthScheduler; +import org.hyperledger.besu.ethereum.eth.sync.SyncMode; import org.hyperledger.besu.ethereum.eth.sync.state.SyncState; import org.hyperledger.besu.ethereum.eth.transactions.BlobCache; import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolFactory; +import org.hyperledger.besu.ethereum.forkid.ForkIdManager; import org.hyperledger.besu.ethereum.mainnet.EpochCalculator; import org.hyperledger.besu.ethereum.mainnet.HeaderValidationMode; import org.hyperledger.besu.ethereum.mainnet.MainnetBlockHeaderFunctions; @@ -73,6 +75,7 @@ import org.hyperledger.besu.util.Subscribers; import org.hyperledger.besu.util.number.Fraction; import java.util.Collections; +import java.util.List; import java.util.Optional; import java.util.concurrent.locks.ReentrantLock; import java.util.function.Supplier; @@ -239,7 +242,9 @@ public class RetestethContext { localNodeKey, MAX_PEERS, MAX_PEERS, - false); + false, + SyncMode.FAST, + new ForkIdManager(blockchain, List.of(), List.of(), false)); final SyncState syncState = new SyncState(blockchain, ethPeers); ethScheduler = new EthScheduler(1, 1, 1, 1, metricsSystem); From 4ee14eca1de3857af218311cf466970999cf0d40 Mon Sep 17 00:00:00 2001 From: Gabriel-Trintinalia Date: Thu, 4 Jul 2024 12:21:25 +1000 Subject: [PATCH 021/259] Implement System Calls (#7263) Signed-off-by: Gabriel-Trintinalia --- .../blockcreation/AbstractBlockCreator.java | 16 +- .../AbstractBlockCreatorTest.java | 4 +- .../mainnet/AbstractBlockProcessor.java | 14 +- .../mainnet/MainnetTransactionProcessor.java | 2 +- .../ethereum/mainnet/SystemCallProcessor.java | 141 ++++++++++++ .../WithdrawalRequestContractHelper.java | 197 ----------------- .../AbstractSystemCallRequestProcessor.java | 102 +++++++++ .../requests/DepositRequestProcessor.java | 7 +- .../requests/ProcessRequestContext.java | 32 +++ .../mainnet/requests/RequestProcessor.java | 6 +- .../requests/RequestProcessorCoordinator.java | 7 +- .../requests/WithdrawalRequestProcessor.java | 63 ++++-- .../requests/WithdrawalRequestValidator.java | 6 +- .../mainnet/SystemCallProcessorTest.java | 113 ++++++++++ .../WithdrawalRequestContractHelperTest.java | 205 ------------------ ...ithdrawalRequestValidatorTestFixtures.java | 2 +- .../hyperledger/besu/evmtool/T8nExecutor.java | 12 +- 17 files changed, 487 insertions(+), 442 deletions(-) create mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/SystemCallProcessor.java delete mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/WithdrawalRequestContractHelper.java create mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/AbstractSystemCallRequestProcessor.java create mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/ProcessRequestContext.java create mode 100644 ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/SystemCallProcessorTest.java delete mode 100644 ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/WithdrawalRequestContractHelperTest.java 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 15f3b16d89..78c32842ff 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 @@ -50,7 +50,9 @@ import org.hyperledger.besu.ethereum.mainnet.WithdrawalsProcessor; import org.hyperledger.besu.ethereum.mainnet.feemarket.BaseFeeMarket; import org.hyperledger.besu.ethereum.mainnet.feemarket.ExcessBlobGasCalculator; import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; +import org.hyperledger.besu.ethereum.mainnet.requests.ProcessRequestContext; import org.hyperledger.besu.ethereum.mainnet.requests.RequestProcessorCoordinator; +import org.hyperledger.besu.ethereum.vm.CachingBlockHashLookup; import org.hyperledger.besu.evm.account.MutableAccount; import org.hyperledger.besu.evm.worldstate.WorldUpdater; import org.hyperledger.besu.plugin.services.exception.StorageException; @@ -241,10 +243,18 @@ public abstract class AbstractBlockCreator implements AsyncBlockCreator { // EIP-7685: process EL requests final Optional requestProcessor = newProtocolSpec.getRequestProcessorCoordinator(); + + ProcessRequestContext context = + new ProcessRequestContext( + processableBlockHeader, + disposableWorldState, + newProtocolSpec, + transactionResults.getReceipts(), + new CachingBlockHashLookup(processableBlockHeader, protocolContext.getBlockchain()), + operationTracer); + Optional> maybeRequests = - requestProcessor.flatMap( - processor -> - processor.process(disposableWorldState, transactionResults.getReceipts())); + requestProcessor.flatMap(processor -> processor.process(context)); throwIfStopped(); 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 856bf874b2..68d13987bb 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 @@ -77,6 +77,7 @@ import org.hyperledger.besu.ethereum.mainnet.WithdrawalsProcessor; import org.hyperledger.besu.ethereum.mainnet.feemarket.CancunFeeMarket; 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.evm.internal.EvmConfiguration; @@ -135,7 +136,8 @@ abstract class AbstractBlockCreatorTest { final List expectedDepositRequests = List.of(expectedDepositRequest); var depositRequestsFromReceipts = - new DepositRequestProcessor(DEFAULT_DEPOSIT_CONTRACT_ADDRESS).process(null, receipts); + new DepositRequestProcessor(DEFAULT_DEPOSIT_CONTRACT_ADDRESS) + .process(new ProcessRequestContext(null, null, null, receipts, null, null)); assertThat(depositRequestsFromReceipts.get()).isEqualTo(expectedDepositRequests); } 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 888bc848f1..8ecfa453d9 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 @@ -29,6 +29,7 @@ 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.Withdrawal; +import org.hyperledger.besu.ethereum.mainnet.requests.ProcessRequestContext; import org.hyperledger.besu.ethereum.mainnet.requests.RequestProcessorCoordinator; import org.hyperledger.besu.ethereum.privacy.storage.PrivateMetadataUpdater; import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult; @@ -107,6 +108,7 @@ public abstract class AbstractBlockProcessor implements BlockProcessor { final ProtocolSpec protocolSpec = protocolSchedule.getByBlockHeader(blockHeader); protocolSpec.getBlockHashProcessor().processBlockHashes(blockchain, worldState, blockHeader); + final BlockHashLookup blockHashLookup = new CachingBlockHashLookup(blockHeader, blockchain); for (final Transaction transaction : transactions) { if (!hasAvailableBlockBudget(blockHeader, transaction, currentGasUsed)) { @@ -115,7 +117,6 @@ public abstract class AbstractBlockProcessor implements BlockProcessor { final WorldUpdater worldStateUpdater = worldState.updater(); - final BlockHashLookup blockHashLookup = new CachingBlockHashLookup(blockHeader, blockchain); final Address miningBeneficiary = miningBeneficiaryCalculator.calculateBeneficiary(blockHeader); @@ -197,7 +198,16 @@ public abstract class AbstractBlockProcessor implements BlockProcessor { protocolSpec.getRequestProcessorCoordinator(); Optional> maybeRequests = Optional.empty(); if (requestProcessor.isPresent()) { - maybeRequests = requestProcessor.get().process(worldState, receipts); + ProcessRequestContext context = + new ProcessRequestContext( + blockHeader, + worldState, + protocolSpec, + receipts, + blockHashLookup, + OperationTracer.NO_TRACING); + + maybeRequests = requestProcessor.get().process(context); } if (!rewardCoinbase(worldState, blockHeader, ommers, skipZeroBlockRewards)) { diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java index d982265f24..53801d14cd 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java @@ -563,7 +563,7 @@ public class MainnetTransactionProcessor { executor.process(frame, operationTracer); } - private AbstractMessageProcessor getMessageProcessor(final MessageFrame.Type type) { + public AbstractMessageProcessor getMessageProcessor(final MessageFrame.Type type) { return switch (type) { case MESSAGE_CALL -> messageCallProcessor; case CONTRACT_CREATION -> contractCreationProcessor; 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 new file mode 100644 index 0000000000..f74de79442 --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/SystemCallProcessor.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.mainnet; + +import static org.hyperledger.besu.evm.frame.MessageFrame.DEFAULT_MAX_STACK_SIZE; + +import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.datatypes.Wei; +import org.hyperledger.besu.ethereum.core.ProcessableBlockHeader; +import org.hyperledger.besu.evm.account.Account; +import org.hyperledger.besu.evm.code.CodeV0; +import org.hyperledger.besu.evm.frame.MessageFrame; +import org.hyperledger.besu.evm.operation.BlockHashOperation; +import org.hyperledger.besu.evm.processor.AbstractMessageProcessor; +import org.hyperledger.besu.evm.tracing.OperationTracer; +import org.hyperledger.besu.evm.worldstate.WorldUpdater; + +import java.util.Deque; +import java.util.Optional; + +import org.apache.tuweni.bytes.Bytes; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SystemCallProcessor { + private static final Logger LOG = LoggerFactory.getLogger(SystemCallProcessor.class); + + /** The system address */ + static final Address SYSTEM_ADDRESS = + Address.fromHexString("0xfffffffffffffffffffffffffffffffffffffffe"); + + private final MainnetTransactionProcessor mainnetTransactionProcessor; + + public SystemCallProcessor(final MainnetTransactionProcessor mainnetTransactionProcessor) { + this.mainnetTransactionProcessor = mainnetTransactionProcessor; + } + + /** + * Processes a system call to a specified address, using the provided world state, block header, + * operation tracer, and block hash lookup. + * + * @param callAddress the address to call. + * @param worldState the current world state. + * @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 + */ + public Bytes process( + final Address callAddress, + final WorldUpdater worldState, + final ProcessableBlockHeader blockHeader, + final OperationTracer operationTracer, + final BlockHashOperation.BlockHashLookup blockHashLookup) { + + // if no code exists at CALL_ADDRESS, the call must fail silently + final Account maybeContract = worldState.get(callAddress); + if (maybeContract == null) { + LOG.trace("System call address not found {}", callAddress); + return null; + } + + final AbstractMessageProcessor messageProcessor = + mainnetTransactionProcessor.getMessageProcessor(MessageFrame.Type.MESSAGE_CALL); + final MessageFrame initialFrame = + createCallFrame(callAddress, worldState, blockHeader, blockHashLookup); + + return processFrame(initialFrame, messageProcessor, operationTracer, worldState); + } + + private Bytes processFrame( + final MessageFrame frame, + final AbstractMessageProcessor processor, + final OperationTracer tracer, + final WorldUpdater updater) { + + if (!frame.getCode().isValid()) { + throw new RuntimeException("System call did not execute to completion - opcode invalid"); + } + + Deque stack = frame.getMessageFrameStack(); + while (!stack.isEmpty()) { + processor.process(stack.peekFirst(), tracer); + } + + if (frame.getState() == MessageFrame.State.COMPLETED_SUCCESS) { + updater.commit(); + return frame.getOutputData(); + } + + // the call must execute to completion + throw new RuntimeException("System call did not execute to completion"); + } + + private MessageFrame createCallFrame( + final Address callAddress, + final WorldUpdater worldUpdater, + final ProcessableBlockHeader blockHeader, + final BlockHashOperation.BlockHashLookup blockHashLookup) { + + final Optional maybeContract = Optional.ofNullable(worldUpdater.get(callAddress)); + final AbstractMessageProcessor processor = + mainnetTransactionProcessor.getMessageProcessor(MessageFrame.Type.MESSAGE_CALL); + + return MessageFrame.builder() + .maxStackSize(DEFAULT_MAX_STACK_SIZE) + .worldUpdater(worldUpdater) + .initialGas(30_000_000L) + .originator(SYSTEM_ADDRESS) + .gasPrice(Wei.ZERO) + .blobGasPrice(Wei.ZERO) + .value(Wei.ZERO) + .apparentValue(Wei.ZERO) + .blockValues(blockHeader) + .completer(__ -> {}) + .miningBeneficiary(Address.ZERO) // Confirm this + .type(MessageFrame.Type.MESSAGE_CALL) + .address(callAddress) + .contract(callAddress) + .inputData(Bytes.EMPTY) + .sender(SYSTEM_ADDRESS) + .blockHashLookup(blockHashLookup) + .code( + maybeContract + .map(c -> processor.getCodeFromEVM(c.getCodeHash(), c.getCode())) + .orElse(CodeV0.EMPTY_CODE)) + .build(); + } +} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/WithdrawalRequestContractHelper.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/WithdrawalRequestContractHelper.java deleted file mode 100644 index c0b7302e86..0000000000 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/WithdrawalRequestContractHelper.java +++ /dev/null @@ -1,197 +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 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.MutableWorldState; -import org.hyperledger.besu.ethereum.core.WithdrawalRequest; -import org.hyperledger.besu.evm.account.Account; -import org.hyperledger.besu.evm.account.MutableAccount; -import org.hyperledger.besu.evm.worldstate.WorldUpdater; - -import java.util.ArrayList; -import java.util.List; - -import com.google.common.annotations.VisibleForTesting; -import org.apache.tuweni.bytes.Bytes; -import org.apache.tuweni.units.bigints.UInt256; -import org.apache.tuweni.units.bigints.UInt64; - -/** - * Helper for interacting with the Validator Withdrawal Request Contract - * (https://eips.ethereum.org/EIPS/eip-7002) - * - *

TODO: Please note that this is not the spec-way of interacting with the Validator Withdrawal - * Request contract. See https://github.com/hyperledger/besu/issues/6918 for more information. - */ -public class WithdrawalRequestContractHelper { - - public static final Address WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS = - Address.fromHexString("0x00A3ca265EBcb825B45F985A16CEFB49958cE017"); - - /** private constructor to prevent instantiations */ - private WithdrawalRequestContractHelper() {} - - @VisibleForTesting - // Storage slot to store the difference between number of withdrawal requests since last block and - // target withdrawal requests - // per block - static final UInt256 EXCESS_WITHDRAWAL_REQUESTS_STORAGE_SLOT = UInt256.valueOf(0L); - - @VisibleForTesting - // Storage slot to store the number of withdrawal requests added since last block - static final UInt256 WITHDRAWAL_REQUEST_COUNT_STORAGE_SLOT = UInt256.valueOf(1L); - - @VisibleForTesting - static final UInt256 WITHDRAWAL_REQUEST_QUEUE_HEAD_STORAGE_SLOT = UInt256.valueOf(2L); - - @VisibleForTesting - static final UInt256 WITHDRAWAL_REQUEST_QUEUE_TAIL_STORAGE_SLOT = UInt256.valueOf(3L); - - private static final UInt256 WITHDRAWAL_REQUEST_QUEUE_STORAGE_OFFSET = UInt256.valueOf(4L); - - // How many slots each withdrawal request occupies in the account state - private static final int WITHDRAWAL_REQUEST_STORAGE_SLOT_SIZE = 3; - - public static final int MAX_WITHDRAWAL_REQUESTS_PER_BLOCK = 16; - - private static final int TARGET_WITHDRAWAL_REQUESTS_PER_BLOCK = 2; - - private static final UInt256 INITIAL_EXCESS_WITHDRAWAL_REQUESTS_STORAGE_SLOT = - UInt256.valueOf(1181); - - // TODO-lucas Add MIN_WITHDRAWAL_REQUEST_FEE and WITHDRAWAL_REQUEST_FEE_UPDATE_FRACTION - - /* - Pop the expected list of withdrawal requests from the smart contract, updating the queue pointers and other - control variables in the contract state. - */ - public static List popWithdrawalRequestsFromQueue( - final MutableWorldState mutableWorldState) { - final WorldUpdater worldUpdater = mutableWorldState.updater(); - final MutableAccount account = worldUpdater.getAccount(WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS); - if (account == null || Hash.EMPTY.equals(account.getCodeHash())) { - return List.of(); - } - - final List withdrawalRequests = dequeueWithdrawalRequests(account); - updateExcessWithdrawalRequests(account); - resetWithdrawalRequestsCount(account); - - worldUpdater.commit(); - - return withdrawalRequests; - } - - private static List dequeueWithdrawalRequests(final MutableAccount account) { - final UInt256 queueHeadIndex = - account.getStorageValue(WITHDRAWAL_REQUEST_QUEUE_HEAD_STORAGE_SLOT); - final UInt256 queueTailIndex = - account.getStorageValue(WITHDRAWAL_REQUEST_QUEUE_TAIL_STORAGE_SLOT); - - final List withdrawalRequests = - peekExpectedWithdrawalRequests(account, queueHeadIndex, queueTailIndex); - - final UInt256 newQueueHeadIndex = queueHeadIndex.plus(withdrawalRequests.size()); - if (newQueueHeadIndex.equals(queueTailIndex)) { - // Queue is empty, reset queue pointers - account.setStorageValue(WITHDRAWAL_REQUEST_QUEUE_HEAD_STORAGE_SLOT, UInt256.valueOf(0L)); - account.setStorageValue(WITHDRAWAL_REQUEST_QUEUE_TAIL_STORAGE_SLOT, UInt256.valueOf(0L)); - } else { - account.setStorageValue(WITHDRAWAL_REQUEST_QUEUE_HEAD_STORAGE_SLOT, newQueueHeadIndex); - } - - return withdrawalRequests; - } - - /* - ;; Each stack element has the following layout: - ;; - ;; A: addr - ;; 0x00 | 00 00 00 00 00 00 00 00 00 00 00 00 aa aa aa aa - ;; 0x10 | aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa - ;; - ;; B: pk[0:32] - ;; 0x00 | bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb - ;; 0x10 | bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb - ;; - ;; C: pk[32:48] ++ am[0:8] -> pk2_am - ;; 0x00 | cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc - ;; 0x10 | dd dd dd dd dd dd dd dd 00 00 00 00 00 00 00 00 - ;; - ;; To get these three stack elements into the correct contiguous format, it is - ;; necessary to combine them in the follow form: - ;; - ;; (A[12:32] ++ B[0:12], B[12:32] ++ C[0:12], C[12:24]) - */ - private static List peekExpectedWithdrawalRequests( - final Account account, final UInt256 queueHeadIndex, final UInt256 queueTailIndex) { - final long numRequestsInQueue = queueTailIndex.subtract(queueHeadIndex).toLong(); - final long numRequestsDequeued = - Long.min(numRequestsInQueue, MAX_WITHDRAWAL_REQUESTS_PER_BLOCK); - - final List withdrawalRequests = new ArrayList<>(); - - for (int i = 0; i < numRequestsDequeued; i++) { - final UInt256 queueStorageSlot = - WITHDRAWAL_REQUEST_QUEUE_STORAGE_OFFSET.plus( - queueHeadIndex.plus(i).multiply(WITHDRAWAL_REQUEST_STORAGE_SLOT_SIZE)); - final Address sourceAddress = - Address.wrap(account.getStorageValue(queueStorageSlot).toBytes().slice(12, 20)); - final BLSPublicKey validatorPubkey = - BLSPublicKey.wrap( - Bytes.concatenate( - account - .getStorageValue(queueStorageSlot.plus(1)) - .toBytes() - .slice(0, 32), // no need to slice - account.getStorageValue(queueStorageSlot.plus(2)).toBytes().slice(0, 16))); - final UInt64 amount = - UInt64.fromBytes(account.getStorageValue(queueStorageSlot.plus(2)).slice(16, 8)); - - withdrawalRequests.add( - new WithdrawalRequest(sourceAddress, validatorPubkey, GWei.of(amount))); - } - - return withdrawalRequests; - } - - private static void updateExcessWithdrawalRequests(final MutableAccount account) { - UInt256 previousExcessRequests = - account.getStorageValue(EXCESS_WITHDRAWAL_REQUESTS_STORAGE_SLOT); - - if (previousExcessRequests.equals(INITIAL_EXCESS_WITHDRAWAL_REQUESTS_STORAGE_SLOT)) { - previousExcessRequests = UInt256.ZERO; - } - - final UInt256 requestsCount = account.getStorageValue(WITHDRAWAL_REQUEST_COUNT_STORAGE_SLOT); - - UInt256 newExcessRequests = UInt256.valueOf(0L); - if (previousExcessRequests.plus(requestsCount).toLong() - > TARGET_WITHDRAWAL_REQUESTS_PER_BLOCK) { - newExcessRequests = - previousExcessRequests.plus(requestsCount).subtract(TARGET_WITHDRAWAL_REQUESTS_PER_BLOCK); - } - - account.setStorageValue(EXCESS_WITHDRAWAL_REQUESTS_STORAGE_SLOT, newExcessRequests); - } - - private static void resetWithdrawalRequestsCount(final MutableAccount account) { - account.setStorageValue(WITHDRAWAL_REQUEST_COUNT_STORAGE_SLOT, UInt256.valueOf(0L)); - } -} 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 new file mode 100644 index 0000000000..a7d959f4b9 --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/AbstractSystemCallRequestProcessor.java @@ -0,0 +1,102 @@ +/* + * 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/DepositRequestProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/DepositRequestProcessor.java index ce3ed6a5f6..8902ecc510 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 @@ -16,7 +16,6 @@ package org.hyperledger.besu.ethereum.mainnet.requests; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.ethereum.core.DepositRequest; -import org.hyperledger.besu.ethereum.core.MutableWorldState; import org.hyperledger.besu.ethereum.core.Request; import org.hyperledger.besu.ethereum.core.TransactionReceipt; import org.hyperledger.besu.ethereum.core.encoding.DepositRequestDecoder; @@ -39,12 +38,12 @@ public class DepositRequestProcessor implements RequestProcessor { } @Override - public Optional> process( - final MutableWorldState ignored, final List transactionReceipts) { + public Optional> process(final ProcessRequestContext context) { if (depositContractAddress.isEmpty()) { return Optional.empty(); } - List depositRequests = findDepositRequestsFromReceipts(transactionReceipts); + List depositRequests = + findDepositRequestsFromReceipts(context.transactionReceipts()); return Optional.of(depositRequests); } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/ProcessRequestContext.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/ProcessRequestContext.java new file mode 100644 index 0000000000..63f4a8d514 --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/ProcessRequestContext.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.mainnet.requests; + +import org.hyperledger.besu.ethereum.core.MutableWorldState; +import org.hyperledger.besu.ethereum.core.ProcessableBlockHeader; +import org.hyperledger.besu.ethereum.core.TransactionReceipt; +import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; +import org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup; +import org.hyperledger.besu.evm.tracing.OperationTracer; + +import java.util.List; + +public record ProcessRequestContext( + ProcessableBlockHeader blockHeader, + MutableWorldState mutableWorldState, + ProtocolSpec protocolSpec, + List transactionReceipts, + BlockHashLookup blockHashLookup, + OperationTracer operationTracer) {} 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 d09b3c47d1..55f3cd4178 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 @@ -14,15 +14,11 @@ */ package org.hyperledger.besu.ethereum.mainnet.requests; -import org.hyperledger.besu.ethereum.core.MutableWorldState; import org.hyperledger.besu.ethereum.core.Request; -import org.hyperledger.besu.ethereum.core.TransactionReceipt; import java.util.List; import java.util.Optional; public interface RequestProcessor { - Optional> process( - final MutableWorldState mutableWorldState, - final List transactionReceipts); + Optional> 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 b72674b4d2..b98274729d 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 @@ -15,9 +15,7 @@ package org.hyperledger.besu.ethereum.mainnet.requests; import org.hyperledger.besu.datatypes.RequestType; -import org.hyperledger.besu.ethereum.core.MutableWorldState; import org.hyperledger.besu.ethereum.core.Request; -import org.hyperledger.besu.ethereum.core.TransactionReceipt; import java.util.ArrayList; import java.util.List; @@ -39,11 +37,10 @@ public class RequestProcessorCoordinator { this.processors = processors; } - public Optional> process( - final MutableWorldState mutableWorldState, final List receipts) { + public Optional> process(final ProcessRequestContext context) { List requests = null; for (RequestProcessor requestProcessor : processors.values()) { - var r = requestProcessor.process(mutableWorldState, receipts); + var r = requestProcessor.process(context); if (r.isPresent()) { if (requests == null) { requests = new ArrayList<>(); 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 index 9803f23f3f..b230a6d610 100644 --- 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 @@ -14,25 +14,60 @@ */ package org.hyperledger.besu.ethereum.mainnet.requests; -import org.hyperledger.besu.ethereum.core.MutableWorldState; -import org.hyperledger.besu.ethereum.core.Request; -import org.hyperledger.besu.ethereum.core.TransactionReceipt; +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.mainnet.WithdrawalRequestContractHelper; -import java.util.List; -import java.util.Optional; +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.units.bigints.UInt64; -public class WithdrawalRequestProcessor implements RequestProcessor { +/** Processor for handling withdrawal requests. */ +public class WithdrawalRequestProcessor + extends AbstractSystemCallRequestProcessor { + + public static final Address WITHDRAWAL_REQUEST_PREDEPLOY_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; + + /** + * Gets the call address for withdrawal requests. + * + * @return The call address. + */ @Override - public Optional> process( - final MutableWorldState mutableWorldState, - final List transactionReceipts) { + protected Address getCallAddress() { + return WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS; + } - List withdrawalRequests = - WithdrawalRequestContractHelper.popWithdrawalRequestsFromQueue(mutableWorldState).stream() - .toList(); + /** + * 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; + } - return Optional.of(withdrawalRequests); + /** + * 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 index d5f04e6ef7..fc108b798f 100644 --- 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 @@ -21,7 +21,6 @@ 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 org.hyperledger.besu.ethereum.mainnet.WithdrawalRequestContractHelper; import java.util.Collections; import java.util.List; @@ -32,6 +31,8 @@ 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( @@ -51,8 +52,7 @@ public class WithdrawalRequestValidator implements RequestValidator { .orElse(Collections.emptyList()); // TODO Do we need to allow for customization? (e.g. if the value changes in the next fork) - if (withdrawalRequestsInBlock.size() - > WithdrawalRequestContractHelper.MAX_WITHDRAWAL_REQUESTS_PER_BLOCK) { + if (withdrawalRequestsInBlock.size() > MAX_WITHDRAWAL_REQUESTS_PER_BLOCK) { LOG.warn( "Block {} has more than the allowed maximum number of withdrawal requests", blockHash); return false; 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 new file mode 100644 index 0000000000..e1d3906e73 --- /dev/null +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/SystemCallProcessorTest.java @@ -0,0 +1,113 @@ +/* + * 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.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider; +import org.hyperledger.besu.ethereum.core.MutableWorldState; +import org.hyperledger.besu.ethereum.core.ProcessableBlockHeader; +import org.hyperledger.besu.evm.frame.MessageFrame; +import org.hyperledger.besu.evm.operation.BlockHashOperation; +import org.hyperledger.besu.evm.processor.AbstractMessageProcessor; +import org.hyperledger.besu.evm.processor.MessageCallProcessor; +import org.hyperledger.besu.evm.tracing.OperationTracer; +import org.hyperledger.besu.evm.worldstate.WorldUpdater; + +import org.apache.tuweni.bytes.Bytes; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class SystemCallProcessorTest { + private static final Address CALL_ADDRESS = Address.fromHexString("0x1"); + private static final Bytes EXPECTED_OUTPUT = Bytes.fromHexString("0x01"); + private ProcessableBlockHeader mockBlockHeader; + private MainnetTransactionProcessor mockTransactionProcessor; + private BlockHashOperation.BlockHashLookup mockBlockHashLookup; + private AbstractMessageProcessor mockMessageCallProcessor; + + @BeforeEach + public void setUp() { + mockBlockHeader = mock(ProcessableBlockHeader.class); + mockTransactionProcessor = mock(MainnetTransactionProcessor.class); + mockMessageCallProcessor = mock(MessageCallProcessor.class); + mockBlockHashLookup = mock(BlockHashOperation.BlockHashLookup.class); + when(mockTransactionProcessor.getMessageProcessor(any())).thenReturn(mockMessageCallProcessor); + } + + @Test + void shouldProcessSuccessfully() { + doAnswer( + invocation -> { + MessageFrame messageFrame = invocation.getArgument(0); + messageFrame.setOutputData(EXPECTED_OUTPUT); + messageFrame.getMessageFrameStack().pop(); + messageFrame.setState(MessageFrame.State.COMPLETED_SUCCESS); + return null; + }) + .when(mockMessageCallProcessor) + .process(any(), any()); + final MutableWorldState worldState = createWorldState(CALL_ADDRESS); + Bytes actualOutput = processSystemCall(worldState); + assertThat(actualOutput).isEqualTo(EXPECTED_OUTPUT); + } + + @Test + void shouldThrowExceptionOnFailedExecution() { + doAnswer( + invocation -> { + MessageFrame messageFrame = invocation.getArgument(0); + messageFrame.getMessageFrameStack().pop(); + messageFrame.setState(MessageFrame.State.COMPLETED_FAILED); + return null; + }) + .when(mockMessageCallProcessor) + .process(any(), any()); + final MutableWorldState worldState = createWorldState(CALL_ADDRESS); + var exception = assertThrows(RuntimeException.class, () -> processSystemCall(worldState)); + assertThat(exception.getMessage()).isEqualTo("System call did not execute to completion"); + } + + @Test + void shouldReturnNullWhenContractDoesNotExist() { + final MutableWorldState worldState = InMemoryKeyValueStorageProvider.createInMemoryWorldState(); + Bytes actualOutput = processSystemCall(worldState); + assertThat(actualOutput).isNull(); + } + + Bytes processSystemCall(final MutableWorldState worldState) { + SystemCallProcessor systemCallProcessor = new SystemCallProcessor(mockTransactionProcessor); + return systemCallProcessor.process( + CALL_ADDRESS, + worldState.updater(), + mockBlockHeader, + OperationTracer.NO_TRACING, + mockBlockHashLookup); + } + + private MutableWorldState createWorldState(final Address address) { + final MutableWorldState worldState = InMemoryKeyValueStorageProvider.createInMemoryWorldState(); + final WorldUpdater updater = worldState.updater(); + updater.getOrCreate(address); + updater.commit(); + return worldState; + } +} diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/WithdrawalRequestContractHelperTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/WithdrawalRequestContractHelperTest.java deleted file mode 100644 index 7e1e857135..0000000000 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/WithdrawalRequestContractHelperTest.java +++ /dev/null @@ -1,205 +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.core.InMemoryKeyValueStorageProvider.createInMemoryWorldStateArchive; -import static org.hyperledger.besu.ethereum.mainnet.WithdrawalRequestContractHelper.EXCESS_WITHDRAWAL_REQUESTS_STORAGE_SLOT; -import static org.hyperledger.besu.ethereum.mainnet.WithdrawalRequestContractHelper.WITHDRAWAL_REQUEST_COUNT_STORAGE_SLOT; -import static org.hyperledger.besu.ethereum.mainnet.WithdrawalRequestContractHelper.WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS; -import static org.hyperledger.besu.ethereum.mainnet.WithdrawalRequestContractHelper.WITHDRAWAL_REQUEST_QUEUE_HEAD_STORAGE_SLOT; -import static org.hyperledger.besu.ethereum.mainnet.WithdrawalRequestContractHelper.WITHDRAWAL_REQUEST_QUEUE_TAIL_STORAGE_SLOT; - -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.BLSPublicKey; -import org.hyperledger.besu.datatypes.GWei; -import org.hyperledger.besu.ethereum.core.MutableWorldState; -import org.hyperledger.besu.ethereum.core.WithdrawalRequest; -import org.hyperledger.besu.evm.account.MutableAccount; -import org.hyperledger.besu.evm.worldstate.WorldUpdater; - -import java.util.List; -import java.util.stream.IntStream; - -import org.apache.tuweni.bytes.Bytes; -import org.apache.tuweni.bytes.Bytes32; -import org.apache.tuweni.bytes.Bytes48; -import org.apache.tuweni.units.bigints.UInt256; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -class WithdrawalRequestContractHelperTest { - - private MutableWorldState worldState; - private MutableAccount contract; - - @BeforeEach - void setUp() { - worldState = createInMemoryWorldStateArchive().getMutable(); - } - - @Test - void popWithdrawalRequestsFromQueue_ReadWithdrawalRequestsCorrectly() { - final List validatorWithdrawalRequests = - List.of(createExit(), createExit(), createExit()); - loadContractStorage(worldState, validatorWithdrawalRequests); - - final List poppedWithdrawalRequests = - WithdrawalRequestContractHelper.popWithdrawalRequestsFromQueue(worldState); - - assertThat(poppedWithdrawalRequests).isEqualTo(validatorWithdrawalRequests); - } - - @Test - void - popWithdrawalRequestsFromQueue_whenContractCodeIsEmpty_ReturnsEmptyListOfWithdrawalRequests() { - // Create account with empty code - final WorldUpdater updater = worldState.updater(); - updater.createAccount(WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS); - updater.commit(); - - assertThat(WithdrawalRequestContractHelper.popWithdrawalRequestsFromQueue(worldState)) - .isEmpty(); - } - - @Test - void popWithdrawalRequestsFromQueue_WhenMoreWithdrawalRequests_UpdatesQueuePointers() { - // Loading contract with more than 16 WithdrawalRequests - final List validatorWithdrawalRequests = - IntStream.range(0, 30).mapToObj(__ -> createExit()).toList(); - loadContractStorage(worldState, validatorWithdrawalRequests); - // After loading the contract, the WithdrawalRequests count since last block should match the - // size of the list - assertContractStorageValue( - WITHDRAWAL_REQUEST_COUNT_STORAGE_SLOT, validatorWithdrawalRequests.size()); - - final List poppedWithdrawalRequests = - WithdrawalRequestContractHelper.popWithdrawalRequestsFromQueue(worldState); - assertThat(poppedWithdrawalRequests).hasSize(16); - - // Check that queue pointers were updated successfully (head advanced to index 16) - assertContractStorageValue(WITHDRAWAL_REQUEST_QUEUE_HEAD_STORAGE_SLOT, 16); - assertContractStorageValue(WITHDRAWAL_REQUEST_QUEUE_TAIL_STORAGE_SLOT, 30); - - // We had 30 WithdrawalRequests in the queue, and target per block is 2, so we have 28 excess - assertContractStorageValue(EXCESS_WITHDRAWAL_REQUESTS_STORAGE_SLOT, 28); - - // We always reset the WithdrawalRequests count after processing the queue - assertContractStorageValue(WITHDRAWAL_REQUEST_COUNT_STORAGE_SLOT, 0); - } - - @Test - void popWithdrawalRequestsFromQueue_WhenNoMoreWithdrawalRequests_ZeroQueuePointers() { - final List withdrawalRequests = - List.of(createExit(), createExit(), createExit()); - loadContractStorage(worldState, withdrawalRequests); - // After loading the contract, the exit count since last block should match the size of the list - assertContractStorageValue(WITHDRAWAL_REQUEST_COUNT_STORAGE_SLOT, withdrawalRequests.size()); - - final List poppedWithdrawalRequests = - WithdrawalRequestContractHelper.popWithdrawalRequestsFromQueue(worldState); - assertThat(poppedWithdrawalRequests).hasSize(3); - - // Check that queue pointers were updated successfully (head and tail zero because queue is - // empty) - assertContractStorageValue(WITHDRAWAL_REQUEST_QUEUE_HEAD_STORAGE_SLOT, 0); - assertContractStorageValue(WITHDRAWAL_REQUEST_QUEUE_TAIL_STORAGE_SLOT, 0); - - // We had 3 WithdrawalRequests in the queue, target per block is 2, so we have 1 excess - assertContractStorageValue(EXCESS_WITHDRAWAL_REQUESTS_STORAGE_SLOT, 1); - - // We always reset the WithdrawalRequests count after processing the queue - assertContractStorageValue(WITHDRAWAL_REQUEST_COUNT_STORAGE_SLOT, 0); - } - - @Test - void popWithdrawalRequestsFromQueue_WhenNoWithdrawalRequests_DoesNothing() { - // Loading contract with 0 WithdrawalRequests - loadContractStorage(worldState, List.of()); - // After loading storage, we have the WithdrawalRequests count as zero because no - // WithdrawalRequests were added - assertContractStorageValue(WITHDRAWAL_REQUEST_COUNT_STORAGE_SLOT, 0); - - final List poppedWithdrawalRequests = - WithdrawalRequestContractHelper.popWithdrawalRequestsFromQueue(worldState); - assertThat(poppedWithdrawalRequests).isEmpty(); - - // Check that queue pointers are correct (head and tail are zero) - assertContractStorageValue(WITHDRAWAL_REQUEST_QUEUE_HEAD_STORAGE_SLOT, 0); - assertContractStorageValue(WITHDRAWAL_REQUEST_QUEUE_TAIL_STORAGE_SLOT, 0); - - // We had 0 WithdrawalRequests in the queue, and target per block is 2, so we have 0 excess - assertContractStorageValue(EXCESS_WITHDRAWAL_REQUESTS_STORAGE_SLOT, 0); - - // We always reset the exit count after processing the queue - assertContractStorageValue(WITHDRAWAL_REQUEST_COUNT_STORAGE_SLOT, 0); - } - - private void assertContractStorageValue(final UInt256 slot, final int expectedValue) { - assertContractStorageValue(slot, UInt256.valueOf(expectedValue)); - } - - private void assertContractStorageValue(final UInt256 slot, final UInt256 expectedValue) { - assertThat(worldState.get(WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS).getStorageValue(slot)) - .isEqualTo(expectedValue); - } - - private void loadContractStorage( - final MutableWorldState worldState, final List withdrawalRequests) { - final WorldUpdater updater = worldState.updater(); - contract = updater.getOrCreate(WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS); - - contract.setCode( - Bytes.fromHexString( - "0x61013680600a5f395ff33373fffffffffffffffffffffffffffffffffffffffe146090573615156028575f545f5260205ff35b36603014156101325760115f54600182026001905f5b5f82111560595781019083028483029004916001019190603e565b90939004341061013257600154600101600155600354806003026004013381556001015f3581556001016020359055600101600355005b6003546002548082038060101160a4575060105b5f5b81811460ed5780604402838201600302600401805490600101805490600101549160601b8160a01c17835260601b8160a01c17826020015260601b906040015260010160a6565b910180921460fe5790600255610109565b90505f6002555f6003555b5f546001546002828201116101205750505f610126565b01600290035b5f555f6001556044025ff35b5f5ffd")); - // excess requests - contract.setStorageValue(UInt256.valueOf(0), UInt256.valueOf(0)); - // requests count - contract.setStorageValue(UInt256.valueOf(1), UInt256.valueOf(withdrawalRequests.size())); - // requests queue head pointer - contract.setStorageValue(UInt256.valueOf(2), UInt256.valueOf(0)); - // requests queue tail pointer - contract.setStorageValue(UInt256.valueOf(3), UInt256.valueOf(withdrawalRequests.size())); - - int offset = 4; - for (int i = 0; i < withdrawalRequests.size(); i++) { - final WithdrawalRequest request = withdrawalRequests.get(i); - // source_account - contract.setStorageValue( - // set account to slot, with 12 bytes padding on the left - UInt256.valueOf(offset++), - UInt256.fromBytes( - Bytes.concatenate( - Bytes.fromHexString("0x000000000000000000000000"), request.getSourceAddress()))); - // validator_pubkey - contract.setStorageValue( - UInt256.valueOf(offset++), UInt256.fromBytes(request.getValidatorPubkey().slice(0, 32))); - contract.setStorageValue( - // set public key to slot, with 16 bytes padding on the right - UInt256.valueOf(offset++), - UInt256.fromBytes( - Bytes.concatenate( - request.getValidatorPubkey().slice(32, 16), - request.getAmount().toBytes(), // 8 bytes for amount - Bytes.fromHexString("0x0000000000000000")))); - } - updater.commit(); - } - - private WithdrawalRequest createExit() { - return new WithdrawalRequest( - Address.extract(Bytes32.random()), BLSPublicKey.wrap(Bytes48.random()), GWei.ONE); - } -} 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 index 7b8b440bb6..e719810c28 100644 --- 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 @@ -14,7 +14,7 @@ */ package org.hyperledger.besu.ethereum.mainnet; -import static org.hyperledger.besu.ethereum.mainnet.WithdrawalRequestContractHelper.MAX_WITHDRAWAL_REQUESTS_PER_BLOCK; +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; 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 d523984882..32ffbe1093 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 @@ -42,6 +42,7 @@ 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; @@ -52,6 +53,7 @@ import org.hyperledger.besu.ethereum.rlp.BytesValueRLPInput; import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; import org.hyperledger.besu.ethereum.rlp.RLP; import org.hyperledger.besu.ethereum.trie.diffbased.common.DiffBasedAccount; +import org.hyperledger.besu.ethereum.vm.CachingBlockHashLookup; import org.hyperledger.besu.evm.account.Account; import org.hyperledger.besu.evm.gascalculator.GasCalculator; import org.hyperledger.besu.evm.log.Log; @@ -511,7 +513,15 @@ public class T8nExecutor { var requestProcessorCoordinator = protocolSpec.getRequestProcessorCoordinator(); if (requestProcessorCoordinator.isPresent()) { var rpc = requestProcessorCoordinator.get(); - Optional> maybeRequests = rpc.process(worldState, receipts); + ProcessRequestContext context = + new ProcessRequestContext( + blockHeader, + worldState, + protocolSpec, + 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()); From d2b42d56d84e41e2be0b77c0ba4c842fba027455 Mon Sep 17 00:00:00 2001 From: Simon Dudley Date: Thu, 4 Jul 2024 21:10:44 +1000 Subject: [PATCH 022/259] Update limit trie logs validation message for sync-mode=FULL (#7279) Signed-off-by: Simon Dudley Co-authored-by: Sally MacFarlane --- .../besu/cli/options/stable/DataStorageOptions.java | 6 ++++-- .../besu/cli/options/stable/DataStorageOptionsTest.java | 8 ++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) 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 index d1cb4f721b..69cf819cb4 100644 --- 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 @@ -147,8 +147,10 @@ public class DataStorageOptions implements CLIOptions throw new CommandLine.ParameterException( commandLine, String.format( - "Cannot enable " + BONSAI_LIMIT_TRIE_LOGS_ENABLED + " with sync-mode %s", - syncMode)); + "Cannot enable %s with sync-mode %s. You must set %s or use a different sync-mode", + BONSAI_LIMIT_TRIE_LOGS_ENABLED, + SyncMode.FULL, + BONSAI_LIMIT_TRIE_LOGS_ENABLED + "=false")); } if (bonsaiMaxLayersToLoad < MINIMUM_BONSAI_TRIE_LOG_RETENTION_LIMIT) { throw new CommandLine.ParameterException( 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 2086381825..5ab2757f88 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 @@ -55,6 +55,14 @@ public class DataStorageOptionsTest "--bonsai-limit-trie-logs-enabled=false"); } + @Test + public void bonsaiTrieLogPruningWindowSizeShouldBePositive2() { + internalTestFailure( + "Cannot enable --bonsai-limit-trie-logs-enabled with sync-mode FULL. You must set --bonsai-limit-trie-logs-enabled=false or use a different sync-mode", + "--sync-mode", + "FULL"); + } + @Test public void bonsaiTrieLogPruningWindowSizeShouldBePositive() { internalTestFailure( From 6673287b177308416f6b93d08b408736258b311c Mon Sep 17 00:00:00 2001 From: Gabriel-Trintinalia Date: Sat, 6 Jul 2024 00:42:47 +1000 Subject: [PATCH 023/259] Execute requests before block persist (#7295) Signed-off-by: Gabriel-Trintinalia --- .../hyperledger/besu/evmtool/T8nExecutor.java | 76 +++++++++---------- 1 file changed, 38 insertions(+), 38 deletions(-) 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 32ffbe1093..429ad59444 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 @@ -468,6 +468,44 @@ public class T8nExecutor { } } + var requestProcessorCoordinator = protocolSpec.getRequestProcessorCoordinator(); + if (requestProcessorCoordinator.isPresent()) { + var rpc = requestProcessorCoordinator.get(); + ProcessRequestContext context = + new ProcessRequestContext( + blockHeader, + worldState, + protocolSpec, + 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 withdrawlRequests = resultObject.putArray("withdrawalRequests"); + RequestUtil.filterRequestsOfType(maybeRequests.orElse(List.of()), WithdrawalRequest.class) + .forEach( + wr -> { + var obj = withdrawlRequests.addObject(); + obj.put("sourceAddress", wr.getSourceAddress().toHexString()); + obj.put("validatorPubkey", wr.getValidatorPubkey().toHexString()); + obj.put("amount", wr.getAmount().toHexString()); + }); + } + worldState.persist(blockHeader); resultObject.put("stateRoot", worldState.rootHash().toHexString()); @@ -510,44 +548,6 @@ public class T8nExecutor { resultObject.put("blobGasUsed", Bytes.ofUnsignedLong(blobGasUsed).toQuantityHexString()); } - var requestProcessorCoordinator = protocolSpec.getRequestProcessorCoordinator(); - if (requestProcessorCoordinator.isPresent()) { - var rpc = requestProcessorCoordinator.get(); - ProcessRequestContext context = - new ProcessRequestContext( - blockHeader, - worldState, - protocolSpec, - 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 withdrawlRequests = resultObject.putArray("withdrawalRequests"); - RequestUtil.filterRequestsOfType(maybeRequests.orElse(List.of()), WithdrawalRequest.class) - .forEach( - wr -> { - var obj = withdrawlRequests.addObject(); - obj.put("sourceAddress", wr.getSourceAddress().toHexString()); - obj.put("validatorPubkey", wr.getValidatorPubkey().toHexString()); - obj.put("amount", wr.getAmount().toHexString()); - }); - } - ObjectNode allocObject = objectMapper.createObjectNode(); worldState .streamAccounts(Bytes32.ZERO, Integer.MAX_VALUE) From 33f2ae272619304243b860fc7e5fc07efce26763 Mon Sep 17 00:00:00 2001 From: gringsam Date: Tue, 9 Jul 2024 22:26:51 -0400 Subject: [PATCH 024/259] Fixed outdated tech redirect link. (#7297) * fix wiki link Signed-off-by: Snazzy * fix format Signed-off-by: Snazzy * change knownHash Signed-off-by: Snazzy --------- Signed-off-by: Snazzy --- plugin-api/build.gradle | 2 +- .../java/org/hyperledger/besu/plugin/services/BesuEvents.java | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/plugin-api/build.gradle b/plugin-api/build.gradle index dbbb5e4f2b..d55efa7fc9 100644 --- a/plugin-api/build.gradle +++ b/plugin-api/build.gradle @@ -70,7 +70,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 = 'Q6EK5By3BNKNa/JYqYjFw43VXWL0KVBUV3dGEQBjZ70=' + knownHash = 'yH50m+z1tnzshJQPdwR86pb2EU3m6iZxwkqoy/5spcs=' } check.dependsOn('checkAPIChanges') diff --git a/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/BesuEvents.java b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/BesuEvents.java index ab9c4eb782..110a66dee5 100644 --- a/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/BesuEvents.java +++ b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/BesuEvents.java @@ -258,7 +258,8 @@ public interface BesuEvents extends BesuService { /** * Invoked for each log (both added and removed) when a new block is added to the blockchain. * - * @param logWithMetadata the log with associated metadata. see https://eth.wiki/json-rpc/API + * @param logWithMetadata the log with associated metadata. see + * https://ethereum.org/en/developers/docs/apis/json-rpc/ */ void onLogEmitted(LogWithMetadata logWithMetadata); } From 5660ebc1cecdd05333dd8675862281a9421a95a6 Mon Sep 17 00:00:00 2001 From: George Tebrean <99179176+gtebrean@users.noreply.github.com> Date: Wed, 10 Jul 2024 06:51:53 +0300 Subject: [PATCH 025/259] Increment private nonce even if transaction failed. (#6593) Increment private nonce even if transaction failed Signed-off-by: George Tebrean Signed-off-by: stefan.pingel@consensys.net Co-authored-by: stefan.pingel@consensys.net Co-authored-by: Stefan Pingel <16143240+pinges@users.noreply.github.com> --- CHANGELOG.md | 1 + .../dsl/node/ProcessBesuNodeRunner.java | 3 + .../node/configuration/BesuNodeFactory.java | 4 +- .../MultiTenancyAcceptanceTest.java | 1 + ...tiTenancyPrivateNonceIncrementingTest.java | 241 ++++++++++++++++++ ...tiTenancyValidationFailAcceptanceTest.java | 1 + .../org/hyperledger/besu/cli/BesuCommand.java | 9 + .../src/test/resources/everything_config.toml | 1 + ...acyPrecompiledContractIntegrationTest.java | 1 + .../besu/ethereum/core/PrivacyParameters.java | 18 ++ .../FlexiblePrivacyPrecompiledContract.java | 7 +- .../privacy/PrivacyPrecompiledContract.java | 29 ++- ...lexiblePrivacyPrecompiledContractTest.java | 6 +- .../PrivacyPrecompiledContractTest.java | 4 +- 14 files changed, 315 insertions(+), 11 deletions(-) create mode 100644 acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/multitenancy/MultiTenancyPrivateNonceIncrementingTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d29b8f8af..1cbfa4cbd3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,7 @@ - Promote experimental `besu storage x-trie-log` subcommand to production-ready [#7278](https://github.com/hyperledger/besu/pull/7278) - Enhanced BFT round-change diagnostics [#7271](https://github.com/hyperledger/besu/pull/7271) - `--Xsnapsync-bft-enabled` option enables experimental support for snap sync with IBFT/QBFT permissioned Bonsai-DB chains [#7140](https://github.com/hyperledger/besu/pull/7140) +- `privacy-nonce-always-increments` option enables private transactions to always increment the nonce, even if the transaction is invalid [#6593](https://github.com/hyperledger/besu/pull/6593) ### Bug fixes - Validation errors ignored in accounts-allowlist and empty list [#7138](https://github.com/hyperledger/besu/issues/7138) 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 583992718a..37906761d1 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 @@ -166,6 +166,9 @@ public class ProcessBesuNodeRunner implements BesuNodeRunner { if (node.getPrivacyParameters().isPrivacyPluginEnabled()) { params.add("--Xprivacy-plugin-enabled"); } + if (node.getPrivacyParameters().isPrivateNonceAlwaysIncrementsEnabled()) { + params.add("privacy-nonce-always-increments"); + } } if (!node.getBootnodes().isEmpty()) { diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeFactory.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeFactory.java index 96ab9cf623..1ea29388bd 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeFactory.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeFactory.java @@ -287,7 +287,8 @@ public class BesuNodeFactory { final String enclaveUrl, final String authFile, final String privTransactionSigningKey, - final boolean enableFlexiblePrivacy) + final boolean enableFlexiblePrivacy, + final boolean enablePrivateNonceAlwaysIncrements) throws IOException, URISyntaxException { final PrivacyParameters.Builder privacyParametersBuilder = new PrivacyParameters.Builder(); final PrivacyParameters privacyParameters = @@ -298,6 +299,7 @@ public class BesuNodeFactory { .setStorageProvider(new InMemoryPrivacyStorageProvider()) .setEnclaveFactory(new EnclaveFactory(Vertx.vertx())) .setEnclaveUrl(URI.create(enclaveUrl)) + .setPrivateNonceAlwaysIncrementsEnabled(enablePrivateNonceAlwaysIncrements) .setPrivateKeyPath( Paths.get(ClassLoader.getSystemResource(privTransactionSigningKey).toURI())) .build(); diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/multitenancy/MultiTenancyAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/multitenancy/MultiTenancyAcceptanceTest.java index e2fdd2188b..b1c175f646 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/multitenancy/MultiTenancyAcceptanceTest.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/multitenancy/MultiTenancyAcceptanceTest.java @@ -104,6 +104,7 @@ public class MultiTenancyAcceptanceTest extends AcceptanceTestBase { "http://127.0.0.1:" + wireMockRule.port(), "authentication/auth_priv.toml", "authentication/auth_priv_key", + false, false); multiTenancyCluster.start(node); final String token = diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/multitenancy/MultiTenancyPrivateNonceIncrementingTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/multitenancy/MultiTenancyPrivateNonceIncrementingTest.java new file mode 100644 index 0000000000..11c405c37a --- /dev/null +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/multitenancy/MultiTenancyPrivateNonceIncrementingTest.java @@ -0,0 +1,241 @@ +/* + * 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.privacy.multitenancy; + +import static com.github.tomakehurst.wiremock.client.WireMock.ok; +import static com.github.tomakehurst.wiremock.client.WireMock.post; +import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; +import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options; +import static java.nio.charset.StandardCharsets.UTF_8; + +import org.hyperledger.besu.crypto.KeyPair; +import org.hyperledger.besu.crypto.SignatureAlgorithm; +import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; +import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.datatypes.Hash; +import org.hyperledger.besu.datatypes.Wei; +import org.hyperledger.besu.enclave.types.PrivacyGroup; +import org.hyperledger.besu.enclave.types.ReceiveResponse; +import org.hyperledger.besu.enclave.types.SendResponse; +import org.hyperledger.besu.ethereum.privacy.PrivateTransaction; +import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; +import org.hyperledger.besu.plugin.data.Restriction; +import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBase; +import org.hyperledger.besu.tests.acceptance.dsl.node.BesuNode; +import org.hyperledger.besu.tests.acceptance.dsl.node.cluster.Cluster; +import org.hyperledger.besu.tests.acceptance.dsl.node.cluster.ClusterConfiguration; +import org.hyperledger.besu.tests.acceptance.dsl.node.cluster.ClusterConfigurationBuilder; + +import java.math.BigInteger; +import java.util.List; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.github.tomakehurst.wiremock.junit.WireMockRule; +import com.google.common.base.Supplier; +import com.google.common.base.Suppliers; +import org.apache.tuweni.bytes.Bytes; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; + +public class MultiTenancyPrivateNonceIncrementingTest extends AcceptanceTestBase { + private BesuNode node; + private final ObjectMapper mapper = new ObjectMapper(); + private Cluster multiTenancyCluster; + + private static final Supplier SIGNATURE_ALGORITHM = + Suppliers.memoize(SignatureAlgorithmFactory::getInstance); + private static final KeyPair TEST_KEY = + SIGNATURE_ALGORITHM + .get() + .createKeyPair( + SIGNATURE_ALGORITHM + .get() + .createPrivateKey( + new BigInteger( + "853d7f0010fd86d0d7811c1f9d968ea89a24484a8127b4a483ddf5d2cfec766d", 16))); + private static final String PRIVACY_GROUP_ID = "B1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo="; + private static final String PARTICIPANT_ENCLAVE_KEY0 = + "A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo="; + private static final String PARTICIPANT_ENCLAVE_KEY1 = + "sgFkVOyFndZe/5SAZJO5UYbrl7pezHetveriBBWWnE8="; + private final Address senderAddress = + Address.wrap(Bytes.fromHexString(accounts.getPrimaryBenefactor().getAddress())); + + @Rule public WireMockRule wireMockRule = new WireMockRule(options().dynamicPort()); + + @Before + public void setUp() throws Exception { + final ClusterConfiguration clusterConfiguration = + new ClusterConfigurationBuilder().awaitPeerDiscovery(false).build(); + multiTenancyCluster = new Cluster(clusterConfiguration, net); + node = + besu.createNodeWithMultiTenantedPrivacy( + "node1", + "http://127.0.0.1:" + wireMockRule.port(), + "authentication/auth_priv.toml", + "authentication/auth_priv_key", + false, + true); + multiTenancyCluster.start(node); + final String token = + node.execute(permissioningTransactions.createSuccessfulLogin("user", "pegasys")); + node.useAuthenticationTokenInHeaderForJsonRpc(token); + } + + @After + public void tearDown() { + multiTenancyCluster.close(); + } + + @Test + public void validateUnsuccessfulPrivateTransactionsNonceIncrementation() + throws JsonProcessingException { + executePrivateFailingTransaction(0, 0, 1); + executePrivateValidTransaction(1, 1, 2); + executePrivateFailingTransaction(2, 2, 3); + executePrivateFailingTransaction(3, 3, 4); + executePrivateValidTransaction(4, 4, 5); + } + + private void executePrivateValidTransaction( + final int nonce, + final int expectedTransactionCountBeforeExecution, + final int expectedTransactionCountAfterExecution) + throws JsonProcessingException { + final PrivateTransaction validSignedPrivateTransaction = + getValidSignedPrivateTransaction(senderAddress, nonce); + + final String accountAddress = validSignedPrivateTransaction.getSender().toHexString(); + final BytesValueRLPOutput rlpOutput = getRLPOutput(validSignedPrivateTransaction); + + processEnclaveStub(validSignedPrivateTransaction); + + node.verify( + priv.getTransactionCount( + accountAddress, PRIVACY_GROUP_ID, expectedTransactionCountBeforeExecution)); + + final Hash transactionReceipt = + node.execute(privacyTransactions.sendRawTransaction(rlpOutput.encoded().toHexString())); + + node.verify(priv.getSuccessfulTransactionReceipt(transactionReceipt)); + node.verify( + priv.getTransactionCount( + accountAddress, PRIVACY_GROUP_ID, expectedTransactionCountAfterExecution)); + } + + private void executePrivateFailingTransaction( + final int nonce, + final int expectedTransactionCountBeforeExecution, + final int expectedTransactionCountAfterExecution) + throws JsonProcessingException { + final PrivateTransaction invalidSignedPrivateTransaction = + getInvalidSignedPrivateTransaction(senderAddress, nonce); + final String accountAddress = invalidSignedPrivateTransaction.getSender().toHexString(); + final BytesValueRLPOutput invalidTxRlp = getRLPOutput(invalidSignedPrivateTransaction); + + processEnclaveStub(invalidSignedPrivateTransaction); + + node.verify( + priv.getTransactionCount( + accountAddress, PRIVACY_GROUP_ID, expectedTransactionCountBeforeExecution)); + final Hash invalidTransactionReceipt = + node.execute(privacyTransactions.sendRawTransaction(invalidTxRlp.encoded().toHexString())); + + node.verify(priv.getFailedTransactionReceipt(invalidTransactionReceipt)); + node.verify( + priv.getTransactionCount( + accountAddress, PRIVACY_GROUP_ID, expectedTransactionCountAfterExecution)); + } + + private void processEnclaveStub(final PrivateTransaction validSignedPrivateTransaction) + throws JsonProcessingException { + retrievePrivacyGroupEnclaveStub(); + sendEnclaveStub(); + receiveEnclaveStub(validSignedPrivateTransaction); + } + + private void retrievePrivacyGroupEnclaveStub() throws JsonProcessingException { + final String retrieveGroupResponse = + mapper.writeValueAsString( + createPrivacyGroup( + List.of(PARTICIPANT_ENCLAVE_KEY0, PARTICIPANT_ENCLAVE_KEY1), + PrivacyGroup.Type.PANTHEON)); + stubFor(post("/retrievePrivacyGroup").willReturn(ok(retrieveGroupResponse))); + } + + private void sendEnclaveStub() throws JsonProcessingException { + final String sendResponse = + mapper.writeValueAsString(new SendResponse(PARTICIPANT_ENCLAVE_KEY1)); + stubFor(post("/send").willReturn(ok(sendResponse))); + } + + private void receiveEnclaveStub(final PrivateTransaction privTx) throws JsonProcessingException { + final BytesValueRLPOutput rlpOutput = getRLPOutput(privTx); + final String senderKey = privTx.getPrivateFrom().toBase64String(); + final String receiveResponse = + mapper.writeValueAsString( + new ReceiveResponse( + rlpOutput.encoded().toBase64String().getBytes(UTF_8), PRIVACY_GROUP_ID, senderKey)); + stubFor(post("/receive").willReturn(ok(receiveResponse))); + } + + private BytesValueRLPOutput getRLPOutput(final PrivateTransaction privateTransaction) { + final BytesValueRLPOutput bvrlpo = new BytesValueRLPOutput(); + privateTransaction.writeTo(bvrlpo); + return bvrlpo; + } + + private PrivacyGroup createPrivacyGroup( + final List groupMembers, final PrivacyGroup.Type groupType) { + return new PrivacyGroup(PRIVACY_GROUP_ID, groupType, "test", "testGroup", groupMembers); + } + + private static PrivateTransaction getInvalidSignedPrivateTransaction( + final Address senderAddress, final int nonce) { + return PrivateTransaction.builder() + .nonce(nonce) + .gasPrice(Wei.ZERO) + .gasLimit(3000000) + .to(null) + .value(Wei.ZERO) + .payload(Bytes.fromHexString("0x1234")) + .sender(senderAddress) + .chainId(BigInteger.valueOf(1337)) + .privateFrom(Bytes.fromBase64String(PARTICIPANT_ENCLAVE_KEY0)) + .restriction(Restriction.RESTRICTED) + .privacyGroupId(Bytes.fromBase64String(PRIVACY_GROUP_ID)) + .signAndBuild(TEST_KEY); + } + + private static PrivateTransaction getValidSignedPrivateTransaction( + final Address senderAddress, final int nonce) { + return PrivateTransaction.builder() + .nonce(nonce) + .gasPrice(Wei.ZERO) + .gasLimit(3000000) + .to(null) + .value(Wei.ZERO) + .payload(Bytes.wrap(new byte[] {})) + .sender(senderAddress) + .chainId(BigInteger.valueOf(1337)) + .privateFrom(Bytes.fromBase64String(PARTICIPANT_ENCLAVE_KEY0)) + .restriction(Restriction.RESTRICTED) + .privacyGroupId(Bytes.fromBase64String(PRIVACY_GROUP_ID)) + .signAndBuild(TEST_KEY); + } +} diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/multitenancy/MultiTenancyValidationFailAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/multitenancy/MultiTenancyValidationFailAcceptanceTest.java index 84e6fa7ea3..28bf140bb3 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/multitenancy/MultiTenancyValidationFailAcceptanceTest.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/multitenancy/MultiTenancyValidationFailAcceptanceTest.java @@ -78,6 +78,7 @@ public class MultiTenancyValidationFailAcceptanceTest extends AcceptanceTestBase "http://127.0.0.1:" + wireMockRule.port(), "authentication/auth_priv.toml", "authentication/auth_priv_key", + false, false); multiTenancyCluster.start(node); 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 12752f2e9a..8b123e70d3 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java @@ -715,6 +715,13 @@ public class BesuCommand implements DefaultCommandValues, Runnable { names = {"--privacy-flexible-groups-enabled"}, description = "Enable flexible privacy groups (default: ${DEFAULT-VALUE})") private final Boolean isFlexiblePrivacyGroupsEnabled = false; + + @Option( + names = {"--privacy-nonce-always-increments"}, + description = + "Enable private nonce " + + "incrementation even if the transaction didn't succeeded (default: ${DEFAULT-VALUE})") + private final Boolean isPrivateNonceAlwaysIncrementsEnabled = false; } // Metrics Option Group @@ -2062,6 +2069,8 @@ public class BesuCommand implements DefaultCommandValues, Runnable { privacyOptionGroup.isFlexiblePrivacyGroupsEnabled); privacyParametersBuilder.setPrivacyPluginEnabled( unstablePrivacyPluginOptions.isPrivacyPluginEnabled()); + privacyParametersBuilder.setPrivateNonceAlwaysIncrementsEnabled( + privacyOptionGroup.isPrivateNonceAlwaysIncrementsEnabled); final boolean hasPrivacyPublicKey = privacyOptionGroup.privacyPublicKeyFile != null; diff --git a/besu/src/test/resources/everything_config.toml b/besu/src/test/resources/everything_config.toml index d5cc291237..a5e03bd599 100644 --- a/besu/src/test/resources/everything_config.toml +++ b/besu/src/test/resources/everything_config.toml @@ -172,6 +172,7 @@ privacy-multi-tenancy-enabled=true privacy-marker-transaction-signing-key-file="./signerKey" privacy-enable-database-migration=false privacy-flexible-groups-enabled=false +privacy-nonce-always-increments=false # Transaction Pool tx-pool="layered" diff --git a/ethereum/core/src/integration-test/java/org/hyperledger/besu/ethereum/mainnet/precompiles/privacy/PrivacyPrecompiledContractIntegrationTest.java b/ethereum/core/src/integration-test/java/org/hyperledger/besu/ethereum/mainnet/precompiles/privacy/PrivacyPrecompiledContractIntegrationTest.java index 090c24e26e..a5ee5f068e 100644 --- a/ethereum/core/src/integration-test/java/org/hyperledger/besu/ethereum/mainnet/precompiles/privacy/PrivacyPrecompiledContractIntegrationTest.java +++ b/ethereum/core/src/integration-test/java/org/hyperledger/besu/ethereum/mainnet/precompiles/privacy/PrivacyPrecompiledContractIntegrationTest.java @@ -205,6 +205,7 @@ public class PrivacyPrecompiledContractIntegrationTest { new PrivateStateRootResolver(privateStateStorage), new PrivateStateGenesisAllocator( false, (privacyGroupId, blockNumber) -> Collections::emptyList), + false, "IntegrationTest"); privacyPrecompiledContract.setPrivateTransactionProcessor(mockPrivateTxProcessor()); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/PrivacyParameters.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/PrivacyParameters.java index 349ff8ffbe..775634a41a 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/PrivacyParameters.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/PrivacyParameters.java @@ -77,6 +77,7 @@ public class PrivacyParameters { private PrivateStateRootResolver privateStateRootResolver; private PrivateWorldStateReader privateWorldStateReader; private PrivacyPluginService privacyPluginService; + private boolean privateNonceAlwaysIncrementsEnabled; public Address getPrivacyAddress() { if (isPrivacyPluginEnabled()) { @@ -228,6 +229,15 @@ public class PrivacyParameters { } } + public boolean isPrivateNonceAlwaysIncrementsEnabled() { + return privateNonceAlwaysIncrementsEnabled; + } + + public void setPrivateNonceAlwaysIncrementsEnabled( + final boolean privateNonceAlwaysIncrementsEnabled) { + this.privateNonceAlwaysIncrementsEnabled = privateNonceAlwaysIncrementsEnabled; + } + @Override public String toString() { return "PrivacyParameters{" @@ -263,6 +273,7 @@ public class PrivacyParameters { private boolean flexiblePrivacyGroupsEnabled; private boolean privacyPluginEnabled; private PrivacyPluginService privacyPluginService; + private boolean privateNonceAlwaysIncrementsEnabled; public Builder setEnclaveUrl(final URI enclaveUrl) { this.enclaveUrl = enclaveUrl; @@ -314,6 +325,12 @@ public class PrivacyParameters { return this; } + public Builder setPrivateNonceAlwaysIncrementsEnabled( + final boolean isPrivateNonceAlwaysIncrementsEnabled) { + this.privateNonceAlwaysIncrementsEnabled = isPrivateNonceAlwaysIncrementsEnabled; + return this; + } + public Builder setPrivacyPluginEnabled(final boolean privacyPluginEnabled) { this.privacyPluginEnabled = privacyPluginEnabled; return this; @@ -382,6 +399,7 @@ public class PrivacyParameters { config.setMultiTenancyEnabled(multiTenancyEnabled); config.setFlexiblePrivacyGroupsEnabled(flexiblePrivacyGroupsEnabled); config.setPrivacyPluginEnabled(privacyPluginEnabled); + config.setPrivateNonceAlwaysIncrementsEnabled(privateNonceAlwaysIncrementsEnabled); return config; } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/precompiles/privacy/FlexiblePrivacyPrecompiledContract.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/precompiles/privacy/FlexiblePrivacyPrecompiledContract.java index 0dd6863f94..98709a4eaa 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/precompiles/privacy/FlexiblePrivacyPrecompiledContract.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/precompiles/privacy/FlexiblePrivacyPrecompiledContract.java @@ -70,13 +70,15 @@ public class FlexiblePrivacyPrecompiledContract extends PrivacyPrecompiledContra final Enclave enclave, final WorldStateArchive worldStateArchive, final PrivateStateRootResolver privateStateRootResolver, - final PrivateStateGenesisAllocator privateStateGenesisAllocator) { + final PrivateStateGenesisAllocator privateStateGenesisAllocator, + final boolean alwaysIncrementPrivateNonce) { super( gasCalculator, enclave, worldStateArchive, privateStateRootResolver, privateStateGenesisAllocator, + alwaysIncrementPrivateNonce, "FlexiblePrivacy"); } @@ -87,7 +89,8 @@ public class FlexiblePrivacyPrecompiledContract extends PrivacyPrecompiledContra privacyParameters.getEnclave(), privacyParameters.getPrivateWorldStateArchive(), privacyParameters.getPrivateStateRootResolver(), - privacyParameters.getPrivateStateGenesisAllocator()); + privacyParameters.getPrivateStateGenesisAllocator(), + privacyParameters.isPrivateNonceAlwaysIncrementsEnabled()); } public long addPrivateTransactionObserver(final PrivateTransactionObserver observer) { diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/precompiles/privacy/PrivacyPrecompiledContract.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/precompiles/privacy/PrivacyPrecompiledContract.java index b1a754c9fe..7e9bfa1ac4 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/precompiles/privacy/PrivacyPrecompiledContract.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/precompiles/privacy/PrivacyPrecompiledContract.java @@ -19,6 +19,7 @@ import static org.hyperledger.besu.ethereum.mainnet.PrivateStateUtils.KEY_PRIVAT import static org.hyperledger.besu.ethereum.mainnet.PrivateStateUtils.KEY_TRANSACTION_HASH; import static org.hyperledger.besu.ethereum.privacy.PrivateStateRootResolver.EMPTY_ROOT_HASH; +import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.enclave.Enclave; import org.hyperledger.besu.enclave.EnclaveClientException; @@ -40,6 +41,7 @@ import org.hyperledger.besu.ethereum.privacy.storage.PrivateTransactionMetadata; import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult; import org.hyperledger.besu.ethereum.rlp.BytesValueRLPInput; import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; +import org.hyperledger.besu.evm.account.MutableAccount; import org.hyperledger.besu.evm.frame.BlockValues; import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.gascalculator.GasCalculator; @@ -61,6 +63,7 @@ public class PrivacyPrecompiledContract extends AbstractPrecompiledContract { final WorldStateArchive privateWorldStateArchive; final PrivateStateRootResolver privateStateRootResolver; private final PrivateStateGenesisAllocator privateStateGenesisAllocator; + final boolean alwaysIncrementPrivateNonce; PrivateTransactionProcessor privateTransactionProcessor; private static final Logger LOG = LoggerFactory.getLogger(PrivacyPrecompiledContract.class); @@ -79,6 +82,7 @@ public class PrivacyPrecompiledContract extends AbstractPrecompiledContract { privacyParameters.getPrivateWorldStateArchive(), privacyParameters.getPrivateStateRootResolver(), privacyParameters.getPrivateStateGenesisAllocator(), + privacyParameters.isPrivateNonceAlwaysIncrementsEnabled(), name); } @@ -88,12 +92,14 @@ public class PrivacyPrecompiledContract extends AbstractPrecompiledContract { final WorldStateArchive worldStateArchive, final PrivateStateRootResolver privateStateRootResolver, final PrivateStateGenesisAllocator privateStateGenesisAllocator, + final boolean alwaysIncrementPrivateNonce, final String name) { super(name, gasCalculator); this.enclave = enclave; this.privateWorldStateArchive = worldStateArchive; this.privateStateRootResolver = privateStateRootResolver; this.privateStateGenesisAllocator = privateStateGenesisAllocator; + this.alwaysIncrementPrivateNonce = alwaysIncrementPrivateNonce; } public void setPrivateTransactionProcessor( @@ -181,18 +187,31 @@ public class PrivacyPrecompiledContract extends AbstractPrecompiledContract { processPrivateTransaction( messageFrame, privateTransaction, privacyGroupId, privateWorldStateUpdater); - if (result.isInvalid() || !result.isSuccessful()) { + final Boolean isPersistingPrivateState = + messageFrame.getContextVariable(KEY_IS_PERSISTING_PRIVATE_STATE, false); + + if (!result.isSuccessful()) { LOG.error( "Failed to process private transaction {}: {}", pmtHash, result.getValidationResult().getErrorMessage()); - - privateMetadataUpdater.putTransactionReceipt(pmtHash, new PrivateTransactionReceipt(result)); - + if (isPersistingPrivateState && alwaysIncrementPrivateNonce) { + final Address senderAddress = privateTransaction.getSender(); + final MutableAccount senderAccount = privateWorldStateUpdater.getOrCreate(senderAddress); + senderAccount.incrementNonce(); + // we can safely commit the updater here, because it is only changed if the transaction is + // successful, + // so we can be sure that the only change is the incremented nonce + privateWorldStateUpdater.commit(); + disposablePrivateState.persist(null); + + storePrivateMetadata( + pmtHash, privacyGroupId, disposablePrivateState, privateMetadataUpdater, result); + } return NO_RESULT; } - if (messageFrame.getContextVariable(KEY_IS_PERSISTING_PRIVATE_STATE, false)) { + if (isPersistingPrivateState) { privateWorldStateUpdater.commit(); disposablePrivateState.persist(null); diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/precompiles/privacy/FlexiblePrivacyPrecompiledContractTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/precompiles/privacy/FlexiblePrivacyPrecompiledContractTest.java index 3c4711a194..fc08f519d3 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/precompiles/privacy/FlexiblePrivacyPrecompiledContractTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/precompiles/privacy/FlexiblePrivacyPrecompiledContractTest.java @@ -383,7 +383,8 @@ public class FlexiblePrivacyPrecompiledContractTest { enclave, worldStateArchive, privateStateRootResolver, - privateStateGenesisAllocator); + privateStateGenesisAllocator, + false); contract.setPrivateTransactionProcessor( mockPrivateTxProcessor( @@ -427,6 +428,7 @@ public class FlexiblePrivacyPrecompiledContractTest { enclave, worldStateArchive, privateStateRootResolver, - privateStateGenesisAllocator); + privateStateGenesisAllocator, + false); } } diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/precompiles/privacy/PrivacyPrecompiledContractTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/precompiles/privacy/PrivacyPrecompiledContractTest.java index 134cfa9eac..7d253057ac 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/precompiles/privacy/PrivacyPrecompiledContractTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/precompiles/privacy/PrivacyPrecompiledContractTest.java @@ -302,6 +302,7 @@ public class PrivacyPrecompiledContractTest { worldStateArchive, privateStateRootResolver, privateStateGenesisAllocator, + false, "RestrictedPrivacyTest"); contract.setPrivateTransactionProcessor( @@ -328,7 +329,7 @@ public class PrivacyPrecompiledContractTest { @Test public void testSimulatedPublicTransactionIsSkipped() { final PrivacyPrecompiledContract emptyContract = - new PrivacyPrecompiledContract(null, null, null, null, null, null); + new PrivacyPrecompiledContract(null, null, null, null, null, false, null); // A simulated public transaction doesn't contain a PrivateMetadataUpdater final MessageFrame frame = mock(MessageFrame.class); @@ -355,6 +356,7 @@ public class PrivacyPrecompiledContractTest { worldStateArchive, privateStateRootResolver, privateStateGenesisAllocator, + false, "PrivacyTests"); } } From ae7ddd1c9adb750026d5314554e8366fda8a97a0 Mon Sep 17 00:00:00 2001 From: Usman Saleem Date: Wed, 10 Jul 2024 14:20:51 +1000 Subject: [PATCH 026/259] feat: Enhance --profile to load external profiles (#7292) * feat: --profile can load external profiles * fix external profile name method * fix ProfilesCompletionCandidate * test: Add unit tests * changelog: Update changelog * test: Fix TomlConfigurationDefaultProviderTest * test: Fix BesuCommandTest --------- Signed-off-by: Usman Saleem --- CHANGELOG.md | 1 + .../org/hyperledger/besu/cli/BesuCommand.java | 7 +- ...fileName.java => InternalProfileName.java} | 38 +++++++- .../config/ProfilesCompletionCandidates.java | 37 +++++++ .../subcommands/ValidateConfigSubCommand.java | 2 +- .../besu/cli/util/ProfileFinder.java | 94 +++++++++++++++--- .../TomlConfigurationDefaultProvider.java | 19 ++-- .../hyperledger/besu/cli/BesuCommandTest.java | 2 +- .../cli/ConfigurationOverviewBuilderTest.java | 4 +- .../hyperledger/besu/cli/ProfilesTest.java | 97 +++++++++++++++++-- .../TomlConfigurationDefaultProviderTest.java | 2 +- .../ProfilesCompletionCandidatesTest.java | 91 +++++++++++++++++ 12 files changed, 355 insertions(+), 39 deletions(-) rename besu/src/main/java/org/hyperledger/besu/cli/config/{ProfileName.java => InternalProfileName.java} (59%) create mode 100644 besu/src/main/java/org/hyperledger/besu/cli/config/ProfilesCompletionCandidates.java create mode 100644 besu/src/test/java/org/hyperledger/besu/cli/config/ProfilesCompletionCandidatesTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 1cbfa4cbd3..1306de83dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Breaking Changes ### Additions and Improvements +- Add support to load external profiles using `--profile` [#7265](https://github.com/hyperledger/besu/issues/7265) ### Bug fixes 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 8b123e70d3..427cac9248 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java @@ -39,7 +39,7 @@ import org.hyperledger.besu.chainimport.JsonBlockImporter; import org.hyperledger.besu.chainimport.RlpBlockImporter; import org.hyperledger.besu.cli.config.EthNetworkConfig; import org.hyperledger.besu.cli.config.NetworkName; -import org.hyperledger.besu.cli.config.ProfileName; +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; @@ -565,9 +565,10 @@ public class BesuCommand implements DefaultCommandValues, Runnable { @Option( names = {PROFILE_OPTION_NAME}, paramLabel = PROFILE_FORMAT_HELP, + completionCandidates = ProfilesCompletionCandidates.class, description = "Overwrite default settings. Possible values are ${COMPLETION-CANDIDATES}. (default: none)") - private final ProfileName profile = null; + private String profile = null; // don't set it as final due to picocli completion candidates @Option( names = {"--nat-method"}, @@ -2773,7 +2774,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { } if (profile != null) { - builder.setProfile(profile.toString()); + builder.setProfile(profile); } builder.setHasCustomGenesis(genesisFile != null); diff --git a/besu/src/main/java/org/hyperledger/besu/cli/config/ProfileName.java b/besu/src/main/java/org/hyperledger/besu/cli/config/InternalProfileName.java similarity index 59% rename from besu/src/main/java/org/hyperledger/besu/cli/config/ProfileName.java rename to besu/src/main/java/org/hyperledger/besu/cli/config/InternalProfileName.java index 8c17dfb4f2..efac7a5203 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/config/ProfileName.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/config/InternalProfileName.java @@ -14,10 +14,18 @@ */ package org.hyperledger.besu.cli.config; +import java.util.Arrays; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + import org.apache.commons.lang3.StringUtils; -/** Enum for profile names. Each profile corresponds to a configuration file. */ -public enum ProfileName { +/** + * Enum for profile names which are bundled. Each profile corresponds to a bundled configuration + * file. + */ +public enum InternalProfileName { /** The 'STAKER' profile */ STAKER("profiles/staker.toml"), /** The 'MINIMALIST_STAKER' profile */ @@ -31,12 +39,36 @@ public enum ProfileName { private final String configFile; + /** + * Returns the InternalProfileName that matches the given name, ignoring case. + * + * @param name The profile name + * @return Optional InternalProfileName if found, otherwise empty + */ + public static Optional valueOfIgnoreCase(final String name) { + return Arrays.stream(values()) + .filter(profile -> profile.name().equalsIgnoreCase(name)) + .findFirst(); + } + + /** + * Returns the set of internal profile names as lowercase. + * + * @return Set of internal profile names + */ + public static Set getInternalProfileNames() { + return Arrays.stream(InternalProfileName.values()) + .map(InternalProfileName::name) + .map(String::toLowerCase) + .collect(Collectors.toSet()); + } + /** * Constructs a new ProfileName. * * @param configFile the configuration file corresponding to the profile */ - ProfileName(final String configFile) { + InternalProfileName(final String configFile) { this.configFile = configFile; } diff --git a/besu/src/main/java/org/hyperledger/besu/cli/config/ProfilesCompletionCandidates.java b/besu/src/main/java/org/hyperledger/besu/cli/config/ProfilesCompletionCandidates.java new file mode 100644 index 0000000000..51e9c49a0a --- /dev/null +++ b/besu/src/main/java/org/hyperledger/besu/cli/config/ProfilesCompletionCandidates.java @@ -0,0 +1,37 @@ +/* + * 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.config; + +import org.hyperledger.besu.cli.util.ProfileFinder; + +import java.util.Iterator; +import java.util.Set; +import java.util.TreeSet; + +/** Provides a list of profile names that can be used for command line completion. */ +public class ProfilesCompletionCandidates implements Iterable { + /** + * Create a new instance of ProfilesCompletionCandidates. This constructor is required for + * Picocli. + */ + public ProfilesCompletionCandidates() {} + + @Override + public Iterator iterator() { + final Set profileNames = new TreeSet<>(InternalProfileName.getInternalProfileNames()); + profileNames.addAll(ProfileFinder.getExternalProfileNames()); + return profileNames.iterator(); + } +} diff --git a/besu/src/main/java/org/hyperledger/besu/cli/subcommands/ValidateConfigSubCommand.java b/besu/src/main/java/org/hyperledger/besu/cli/subcommands/ValidateConfigSubCommand.java index f17f1a09fc..12500748ce 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/subcommands/ValidateConfigSubCommand.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/subcommands/ValidateConfigSubCommand.java @@ -70,7 +70,7 @@ public class ValidateConfigSubCommand implements Runnable { checkNotNull(parentCommand); try { TomlConfigurationDefaultProvider.fromFile(commandLine, dataPath.toFile()) - .loadConfigurationFromFile(); + .loadConfigurationIfNotLoaded(); } catch (Exception e) { this.out.println(e); return; diff --git a/besu/src/main/java/org/hyperledger/besu/cli/util/ProfileFinder.java b/besu/src/main/java/org/hyperledger/besu/cli/util/ProfileFinder.java index edb94f667a..ba35f6b69d 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/util/ProfileFinder.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/util/ProfileFinder.java @@ -16,11 +16,19 @@ package org.hyperledger.besu.cli.util; import static org.hyperledger.besu.cli.DefaultCommandValues.PROFILE_OPTION_NAME; -import org.hyperledger.besu.cli.config.ProfileName; +import org.hyperledger.besu.cli.config.InternalProfileName; +import java.io.IOException; import java.io.InputStream; +import java.io.UncheckedIOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.Map; import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; import picocli.CommandLine; @@ -50,30 +58,94 @@ public class ProfileFinder extends AbstractConfigurationFinder { @Override public Optional getFromOption( final CommandLine.ParseResult parseResult, final CommandLine commandLine) { + final String profileName; try { - return getProfile(parseResult.matchedOption(PROFILE_OPTION_NAME).getter().get(), commandLine); - } catch (Exception e) { - throw new RuntimeException(e); + profileName = parseResult.matchedOption(PROFILE_OPTION_NAME).getter().get(); + } catch (final Exception e) { + throw new CommandLine.ParameterException( + commandLine, "Unexpected error in obtaining value of --profile", e); } + return getProfile(profileName, commandLine); } @Override public Optional getFromEnvironment( final Map environment, final CommandLine commandLine) { - return getProfile(ProfileName.valueOf(environment.get(PROFILE_ENV_NAME)), commandLine); + return getProfile(environment.get(PROFILE_ENV_NAME), commandLine); } private static Optional getProfile( - final ProfileName profileName, final CommandLine commandLine) { - return Optional.of(getTomlFile(commandLine, profileName.getConfigFile())); + final String profileName, final CommandLine commandLine) { + final Optional internalProfileConfigPath = + InternalProfileName.valueOfIgnoreCase(profileName).map(InternalProfileName::getConfigFile); + if (internalProfileConfigPath.isPresent()) { + return Optional.of(getTomlFileFromClasspath(internalProfileConfigPath.get())); + } else { + final Path externalProfileFile = defaultProfilesDir().resolve(profileName + ".toml"); + if (Files.exists(externalProfileFile)) { + try { + return Optional.of(Files.newInputStream(externalProfileFile)); + } catch (IOException e) { + throw new CommandLine.ParameterException( + commandLine, "Error reading external profile: " + profileName); + } + } else { + throw new CommandLine.ParameterException( + commandLine, "Unable to load external profile: " + profileName); + } + } } - private static InputStream getTomlFile(final CommandLine commandLine, final String file) { - InputStream resourceUrl = ProfileFinder.class.getClassLoader().getResourceAsStream(file); + private static InputStream getTomlFileFromClasspath(final String profileConfigFile) { + InputStream resourceUrl = + ProfileFinder.class.getClassLoader().getResourceAsStream(profileConfigFile); + // this is not meant to happen, because for each InternalProfileName there is a corresponding + // TOML file in resources if (resourceUrl == null) { - throw new CommandLine.ParameterException( - commandLine, String.format("TOML file %s not found", file)); + throw new IllegalStateException( + String.format("Internal Profile TOML %s not found", profileConfigFile)); } return resourceUrl; } + + /** + * Returns the external profile names which are file names without extension in the default + * profiles directory. + * + * @return Set of external profile names + */ + public static Set getExternalProfileNames() { + final Path profilesDir = defaultProfilesDir(); + if (!Files.exists(profilesDir)) { + return Set.of(); + } + + try (Stream pathStream = Files.list(profilesDir)) { + return pathStream + .filter(Files::isRegularFile) + .filter(path -> path.toString().endsWith(".toml")) + .map( + path -> + path.getFileName() + .toString() + .substring(0, path.getFileName().toString().length() - 5)) + .collect(Collectors.toSet()); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + /** + * Return default profiles directory location + * + * @return Path to default profiles directory + */ + private static Path defaultProfilesDir() { + final String profilesDir = System.getProperty("besu.profiles.dir"); + if (profilesDir == null) { + return Paths.get(System.getProperty("besu.home", "."), "profiles"); + } else { + return Paths.get(profilesDir); + } + } } diff --git a/besu/src/main/java/org/hyperledger/besu/cli/util/TomlConfigurationDefaultProvider.java b/besu/src/main/java/org/hyperledger/besu/cli/util/TomlConfigurationDefaultProvider.java index 1747f461dc..ca76b40b68 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/util/TomlConfigurationDefaultProvider.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/util/TomlConfigurationDefaultProvider.java @@ -96,7 +96,7 @@ public class TomlConfigurationDefaultProvider implements IDefaultValueProvider { @Override public String defaultValue(final ArgSpec argSpec) { - loadConfigurationFromFile(); + loadConfigurationIfNotLoaded(); // only options can be used in config because a name is needed for the key // so we skip default for positional params @@ -227,10 +227,10 @@ public class TomlConfigurationDefaultProvider implements IDefaultValueProvider { } private void checkConfigurationValidity() { - if (result == null || result.isEmpty()) + if (result == null || result.isEmpty()) { throw new ParameterException( - commandLine, - String.format("Unable to read TOML configuration file %s", configurationInputStream)); + commandLine, "Unable to read from empty TOML configuration file."); + } if (!isUnknownOptionsChecked && !commandLine.isUnmatchedArgumentsAllowed()) { checkUnknownOptions(result); @@ -239,8 +239,7 @@ public class TomlConfigurationDefaultProvider implements IDefaultValueProvider { } /** Load configuration from file. */ - public void loadConfigurationFromFile() { - + public void loadConfigurationIfNotLoaded() { if (result == null) { try { final TomlParseResult result = Toml.parse(configurationInputStream); @@ -289,12 +288,12 @@ public class TomlConfigurationDefaultProvider implements IDefaultValueProvider { .collect(Collectors.toSet()); if (!unknownOptionsList.isEmpty()) { - final String options = unknownOptionsList.size() > 1 ? "options" : "option"; - final String csvUnknownOptions = - unknownOptionsList.stream().collect(Collectors.joining(", ")); + final String csvUnknownOptions = String.join(", ", unknownOptionsList); throw new ParameterException( commandLine, - String.format("Unknown %s in TOML configuration file: %s", options, csvUnknownOptions)); + String.format( + "Unknown option%s in TOML configuration file: %s", + unknownOptionsList.size() > 1 ? "s" : "", csvUnknownOptions)); } } } 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 641e69dba6..c6ffbdc175 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java @@ -259,7 +259,7 @@ public class BesuCommandTest extends CommandTestAbstract { final Path tempConfigFilePath = createTempFile("an-invalid-file-name-without-extension", ""); parseCommand("--config-file", tempConfigFilePath.toString()); - final String expectedOutputStart = "Unable to read TOML configuration file"; + final String expectedOutputStart = "Unable to read from empty TOML configuration file."; assertThat(commandErrorOutput.toString(UTF_8)).startsWith(expectedOutputStart); assertThat(commandOutput.toString(UTF_8)).isEmpty(); } 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 07e440430a..841c668000 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/ConfigurationOverviewBuilderTest.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/ConfigurationOverviewBuilderTest.java @@ -20,7 +20,7 @@ import static org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConf import static org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration.Implementation.SEQUENCED; import static org.mockito.Mockito.mock; -import org.hyperledger.besu.cli.config.ProfileName; +import org.hyperledger.besu.cli.config.InternalProfileName; import org.hyperledger.besu.evm.internal.EvmConfiguration; import java.math.BigInteger; @@ -213,7 +213,7 @@ class ConfigurationOverviewBuilderTest { @Test void setProfile() { - builder.setProfile(ProfileName.DEV.name()); + builder.setProfile(InternalProfileName.DEV.name()); final String profileSelected = builder.build(); assertThat(profileSelected).contains("Profile: DEV"); } diff --git a/besu/src/test/java/org/hyperledger/besu/cli/ProfilesTest.java b/besu/src/test/java/org/hyperledger/besu/cli/ProfilesTest.java index cdfe09964f..019ff7a7ed 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/ProfilesTest.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/ProfilesTest.java @@ -17,21 +17,104 @@ package org.hyperledger.besu.cli; import static java.nio.charset.StandardCharsets.UTF_8; import static org.assertj.core.api.Assertions.assertThat; -import org.hyperledger.besu.cli.config.ProfileName; +import org.hyperledger.besu.cli.config.InternalProfileName; +import org.hyperledger.besu.cli.util.ProfileFinder; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Set; +import java.util.TreeSet; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.EnumSource; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; public class ProfilesTest extends CommandTestAbstract { + @TempDir private static Path tempProfilesDir; + private static String originalProfilesDirProperty; - /** Test if besu will validate the combination of options within the given profile. */ - @ParameterizedTest - @EnumSource(ProfileName.class) - public void testProfileWithNoOverrides_doesNotError(final ProfileName profileName) { + @BeforeAll + public static void copyExternalProfiles() throws IOException { + for (String internalProfileName : InternalProfileName.getInternalProfileNames()) { + final Path profilePath = tempProfilesDir.resolve(internalProfileName + "_external.toml"); + + String profileConfigFile = + InternalProfileName.valueOfIgnoreCase(internalProfileName).get().getConfigFile(); + try (InputStream resourceUrl = + ProfileFinder.class.getClassLoader().getResourceAsStream(profileConfigFile)) { + if (resourceUrl != null) { + Files.copy(resourceUrl, profilePath); + } + } + } + + // add an empty external profile + Files.createFile(tempProfilesDir.resolve("empty_external.toml")); + } - parseCommand("--profile", profileName.name()); + @BeforeAll + public static void setupSystemProperty() { + originalProfilesDirProperty = System.getProperty("besu.profiles.dir"); + // sets the system property for the test + System.setProperty("besu.profiles.dir", tempProfilesDir.toString()); + } + + static Stream profileNameProvider() { + final Set profileNames = new TreeSet<>(InternalProfileName.getInternalProfileNames()); + final Set externalProfileNames = + InternalProfileName.getInternalProfileNames().stream() + .map(name -> name + "_external") + .collect(Collectors.toSet()); + profileNames.addAll(externalProfileNames); + return profileNames.stream().map(Arguments::of); + } + + /** Test if besu will validate the combination of options within the given profile. */ + @ParameterizedTest(name = "{index} - Profile Name override: {0}") + @DisplayName("Valid Profile with overrides does not error") + @MethodSource("profileNameProvider") + public void testProfileWithNoOverrides_doesNotError(final String profileName) { + parseCommand("--profile", profileName); assertThat(commandOutput.toString(UTF_8)).isEmpty(); assertThat(commandErrorOutput.toString(UTF_8)).isEmpty(); } + + @Test + @DisplayName("Empty external profile file results in error") + public void emptyProfileFile_ShouldResultInError() { + parseCommand("--profile", "empty_external"); + + assertThat(commandOutput.toString(UTF_8)).isEmpty(); + assertThat(commandErrorOutput.toString(UTF_8)) + .contains("Unable to read from empty TOML configuration file."); + } + + @Test + @DisplayName("Non Existing profile results in error") + public void nonExistentProfileFile_ShouldResultInError() { + parseCommand("--profile", "non_existent_profile"); + + assertThat(commandOutput.toString(UTF_8)).isEmpty(); + assertThat(commandErrorOutput.toString(UTF_8)) + .contains("Unable to load external profile: non_existent_profile"); + } + + @AfterAll + public static void clearSystemProperty() { + if (originalProfilesDirProperty != null) { + System.setProperty("besu.profiles.dir", originalProfilesDirProperty); + } else { + System.clearProperty("besu.profiles.dir"); + } + } } diff --git a/besu/src/test/java/org/hyperledger/besu/cli/TomlConfigurationDefaultProviderTest.java b/besu/src/test/java/org/hyperledger/besu/cli/TomlConfigurationDefaultProviderTest.java index 0b47654f58..983e92cec1 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/TomlConfigurationDefaultProviderTest.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/TomlConfigurationDefaultProviderTest.java @@ -241,7 +241,7 @@ public class TomlConfigurationDefaultProviderTest { providerUnderTest.defaultValue( OptionSpec.builder("an-option").type(String.class).build())) .isInstanceOf(ParameterException.class) - .hasMessageContaining("Unable to read TOML configuration file"); + .hasMessageContaining("Unable to read from empty TOML configuration file."); } @Test diff --git a/besu/src/test/java/org/hyperledger/besu/cli/config/ProfilesCompletionCandidatesTest.java b/besu/src/test/java/org/hyperledger/besu/cli/config/ProfilesCompletionCandidatesTest.java new file mode 100644 index 0000000000..69cbf1de70 --- /dev/null +++ b/besu/src/test/java/org/hyperledger/besu/cli/config/ProfilesCompletionCandidatesTest.java @@ -0,0 +1,91 @@ +/* + * 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.config; + +import org.hyperledger.besu.cli.util.ProfileFinder; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.TreeSet; +import java.util.stream.Collectors; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +class ProfilesCompletionCandidatesTest { + @TempDir private static Path tempProfilesDir; + private static String originalProfilesDirProperty; + + @BeforeAll + public static void copyExternalProfiles() throws IOException { + for (String internalProfileName : InternalProfileName.getInternalProfileNames()) { + final Path profilePath = tempProfilesDir.resolve(internalProfileName + "_external.toml"); + + String profileConfigFile = + InternalProfileName.valueOfIgnoreCase(internalProfileName).get().getConfigFile(); + try (InputStream resourceUrl = + ProfileFinder.class.getClassLoader().getResourceAsStream(profileConfigFile)) { + if (resourceUrl != null) { + Files.copy(resourceUrl, profilePath); + } + } + } + } + + @BeforeAll + public static void setupSystemProperty() { + originalProfilesDirProperty = System.getProperty("besu.profiles.dir"); + // sets the system property for the test + System.setProperty("besu.profiles.dir", tempProfilesDir.toString()); + } + + @Test + void profileCompletionCandidates_shouldIncludeInternalAndExternalProfiles() { + Iterator candidates = new ProfilesCompletionCandidates().iterator(); + // convert Iterator to List + List candidatesList = new ArrayList<>(); + candidates.forEachRemaining(candidatesList::add); + + Assertions.assertThat(candidatesList).containsExactlyInAnyOrderElementsOf(allProfileNames()); + } + + static Set allProfileNames() { + final Set profileNames = new TreeSet<>(InternalProfileName.getInternalProfileNames()); + final Set externalProfileNames = + InternalProfileName.getInternalProfileNames().stream() + .map(name -> name + "_external") + .collect(Collectors.toSet()); + profileNames.addAll(externalProfileNames); + return profileNames; + } + + @AfterAll + public static void clearSystemProperty() { + if (originalProfilesDirProperty != null) { + System.setProperty("besu.profiles.dir", originalProfilesDirProperty); + } else { + System.clearProperty("besu.profiles.dir"); + } + } +} From 3117f15a3a3497fe8d4ccc553b739e5f390001ac Mon Sep 17 00:00:00 2001 From: Chaminda Divitotawela Date: Wed, 10 Jul 2024 18:43:07 +1000 Subject: [PATCH 027/259] Fix status badge for documentation (#7304) Documentation has been moved to GitHub pages and no longer use readthedocs. Updated the README status badge for docs with correct link Signed-off-by: Chaminda Divitotawela --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2a2262086b..d54b6bb329 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Besu Ethereum Client [![CircleCI](https://circleci.com/gh/hyperledger/besu/tree/main.svg?style=svg)](https://circleci.com/gh/hyperledger/besu/tree/main) - [![Documentation Status](https://readthedocs.org/projects/hyperledger-besu/badge/?version=latest)](https://besu.hyperledger.org/en/latest/?badge=latest) + [![Documentation](https://img.shields.io/github/actions/workflow/status/hyperledger/besu-docs/publish-main-docs.yml?branch=main&label=docs)](https://github.com/hyperledger/besu-docs/actions/workflows/publish-main-docs.yml) [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/3174/badge)](https://bestpractices.coreinfrastructure.org/projects/3174) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/hyperledger/besu/blob/main/LICENSE) [![Discord](https://img.shields.io/discord/905194001349627914?logo=Hyperledger&style=plastic)](https://discord.gg/hyperledger) From 3f00bad598e99ea51d17456e9693abb3cd999b76 Mon Sep 17 00:00:00 2001 From: Sally MacFarlane Date: Thu, 11 Jul 2024 09:49:37 +1000 Subject: [PATCH 028/259] [MINOR] Fixed some typos (#7299) * typos Signed-off-by: Sally MacFarlane --------- Signed-off-by: Sally MacFarlane --- .github/workflows/container-security-scan.yml | 2 +- .../besu/ethereum/mainnet/MainnetProtocolSpecs.java | 4 ++-- .../besu/ethereum/eth/manager/snap/SnapProtocolManager.java | 2 +- .../java/org/hyperledger/besu/ethereum/trie/MerkleTrie.java | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/container-security-scan.yml b/.github/workflows/container-security-scan.yml index f945d13220..9d41e819b5 100644 --- a/.github/workflows/container-security-scan.yml +++ b/.github/workflows/container-security-scan.yml @@ -8,7 +8,7 @@ on: required: false default: 'develop' schedule: - # Start of the hour is the busy time. Scheule it to run 8:17am UTC + # Start of the hour is the busy time. Schedule it to run 8:17am UTC - cron: '17 8 * * *' jobs: 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 b4a75c49c2..4ae30f8de9 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 @@ -642,9 +642,9 @@ public abstract class MainnetProtocolSpecs { return cancunDefinition( chainId, enableRevertReason, genesisConfigOptions, evmConfiguration, miningParameters) - // EIP-3074 AUTH and AUTCALL gas + // EIP-3074 AUTH and AUTHCALL gas .gasCalculator(PragueGasCalculator::new) - // EIP-3074 AUTH and AUTCALL + // EIP-3074 AUTH and AUTHCALL .evmBuilder( (gasCalculator, jdCacheConfig) -> MainnetEVMs.prague( diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/SnapProtocolManager.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/SnapProtocolManager.java index 2c717d77a1..c65a1c6b0c 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/SnapProtocolManager.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/SnapProtocolManager.java @@ -84,7 +84,7 @@ public class SnapProtocolManager implements ProtocolManager { public void awaitStop() throws InterruptedException {} /** - * This function is called by the P2P framework when an "SNAP message has been received. + * This function is called by the P2P framework when a SNAP message has been received. * * @param cap The capability under which the message was transmitted. * @param message The message to be decoded. diff --git a/ethereum/trie/src/main/java/org/hyperledger/besu/ethereum/trie/MerkleTrie.java b/ethereum/trie/src/main/java/org/hyperledger/besu/ethereum/trie/MerkleTrie.java index 2fdb494703..c9442e2684 100644 --- a/ethereum/trie/src/main/java/org/hyperledger/besu/ethereum/trie/MerkleTrie.java +++ b/ethereum/trie/src/main/java/org/hyperledger/besu/ethereum/trie/MerkleTrie.java @@ -28,7 +28,7 @@ import java.util.function.Function; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; -/** An Merkle Patricial Trie. */ +/** A Merkle Patricia Trie. */ public interface MerkleTrie { Bytes EMPTY_TRIE_NODE = RLP.NULL; From 812dc747424a0c984e483b2a01fdaab97d50a42c Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Thu, 11 Jul 2024 21:19:50 -0600 Subject: [PATCH 029/259] Add evmtool block-test subcommand (#7293) * Add evmtool block-test subcommand Add an evmtool subcommand that will run non-hive blockchain tests. Signed-off-by: Danno Ferrin --- CHANGELOG.md | 5 +- .../evmtool/BlockchainTestSubCommand.java | 254 ++++++++++++++++++ .../besu/evmtool/EvmToolCommand.java | 16 +- .../besu/evmtool/EvmToolSpecTests.java | 13 +- .../evmtool/block-test/prague-eof-rjump.json | 250 +++++++++++++++++ .../referencetests/EOFTestCaseSpec.java | 3 +- 6 files changed, 531 insertions(+), 10 deletions(-) create mode 100644 ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/BlockchainTestSubCommand.java create mode 100644 ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/block-test/prague-eof-rjump.json diff --git a/CHANGELOG.md b/CHANGELOG.md index 1306de83dd..0b783b1dc3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,10 @@ ### Breaking Changes ### Additions and Improvements +- `--Xsnapsync-bft-enabled` option enables experimental support for snap sync with IBFT/QBFT permissioned Bonsai-DB chains [#7140](https://github.com/hyperledger/besu/pull/7140) - Add support to load external profiles using `--profile` [#7265](https://github.com/hyperledger/besu/issues/7265) +- `privacy-nonce-always-increments` option enables private transactions to always increment the nonce, even if the transaction is invalid [#6593](https://github.com/hyperledger/besu/pull/6593) +- Added `block-test` subcommand to the evmtool which runs blockchain reference tests [#7293](https://github.com/hyperledger/besu/pull/7293) ### Bug fixes @@ -34,8 +37,6 @@ - Nodes in a permissioned chain maintain (and retry) connections to bootnodes [#7257](https://github.com/hyperledger/besu/pull/7257) - Promote experimental `besu storage x-trie-log` subcommand to production-ready [#7278](https://github.com/hyperledger/besu/pull/7278) - Enhanced BFT round-change diagnostics [#7271](https://github.com/hyperledger/besu/pull/7271) -- `--Xsnapsync-bft-enabled` option enables experimental support for snap sync with IBFT/QBFT permissioned Bonsai-DB chains [#7140](https://github.com/hyperledger/besu/pull/7140) -- `privacy-nonce-always-increments` option enables private transactions to always increment the nonce, even if the transaction is invalid [#6593](https://github.com/hyperledger/besu/pull/6593) ### Bug fixes - Validation errors ignored in accounts-allowlist and empty list [#7138](https://github.com/hyperledger/besu/issues/7138) diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/BlockchainTestSubCommand.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/BlockchainTestSubCommand.java new file mode 100644 index 0000000000..5b9bc2cdfe --- /dev/null +++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/BlockchainTestSubCommand.java @@ -0,0 +1,254 @@ +/* + * 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.evmtool; + +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.hyperledger.besu.evmtool.BlockchainTestSubCommand.COMMAND_NAME; + +import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; +import org.hyperledger.besu.ethereum.ProtocolContext; +import org.hyperledger.besu.ethereum.chain.MutableBlockchain; +import org.hyperledger.besu.ethereum.core.Block; +import org.hyperledger.besu.ethereum.core.BlockHeader; +import org.hyperledger.besu.ethereum.core.BlockImporter; +import org.hyperledger.besu.ethereum.core.MutableWorldState; +import org.hyperledger.besu.ethereum.mainnet.BlockImportResult; +import org.hyperledger.besu.ethereum.mainnet.HeaderValidationMode; +import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; +import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; +import org.hyperledger.besu.ethereum.referencetests.BlockchainReferenceTestCaseSpec; +import org.hyperledger.besu.ethereum.referencetests.ReferenceTestProtocolSchedules; +import org.hyperledger.besu.ethereum.rlp.RLPException; +import org.hyperledger.besu.evm.EVM; +import org.hyperledger.besu.evm.EvmSpecVersion; +import org.hyperledger.besu.evm.account.AccountState; +import org.hyperledger.besu.evm.internal.EvmConfiguration.WorldUpdaterMode; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.function.Supplier; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.base.Suppliers; +import org.apache.tuweni.bytes.Bytes32; +import picocli.CommandLine.Command; +import picocli.CommandLine.Option; +import picocli.CommandLine.Parameters; +import picocli.CommandLine.ParentCommand; + +/** + * This class, BlockchainTestSubCommand, is a command-line interface (CLI) command that executes an + * Ethereum State Test. It implements the Runnable interface, meaning it can be used in a thread of + * execution. + * + *

The class is annotated with @CommandLine.Command, which is a PicoCLI annotation that + * designates this class as a command-line command. The annotation parameters define the command's + * name, description, whether it includes standard help options, and the version provider. + * + *

validators, - final Bytes cms) { - super(vanityData, seals, vote, round, validators); - this.cms = cms; - } - - /** - * Instantiates a new Pki Qbft extra data. - * - * @param bftExtraData the bft extra data - * @param cms the cms - */ - public PkiQbftExtraData(final BftExtraData bftExtraData, final Bytes cms) { - this( - bftExtraData.getVanityData(), - bftExtraData.getSeals(), - bftExtraData.getVote(), - bftExtraData.getRound(), - bftExtraData.getValidators(), - cms); - } - - /** - * Gets cms. - * - * @return the cms - */ - public Bytes getCms() { - return cms; - } -} diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/pki/PkiQbftExtraDataCodec.java b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/pki/PkiQbftExtraDataCodec.java deleted file mode 100644 index 655ea91695..0000000000 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/pki/PkiQbftExtraDataCodec.java +++ /dev/null @@ -1,95 +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.consensus.qbft.pki; - -import org.hyperledger.besu.consensus.common.bft.BftExtraData; -import org.hyperledger.besu.consensus.qbft.QbftExtraDataCodec; -import org.hyperledger.besu.ethereum.rlp.BytesValueRLPInput; -import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; -import org.hyperledger.besu.ethereum.rlp.RLPInput; - -import java.util.List; - -import org.apache.tuweni.bytes.Bytes; - -/** - * The PkiQbftExtraData encoding format is different from the "regular" QbftExtraData encoding. We - * have an extra bytes element in the end of the list. - */ -public class PkiQbftExtraDataCodec extends QbftExtraDataCodec { - - /** The constant QBFT_EXTRA_DATA_LIST_SIZE. */ - public static final int QBFT_EXTRA_DATA_LIST_SIZE = 5; - - /** Default constructor */ - public PkiQbftExtraDataCodec() {} - - @Override - public BftExtraData decodeRaw(final Bytes input) { - if (input.isEmpty()) { - throw new IllegalArgumentException("Invalid Bytes supplied - Bft Extra Data required."); - } - - final BftExtraData bftExtraData = super.decodeRaw(input); - - final RLPInput rlpInput = new BytesValueRLPInput(input, false); - - final Bytes cms; - final List elements = rlpInput.readList(RLPInput::readAsRlp); - if (elements.size() > QBFT_EXTRA_DATA_LIST_SIZE) { - final RLPInput cmsElement = elements.get(elements.size() - 1); - cms = cmsElement.readBytes(); - } else { - cms = Bytes.EMPTY; - } - - return new PkiQbftExtraData(bftExtraData, cms); - } - - @Override - protected Bytes encode(final BftExtraData bftExtraData, final EncodingType encodingType) { - return encode(bftExtraData, encodingType, true); - } - - private Bytes encode( - final BftExtraData bftExtraData, final EncodingType encodingType, final boolean includeCms) { - final Bytes encoded = super.encode(bftExtraData, encodingType); - if (!(bftExtraData instanceof PkiQbftExtraData) || !includeCms) { - return encoded; - } - - final BytesValueRLPOutput rlpOutput = new BytesValueRLPOutput(); - rlpOutput.startList(); - // Read through extraData RLP list elements and write them to the new RLP output - new BytesValueRLPInput(encoded, false) - .readList(RLPInput::readAsRlp).stream() - .map(RLPInput::raw) - .forEach(rlpOutput::writeRLPBytes); - rlpOutput.writeBytes(((PkiQbftExtraData) bftExtraData).getCms()); - rlpOutput.endList(); - - return rlpOutput.encoded(); - } - - /** - * Encode without cms. - * - * @param bftExtraData the bft extra data - * @return the bytes - */ - public Bytes encodeWithoutCms(final BftExtraData bftExtraData) { - return encode(bftExtraData, EncodingType.ALL, false); - } -} diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/validation/ProposalPayloadValidator.java b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/validation/ProposalPayloadValidator.java index 640216e9a9..3d04f699c0 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/validation/ProposalPayloadValidator.java +++ b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/validation/ProposalPayloadValidator.java @@ -16,24 +16,14 @@ package org.hyperledger.besu.consensus.qbft.validation; import static com.google.common.base.Preconditions.checkState; -import org.hyperledger.besu.consensus.common.bft.BftBlockInterface; -import org.hyperledger.besu.consensus.common.bft.BftExtraDataCodec; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; import org.hyperledger.besu.consensus.common.bft.payload.SignedData; -import org.hyperledger.besu.consensus.qbft.QbftContext; import org.hyperledger.besu.consensus.qbft.payload.ProposalPayload; -import org.hyperledger.besu.consensus.qbft.pki.PkiQbftBlockHeaderFunctions; -import org.hyperledger.besu.consensus.qbft.pki.PkiQbftExtraData; -import org.hyperledger.besu.consensus.qbft.pki.PkiQbftExtraDataCodec; import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.BlockValidator; import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.core.Block; import org.hyperledger.besu.ethereum.mainnet.HeaderValidationMode; -import org.hyperledger.besu.pki.cms.CmsValidator; - -import java.util.Optional; import com.google.common.annotations.VisibleForTesting; import org.slf4j.Logger; @@ -49,35 +39,6 @@ public class ProposalPayloadValidator { private final ConsensusRoundIdentifier targetRound; private final BlockValidator blockValidator; private final ProtocolContext protocolContext; - private final BftExtraDataCodec bftExtraDataCodec; - private final Optional cmsValidator; - - /** - * Instantiates a new Proposal payload validator. - * - * @param expectedProposer the expected proposer - * @param targetRound the target round - * @param blockValidator the block validator - * @param protocolContext the protocol context - * @param bftExtraDataCodec the bft extra data codec - */ - public ProposalPayloadValidator( - final Address expectedProposer, - final ConsensusRoundIdentifier targetRound, - final BlockValidator blockValidator, - final ProtocolContext protocolContext, - final BftExtraDataCodec bftExtraDataCodec) { - this( - expectedProposer, - targetRound, - blockValidator, - protocolContext, - bftExtraDataCodec, - protocolContext - .getConsensusContext(QbftContext.class) - .getPkiBlockCreationConfiguration() - .map(config -> new CmsValidator(config.getTrustStore()))); - } /** * Instantiates a new Proposal payload validator. @@ -86,23 +47,17 @@ public class ProposalPayloadValidator { * @param targetRound the target round * @param blockValidator the block validator * @param protocolContext the protocol context - * @param bftExtraDataCodec the bft extra data codec - * @param cmsValidator the cms validator */ @VisibleForTesting public ProposalPayloadValidator( final Address expectedProposer, final ConsensusRoundIdentifier targetRound, final BlockValidator blockValidator, - final ProtocolContext protocolContext, - final BftExtraDataCodec bftExtraDataCodec, - final Optional cmsValidator) { + final ProtocolContext protocolContext) { this.expectedProposer = expectedProposer; this.targetRound = targetRound; this.blockValidator = blockValidator; this.protocolContext = protocolContext; - this.bftExtraDataCodec = bftExtraDataCodec; - this.cmsValidator = cmsValidator; } /** @@ -135,13 +90,6 @@ public class ProposalPayloadValidator { return false; } - if (cmsValidator.isPresent()) { - return validateCms( - block, - protocolContext.getConsensusContext(QbftContext.class).getBlockInterface(), - cmsValidator.get()); - } - return true; } @@ -162,26 +110,4 @@ public class ProposalPayloadValidator { return true; } - - private boolean validateCms( - final Block block, - final BftBlockInterface bftBlockInterface, - final CmsValidator cmsValidator) { - final PkiQbftExtraData pkiExtraData = - (PkiQbftExtraData) bftBlockInterface.getExtraData(block.getHeader()); - - final Hash hashWithoutCms = - PkiQbftBlockHeaderFunctions.forCmsSignature((PkiQbftExtraDataCodec) bftExtraDataCodec) - .hash(block.getHeader()); - - LOG.debug("Validating CMS with signed hash {} in block {}", hashWithoutCms, block.getHash()); - - if (!cmsValidator.validate(pkiExtraData.getCms(), hashWithoutCms)) { - LOG.info("{}: invalid CMS in block {}", ERROR_PREFIX, block.getHash()); - return false; - } else { - LOG.trace("Valid CMS in block {}", block.getHash()); - return true; - } - } } diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/validation/ProposalValidator.java b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/validation/ProposalValidator.java index 53f81fa25d..81cbffdff9 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/validation/ProposalValidator.java +++ b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/validation/ProposalValidator.java @@ -98,7 +98,7 @@ public class ProposalValidator { final ProposalPayloadValidator payloadValidator = new ProposalPayloadValidator( - expectedProposer, roundIdentifier, blockValidator, protocolContext, bftExtraDataCodec); + expectedProposer, roundIdentifier, blockValidator, protocolContext); if (!payloadValidator.validate(msg.getSignedPayload())) { LOG.info("{}: invalid proposal payload in proposal message", ERROR_PREFIX); diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/validation/ProposalPayloadValidatorTest.java b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/validation/ProposalPayloadValidatorTest.java index 182393484e..9c9422e108 100644 --- a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/validation/ProposalPayloadValidatorTest.java +++ b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/validation/ProposalPayloadValidatorTest.java @@ -21,8 +21,6 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; -import org.hyperledger.besu.consensus.common.bft.BftBlockHeaderFunctions; -import org.hyperledger.besu.consensus.common.bft.BftExtraDataCodec; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundHelpers; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; import org.hyperledger.besu.consensus.common.bft.ProposedBlockHelpers; @@ -30,31 +28,21 @@ import org.hyperledger.besu.consensus.qbft.QbftContext; import org.hyperledger.besu.consensus.qbft.QbftExtraDataCodec; import org.hyperledger.besu.consensus.qbft.messagewrappers.Proposal; import org.hyperledger.besu.consensus.qbft.payload.MessageFactory; -import org.hyperledger.besu.consensus.qbft.pki.PkiQbftBlockHeaderFunctions; -import org.hyperledger.besu.consensus.qbft.pki.PkiQbftExtraData; -import org.hyperledger.besu.consensus.qbft.pki.PkiQbftExtraDataCodec; import org.hyperledger.besu.cryptoservices.NodeKey; import org.hyperledger.besu.cryptoservices.NodeKeyUtils; import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.BlockProcessingResult; import org.hyperledger.besu.ethereum.BlockValidator; 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.Block; -import org.hyperledger.besu.ethereum.core.BlockDataGenerator; -import org.hyperledger.besu.ethereum.core.BlockDataGenerator.BlockOptions; import org.hyperledger.besu.ethereum.core.Util; import org.hyperledger.besu.ethereum.mainnet.HeaderValidationMode; import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; -import org.hyperledger.besu.pki.cms.CmsValidator; -import java.util.Collections; -import java.util.List; import java.util.Optional; -import org.apache.tuweni.bytes.Bytes; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -67,7 +55,6 @@ public class ProposalPayloadValidatorTest { @Mock private BlockValidator blockValidator; @Mock private MutableBlockchain blockChain; @Mock private WorldStateArchive worldStateArchive; - @Mock private CmsValidator cmsValidator; private ProtocolContext protocolContext; private static final int CHAIN_HEIGHT = 3; @@ -95,7 +82,7 @@ public class ProposalPayloadValidatorTest { public void validationPassesWhenProposerAndRoundMatchAndBlockIsValid() { final ProposalPayloadValidator payloadValidator = new ProposalPayloadValidator( - expectedProposer, roundIdentifier, blockValidator, protocolContext, bftExtraDataCodec); + expectedProposer, roundIdentifier, blockValidator, protocolContext); final Block block = ProposedBlockHelpers.createProposalBlock(emptyList(), roundIdentifier, bftExtraDataCodec); final Proposal proposal = @@ -116,7 +103,7 @@ public class ProposalPayloadValidatorTest { public void validationPassesWhenBlockRoundDoesNotMatchProposalRound() { final ProposalPayloadValidator payloadValidator = new ProposalPayloadValidator( - expectedProposer, roundIdentifier, blockValidator, protocolContext, bftExtraDataCodec); + expectedProposer, roundIdentifier, blockValidator, protocolContext); final Block block = ProposedBlockHelpers.createProposalBlock( @@ -144,7 +131,7 @@ public class ProposalPayloadValidatorTest { final ProposalPayloadValidator payloadValidator = new ProposalPayloadValidator( - expectedProposer, roundIdentifier, blockValidator, protocolContext, bftExtraDataCodec); + expectedProposer, roundIdentifier, blockValidator, protocolContext); final Block block = ProposedBlockHelpers.createProposalBlock(emptyList(), roundIdentifier, bftExtraDataCodec); final Proposal proposal = @@ -165,11 +152,7 @@ public class ProposalPayloadValidatorTest { public void validationFailsWhenExpectedProposerDoesNotMatchPayloadsAuthor() { final ProposalPayloadValidator payloadValidator = new ProposalPayloadValidator( - Address.fromHexString("0x1"), - roundIdentifier, - blockValidator, - protocolContext, - bftExtraDataCodec); + Address.fromHexString("0x1"), roundIdentifier, blockValidator, protocolContext); final Block block = ProposedBlockHelpers.createProposalBlock(emptyList(), roundIdentifier); final Proposal proposal = messageFactory.createProposal(roundIdentifier, block, emptyList(), emptyList()); @@ -182,7 +165,7 @@ public class ProposalPayloadValidatorTest { public void validationFailsWhenMessageMismatchesExpectedRound() { final ProposalPayloadValidator payloadValidator = new ProposalPayloadValidator( - expectedProposer, roundIdentifier, blockValidator, protocolContext, bftExtraDataCodec); + expectedProposer, roundIdentifier, blockValidator, protocolContext); final Block block = ProposedBlockHelpers.createProposalBlock(emptyList(), roundIdentifier); final Proposal proposal = @@ -200,7 +183,7 @@ public class ProposalPayloadValidatorTest { public void validationFailsWhenMessageMismatchesExpectedHeight() { final ProposalPayloadValidator payloadValidator = new ProposalPayloadValidator( - expectedProposer, roundIdentifier, blockValidator, protocolContext, bftExtraDataCodec); + expectedProposer, roundIdentifier, blockValidator, protocolContext); final Block block = ProposedBlockHelpers.createProposalBlock(emptyList(), roundIdentifier); final Proposal proposal = @@ -218,7 +201,7 @@ public class ProposalPayloadValidatorTest { public void validationFailsForBlockWithIncorrectHeight() { final ProposalPayloadValidator payloadValidator = new ProposalPayloadValidator( - expectedProposer, roundIdentifier, blockValidator, protocolContext, bftExtraDataCodec); + expectedProposer, roundIdentifier, blockValidator, protocolContext); final Block block = ProposedBlockHelpers.createProposalBlock( emptyList(), @@ -237,104 +220,4 @@ public class ProposalPayloadValidatorTest { assertThat(payloadValidator.validate(proposal.getSignedPayload())).isFalse(); } - - @Test - public void validationForCmsFailsWhenCmsFailsValidation() { - final PkiQbftExtraDataCodec pkiQbftExtraDataCodec = new PkiQbftExtraDataCodec(); - final QbftContext qbftContext = - setupContextWithBftExtraDataEncoder(QbftContext.class, emptyList(), pkiQbftExtraDataCodec); - final Bytes cms = Bytes.fromHexStringLenient("0x1"); - final ProtocolContext protocolContext = - new ProtocolContext(blockChain, worldStateArchive, qbftContext, new BadBlockManager()); - - final ProposalPayloadValidator payloadValidator = - new ProposalPayloadValidator( - expectedProposer, - roundIdentifier, - blockValidator, - protocolContext, - pkiQbftExtraDataCodec, - Optional.of(cmsValidator)); - final Block block = - createPkiProposalBlock(emptyList(), roundIdentifier, pkiQbftExtraDataCodec, cms); - final Proposal proposal = - messageFactory.createProposal(roundIdentifier, block, emptyList(), emptyList()); - final Hash hashWithoutCms = - PkiQbftBlockHeaderFunctions.forCmsSignature(pkiQbftExtraDataCodec).hash(block.getHeader()); - - when(blockValidator.validateAndProcessBlock( - eq(protocolContext), - eq(block), - eq(HeaderValidationMode.LIGHT), - eq(HeaderValidationMode.FULL), - eq(false))) - .thenReturn(new BlockProcessingResult(Optional.empty())); - when(cmsValidator.validate(eq(cms), eq(hashWithoutCms))).thenReturn(false); - - assertThat(payloadValidator.validate(proposal.getSignedPayload())).isFalse(); - } - - @Test - public void validationForCmsPassesWhenCmsIsValid() { - final PkiQbftExtraDataCodec pkiQbftExtraDataCodec = new PkiQbftExtraDataCodec(); - final QbftContext qbftContext = - setupContextWithBftExtraDataEncoder(QbftContext.class, emptyList(), pkiQbftExtraDataCodec); - final Bytes cms = Bytes.fromHexStringLenient("0x1"); - final ProtocolContext protocolContext = - new ProtocolContext(blockChain, worldStateArchive, qbftContext, new BadBlockManager()); - - final ProposalPayloadValidator payloadValidator = - new ProposalPayloadValidator( - expectedProposer, - roundIdentifier, - blockValidator, - protocolContext, - pkiQbftExtraDataCodec, - Optional.of(cmsValidator)); - final Block block = - createPkiProposalBlock(emptyList(), roundIdentifier, pkiQbftExtraDataCodec, cms); - final Proposal proposal = - messageFactory.createProposal(roundIdentifier, block, emptyList(), emptyList()); - final Hash hashWithoutCms = - PkiQbftBlockHeaderFunctions.forCmsSignature(pkiQbftExtraDataCodec).hash(block.getHeader()); - - when(blockValidator.validateAndProcessBlock( - eq(protocolContext), - eq(block), - eq(HeaderValidationMode.LIGHT), - eq(HeaderValidationMode.FULL), - eq(false))) - .thenReturn(new BlockProcessingResult(Optional.empty())); - when(cmsValidator.validate(eq(cms), eq(hashWithoutCms))).thenReturn(true); - - assertThat(payloadValidator.validate(proposal.getSignedPayload())).isTrue(); - } - - public static Block createPkiProposalBlock( - final List
validators, - final ConsensusRoundIdentifier roundId, - final BftExtraDataCodec bftExtraDataCodec, - final Bytes cms) { - final Bytes extraData = - bftExtraDataCodec.encode( - new PkiQbftExtraData( - Bytes.wrap(new byte[32]), - Collections.emptyList(), - Optional.empty(), - roundId.getRoundNumber(), - validators, - cms)); - final BlockOptions blockOptions = - BlockOptions.create() - .setExtraData(extraData) - .setBlockNumber(roundId.getSequenceNumber()) - .setBlockHeaderFunctions(BftBlockHeaderFunctions.forCommittedSeal(bftExtraDataCodec)) - .hasOmmers(false) - .hasTransactions(false); - - if (validators.size() > 0) { - blockOptions.setCoinbase(validators.get(0)); - } - return new BlockDataGenerator().block(blockOptions); - } } From 223f1bc3bb68267fb4841601d86fbb7b76ec0cf2 Mon Sep 17 00:00:00 2001 From: Sally MacFarlane Date: Tue, 16 Jul 2024 10:44:06 +1000 Subject: [PATCH 040/259] EIP-7251 add consolidation request type (#7266) * add request type for consolidations, encoder, decoder and tests * added raw tx for consolidation * add consolidation reqs to EngineGetPayloadResultV4 * set storage slot value to 0 initially and value for tx * updates plugin api Signed-off-by: Justin Florentine Signed-off-by: Sally MacFarlane --------- Signed-off-by: Sally MacFarlane Signed-off-by: Justin Florentine Co-authored-by: Justin Florentine --- .../jsonrpc/engine/prague/genesis.json | 16 ++- .../test-cases/00_get_genesis_block_info.json | 43 ++++++ .../test-cases/01_cancun_prepare_payload.json | 8 +- .../test-cases/02_cancun_getPayloadV3.json | 8 +- .../test-cases/03_cancun_newPayloadV3.json | 8 +- .../04_cancun_forkchoiceUpdatedV3.json | 8 +- .../05_prague_forkchoiceUpdatedV3.json | 10 +- .../test-cases/06_prague_getPayloadV4.json | 9 +- ...invalid_null_deposits_execute_payload.json | 2 +- .../test-cases/09_prague_newPayloadV4.json | 9 +- .../10_prague_forkchoiceUpdatedV3.json | 10 +- .../test-cases/11_prague_getPayloadV4.json | 9 +- ...oadV4.json => 12_cancun_newPayloadV3.json} | 8 +- ...raw_transaction_consolidation_request.json | 14 ++ ...son => 15_prague_forkchoiceUpdatedV3.json} | 10 +- ...oadV4.json => 16_prague_getPayloadV4.json} | 24 ++-- .../besu/datatypes/RequestType.java | 5 +- .../engine/AbstractEngineNewPayload.java | 19 ++- .../engine/RequestValidatorProvider.java | 6 + .../ConsolidationRequestParameter.java | 102 +++++++++++++ .../parameters/EnginePayloadParameter.java | 11 +- .../internal/results/BlockResultFactory.java | 2 + .../results/EngineGetPayloadResultV4.java | 30 +++- .../engine/AbstractEngineNewPayloadTest.java | 9 +- .../engine/EngineGetPayloadV4Test.java | 1 + .../engine/EngineNewPayloadV2Test.java | 14 +- .../engine/EngineNewPayloadV3Test.java | 8 +- .../engine/EngineNewPayloadV4Test.java | 16 ++- .../ethereum/core/ConsolidationRequest.java | 90 ++++++++++++ .../encoding/ConsolidationRequestDecoder.java | 40 ++++++ .../encoding/ConsolidationRequestEncoder.java | 60 ++++++++ .../core/encoding/RequestDecoder.java | 4 +- .../core/encoding/RequestEncoder.java | 4 +- .../ConsolidationRequestProcessor.java | 68 +++++++++ .../ConsolidationRequestValidator.java | 92 ++++++++++++ .../requests/MainnetRequestsValidator.java | 2 + .../mainnet/requests/RequestUtil.java | 21 ++- .../ConsolidationRequestDecoderTest.java | 46 ++++++ .../ConsolidationRequestEncoderTest.java | 55 +++++++ ...st.java => DepositRequestDecoderTest.java} | 2 +- ...st.java => DepositRequestEncoderTest.java} | 2 +- ...olidationRequestValidatorTestFixtures.java | 136 ++++++++++++++++++ ...agueConsolidationRequestValidatorTest.java | 76 ++++++++++ .../hyperledger/besu/evmtool/T8nExecutor.java | 15 +- .../besu/evmtool/t8n/prague-deposit.json | 13 +- .../besu/evmtool/t8n/prague-withdrawal.json | 1 + .../vm/BlockchainReferenceTestTools.java | 4 +- plugin-api/build.gradle | 2 +- .../plugin/data/ConsolidationRequest.java | 45 ++++++ 49 files changed, 1099 insertions(+), 98 deletions(-) create mode 100644 acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/00_get_genesis_block_info.json rename acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/{12_cancun_newPayloadV4.json => 12_cancun_newPayloadV3.json} (80%) create mode 100644 acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/14_prague_send_raw_transaction_consolidation_request.json rename acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/{14_prague_forkchoiceUpdatedV3.json => 15_prague_forkchoiceUpdatedV3.json} (61%) rename acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/{15_prague_getPayloadV4.json => 16_prague_getPayloadV4.json} (62%) create mode 100644 ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/ConsolidationRequestParameter.java create mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/ConsolidationRequest.java create mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/ConsolidationRequestDecoder.java create 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/mainnet/requests/ConsolidationRequestProcessor.java create mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/ConsolidationRequestValidator.java create mode 100644 ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/ConsolidationRequestDecoderTest.java create 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/{DepositRequestRequestDecoderTest.java => DepositRequestDecoderTest.java} (99%) rename ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/{DepositRequestRequestEncoderTest.java => DepositRequestEncoderTest.java} (98%) create mode 100644 ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/ConsolidationRequestValidatorTestFixtures.java create mode 100644 ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/PragueConsolidationRequestValidatorTest.java create mode 100644 plugin-api/src/main/java/org/hyperledger/besu/plugin/data/ConsolidationRequest.java 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 3f2645d4d3..ac474c0245 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 @@ -33,7 +33,7 @@ "balance": "1000000000000000000000000000" }, "0x23618e81E3f5cdF7f54C3d65f7FBc0aBf5B21E8f": { - "comment": "This is the account used to sign the transaction that creates a validator exit", + "comment": "This is the account used to sign the transactions that create a validator exit, and consolidation request", "balance": "1000000000000000000000000000" }, "0x00A3ca265EBcb825B45F985A16CEFB49958cE017": { @@ -50,6 +50,20 @@ "0x0000000000000000000000000000000000000000000000000000000000000006": "5d8601f0cb3bcc4ce1af9864779a416e00000000000000000000000000000000" } }, + "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", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000000": "0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000001": "0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000002": "0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000003": "0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000004": "0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000005": "0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000006": "0000000000000000000000000000000000000000000000000000000000000000" + } + }, "0x4242424242424242424242424242424242424242": { "balance": "0", "code": "0x60806040526004361061003f5760003560e01c806301ffc9a71461004457806322895118146100a4578063621fd130146101ba578063c5f2892f14610244575b600080fd5b34801561005057600080fd5b506100906004803603602081101561006757600080fd5b50357fffffffff000000000000000000000000000000000000000000000000000000001661026b565b604080519115158252519081900360200190f35b6101b8600480360360808110156100ba57600080fd5b8101906020810181356401000000008111156100d557600080fd5b8201836020820111156100e757600080fd5b8035906020019184600183028401116401000000008311171561010957600080fd5b91939092909160208101903564010000000081111561012757600080fd5b82018360208201111561013957600080fd5b8035906020019184600183028401116401000000008311171561015b57600080fd5b91939092909160208101903564010000000081111561017957600080fd5b82018360208201111561018b57600080fd5b803590602001918460018302840111640100000000831117156101ad57600080fd5b919350915035610304565b005b3480156101c657600080fd5b506101cf6110b5565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102095781810151838201526020016101f1565b50505050905090810190601f1680156102365780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561025057600080fd5b506102596110c7565b60408051918252519081900360200190f35b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a70000000000000000000000000000000000000000000000000000000014806102fe57507fffffffff0000000000000000000000000000000000000000000000000000000082167f8564090700000000000000000000000000000000000000000000000000000000145b92915050565b6030861461035d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118056026913960400191505060405180910390fd5b602084146103b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603681526020018061179c6036913960400191505060405180910390fd5b6060821461040f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260298152602001806118786029913960400191505060405180910390fd5b670de0b6b3a7640000341015610470576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118526026913960400191505060405180910390fd5b633b9aca003406156104cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260338152602001806117d26033913960400191505060405180910390fd5b633b9aca00340467ffffffffffffffff811115610535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602781526020018061182b6027913960400191505060405180910390fd5b6060610540826114ba565b90507f649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c589898989858a8a6105756020546114ba565b6040805160a0808252810189905290819060208201908201606083016080840160c085018e8e80828437600083820152601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690910187810386528c815260200190508c8c808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690920188810386528c5181528c51602091820193918e019250908190849084905b83811015610648578181015183820152602001610630565b50505050905090810190601f1680156106755780820380516001836020036101000a031916815260200191505b5086810383528881526020018989808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169092018881038452895181528951602091820193918b019250908190849084905b838110156106ef5781810151838201526020016106d7565b50505050905090810190601f16801561071c5780820380516001836020036101000a031916815260200191505b509d505050505050505050505050505060405180910390a1600060028a8a600060801b604051602001808484808284377fffffffffffffffffffffffffffffffff0000000000000000000000000000000090941691909301908152604080517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0818403018152601090920190819052815191955093508392506020850191508083835b602083106107fc57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016107bf565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610859573d6000803e3d6000fd5b5050506040513d602081101561086e57600080fd5b5051905060006002806108846040848a8c6116fe565b6040516020018083838082843780830192505050925050506040516020818303038152906040526040518082805190602001908083835b602083106108f857805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016108bb565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610955573d6000803e3d6000fd5b5050506040513d602081101561096a57600080fd5b5051600261097b896040818d6116fe565b60405160009060200180848480828437919091019283525050604080518083038152602092830191829052805190945090925082918401908083835b602083106109f457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016109b7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610a51573d6000803e3d6000fd5b5050506040513d6020811015610a6657600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610ada57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610a9d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610b37573d6000803e3d6000fd5b5050506040513d6020811015610b4c57600080fd5b50516040805160208101858152929350600092600292839287928f928f92018383808284378083019250505093505050506040516020818303038152906040526040518082805190602001908083835b60208310610bd957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610b9c565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610c36573d6000803e3d6000fd5b5050506040513d6020811015610c4b57600080fd5b50516040518651600291889160009188916020918201918291908601908083835b60208310610ca957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610c6c565b6001836020036101000a0380198251168184511680821785525050505050509050018367ffffffffffffffff191667ffffffffffffffff1916815260180182815260200193505050506040516020818303038152906040526040518082805190602001908083835b60208310610d4e57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610d11565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610dab573d6000803e3d6000fd5b5050506040513d6020811015610dc057600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610e3457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610df7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610e91573d6000803e3d6000fd5b5050506040513d6020811015610ea657600080fd5b50519050858114610f02576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260548152602001806117486054913960600191505060405180910390fd5b60205463ffffffff11610f60576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806117276021913960400191505060405180910390fd5b602080546001019081905560005b60208110156110a9578160011660011415610fa0578260008260208110610f9157fe5b0155506110ac95505050505050565b600260008260208110610faf57fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061102557805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610fe8565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015611082573d6000803e3d6000fd5b5050506040513d602081101561109757600080fd5b50519250600282049150600101610f6e565b50fe5b50505050505050565b60606110c26020546114ba565b905090565b6020546000908190815b60208110156112f05781600116600114156111e6576002600082602081106110f557fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061116b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161112e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156111c8573d6000803e3d6000fd5b5050506040513d60208110156111dd57600080fd5b505192506112e2565b600283602183602081106111f657fe5b015460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061126b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161122e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156112c8573d6000803e3d6000fd5b5050506040513d60208110156112dd57600080fd5b505192505b6002820491506001016110d1565b506002826112ff6020546114ba565b600060401b6040516020018084815260200183805190602001908083835b6020831061135a57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161131d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790527fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000095909516920191825250604080518083037ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8018152601890920190819052815191955093508392850191508083835b6020831061143f57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611402565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa15801561149c573d6000803e3d6000fd5b5050506040513d60208110156114b157600080fd5b50519250505090565b60408051600880825281830190925260609160208201818036833701905050905060c082901b8060071a60f81b826000815181106114f457fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060061a60f81b8260018151811061153757fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060051a60f81b8260028151811061157a57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060041a60f81b826003815181106115bd57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060031a60f81b8260048151811061160057fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060021a60f81b8260058151811061164357fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060011a60f81b8260068151811061168657fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060001a60f81b826007815181106116c957fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535050919050565b6000808585111561170d578182fd5b83861115611719578182fd5b505082019391909203915056fe4465706f736974436f6e74726163743a206d65726b6c6520747265652066756c6c4465706f736974436f6e74726163743a207265636f6e7374727563746564204465706f7369744461746120646f6573206e6f74206d6174636820737570706c696564206465706f7369745f646174615f726f6f744465706f736974436f6e74726163743a20696e76616c6964207769746864726177616c5f63726564656e7469616c73206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c7565206e6f74206d756c7469706c65206f6620677765694465706f736974436f6e74726163743a20696e76616c6964207075626b6579206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f20686967684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f206c6f774465706f736974436f6e74726163743a20696e76616c6964207369676e6174757265206c656e677468a26469706673582212201dd26f37a621703009abf16e77e69c93dc50c79db7f6cc37543e3e0e3decdc9764736f6c634300060b0033", 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 new file mode 100644 index 0000000000..d1a18826a9 --- /dev/null +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/00_get_genesis_block_info.json @@ -0,0 +1,43 @@ +{ + "request": { + "jsonrpc": "2.0", + "method": "eth_getBlockByNumber", + "params": [ + "0x00", true + ], + "id": 67 + }, + "response": { + "jsonrpc": "2.0", + "id": 67, + "result": { + "number": "0x0", + "hash" : "0x38d7daa68e8bac41a0a237b7cbfcef480cb9bd9adc7b282d7b0d23ff4eb8d6e5", + "mixHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "nonce" : "0x0000000000000042", + "sha3Uncles" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "logsBloom" : "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "transactionsRoot" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0x3ed8435adb5f3526144e6babdd3fc8c661a86097cf7e743441b41fda096fc4dd", + "receiptsRoot" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "miner" : "0x0000000000000000000000000000000000000000", + "difficulty" : "0x400000000", + "totalDifficulty" : "0x400000000", + "extraData" : "0x0000000000000000000000000000000000000000000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "baseFeePerGas" : "0x7", + "size" : "0x2ba", + "gasLimit" : "0x1c9c380", + "gasUsed" : "0x0", + "timestamp" : "0x0", + "uncles" : [ ], + "transactions" : [ ], + "withdrawalsRoot" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "withdrawals" : [ ], + "blobGasUsed" : "0x0", + "excessBlobGas" : "0x0", + "parentBeaconBlockRoot" : "0x0000000000000000000000000000000000000000000000000000000000000000" + } + }, + "statusCode": 200 +} \ No newline at end of file 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 21a2e70a48..ad4b9be2d0 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": "0x3ca89f1d6b71aeb56389ac8270e9ae369d0bb8edeea747f2d868a5eb31892b04", - "safeBlockHash": "0x3ca89f1d6b71aeb56389ac8270e9ae369d0bb8edeea747f2d868a5eb31892b04", + "headBlockHash": "0x38d7daa68e8bac41a0a237b7cbfcef480cb9bd9adc7b282d7b0d23ff4eb8d6e5", + "safeBlockHash": "0x38d7daa68e8bac41a0a237b7cbfcef480cb9bd9adc7b282d7b0d23ff4eb8d6e5", "finalizedBlockHash": "0x0000000000000000000000000000000000000000000000000000000000000000" }, { @@ -24,10 +24,10 @@ "result": { "payloadStatus": { "status": "VALID", - "latestValidHash": "0x3ca89f1d6b71aeb56389ac8270e9ae369d0bb8edeea747f2d868a5eb31892b04", + "latestValidHash": "0x38d7daa68e8bac41a0a237b7cbfcef480cb9bd9adc7b282d7b0d23ff4eb8d6e5", "validationError": null }, - "payloadId": "0x282643d318bdab11" + "payloadId": "0x28264396eca1deef" } }, "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 0c9281fc6a..63cfeec26a 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": [ - "0x282643d318bdab11" + "0x28264396eca1deef" ], "id": 67 }, @@ -12,9 +12,9 @@ "id": 67, "result": { "executionPayload": { - "parentHash": "0x3ca89f1d6b71aeb56389ac8270e9ae369d0bb8edeea747f2d868a5eb31892b04", + "parentHash": "0x38d7daa68e8bac41a0a237b7cbfcef480cb9bd9adc7b282d7b0d23ff4eb8d6e5", "feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", - "stateRoot": "0x2b6a1166ce24fe0af741c7313e6049e9e19351742bfaf4179154bc594ca9eb90", + "stateRoot": "0x3ed8435adb5f3526144e6babdd3fc8c661a86097cf7e743441b41fda096fc4dd", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "gasLimit": "0x1c9c380", @@ -29,7 +29,7 @@ "blockNumber": "0x1", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "blobGasUsed": "0x0", - "blockHash": "0x74e8ce9d96d325a605675a34175adfa34581f35091dcd7b107c525a82b0b9950" + "blockHash": "0x8082deff44f79489ea92415be59afb48b6f46b939553f855479828a6f87f9593" }, "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 583bdc1a20..9f984b2f35 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": "0x3ca89f1d6b71aeb56389ac8270e9ae369d0bb8edeea747f2d868a5eb31892b04", + "parentHash": "0x38d7daa68e8bac41a0a237b7cbfcef480cb9bd9adc7b282d7b0d23ff4eb8d6e5", "feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", - "stateRoot": "0x2b6a1166ce24fe0af741c7313e6049e9e19351742bfaf4179154bc594ca9eb90", + "stateRoot": "0x3ed8435adb5f3526144e6babdd3fc8c661a86097cf7e743441b41fda096fc4dd", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "gasLimit": "0x1c9c380", @@ -17,7 +17,7 @@ "transactions": [], "withdrawals": [], "blockNumber": "0x1", - "blockHash": "0x74e8ce9d96d325a605675a34175adfa34581f35091dcd7b107c525a82b0b9950", + "blockHash": "0x8082deff44f79489ea92415be59afb48b6f46b939553f855479828a6f87f9593", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "excessBlobGas": "0x0", "blobGasUsed": "0x0" @@ -32,7 +32,7 @@ "id": 67, "result": { "status": "VALID", - "latestValidHash": "0x74e8ce9d96d325a605675a34175adfa34581f35091dcd7b107c525a82b0b9950", + "latestValidHash": "0x8082deff44f79489ea92415be59afb48b6f46b939553f855479828a6f87f9593", "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 229ca2cf51..b0ce0f70c1 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": "0x74e8ce9d96d325a605675a34175adfa34581f35091dcd7b107c525a82b0b9950", - "safeBlockHash": "0x74e8ce9d96d325a605675a34175adfa34581f35091dcd7b107c525a82b0b9950", - "finalizedBlockHash": "0x74e8ce9d96d325a605675a34175adfa34581f35091dcd7b107c525a82b0b9950" + "headBlockHash": "0x8082deff44f79489ea92415be59afb48b6f46b939553f855479828a6f87f9593", + "safeBlockHash": "0x8082deff44f79489ea92415be59afb48b6f46b939553f855479828a6f87f9593", + "finalizedBlockHash": "0x8082deff44f79489ea92415be59afb48b6f46b939553f855479828a6f87f9593" }, null ], @@ -18,7 +18,7 @@ "result": { "payloadStatus": { "status": "VALID", - "latestValidHash": "0x74e8ce9d96d325a605675a34175adfa34581f35091dcd7b107c525a82b0b9950", + "latestValidHash": "0x8082deff44f79489ea92415be59afb48b6f46b939553f855479828a6f87f9593", "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 721a625b6a..1eae1c881a 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": "0x74e8ce9d96d325a605675a34175adfa34581f35091dcd7b107c525a82b0b9950", - "safeBlockHash": "0x74e8ce9d96d325a605675a34175adfa34581f35091dcd7b107c525a82b0b9950", - "finalizedBlockHash": "0x74e8ce9d96d325a605675a34175adfa34581f35091dcd7b107c525a82b0b9950" + "headBlockHash": "0x8082deff44f79489ea92415be59afb48b6f46b939553f855479828a6f87f9593", + "safeBlockHash": "0x8082deff44f79489ea92415be59afb48b6f46b939553f855479828a6f87f9593", + "finalizedBlockHash": "0x8082deff44f79489ea92415be59afb48b6f46b939553f855479828a6f87f9593" }, { "timestamp": "0x20", @@ -24,10 +24,10 @@ "result": { "payloadStatus": { "status": "VALID", - "latestValidHash": "0x74e8ce9d96d325a605675a34175adfa34581f35091dcd7b107c525a82b0b9950", + "latestValidHash": "0x8082deff44f79489ea92415be59afb48b6f46b939553f855479828a6f87f9593", "validationError": null }, - "payloadId": "0x282643c6d89e12df" + "payloadId": "0x282643d3a905e721" } }, "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 6ff3614cdf..4cb85d5f54 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": [ - "0x282643c6d89e12df" + "0x282643d3a905e721" ], "id": 67 }, @@ -12,9 +12,9 @@ "id": 67, "result": { "executionPayload": { - "parentHash": "0x74e8ce9d96d325a605675a34175adfa34581f35091dcd7b107c525a82b0b9950", + "parentHash": "0x8082deff44f79489ea92415be59afb48b6f46b939553f855479828a6f87f9593", "feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", - "stateRoot": "0x546ac65b9d37c72d7185f8dd67419803c636dd4e5ddf9b325fb64e9ecf570871", + "stateRoot": "0x2e59916a57b535875bcd80d8472aeaa0027aa685d159804e8caa2f12d060155e", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "gasLimit": "0x1c9c380", @@ -34,8 +34,9 @@ "amount": "0x0" } ], + "consolidationRequests" : [], "blockNumber": "0x2", - "blockHash": "0xa7a92cc82e1d876476ad6433538599b0d592f88ba0823c23e80af93fb1748f14", + "blockHash": "0x27a2bc2ac21b3fc796f636bec1ec9cba100435f9a793176a83a5d4fa7cc13006", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "blobGasUsed": "0x0" }, 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_deposits_execute_payload.json index 7263aea00f..ed75e54aaf 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_deposits_execute_payload.json @@ -4,7 +4,7 @@ "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xa7a92cc82e1d876476ad6433538599b0d592f88ba0823c23e80af93fb1748f14", + "parentHash": "0x27a2bc2ac21b3fc796f636bec1ec9cba100435f9a793176a83a5d4fa7cc13006", "feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", "stateRoot": "0x9b8c4a9a86cb49252075c0db2f0e72fb1e49350a0f70ea36f26f700201961e62", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 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 a5ff6fa7ec..17496f9ed7 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": "0x74e8ce9d96d325a605675a34175adfa34581f35091dcd7b107c525a82b0b9950", + "parentHash": "0x8082deff44f79489ea92415be59afb48b6f46b939553f855479828a6f87f9593", "feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", - "stateRoot": "0xdb2a9bb9097dd6946525203a14437cd925ef549289e1fe17c6ed845c53647a26", + "stateRoot": "0x961878fdcdff52ea42db0026f59aa414a5ec2835e56ed1a8ae50c80a9fe3a04b", "logsBloom": "0x10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "gasLimit": "0x1c9c380", @@ -35,8 +35,9 @@ "validatorPubkey": "0xb10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e" } ], + "consolidationRequests": [], "blockNumber": "0x2", - "blockHash": "0x5200df2eb24d08e7bceec64194d073e81a6e9c00c4f61d323fad5d70b40e6d6d", + "blockHash": "0xc67a660f5d3c20ee603911bdff1e409e976f306883dff8ef4999dca3176f7dca", "receiptsRoot": "0x79ee3424eb720a3ad4b1c5a372bb8160580cbe4d893778660f34213c685627a9", "blobGasUsed": "0x0" }, @@ -50,7 +51,7 @@ "id": 67, "result": { "status": "VALID", - "latestValidHash": "0x5200df2eb24d08e7bceec64194d073e81a6e9c00c4f61d323fad5d70b40e6d6d", + "latestValidHash": "0xc67a660f5d3c20ee603911bdff1e409e976f306883dff8ef4999dca3176f7dca", "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 d8594f6280..ba0f1e8e5b 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": "0x5200df2eb24d08e7bceec64194d073e81a6e9c00c4f61d323fad5d70b40e6d6d", - "safeBlockHash": "0x5200df2eb24d08e7bceec64194d073e81a6e9c00c4f61d323fad5d70b40e6d6d", - "finalizedBlockHash": "0x5200df2eb24d08e7bceec64194d073e81a6e9c00c4f61d323fad5d70b40e6d6d" + "headBlockHash": "0xc67a660f5d3c20ee603911bdff1e409e976f306883dff8ef4999dca3176f7dca", + "safeBlockHash": "0xc67a660f5d3c20ee603911bdff1e409e976f306883dff8ef4999dca3176f7dca", + "finalizedBlockHash": "0xc67a660f5d3c20ee603911bdff1e409e976f306883dff8ef4999dca3176f7dca" }, { "timestamp": "0x30", @@ -24,10 +24,10 @@ "result": { "payloadStatus": { "status": "VALID", - "latestValidHash": "0x5200df2eb24d08e7bceec64194d073e81a6e9c00c4f61d323fad5d70b40e6d6d", + "latestValidHash": "0xc67a660f5d3c20ee603911bdff1e409e976f306883dff8ef4999dca3176f7dca", "validationError": null }, - "payloadId": "0x282643e2da21a7cf" + "payloadId": "0x282643a16a58b5cf" } }, "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 6a22938a69..3b76fac10a 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": [ - "0x282643e2da21a7cf" + "0x282643a16a58b5cf" ], "id": 67 }, @@ -12,9 +12,9 @@ "id": 67, "result": { "executionPayload": { - "parentHash": "0x5200df2eb24d08e7bceec64194d073e81a6e9c00c4f61d323fad5d70b40e6d6d", + "parentHash": "0xc67a660f5d3c20ee603911bdff1e409e976f306883dff8ef4999dca3176f7dca", "feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", - "stateRoot": "0xcd9f15de5f17cf87a02bf795a0dc98c108eead4651eca57fc7195bda0d9c20ee", + "stateRoot": "0x5fc31c01a451fe02f0e938de7ec7044aaba1159a81a1be64357bc70af226f304", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "gasLimit": "0x1c9c380", @@ -28,8 +28,9 @@ "withdrawals": [], "depositRequests": [], "withdrawalRequests": [], + "consolidationRequests" : [], "blockNumber": "0x3", - "blockHash": "0x79858f6eb8e82f0ec11087983ce4eb8c7edc10c9363a2a124dd78fd2c305dc42", + "blockHash": "0xdbb55a049f14b8152695bf3bbd754aa1fd55bbe10b306eb49caa4bd7d7fcb634", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "blobGasUsed": "0x0" }, diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/12_cancun_newPayloadV4.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/12_cancun_newPayloadV3.json similarity index 80% rename from acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/12_cancun_newPayloadV4.json rename to acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/12_cancun_newPayloadV3.json index 5d9f96c53b..546872807c 100644 --- a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/12_cancun_newPayloadV4.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": "0x5200df2eb24d08e7bceec64194d073e81a6e9c00c4f61d323fad5d70b40e6d6d", + "parentHash": "0xc67a660f5d3c20ee603911bdff1e409e976f306883dff8ef4999dca3176f7dca", "feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", - "stateRoot": "0xcd9f15de5f17cf87a02bf795a0dc98c108eead4651eca57fc7195bda0d9c20ee", + "stateRoot": "0x5fc31c01a451fe02f0e938de7ec7044aaba1159a81a1be64357bc70af226f304", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "gasLimit": "0x1c9c380", @@ -19,7 +19,7 @@ "depositRequests": [], "withdrawalRequests": [], "blockNumber": "0x3", - "blockHash": "0x79858f6eb8e82f0ec11087983ce4eb8c7edc10c9363a2a124dd78fd2c305dc42", + "blockHash": "0xdbb55a049f14b8152695bf3bbd754aa1fd55bbe10b306eb49caa4bd7d7fcb634", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "excessBlobGas": "0x0", "blobGasUsed": "0x0" @@ -34,7 +34,7 @@ "id": 67, "result": { "status": "VALID", - "latestValidHash": "0x79858f6eb8e82f0ec11087983ce4eb8c7edc10c9363a2a124dd78fd2c305dc42", + "latestValidHash": "0xdbb55a049f14b8152695bf3bbd754aa1fd55bbe10b306eb49caa4bd7d7fcb634", "validationError": null } }, diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/14_prague_send_raw_transaction_consolidation_request.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/14_prague_send_raw_transaction_consolidation_request.json new file mode 100644 index 0000000000..85c41f2991 --- /dev/null +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/14_prague_send_raw_transaction_consolidation_request.json @@ -0,0 +1,14 @@ +{ + "request": { + "jsonrpc": "2.0", + "method": "eth_sendRawTransaction", + "params": ["0xf8c80185e8d4a51000832dc6c09400b42dbf2194e931e80326d950320f7d9dbeac0201b860fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe822fe0a05b88b593926d340f448918ef1c6263356c37f2434774e0fdb1cb9d90cfa5a23ba003a86aac4adb774181ba51eda17efb5fbed99ad57895e6eb56ccdf508a88a7cc"], + "id": 67 + }, + "response": { + "jsonrpc": "2.0", + "id": 67, + "result": "0xa4252f576c4e16cb020f86f8a30d4fa990ee0cbfc84198a6d0eb118dd2f8b72d" + }, + "statusCode": 200 +} \ No newline at end of file diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/14_prague_forkchoiceUpdatedV3.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/15_prague_forkchoiceUpdatedV3.json similarity index 61% rename from acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/14_prague_forkchoiceUpdatedV3.json rename to acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/15_prague_forkchoiceUpdatedV3.json index bf2b3dca5a..61750afbe7 100644 --- a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/14_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": "0x79858f6eb8e82f0ec11087983ce4eb8c7edc10c9363a2a124dd78fd2c305dc42", - "safeBlockHash": "0x79858f6eb8e82f0ec11087983ce4eb8c7edc10c9363a2a124dd78fd2c305dc42", - "finalizedBlockHash": "0x79858f6eb8e82f0ec11087983ce4eb8c7edc10c9363a2a124dd78fd2c305dc42" + "headBlockHash": "0xdbb55a049f14b8152695bf3bbd754aa1fd55bbe10b306eb49caa4bd7d7fcb634", + "safeBlockHash": "0xdbb55a049f14b8152695bf3bbd754aa1fd55bbe10b306eb49caa4bd7d7fcb634", + "finalizedBlockHash": "0xdbb55a049f14b8152695bf3bbd754aa1fd55bbe10b306eb49caa4bd7d7fcb634" }, { "timestamp": "0x40", @@ -24,10 +24,10 @@ "result": { "payloadStatus": { "status": "VALID", - "latestValidHash": "0x79858f6eb8e82f0ec11087983ce4eb8c7edc10c9363a2a124dd78fd2c305dc42", + "latestValidHash": "0xdbb55a049f14b8152695bf3bbd754aa1fd55bbe10b306eb49caa4bd7d7fcb634", "validationError": null }, - "payloadId": "0x282643de0e3d43bf" + "payloadId": "0x28264396a9634d41" } }, "statusCode": 200 diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/15_prague_getPayloadV4.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/16_prague_getPayloadV4.json similarity index 62% rename from acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/15_prague_getPayloadV4.json rename to acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/16_prague_getPayloadV4.json index c287cfaed8..c3fdd33ada 100644 --- a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/15_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": [ - "0x282643de0e3d43bf" + "0x28264396a9634d41" ], "id": 67 }, @@ -12,20 +12,21 @@ "id": 67, "result": { "executionPayload": { - "parentHash": "0x79858f6eb8e82f0ec11087983ce4eb8c7edc10c9363a2a124dd78fd2c305dc42", + "parentHash": "0xdbb55a049f14b8152695bf3bbd754aa1fd55bbe10b306eb49caa4bd7d7fcb634", "feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", - "stateRoot": "0xe4642cc58d61f2392fe056042c226e286f22a25e3104f4a4acb423dad9a43311", + "stateRoot": "0x49df1f1a1d28a23fa752230d442077768787d392e9edb70c83d727d31e55eaac", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "gasLimit": "0x1c9c380", - "gasUsed": "0x145d3", + "gasUsed": "0x3ad4d", "timestamp": "0x40", "extraData": "0x", "baseFeePerGas": "0x7", "excessBlobGas": "0x0", "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", "transactions": [ - "0xf8a08085e8d4a51000832dc6c09400a3ca265ebcb825b45f985a16cefb49958ce01702b8388706d19a62f28a6a6549f96c5adaebac9124a61d44868ec94f6d2d707c6a2f82c9162071231dfeb40e24bfde4ffdf2430000000000000000822fdfa00476c1a81f80f4c130acb5f8b8075468ba0893d766b7ec51a8d9723c573ad034a03bd3eaedabbaaf745f15023185ba66584ad3ee8bb40b9bef8c0b9ed27f8b1959" + "0xf8a08085e8d4a51000832dc6c09400a3ca265ebcb825b45f985a16cefb49958ce01702b8388706d19a62f28a6a6549f96c5adaebac9124a61d44868ec94f6d2d707c6a2f82c9162071231dfeb40e24bfde4ffdf2430000000000000000822fdfa00476c1a81f80f4c130acb5f8b8075468ba0893d766b7ec51a8d9723c573ad034a03bd3eaedabbaaf745f15023185ba66584ad3ee8bb40b9bef8c0b9ed27f8b1959", + "0xf8c80185e8d4a51000832dc6c09400b42dbf2194e931e80326d950320f7d9dbeac0201b860fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe822fe0a05b88b593926d340f448918ef1c6263356c37f2434774e0fdb1cb9d90cfa5a23ba003a86aac4adb774181ba51eda17efb5fbed99ad57895e6eb56ccdf508a88a7cc" ], "withdrawals": [], "depositRequests": [], @@ -36,12 +37,19 @@ "validatorPubkey": "0x8706d19a62f28a6a6549f96c5adaebac9124a61d44868ec94f6d2d707c6a2f82c9162071231dfeb40e24bfde4ffdf243" } ], + "consolidationRequests": [ + { + "sourceAddress": "0x23618e81e3f5cdf7f54c3d65f7fbc0abf5b21e8f", + "sourcePubKey": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "targetPubKey": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe" + } + ], "blockNumber": "0x4", - "receiptsRoot": "0x765bd9d63cc10fa47117d6cc0958f15e55a3bde540d4ed15d220f573fbb82cba", + "receiptsRoot": "0x970fc81bb3e7fb21435f9a65a184aa9e3fd2f52b89fd859302b46954354266b5", "blobGasUsed": "0x0", - "blockHash": "0xb2d60adb2a0c73313ebdacf425b1d6bbd810c3ec6b28ad0d62a73cdc34cb696a" + "blockHash": "0x93df6f3484202f24c692354e2ab96e9948ae45eea6ad85faea121a389e468ea8" }, - "blockValue": "0x12855dcd153473b", + "blockValue": "0x3581baab15c12e5", "blobsBundle": { "commitments": [], "proofs": [], diff --git a/datatypes/src/main/java/org/hyperledger/besu/datatypes/RequestType.java b/datatypes/src/main/java/org/hyperledger/besu/datatypes/RequestType.java index 628baa6d5f..5a8fe97a36 100644 --- a/datatypes/src/main/java/org/hyperledger/besu/datatypes/RequestType.java +++ b/datatypes/src/main/java/org/hyperledger/besu/datatypes/RequestType.java @@ -19,7 +19,9 @@ public enum RequestType { /** DEPOSITS */ DEPOSIT(0x00), /** WITHDRAWAL */ - WITHDRAWAL(0x01); + WITHDRAWAL(0x01), + /** CONSOLIDATION */ + CONSOLIDATION(0x02); private final int typeValue; @@ -48,6 +50,7 @@ public enum RequestType { return switch (serializedTypeValue) { case 0x00 -> DEPOSIT; case 0x01 -> WITHDRAWAL; + case 0x02 -> CONSOLIDATION; default -> throw new IllegalArgumentException( String.format("Unsupported request type: 0x%02X", serializedTypeValue)); 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 e8134fdb1a..543c965c80 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 @@ -20,6 +20,7 @@ import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.Executi import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod.EngineStatus.INVALID_BLOCK_HASH; 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.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.WithdrawalsValidatorProvider.getWithdrawalsValidator; @@ -35,6 +36,7 @@ import org.hyperledger.besu.ethereum.BlockProcessingResult; import org.hyperledger.besu.ethereum.ProtocolContext; 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.WithdrawalParameter; @@ -185,8 +187,23 @@ public abstract class AbstractEngineNewPayload extends ExecutionEngineJsonRpcMet reqId, new JsonRpcError(INVALID_PARAMS, "Invalid withdrawal request")); } + final Optional> maybeConsolidationRequests = + Optional.ofNullable(blockParam.getConsolidationRequests()) + .map( + consolidationRequest -> + consolidationRequest.stream() + .map(ConsolidationRequestParameter::toConsolidationRequest) + .collect(toList())); + if (!getConsolidationRequestValidator( + protocolSchedule.get(), blockParam.getTimestamp(), blockParam.getBlockNumber()) + .validateParameter(maybeConsolidationRequests)) { + return new JsonRpcErrorResponse( + reqId, new JsonRpcError(INVALID_PARAMS, "Invalid consolidation request")); + } + Optional> maybeRequests = - RequestUtil.combine(maybeDepositRequests, maybeWithdrawalRequests); + RequestUtil.combine( + maybeDepositRequests, maybeWithdrawalRequests, maybeConsolidationRequests); if (mergeContext.get().isSyncing()) { LOG.debug("We are syncing"); 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 505d369518..c3d9c8376b 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 @@ -38,6 +38,12 @@ public class RequestValidatorProvider { 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, 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 new file mode 100644 index 0000000000..d33b12c6a7 --- /dev/null +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/ConsolidationRequestParameter.java @@ -0,0 +1,102 @@ +/* + * 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/EnginePayloadParameter.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/EnginePayloadParameter.java index 4fd24e15a6..fdcec45c6b 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 @@ -45,6 +45,7 @@ public class EnginePayloadParameter { private final String excessBlobGas; private final List depositRequests; private final List withdrawalRequests; + private final List consolidationRequests; /** * Creates an instance of EnginePayloadParameter. @@ -68,6 +69,7 @@ public class EnginePayloadParameter { * @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. */ @JsonCreator public EnginePayloadParameter( @@ -90,7 +92,9 @@ public class EnginePayloadParameter { @JsonProperty("excessBlobGas") final String excessBlobGas, @JsonProperty("depositRequests") final List depositRequests, @JsonProperty("withdrawalRequests") - final List withdrawalRequestParameters) { + final List withdrawalRequestParameters, + @JsonProperty("consolidationRequests") + final List consolidationRequests) { this.blockHash = blockHash; this.parentHash = parentHash; this.feeRecipient = feeRecipient; @@ -110,6 +114,7 @@ public class EnginePayloadParameter { this.excessBlobGas = excessBlobGas; this.depositRequests = depositRequests; this.withdrawalRequests = withdrawalRequestParameters; + this.consolidationRequests = consolidationRequests; } public Hash getBlockHash() { @@ -187,4 +192,8 @@ public class EnginePayloadParameter { public List getWithdrawalRequests() { return withdrawalRequests; } + + public List getConsolidationRequests() { + return consolidationRequests; + } } 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 2f89ef12ce..b8111c00c7 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,6 +14,7 @@ */ 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; @@ -170,6 +171,7 @@ public class BlockResultFactory { blockWithReceipts.getBlock().getBody().getWithdrawals(), getDepositRequests(blockWithReceipts.getBlock().getBody().getRequests()), getWithdrawalRequests(blockWithReceipts.getBlock().getBody().getRequests()), + getConsolidationRequests(blockWithReceipts.getBlock().getBody().getRequests()), 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 133fbabe60..39772ff7db 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,10 +14,12 @@ */ 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; @@ -44,10 +46,17 @@ public class EngineGetPayloadResultV4 { final Optional> withdrawals, final Optional> depositRequests, final Optional> withdrawalRequests, + final Optional> consolidationRequests, final String blockValue, final BlobsBundleV1 blobsBundle) { this.executionPayload = - new PayloadResult(header, transactions, withdrawals, depositRequests, withdrawalRequests); + new PayloadResult( + header, + transactions, + withdrawals, + depositRequests, + withdrawalRequests, + consolidationRequests); this.blockValue = blockValue; this.blobsBundle = blobsBundle; this.shouldOverrideBuilder = false; @@ -96,13 +105,15 @@ public class EngineGetPayloadResultV4 { 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> withdrawalRequests, + final Optional> consolidationRequests) { this.blockNumber = Quantity.create(header.getNumber()); this.blockHash = header.getHash().toString(); this.parentHash = header.getParentHash().toString(); @@ -141,6 +152,14 @@ public class EngineGetPayloadResultV4 { .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); @@ -228,6 +247,11 @@ public class EngineGetPayloadResultV4 { return withdrawalRequests; } + @JsonGetter(value = "consolidationRequests") + public List getConsolidationRequests() { + return consolidationRequests; + } + @JsonGetter(value = "feeRecipient") @JsonInclude(JsonInclude.Include.NON_NULL) public String getFeeRecipient() { @@ -240,7 +264,7 @@ public class EngineGetPayloadResultV4 { } @JsonGetter(value = "blobGasUsed") - public String getBlobGasUseds() { + public String getBlobGasUsed() { return blobGasUsed; } 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 26d0dad955..10da8a4486 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,6 +38,7 @@ 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.UnsignedLongParameter; @@ -403,7 +404,7 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT protected EnginePayloadParameter mockEnginePayload( final BlockHeader header, final List txs) { - return mockEnginePayload(header, txs, null, null, null); + return mockEnginePayload(header, txs, null, null, null, null); } protected EnginePayloadParameter mockEnginePayload( @@ -411,7 +412,8 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT final List txs, final List withdrawals, final List depositRequests, - final List withdrawalRequests) { + final List withdrawalRequests, + final List consolidationRequests) { return new EnginePayloadParameter( header.getHash(), header.getParentHash(), @@ -431,7 +433,8 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT header.getBlobGasUsed().map(UnsignedLongParameter::new).orElse(null), header.getExcessBlobGas().map(BlobGas::toHexString).orElse(null), depositRequests, - withdrawalRequests); + withdrawalRequests, + consolidationRequests); } protected BlockHeader setupValidPayload( 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 535b2c9983..134c7a2c0c 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 @@ -150,6 +150,7 @@ public class EngineGetPayloadV4Test extends AbstractEngineGetPayloadTest { 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)); 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 1d79417021..412dc6f892 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 @@ -87,7 +87,9 @@ public class EngineNewPayloadV2Test extends AbstractEngineNewPayloadTest { .when(blockchain.getBlockHeader(mockHeader.getParentHash())) .thenReturn(Optional.of(mock(BlockHeader.class))); var resp = - resp(mockEnginePayload(mockHeader, Collections.emptyList(), withdrawalsParam, null, null)); + resp( + mockEnginePayload( + mockHeader, Collections.emptyList(), withdrawalsParam, null, null, null)); assertValidResponse(mockHeader, resp); } @@ -107,7 +109,7 @@ public class EngineNewPayloadV2Test extends AbstractEngineNewPayloadTest { .when(blockchain.getBlockHeader(mockHeader.getParentHash())) .thenReturn(Optional.of(mock(BlockHeader.class))); var resp = - resp(mockEnginePayload(mockHeader, Collections.emptyList(), withdrawals, null, null)); + resp(mockEnginePayload(mockHeader, Collections.emptyList(), withdrawals, null, null, null)); assertValidResponse(mockHeader, resp); } @@ -127,6 +129,7 @@ public class EngineNewPayloadV2Test extends AbstractEngineNewPayloadTest { Collections.emptyList(), withdrawals, null, + null, null)); final JsonRpcError jsonRpcError = fromErrorResp(resp); @@ -143,7 +146,8 @@ public class EngineNewPayloadV2Test extends AbstractEngineNewPayloadTest { .blobGasUsed(100L) .buildHeader(); - var resp = resp(mockEnginePayload(blockHeader, Collections.emptyList(), List.of(), null, null)); + var resp = + resp(mockEnginePayload(blockHeader, Collections.emptyList(), List.of(), null, null, null)); final JsonRpcError jsonRpcError = fromErrorResp(resp); assertThat(jsonRpcError.getCode()).isEqualTo(INVALID_PARAMS.getCode()); assertThat(jsonRpcError.getData()).isEqualTo("non-null BlobGasUsed pre-cancun"); @@ -159,7 +163,8 @@ public class EngineNewPayloadV2Test extends AbstractEngineNewPayloadTest { .excessBlobGas(BlobGas.MAX_BLOB_GAS) .buildHeader(); - var resp = resp(mockEnginePayload(blockHeader, Collections.emptyList(), List.of(), null, null)); + var resp = + resp(mockEnginePayload(blockHeader, Collections.emptyList(), List.of(), null, null, null)); final JsonRpcError jsonRpcError = fromErrorResp(resp); assertThat(jsonRpcError.getCode()).isEqualTo(INVALID_PARAMS.getCode()); @@ -180,6 +185,7 @@ public class EngineNewPayloadV2Test extends AbstractEngineNewPayloadTest { Collections.emptyList(), withdrawals, null, + null, null)); assertThat(fromErrorResp(resp).getCode()).isEqualTo(INVALID_PARAMS.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 98a71ebf35..c19bb8fbcb 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 @@ -137,7 +137,7 @@ public class EngineNewPayloadV3Test extends EngineNewPayloadV2Test { Optional.empty(), Optional.empty()); final EnginePayloadParameter payload = - mockEnginePayload(mockHeader, Collections.emptyList(), null, null, null); + mockEnginePayload(mockHeader, Collections.emptyList(), null, null, null, null); ValidationResult res = method.validateParameters( @@ -193,7 +193,8 @@ public class EngineNewPayloadV3Test extends EngineNewPayloadV2Test { .blobGasUsed(null) .buildHeader(); - var resp = resp(mockEnginePayload(blockHeader, Collections.emptyList(), List.of(), null, null)); + var resp = + resp(mockEnginePayload(blockHeader, Collections.emptyList(), List.of(), null, null, null)); final JsonRpcError jsonRpcError = fromErrorResp(resp); assertThat(jsonRpcError.getCode()).isEqualTo(INVALID_PARAMS.getCode()); @@ -212,7 +213,8 @@ public class EngineNewPayloadV3Test extends EngineNewPayloadV2Test { .blobGasUsed(100L) .buildHeader(); - var resp = resp(mockEnginePayload(blockHeader, Collections.emptyList(), List.of(), null, null)); + var resp = + resp(mockEnginePayload(blockHeader, Collections.emptyList(), List.of(), null, null, null)); final JsonRpcError jsonRpcError = fromErrorResp(resp); assertThat(jsonRpcError.getCode()).isEqualTo(INVALID_PARAMS.getCode()); 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 86b096cf1e..9ea1721305 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 @@ -109,7 +109,9 @@ public class EngineNewPayloadV4Test extends EngineNewPayloadV3Test { .thenReturn(Optional.of(mockHeader.getHash())); var resp = - resp(mockEnginePayload(mockHeader, Collections.emptyList(), null, depositRequests, null)); + resp( + mockEnginePayload( + mockHeader, Collections.emptyList(), null, depositRequests, null, null)); assertValidResponse(mockHeader, resp); } @@ -125,6 +127,7 @@ public class EngineNewPayloadV4Test extends EngineNewPayloadV3Test { Collections.emptyList(), null, depositRequests, + null, null)); assertThat(fromErrorResp(resp).getCode()).isEqualTo(INVALID_PARAMS.getCode()); @@ -152,7 +155,7 @@ public class EngineNewPayloadV4Test extends EngineNewPayloadV3Test { var resp = resp( mockEnginePayload( - mockHeader, Collections.emptyList(), null, depositRequestsParam, null)); + mockHeader, Collections.emptyList(), null, depositRequestsParam, null, null)); assertValidResponse(mockHeader, resp); } @@ -172,6 +175,7 @@ public class EngineNewPayloadV4Test extends EngineNewPayloadV3Test { Collections.emptyList(), null, depositRequests, + null, null)); final JsonRpcError jsonRpcError = fromErrorResp(resp); @@ -195,7 +199,7 @@ public class EngineNewPayloadV4Test extends EngineNewPayloadV3Test { when(mergeCoordinator.getLatestValidAncestor(mockHeader)) .thenReturn(Optional.of(mockHeader.getHash())); - var resp = resp(mockEnginePayload(mockHeader, Collections.emptyList(), null, null, null)); + var resp = resp(mockEnginePayload(mockHeader, Collections.emptyList(), null, null, null, null)); assertValidResponse(mockHeader, resp); } @@ -211,6 +215,7 @@ public class EngineNewPayloadV4Test extends EngineNewPayloadV3Test { Collections.emptyList(), null, null, + null, null)); assertThat(fromErrorResp(resp).getCode()).isEqualTo(INVALID_PARAMS.getCode()); @@ -239,7 +244,7 @@ public class EngineNewPayloadV4Test extends EngineNewPayloadV3Test { var resp = resp( mockEnginePayload( - mockHeader, Collections.emptyList(), null, null, withdrawalRequestsParams)); + mockHeader, Collections.emptyList(), null, null, withdrawalRequestsParams, null)); assertValidResponse(mockHeader, resp); } @@ -258,7 +263,8 @@ public class EngineNewPayloadV4Test extends EngineNewPayloadV3Test { Collections.emptyList(), null, null, - withdrawalRequests)); + withdrawalRequests, + null)); final JsonRpcError jsonRpcError = fromErrorResp(resp); assertThat(jsonRpcError.getCode()).isEqualTo(INVALID_PARAMS.getCode()); 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 new file mode 100644 index 0000000000..38345d1a31 --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/ConsolidationRequest.java @@ -0,0 +1,90 @@ +/* + * 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/encoding/ConsolidationRequestDecoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/ConsolidationRequestDecoder.java new file mode 100644 index 0000000000..29be31f46d --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/ConsolidationRequestDecoder.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.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 new file mode 100644 index 0000000000..9551f7b974 --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/ConsolidationRequestEncoder.java @@ -0,0 +1,60 @@ +/* + * 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/RequestDecoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/RequestDecoder.java index 4953cbb84f..64191e104b 100644 --- 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 @@ -41,7 +41,9 @@ public class RequestDecoder { RequestType.WITHDRAWAL, WithdrawalRequestDecoder::decode, RequestType.DEPOSIT, - DepositRequestDecoder::decode); + DepositRequestDecoder::decode, + RequestType.CONSOLIDATION, + ConsolidationRequestDecoder::decode); /** * Decodes a request from its RLP encoded bytes. 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 index 4f79da453c..3c61a77ac0 100644 --- 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 @@ -38,7 +38,9 @@ public class RequestEncoder { RequestType.WITHDRAWAL, WithdrawalRequestEncoder::encode, RequestType.DEPOSIT, - DepositRequestEncoder::encode); + DepositRequestEncoder::encode, + RequestType.CONSOLIDATION, + ConsolidationRequestEncoder::encode); /** * Encodes a Request into the provided RLPOutput. 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 new file mode 100644 index 0000000000..0a48d8278c --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/ConsolidationRequestProcessor.java @@ -0,0 +1,68 @@ +/* + * 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_PREDEPLOY_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; + + /** + * Gets the call address for consolidation requests. + * + * @return The call address. + */ + @Override + protected Address getCallAddress() { + return CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS; + } + + /** + * 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 new file mode 100644 index 0000000000..f03de5e6b5 --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/ConsolidationRequestValidator.java @@ -0,0 +1,92 @@ +/* + * 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/MainnetRequestsValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/MainnetRequestsValidator.java index 56e47aea50..d855544ede 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 @@ -22,6 +22,7 @@ public class MainnetRequestsValidator { final Address depositContractAddress) { return new RequestsValidatorCoordinator.Builder() .addValidator(RequestType.WITHDRAWAL, new WithdrawalRequestValidator()) + .addValidator(RequestType.CONSOLIDATION, new ConsolidationRequestValidator()) .addValidator(RequestType.DEPOSIT, new DepositRequestValidator(depositContractAddress)) .build(); } @@ -30,6 +31,7 @@ public class MainnetRequestsValidator { final Address depositContractAddress) { return new RequestProcessorCoordinator.Builder() .addProcessor(RequestType.WITHDRAWAL, new WithdrawalRequestProcessor()) + .addProcessor(RequestType.CONSOLIDATION, new ConsolidationRequestProcessor()) .addProcessor(RequestType.DEPOSIT, new DepositRequestProcessor(depositContractAddress)) .build(); } 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 index 459fdbe110..f3a10161a4 100644 --- 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 @@ -14,6 +14,7 @@ */ 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; @@ -52,23 +53,33 @@ public class RequestUtil { return requests.map(r -> filterRequestsOfType(r, WithdrawalRequest.class)); } + public static Optional> getConsolidationRequests( + final Optional> requests) { + return requests.map(r -> filterRequestsOfType(r, ConsolidationRequest.class)); + } + /** - * Combines two optional lists of requests into a single optional list. + * 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. - * @return An Optional containing the combined list of requests, or an empty Optional if both - * inputs are empty. + * @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) { - if (maybeDepositRequests.isEmpty() && maybeWithdrawalRequest.isEmpty()) { + 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/test/java/org/hyperledger/besu/ethereum/core/encoding/ConsolidationRequestDecoderTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/ConsolidationRequestDecoderTest.java new file mode 100644 index 0000000000..bb264dfa23 --- /dev/null +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/ConsolidationRequestDecoderTest.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.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 new file mode 100644 index 0000000000..10a53379b8 --- /dev/null +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/ConsolidationRequestEncoderTest.java @@ -0,0 +1,55 @@ +/* + * 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/DepositRequestRequestDecoderTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/DepositRequestDecoderTest.java similarity index 99% rename from ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/DepositRequestRequestDecoderTest.java rename to ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/DepositRequestDecoderTest.java index 0a6cee956d..622bd89754 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/DepositRequestRequestDecoderTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/DepositRequestDecoderTest.java @@ -31,7 +31,7 @@ import org.apache.tuweni.bytes.Bytes32; import org.apache.tuweni.units.bigints.UInt64; import org.junit.jupiter.api.Test; -class DepositRequestRequestDecoderTest { +class DepositRequestDecoderTest { @Test void shouldDecodeDeposit() { final DepositRequest expectedDepositRequest = diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/DepositRequestRequestEncoderTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/DepositRequestEncoderTest.java similarity index 98% rename from ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/DepositRequestRequestEncoderTest.java rename to ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/DepositRequestEncoderTest.java index 8f0de595f6..1e6dde6aa8 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/DepositRequestRequestEncoderTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/DepositRequestEncoderTest.java @@ -26,7 +26,7 @@ import org.apache.tuweni.bytes.Bytes32; import org.apache.tuweni.units.bigints.UInt64; import org.junit.jupiter.api.Test; -class DepositRequestRequestEncoderTest { +class DepositRequestEncoderTest { private final String expectedDepositEncodedBytes = "f8bbb0b10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416ea00017a7fcf06faf493d30bbe2632ea7c2383cd86825e12797165de7aa35589483850773594000b860a889db8300194050a2636c92a95bc7160515867614b7971a9500cdb62f9c0890217d2901c3241f86fac029428fc106930606154bd9e406d7588934a5f15b837180b17194d6e44bd6de23e43b163dfe12e369dcc75a3852cd997963f158217eb501"; 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 new file mode 100644 index 0000000000..fbd304d1cd --- /dev/null +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/ConsolidationRequestValidatorTestFixtures.java @@ -0,0 +1,136 @@ +/* + * 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/PragueConsolidationRequestValidatorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/PragueConsolidationRequestValidatorTest.java new file mode 100644 index 0000000000..9d0c9588cc --- /dev/null +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/PragueConsolidationRequestValidatorTest.java @@ -0,0 +1,76 @@ +/* + * 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/evmtool/src/main/java/org/hyperledger/besu/evmtool/T8nExecutor.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/T8nExecutor.java index 429ad59444..ee6c5d5f70 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 @@ -32,6 +32,7 @@ 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; @@ -495,15 +496,25 @@ public class T8nExecutor { obj.put("index", deposit.getIndex().toHexString()); }); - var withdrawlRequests = resultObject.putArray("withdrawalRequests"); + var withdrawalRequests = resultObject.putArray("withdrawalRequests"); RequestUtil.filterRequestsOfType(maybeRequests.orElse(List.of()), WithdrawalRequest.class) .forEach( wr -> { - var obj = withdrawlRequests.addObject(); + 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()); + }); } worldState.persist(blockHeader); 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 d48fc66c70..1a32e50e8b 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 @@ -172,6 +172,11 @@ "balance": "0x3782dace9d9000000", "nonce": "0x1" }, + "0x00a3ca265ebcb825b45f985a16cefb49958ce017": { + "code": "0x3373fffffffffffffffffffffffffffffffffffffffe146090573615156028575f545f5260205ff35b366038141561012e5760115f54600182026001905f5b5f82111560595781019083028483029004916001019190603e565b90939004341061012e57600154600101600155600354806003026004013381556001015f3581556001016020359055600101600355005b6003546002548082038060101160a4575060105b5f5b81811460dd5780604c02838201600302600401805490600101805490600101549160601b83528260140152906034015260010160a6565b910180921460ed579060025560f8565b90505f6002555f6003555b5f548061049d141561010757505f5b60015460028282011161011c5750505f610122565b01600290035b5f555f600155604c025ff35b5f5ffd", + "balance": "0x0", + "nonce": "0x1" + }, "0x000f3df6d732807ef1319fb7b8bb8522d0beac02": { "code": "0x3373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500", "storage": { @@ -180,11 +185,6 @@ "balance": "0x0", "nonce": "0x1" }, - "0x00a3ca265ebcb825b45f985a16cefb49958ce017": { - "code": "0x3373fffffffffffffffffffffffffffffffffffffffe146090573615156028575f545f5260205ff35b366038141561012e5760115f54600182026001905f5b5f82111560595781019083028483029004916001019190603e565b90939004341061012e57600154600101600155600354806003026004013381556001015f3581556001016020359055600101600355005b6003546002548082038060101160a4575060105b5f5b81811460dd5780604c02838201600302600401805490600101805490600101549160601b83528260140152906034015260010160a6565b910180921460ed579060025560f8565b90505f6002555f6003555b5f548061049d141561010757505f5b60015460028282011161011c5750505f610122565b01600290035b5f555f600155604c025ff35b5f5ffd", - "balance": "0x0", - "nonce": "0x1" - }, "0x0aae40965e6800cd9b1f4b05ff21581047e3f91e": { "code": "0x3373fffffffffffffffffffffffffffffffffffffffe1460575767ffffffffffffffff5f3511605357600143035f3511604b575f35612000014311604b57611fff5f3516545f5260205ff35b5f5f5260205ff35b5f5ffd5b5f35611fff60014303165500", "storage": { @@ -282,7 +282,8 @@ "index": "0x0000000000000001" } ], - "withdrawalRequests": [] + "withdrawalRequests": [], + "consolidationRequests":[] } } } \ 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 cc8958b07c..148c7a23e3 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 @@ -314,6 +314,7 @@ "amount": "0x0000000000000000" } ], + "consolidationRequests":[], "stateRoot": "0xf63d7552dc407993393315e99272781d04eedfcf369a1acd3e386d1e6710229d", "txRoot": "0x8521df63211790726b6f1a437bb0fd4b27c00e13e7678d324c4cfddb8d834ad2", "receiptsRoot": "0x4bd8bd5580caf4ed45f873794ad7ff9d6fd2363ae529269b17b891b68d349d75", 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 5512923c61..1d9ce8eefa 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 @@ -90,10 +90,10 @@ public class BlockchainReferenceTestTools { params.ignore( "UncleFromSideChain_(Merge|Paris|Shanghai|Cancun|Prague|Osaka|Amsterdam|Bogota|Polis|Bangkok)"); - // EOF tests don't have Prague stuff like deopsits right now + // EOF tests don't have Prague stuff like deposits right now params.ignore("/stEOF/"); - // None of the Prague tests have withdrawls and deposits handling + // None of the Prague tests have withdrawals and deposits handling params.ignore("\\[Prague\\]"); } diff --git a/plugin-api/build.gradle b/plugin-api/build.gradle index d55efa7fc9..30ab85d37a 100644 --- a/plugin-api/build.gradle +++ b/plugin-api/build.gradle @@ -70,7 +70,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 = 'yH50m+z1tnzshJQPdwR86pb2EU3m6iZxwkqoy/5spcs=' + knownHash = 'Yv6CY8fh0yrIz3Q8Moy/j1TNGL+O8Mewp4SIgM1JE6M=' } check.dependsOn('checkAPIChanges') 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 new file mode 100644 index 0000000000..5d7e66b4ae --- /dev/null +++ b/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/ConsolidationRequest.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.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(); +} From 3366f79c958acc559716629ae0c8a58e1dc11dec Mon Sep 17 00:00:00 2001 From: Usman Saleem Date: Tue, 16 Jul 2024 19:19:22 +1000 Subject: [PATCH 041/259] fix: `eth_call` deserialization to correctly ignore unknown fields in the transaction object (#7323) * fix: Use Builder for JsonCallParameter * changelog * add additional unit tests * fix: Update builder to withGas to match the json eth_call --------- Signed-off-by: Usman Saleem --- CHANGELOG.md | 1 + .../fork/frontier/EthCallIntegrationTest.java | 291 +++++---------- .../EthCreateAccessListIntegrationTest.java | 128 +++---- .../EthEstimateGasIntegrationTest.java | 98 ++--- .../fork/london/EthCallIntegrationTest.java | 190 ++++------ .../london/EthEstimateGasIntegrationTest.java | 84 ++--- .../internal/methods/AbstractEstimateGas.java | 11 - .../internal/methods/EthCreateAccessList.java | 2 + .../internal/methods/EthEstimateGas.java | 2 + .../parameters/JsonCallParameter.java | 344 ++++++++++++++++-- .../jsonrpc/internal/methods/EthCallTest.java | 27 +- .../methods/EthCreateAccessListTest.java | 50 ++- .../internal/methods/EthEstimateGasTest.java | 49 +-- .../parameters/JsonCallParameterTest.java | 80 +++- .../privacy/methods/priv/PrivCallTest.java | 60 +-- 15 files changed, 725 insertions(+), 692 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e2b3ea072b..bee4620060 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ - Implement gnark-crypto for eip-2537 [#7316](https://github.com/hyperledger/besu/pull/7316) ### Bug fixes +- Fix `eth_call` deserialization to correctly ignore unknown fields in the transaction object. [#7323](https://github.com/hyperledger/besu/pull/7323) ## 24.7.0 diff --git a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/frontier/EthCallIntegrationTest.java b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/frontier/EthCallIntegrationTest.java index 14aa15c5c8..886f7bc015 100644 --- a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/frontier/EthCallIntegrationTest.java +++ b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/frontier/EthCallIntegrationTest.java @@ -64,20 +64,12 @@ public class EthCallIntegrationTest { @Test public void shouldReturnExpectedResultForCallAtLatestBlock() { final JsonCallParameter callParameter = - new JsonCallParameter( - Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"), - Address.fromHexString("0x6295ee1b4f6dd65047762f924ecd367c17eabf8f"), - null, - null, - null, - null, - null, - Bytes.fromHexString("0x12a7b914"), - null, - null, - null, - null, - null); + new JsonCallParameter.JsonCallParameterBuilder() + .withFrom(Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b")) + .withTo(Address.fromHexString("0x6295ee1b4f6dd65047762f924ecd367c17eabf8f")) + .withInput(Bytes.fromHexString("0x12a7b914")) + .build(); + final JsonRpcRequestContext request = requestWithParams(callParameter, "latest"); final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse( @@ -91,20 +83,12 @@ public class EthCallIntegrationTest { @Test public void shouldReturnExpectedResultForCallAtSpecificBlock() { final JsonCallParameter callParameter = - new JsonCallParameter( - Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"), - Address.fromHexString("0x6295ee1b4f6dd65047762f924ecd367c17eabf8f"), - null, - null, - null, - null, - null, - Bytes.fromHexString("0x12a7b914"), - null, - null, - null, - null, - null); + new JsonCallParameter.JsonCallParameterBuilder() + .withFrom(Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b")) + .withTo(Address.fromHexString("0x6295ee1b4f6dd65047762f924ecd367c17eabf8f")) + .withInput(Bytes.fromHexString("0x12a7b914")) + .build(); + final JsonRpcRequestContext request = requestWithParams(callParameter, "0x8"); final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse( @@ -118,21 +102,13 @@ public class EthCallIntegrationTest { @Test public void shouldReturnSuccessWhenCreatingContract() { final JsonCallParameter callParameter = - new JsonCallParameter( - Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"), - null, - null, - null, - null, - null, - null, - Bytes.fromHexString( - "0x608060405234801561001057600080fd5b50610157806100206000396000f30060806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680633bdab8bf146100515780639ae97baa14610068575b600080fd5b34801561005d57600080fd5b5061006661007f565b005b34801561007457600080fd5b5061007d6100b9565b005b7fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60016040518082815260200191505060405180910390a1565b7fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60026040518082815260200191505060405180910390a17fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60036040518082815260200191505060405180910390a15600a165627a7a7230582010ddaa52e73a98c06dbcd22b234b97206c1d7ed64a7c048e10c2043a3d2309cb0029"), - null, - null, - null, - null, - null); + new JsonCallParameter.JsonCallParameterBuilder() + .withFrom(Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b")) + .withInput( + Bytes.fromHexString( + "0x608060405234801561001057600080fd5b50610157806100206000396000f30060806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680633bdab8bf146100515780639ae97baa14610068575b600080fd5b34801561005d57600080fd5b5061006661007f565b005b34801561007457600080fd5b5061007d6100b9565b005b7fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60016040518082815260200191505060405180910390a1565b7fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60026040518082815260200191505060405180910390a17fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60036040518082815260200191505060405180910390a15600a165627a7a7230582010ddaa52e73a98c06dbcd22b234b97206c1d7ed64a7c048e10c2043a3d2309cb0029")) + .build(); + final JsonRpcRequestContext request = requestWithParams(callParameter, "latest"); final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse( @@ -147,20 +123,13 @@ public class EthCallIntegrationTest { @Test public void shouldReturnErrorWithGasLimitTooLow() { final JsonCallParameter callParameter = - new JsonCallParameter( - Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"), - Address.fromHexString("0x6295ee1b4f6dd65047762f924ecd367c17eabf8f"), - 0L, - null, - null, - null, - null, - Bytes.fromHexString("0x12a7b914"), - null, - null, - null, - null, - null); + new JsonCallParameter.JsonCallParameterBuilder() + .withFrom(Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b")) + .withTo(Address.fromHexString("0x6295ee1b4f6dd65047762f924ecd367c17eabf8f")) + .withGas(0L) + .withInput(Bytes.fromHexString("0x12a7b914")) + .build(); + final JsonRpcRequestContext request = requestWithParams(callParameter, "latest"); final JsonRpcResponse expectedResponse = new JsonRpcErrorResponse(null, RpcErrorType.INTRINSIC_GAS_EXCEEDS_LIMIT); @@ -173,20 +142,14 @@ public class EthCallIntegrationTest { @Test public void shouldReturnErrorWithGasPriceTooHighAndStrict() { final JsonCallParameter callParameter = - new JsonCallParameter( - Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"), - Address.fromHexString("0x6295ee1b4f6dd65047762f924ecd367c17eabf8f"), - null, - Wei.fromHexString("0x10000000000000"), - null, - null, - null, - Bytes.fromHexString("0x12a7b914"), - null, - true, - null, - null, - null); + new JsonCallParameter.JsonCallParameterBuilder() + .withFrom(Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b")) + .withTo(Address.fromHexString("0x6295ee1b4f6dd65047762f924ecd367c17eabf8f")) + .withGasPrice(Wei.fromHexString("0x10000000000000")) + .withInput(Bytes.fromHexString("0x12a7b914")) + .withStrict(true) + .build(); + final JsonRpcRequestContext request = requestWithParams(callParameter, "latest"); final JsonRpcResponse expectedResponse = new JsonRpcErrorResponse(null, RpcErrorType.TRANSACTION_UPFRONT_COST_EXCEEDS_BALANCE); @@ -199,20 +162,14 @@ public class EthCallIntegrationTest { @Test public void shouldReturnSuccessWithGasPriceTooHighNotStrict() { final JsonCallParameter callParameter = - new JsonCallParameter( - Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"), - Address.fromHexString("0x6295ee1b4f6dd65047762f924ecd367c17eabf8f"), - null, - Wei.fromHexString("0x10000000000000"), - null, - null, - null, - Bytes.fromHexString("0x12a7b914"), - null, - false, - null, - null, - null); + new JsonCallParameter.JsonCallParameterBuilder() + .withFrom(Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b")) + .withTo(Address.fromHexString("0x6295ee1b4f6dd65047762f924ecd367c17eabf8f")) + .withGasPrice(Wei.fromHexString("0x10000000000000")) + .withInput(Bytes.fromHexString("0x12a7b914")) + .withStrict(false) + .build(); + final JsonRpcRequestContext request = requestWithParams(callParameter, "latest"); final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse( @@ -226,20 +183,13 @@ public class EthCallIntegrationTest { @Test public void shouldReturnErrorWithGasPriceTooHigh() { final JsonCallParameter callParameter = - new JsonCallParameter( - Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"), - Address.fromHexString("0x6295ee1b4f6dd65047762f924ecd367c17eabf8f"), - null, - Wei.fromHexString("0x10000000000000"), - null, - null, - null, - Bytes.fromHexString("0x12a7b914"), - null, - null, - null, - null, - null); + new JsonCallParameter.JsonCallParameterBuilder() + .withFrom(Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b")) + .withTo(Address.fromHexString("0x6295ee1b4f6dd65047762f924ecd367c17eabf8f")) + .withGasPrice(Wei.fromHexString("0x10000000000000")) + .withInput(Bytes.fromHexString("0x12a7b914")) + .build(); + final JsonRpcRequestContext request = requestWithParams(callParameter, "latest"); final JsonRpcResponse expectedResponse = new JsonRpcErrorResponse(null, RpcErrorType.TRANSACTION_UPFRONT_COST_EXCEEDS_BALANCE); @@ -252,20 +202,13 @@ public class EthCallIntegrationTest { @Test public void shouldReturnSuccessWithValidGasPrice() { final JsonCallParameter callParameter = - new JsonCallParameter( - Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"), - Address.fromHexString("0x6295ee1b4f6dd65047762f924ecd367c17eabf8f"), - null, - Wei.fromHexString("0x10"), - null, - null, - null, - Bytes.fromHexString("0x12a7b914"), - null, - null, - null, - null, - null); + new JsonCallParameter.JsonCallParameterBuilder() + .withFrom(Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b")) + .withTo(Address.fromHexString("0x6295ee1b4f6dd65047762f924ecd367c17eabf8f")) + .withGasPrice(Wei.fromHexString("0x10")) + .withInput(Bytes.fromHexString("0x12a7b914")) + .build(); + final JsonRpcRequestContext request = requestWithParams(callParameter, "latest"); final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse( @@ -279,20 +222,13 @@ public class EthCallIntegrationTest { @Test public void shouldReturnErrorWithGasPriceAndEmptyBalance() { final JsonCallParameter callParameter = - new JsonCallParameter( - Address.fromHexString("0xdeadbeef00000000000000000000000000000000"), - Address.fromHexString("0x6295ee1b4f6dd65047762f924ecd367c17eabf8f"), - null, - Wei.fromHexString("0x10"), - null, - null, - null, - Bytes.fromHexString("0x12a7b914"), - null, - null, - null, - null, - null); + new JsonCallParameter.JsonCallParameterBuilder() + .withFrom(Address.fromHexString("0xdeadbeef00000000000000000000000000000000")) + .withTo(Address.fromHexString("0x6295ee1b4f6dd65047762f924ecd367c17eabf8f")) + .withGasPrice(Wei.fromHexString("0x10")) + .withInput(Bytes.fromHexString("0x12a7b914")) + .build(); + final JsonRpcRequestContext request = requestWithParams(callParameter, "latest"); final JsonRpcResponse expectedResponse = new JsonRpcErrorResponse(null, RpcErrorType.TRANSACTION_UPFRONT_COST_EXCEEDS_BALANCE); @@ -305,20 +241,13 @@ public class EthCallIntegrationTest { @Test public void shouldReturnSuccessWithZeroGasPriceAndEmptyBalance() { final JsonCallParameter callParameter = - new JsonCallParameter( - Address.fromHexString("0xdeadbeef00000000000000000000000000000000"), - Address.fromHexString("0x6295ee1b4f6dd65047762f924ecd367c17eabf8f"), - null, - Wei.fromHexString("0x0"), - null, - null, - null, - Bytes.fromHexString("0x12a7b914"), - null, - null, - null, - null, - null); + new JsonCallParameter.JsonCallParameterBuilder() + .withFrom(Address.fromHexString("0xdeadbeef00000000000000000000000000000000")) + .withTo(Address.fromHexString("0x6295ee1b4f6dd65047762f924ecd367c17eabf8f")) + .withGasPrice(Wei.fromHexString("0x0")) + .withInput(Bytes.fromHexString("0x12a7b914")) + .build(); + final JsonRpcRequestContext request = requestWithParams(callParameter, "latest"); final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse( @@ -332,20 +261,12 @@ public class EthCallIntegrationTest { @Test public void shouldReturnSuccessWithoutGasPriceAndEmptyBalance() { final JsonCallParameter callParameter = - new JsonCallParameter( - Address.fromHexString("0xdeadbeef00000000000000000000000000000000"), - Address.fromHexString("0x6295ee1b4f6dd65047762f924ecd367c17eabf8f"), - null, - null, - null, - null, - null, - Bytes.fromHexString("0x12a7b914"), - null, - null, - null, - null, - null); + new JsonCallParameter.JsonCallParameterBuilder() + .withFrom(Address.fromHexString("0xdeadbeef00000000000000000000000000000000")) + .withTo(Address.fromHexString("0x6295ee1b4f6dd65047762f924ecd367c17eabf8f")) + .withInput(Bytes.fromHexString("0x12a7b914")) + .build(); + final JsonRpcRequestContext request = requestWithParams(callParameter, "latest"); final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse( @@ -359,20 +280,13 @@ public class EthCallIntegrationTest { @Test public void shouldReturnSuccessWithInvalidGasPricingAndEmptyBalance() { final JsonCallParameter callParameter = - new JsonCallParameter( - Address.fromHexString("0xdeadbeef00000000000000000000000000000000"), - Address.fromHexString("0x6295ee1b4f6dd65047762f924ecd367c17eabf8f"), - null, - null, - Wei.fromHexString("0x0A"), - null, - null, - Bytes.fromHexString("0x12a7b914"), - null, - null, - null, - null, - null); + new JsonCallParameter.JsonCallParameterBuilder() + .withFrom(Address.fromHexString("0xdeadbeef00000000000000000000000000000000")) + .withTo(Address.fromHexString("0x6295ee1b4f6dd65047762f924ecd367c17eabf8f")) + .withMaxPriorityFeePerGas(Wei.fromHexString("0x0A")) + .withInput(Bytes.fromHexString("0x12a7b914")) + .build(); + final JsonRpcRequestContext request = requestWithParams(callParameter, "latest"); final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse( @@ -386,20 +300,10 @@ public class EthCallIntegrationTest { @Test public void shouldReturnEmptyHashResultForCallWithOnlyToField() { final JsonCallParameter callParameter = - new JsonCallParameter( - null, - Address.fromHexString("0x6295ee1b4f6dd65047762f924ecd367c17eabf8f"), - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null); + new JsonCallParameter.JsonCallParameterBuilder() + .withTo(Address.fromHexString("0x6295ee1b4f6dd65047762f924ecd367c17eabf8f")) + .build(); + final JsonRpcRequestContext request = requestWithParams(callParameter, "latest"); final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse(null, "0x"); @@ -411,20 +315,13 @@ public class EthCallIntegrationTest { @Test public void shouldReturnSuccessWithInputAndDataFieldSetToSameValue() { final JsonCallParameter callParameter = - new JsonCallParameter( - Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"), - Address.fromHexString("0x6295ee1b4f6dd65047762f924ecd367c17eabf8f"), - null, - null, - null, - null, - null, - Bytes.fromHexString("0x12a7b914"), - Bytes.fromHexString("0x12a7b914"), - null, - null, - null, - null); + new JsonCallParameter.JsonCallParameterBuilder() + .withFrom(Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b")) + .withTo(Address.fromHexString("0x6295ee1b4f6dd65047762f924ecd367c17eabf8f")) + .withInput(Bytes.fromHexString("0x12a7b914")) + .withData(Bytes.fromHexString("0x12a7b914")) + .build(); + final JsonRpcRequestContext request = requestWithParams(callParameter, "latest"); final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse( diff --git a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/frontier/EthCreateAccessListIntegrationTest.java b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/frontier/EthCreateAccessListIntegrationTest.java index e68fd29d18..49b9659fd9 100644 --- a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/frontier/EthCreateAccessListIntegrationTest.java +++ b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/frontier/EthCreateAccessListIntegrationTest.java @@ -79,10 +79,11 @@ public class EthCreateAccessListIntegrationTest { "0x0000000000000000000000000000000000000000000000000000000000000003")))); final JsonCallParameter callParameter = - createAccessListJsonCallParameters( - "0x658bdf435d810c91414ec09147daa6db62406379", - "0xbb00000000000000000000000000000000000000", - null); + new JsonCallParameter.JsonCallParameterBuilder() + .withFrom(Address.fromHexString("0x658bdf435d810c91414ec09147daa6db62406379")) + .withTo(Address.fromHexString("0xbb00000000000000000000000000000000000000")) + .withAccessList(null) + .build(); assertAccessListExpectedResult(callParameter, expectedAccessListEntryList, expectedGasUsed); } @@ -101,10 +102,11 @@ public class EthCreateAccessListIntegrationTest { "0x0000000000000000000000000000000000000000000000000000000000000003")))); final JsonCallParameter callParameter = - createAccessListJsonCallParameters( - "0x658bdf435d810c91414ec09147daa6db62406379", - "0xbb00000000000000000000000000000000000000", - expectedAccessListEntryList); + new JsonCallParameter.JsonCallParameterBuilder() + .withFrom(Address.fromHexString("0x658bdf435d810c91414ec09147daa6db62406379")) + .withTo(Address.fromHexString("0xbb00000000000000000000000000000000000000")) + .withAccessList(expectedAccessListEntryList) + .build(); assertAccessListExpectedResult(callParameter, expectedAccessListEntryList, expectedGasUsed); } @@ -115,10 +117,11 @@ public class EthCreateAccessListIntegrationTest { final List expectedAccessListEntryList = new ArrayList<>(); final JsonCallParameter callParameter = - createAccessListJsonCallParameters( - "0x658bdf435d810c91414ec09147daa6db62406379", - "0x0100000000000000000000000000000000000000", - expectedAccessListEntryList); + new JsonCallParameter.JsonCallParameterBuilder() + .withFrom(Address.fromHexString("0x658bdf435d810c91414ec09147daa6db62406379")) + .withTo(Address.fromHexString("0x0100000000000000000000000000000000000000")) + .withAccessList(expectedAccessListEntryList) + .build(); assertAccessListExpectedResult(callParameter, expectedAccessListEntryList, expectedGasUsed); } @@ -129,10 +132,11 @@ public class EthCreateAccessListIntegrationTest { final List expectedAccessListEntryList = new ArrayList<>(); final JsonCallParameter callParameter = - createAccessListJsonCallParameters( - "0x658bdf435d810c91414ec09147daa6db62406379", - "0xaa00000000000000000000000000000000000000", - null); + new JsonCallParameter.JsonCallParameterBuilder() + .withFrom(Address.fromHexString("0x658bdf435d810c91414ec09147daa6db62406379")) + .withTo(Address.fromHexString("0xaa00000000000000000000000000000000000000")) + .withAccessList(null) + .build(); assertAccessListExpectedResult(callParameter, expectedAccessListEntryList, expectedGasUsed); } @@ -140,8 +144,8 @@ public class EthCreateAccessListIntegrationTest { @Test public void shouldReturnExpectedValueForEmptyCallParameter() { final JsonCallParameter callParameter = - new JsonCallParameter( - null, null, null, null, null, null, null, null, null, null, null, null, null); + new JsonCallParameter.JsonCallParameterBuilder().build(); + final JsonRpcRequestContext request = requestWithParams(callParameter); final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse(null, new CreateAccessListResult(new ArrayList<>(), 0xcf08)); @@ -154,20 +158,12 @@ public class EthCreateAccessListIntegrationTest { @Test public void shouldReturnExpectedValueForTransfer() { final JsonCallParameter callParameter = - new JsonCallParameter( - Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"), - Address.fromHexString("0x8888f1f195afa192cfee860698584c030f4c9db1"), - null, - null, - null, - null, - Wei.ZERO, - null, - null, - null, - null, - null, - null); + new JsonCallParameter.JsonCallParameterBuilder() + .withFrom(Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b")) + .withTo(Address.fromHexString("0x8888f1f195afa192cfee860698584c030f4c9db1")) + .withValue(Wei.ZERO) + .build(); + final JsonRpcRequestContext request = requestWithParams(callParameter); final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse(null, new CreateAccessListResult(new ArrayList<>(), 0x5208)); @@ -180,21 +176,13 @@ public class EthCreateAccessListIntegrationTest { @Test public void shouldReturnExpectedValueForContractDeploy() { final JsonCallParameter callParameter = - new JsonCallParameter( - Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"), - null, - null, - null, - null, - null, - null, - Bytes.fromHexString( - "0x608060405234801561001057600080fd5b50610157806100206000396000f30060806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680633bdab8bf146100515780639ae97baa14610068575b600080fd5b34801561005d57600080fd5b5061006661007f565b005b34801561007457600080fd5b5061007d6100b9565b005b7fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60016040518082815260200191505060405180910390a1565b7fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60026040518082815260200191505060405180910390a17fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60036040518082815260200191505060405180910390a15600a165627a7a7230582010ddaa52e73a98c06dbcd22b234b97206c1d7ed64a7c048e10c2043a3d2309cb0029"), - null, - null, - null, - null, - null); + new JsonCallParameter.JsonCallParameterBuilder() + .withFrom(Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b")) + .withInput( + Bytes.fromHexString( + "0x608060405234801561001057600080fd5b50610157806100206000396000f30060806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680633bdab8bf146100515780639ae97baa14610068575b600080fd5b34801561005d57600080fd5b5061006661007f565b005b34801561007457600080fd5b5061007d6100b9565b005b7fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60016040518082815260200191505060405180910390a1565b7fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60026040518082815260200191505060405180910390a17fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60036040518082815260200191505060405180910390a15600a165627a7a7230582010ddaa52e73a98c06dbcd22b234b97206c1d7ed64a7c048e10c2043a3d2309cb0029")) + .build(); + final JsonRpcRequestContext request = requestWithParams(callParameter); final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse(null, new CreateAccessListResult(new ArrayList<>(), 0x1f081)); @@ -207,21 +195,16 @@ public class EthCreateAccessListIntegrationTest { @Test public void shouldIgnoreSenderBalanceAccountWhenStrictModeDisabledAndReturnExpectedValue() { final JsonCallParameter callParameter = - new JsonCallParameter( - Address.fromHexString("0x0000000000000000000000000000000000000000"), - null, - 1L, - Wei.fromHexString("0x9999999999"), - null, - null, - null, - Bytes.fromHexString( - "0x608060405234801561001057600080fd5b50610157806100206000396000f30060806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680633bdab8bf146100515780639ae97baa14610068575b600080fd5b34801561005d57600080fd5b5061006661007f565b005b34801561007457600080fd5b5061007d6100b9565b005b7fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60016040518082815260200191505060405180910390a1565b7fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60026040518082815260200191505060405180910390a17fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60036040518082815260200191505060405180910390a15600a165627a7a7230582010ddaa52e73a98c06dbcd22b234b97206c1d7ed64a7c048e10c2043a3d2309cb0029"), - null, - false, - null, - null, - null); + new JsonCallParameter.JsonCallParameterBuilder() + .withFrom(Address.fromHexString("0x0000000000000000000000000000000000000000")) + .withGas(1L) + .withGasPrice(Wei.fromHexString("0x9999999999")) + .withInput( + Bytes.fromHexString( + "0x608060405234801561001057600080fd5b50610157806100206000396000f30060806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680633bdab8bf146100515780639ae97baa14610068575b600080fd5b34801561005d57600080fd5b5061006661007f565b005b34801561007457600080fd5b5061007d6100b9565b005b7fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60016040518082815260200191505060405180910390a1565b7fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60026040518082815260200191505060405180910390a17fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60036040518082815260200191505060405180910390a15600a165627a7a7230582010ddaa52e73a98c06dbcd22b234b97206c1d7ed64a7c048e10c2043a3d2309cb0029")) + .withStrict(false) + .build(); + final JsonRpcRequestContext request = requestWithParams(callParameter); final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse(null, new CreateAccessListResult(new ArrayList<>(), 0x1f081)); @@ -234,8 +217,7 @@ public class EthCreateAccessListIntegrationTest { @Test public void shouldReturnExpectedValueForInsufficientGas() { final JsonCallParameter callParameter = - new JsonCallParameter( - null, null, 1L, null, null, null, null, null, null, null, null, null, null); + new JsonCallParameter.JsonCallParameterBuilder().withGas(1L).build(); final JsonRpcRequestContext request = requestWithParams(callParameter); final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse(null, new CreateAccessListResult(new ArrayList<>(), 0xcf08)); @@ -257,24 +239,6 @@ public class EthCreateAccessListIntegrationTest { assertThat(response).usingRecursiveComparison().isEqualTo(expectedResponse); } - private JsonCallParameter createAccessListJsonCallParameters( - final String from, final String to, final List accessList) { - return new JsonCallParameter( - Address.fromHexString(from), - Address.fromHexString(to), - null, - null, - null, - null, - null, - null, - null, - null, - accessList, - null, - null); - } - private JsonRpcRequestContext requestWithParams(final Object... params) { return new JsonRpcRequestContext(new JsonRpcRequest("2.0", "eth_createAccessList", params)); } diff --git a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/frontier/EthEstimateGasIntegrationTest.java b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/frontier/EthEstimateGasIntegrationTest.java index a461539030..d17a2774e6 100644 --- a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/frontier/EthEstimateGasIntegrationTest.java +++ b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/frontier/EthEstimateGasIntegrationTest.java @@ -66,8 +66,7 @@ public class EthEstimateGasIntegrationTest { @Test public void shouldReturnExpectedValueForEmptyCallParameter() { final JsonCallParameter callParameter = - new JsonCallParameter( - null, null, null, null, null, null, null, null, null, null, null, null, null); + new JsonCallParameter.JsonCallParameterBuilder().build(); final JsonRpcRequestContext request = requestWithParams(callParameter); final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse(null, "0x5208"); @@ -79,20 +78,12 @@ public class EthEstimateGasIntegrationTest { @Test public void shouldReturnExpectedValueForTransfer() { final JsonCallParameter callParameter = - new JsonCallParameter( - Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"), - Address.fromHexString("0x8888f1f195afa192cfee860698584c030f4c9db1"), - null, - null, - null, - null, - Wei.ONE, - null, - null, - null, - null, - null, - null); + new JsonCallParameter.JsonCallParameterBuilder() + .withFrom(Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b")) + .withTo(Address.fromHexString("0x8888f1f195afa192cfee860698584c030f4c9db1")) + .withValue(Wei.ONE) + .build(); + final JsonRpcRequestContext request = requestWithParams(callParameter); final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse(null, "0x5208"); @@ -104,21 +95,13 @@ public class EthEstimateGasIntegrationTest { @Test public void shouldReturnExpectedValueForContractDeploy() { final JsonCallParameter callParameter = - new JsonCallParameter( - Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"), - null, - null, - null, - null, - null, - null, - Bytes.fromHexString( - "0x608060405234801561001057600080fd5b50610157806100206000396000f30060806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680633bdab8bf146100515780639ae97baa14610068575b600080fd5b34801561005d57600080fd5b5061006661007f565b005b34801561007457600080fd5b5061007d6100b9565b005b7fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60016040518082815260200191505060405180910390a1565b7fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60026040518082815260200191505060405180910390a17fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60036040518082815260200191505060405180910390a15600a165627a7a7230582010ddaa52e73a98c06dbcd22b234b97206c1d7ed64a7c048e10c2043a3d2309cb0029"), - null, - null, - null, - null, - null); + new JsonCallParameter.JsonCallParameterBuilder() + .withFrom(Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b")) + .withInput( + Bytes.fromHexString( + "0x608060405234801561001057600080fd5b50610157806100206000396000f30060806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680633bdab8bf146100515780639ae97baa14610068575b600080fd5b34801561005d57600080fd5b5061006661007f565b005b34801561007457600080fd5b5061007d6100b9565b005b7fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60016040518082815260200191505060405180910390a1565b7fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60026040518082815260200191505060405180910390a17fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60036040518082815260200191505060405180910390a15600a165627a7a7230582010ddaa52e73a98c06dbcd22b234b97206c1d7ed64a7c048e10c2043a3d2309cb0029")) + .build(); + final JsonRpcRequestContext request = requestWithParams(callParameter); final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse(null, "0x1b551"); @@ -130,21 +113,16 @@ public class EthEstimateGasIntegrationTest { @Test public void shouldIgnoreSenderBalanceAccountWhenStrictModeDisabledAndReturnExpectedValue() { final JsonCallParameter callParameter = - new JsonCallParameter( - Address.fromHexString("0x0000000000000000000000000000000000000000"), - null, - 1L, - Wei.fromHexString("0x9999999999"), - null, - null, - null, - Bytes.fromHexString( - "0x608060405234801561001057600080fd5b50610157806100206000396000f30060806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680633bdab8bf146100515780639ae97baa14610068575b600080fd5b34801561005d57600080fd5b5061006661007f565b005b34801561007457600080fd5b5061007d6100b9565b005b7fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60016040518082815260200191505060405180910390a1565b7fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60026040518082815260200191505060405180910390a17fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60036040518082815260200191505060405180910390a15600a165627a7a7230582010ddaa52e73a98c06dbcd22b234b97206c1d7ed64a7c048e10c2043a3d2309cb0029"), - null, - false, - null, - null, - null); + new JsonCallParameter.JsonCallParameterBuilder() + .withFrom(Address.fromHexString("0x0000000000000000000000000000000000000000")) + .withGas(1L) + .withGasPrice(Wei.fromHexString("0x9999999999")) + .withInput( + Bytes.fromHexString( + "0x608060405234801561001057600080fd5b50610157806100206000396000f30060806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680633bdab8bf146100515780639ae97baa14610068575b600080fd5b34801561005d57600080fd5b5061006661007f565b005b34801561007457600080fd5b5061007d6100b9565b005b7fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60016040518082815260200191505060405180910390a1565b7fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60026040518082815260200191505060405180910390a17fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60036040518082815260200191505060405180910390a15600a165627a7a7230582010ddaa52e73a98c06dbcd22b234b97206c1d7ed64a7c048e10c2043a3d2309cb0029")) + .withStrict(false) + .build(); + final JsonRpcRequestContext request = requestWithParams(callParameter); final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse(null, "0x1b551"); @@ -156,21 +134,16 @@ public class EthEstimateGasIntegrationTest { @Test public void shouldNotIgnoreSenderBalanceAccountWhenStrictModeDisabledAndThrowError() { final JsonCallParameter callParameter = - new JsonCallParameter( - Address.fromHexString("0x6295ee1b4f6dd65047762f924ecd367c17eabf8f"), - null, - 1L, - Wei.fromHexString("0x9999999999"), - null, - null, - null, - Bytes.fromHexString( - "0x608060405234801561001057600080fd5b50610157806100206000396000f30060806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680633bdab8bf146100515780639ae97baa14610068575b600080fd5b34801561005d57600080fd5b5061006661007f565b005b34801561007457600080fd5b5061007d6100b9565b005b7fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60016040518082815260200191505060405180910390a1565b7fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60026040518082815260200191505060405180910390a17fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60036040518082815260200191505060405180910390a15600a165627a7a7230582010ddaa52e73a98c06dbcd22b234b97206c1d7ed64a7c048e10c2043a3d2309cb0029"), - null, - true, - null, - null, - null); + new JsonCallParameter.JsonCallParameterBuilder() + .withFrom(Address.fromHexString("0x6295ee1b4f6dd65047762f924ecd367c17eabf8f")) + .withGas(1L) + .withGasPrice(Wei.fromHexString("0x9999999999")) + .withInput( + Bytes.fromHexString( + "0x608060405234801561001057600080fd5b50610157806100206000396000f30060806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680633bdab8bf146100515780639ae97baa14610068575b600080fd5b34801561005d57600080fd5b5061006661007f565b005b34801561007457600080fd5b5061007d6100b9565b005b7fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60016040518082815260200191505060405180910390a1565b7fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60026040518082815260200191505060405180910390a17fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60036040518082815260200191505060405180910390a15600a165627a7a7230582010ddaa52e73a98c06dbcd22b234b97206c1d7ed64a7c048e10c2043a3d2309cb0029")) + .withStrict(true) + .build(); + final JsonRpcRequestContext request = requestWithParams(callParameter); final ValidationResult validationResult = ValidationResult.invalid( @@ -186,8 +159,7 @@ public class EthEstimateGasIntegrationTest { @Test public void shouldReturnExpectedValueForInsufficientGas() { final JsonCallParameter callParameter = - new JsonCallParameter( - null, null, 1L, null, null, null, null, null, null, null, null, null, null); + new JsonCallParameter.JsonCallParameterBuilder().withGas(1L).build(); final JsonRpcRequestContext request = requestWithParams(callParameter); final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse(null, "0x5208"); 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 e92076123b..5f03d7f4d5 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 @@ -64,20 +64,12 @@ public class EthCallIntegrationTest { @Test public void shouldReturnSuccessWithoutGasPriceAndEmptyBalance() { final JsonCallParameter callParameter = - new JsonCallParameter( - Address.fromHexString("0xdeadbeef00000000000000000000000000000000"), - Address.fromHexString("0x9b8397f1b0fecd3a1a40cdd5e8221fa461898517"), - null, - null, - null, - null, - null, - Bytes.fromHexString("0x2e64cec1"), - null, - null, - null, - null, - null); + new JsonCallParameter.JsonCallParameterBuilder() + .withFrom(Address.fromHexString("0xdeadbeef00000000000000000000000000000000")) + .withTo(Address.fromHexString("0x9b8397f1b0fecd3a1a40cdd5e8221fa461898517")) + .withInput(Bytes.fromHexString("0x2e64cec1")) + .build(); + final JsonRpcRequestContext request = requestWithParams(callParameter, "latest"); final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse( @@ -91,20 +83,13 @@ public class EthCallIntegrationTest { @Test public void shouldReturnErrorWithGasPriceTooHigh() { final JsonCallParameter callParameter = - new JsonCallParameter( - Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"), - Address.fromHexString("0x9b8397f1b0fecd3a1a40cdd5e8221fa461898517"), - null, - Wei.fromHexString("0x10000000000000"), - null, - null, - null, - Bytes.fromHexString("0x2e64cec1"), - null, - null, - null, - null, - null); + new JsonCallParameter.JsonCallParameterBuilder() + .withFrom(Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b")) + .withTo(Address.fromHexString("0x9b8397f1b0fecd3a1a40cdd5e8221fa461898517")) + .withGasPrice(Wei.fromHexString("0x10000000000000")) + .withInput(Bytes.fromHexString("0x2e64cec1")) + .build(); + final JsonRpcRequestContext request = requestWithParams(callParameter, "latest"); final JsonRpcResponse expectedResponse = new JsonRpcErrorResponse(null, RpcErrorType.TRANSACTION_UPFRONT_COST_EXCEEDS_BALANCE); @@ -117,20 +102,13 @@ public class EthCallIntegrationTest { @Test public void shouldReturnSuccessWithValidGasPrice() { final JsonCallParameter callParameter = - new JsonCallParameter( - Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"), - Address.fromHexString("0x9b8397f1b0fecd3a1a40cdd5e8221fa461898517"), - null, - Wei.fromHexString("0x3B9ACA01"), - null, - null, - null, - Bytes.fromHexString("0x2e64cec1"), - null, - null, - null, - null, - null); + new JsonCallParameter.JsonCallParameterBuilder() + .withFrom(Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b")) + .withTo(Address.fromHexString("0x9b8397f1b0fecd3a1a40cdd5e8221fa461898517")) + .withGasPrice(Wei.fromHexString("0x3B9ACA01")) + .withInput(Bytes.fromHexString("0x2e64cec1")) + .build(); + final JsonRpcRequestContext request = requestWithParams(callParameter, "latest"); final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse( @@ -144,20 +122,13 @@ public class EthCallIntegrationTest { @Test public void shouldReturnErrorWithGasPriceLessThanCurrentBaseFee() { final JsonCallParameter callParameter = - new JsonCallParameter( - Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"), - Address.fromHexString("0x9b8397f1b0fecd3a1a40cdd5e8221fa461898517"), - null, - Wei.fromHexString("0x0A"), - null, - null, - null, - Bytes.fromHexString("0x2e64cec1"), - null, - null, - null, - null, - null); + new JsonCallParameter.JsonCallParameterBuilder() + .withFrom(Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b")) + .withTo(Address.fromHexString("0x9b8397f1b0fecd3a1a40cdd5e8221fa461898517")) + .withGasPrice(Wei.fromHexString("0x0A")) + .withInput(Bytes.fromHexString("0x2e64cec1")) + .build(); + final JsonRpcRequestContext request = requestWithParams(callParameter, "latest"); final JsonRpcResponse expectedResponse = new JsonRpcErrorResponse(null, RpcErrorType.GAS_PRICE_BELOW_CURRENT_BASE_FEE); @@ -170,20 +141,13 @@ public class EthCallIntegrationTest { @Test public void shouldReturnSuccessWithValidMaxFeePerGas() { final JsonCallParameter callParameter = - new JsonCallParameter( - Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"), - Address.fromHexString("0x9b8397f1b0fecd3a1a40cdd5e8221fa461898517"), - null, - null, - null, - Wei.fromHexString("0x3B9ACA01"), - null, - Bytes.fromHexString("0x2e64cec1"), - null, - null, - null, - null, - null); + new JsonCallParameter.JsonCallParameterBuilder() + .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 JsonRpcSuccessResponse( @@ -197,20 +161,14 @@ public class EthCallIntegrationTest { @Test public void shouldReturnSuccessWithValidMaxFeePerGasAndMaxPriorityFeePerGas() { final JsonCallParameter callParameter = - new JsonCallParameter( - Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"), - Address.fromHexString("0x9b8397f1b0fecd3a1a40cdd5e8221fa461898517"), - null, - null, - Wei.fromHexString("0x3B9ACA00"), - Wei.fromHexString("0x3B9ACA01"), - null, - Bytes.fromHexString("0x2e64cec1"), - null, - null, - null, - null, - null); + new JsonCallParameter.JsonCallParameterBuilder() + .withFrom(Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b")) + .withTo(Address.fromHexString("0x9b8397f1b0fecd3a1a40cdd5e8221fa461898517")) + .withMaxPriorityFeePerGas(Wei.fromHexString("0x3B9ACA00")) + .withMaxFeePerGas(Wei.fromHexString("0x3B9ACA01")) + .withInput(Bytes.fromHexString("0x2e64cec1")) + .build(); + final JsonRpcRequestContext request = requestWithParams(callParameter, "latest"); final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse( @@ -224,20 +182,13 @@ public class EthCallIntegrationTest { @Test public void shouldReturnErrorWithValidMaxFeePerGasLessThanCurrentBaseFee() { final JsonCallParameter callParameter = - new JsonCallParameter( - Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"), - Address.fromHexString("0x9b8397f1b0fecd3a1a40cdd5e8221fa461898517"), - null, - null, - null, - Wei.fromHexString("0x0A"), - null, - Bytes.fromHexString("0x2e64cec1"), - null, - null, - null, - null, - null); + new JsonCallParameter.JsonCallParameterBuilder() + .withFrom(Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b")) + .withTo(Address.fromHexString("0x9b8397f1b0fecd3a1a40cdd5e8221fa461898517")) + .withMaxFeePerGas(Wei.fromHexString("0x0A")) + .withInput(Bytes.fromHexString("0x2e64cec1")) + .build(); + final JsonRpcRequestContext request = requestWithParams(callParameter, "latest"); final JsonRpcResponse expectedResponse = new JsonRpcErrorResponse(null, RpcErrorType.GAS_PRICE_BELOW_CURRENT_BASE_FEE); @@ -250,20 +201,14 @@ public class EthCallIntegrationTest { @Test public void shouldReturnErrorWithValidMaxFeePerGasLessThanMaxPriorityFeePerGas() { final JsonCallParameter callParameter = - new JsonCallParameter( - Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"), - Address.fromHexString("0x9b8397f1b0fecd3a1a40cdd5e8221fa461898517"), - null, - null, - Wei.fromHexString("0x3B9ACA02"), - Wei.fromHexString("0x3B9ACA01"), - null, - Bytes.fromHexString("0x2e64cec1"), - null, - null, - null, - null, - null); + new JsonCallParameter.JsonCallParameterBuilder() + .withFrom(Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b")) + .withTo(Address.fromHexString("0x9b8397f1b0fecd3a1a40cdd5e8221fa461898517")) + .withMaxPriorityFeePerGas(Wei.fromHexString("0x3B9ACA02")) + .withMaxFeePerGas(Wei.fromHexString("0x3B9ACA01")) + .withInput(Bytes.fromHexString("0x2e64cec1")) + .build(); + final JsonRpcRequestContext request = requestWithParams(callParameter, "latest"); final JsonRpcResponse expectedResponse = new JsonRpcErrorResponse( @@ -277,20 +222,13 @@ public class EthCallIntegrationTest { @Test public void shouldReturnErrorWithMaxFeePerGasAndEmptyBalance() { final JsonCallParameter callParameter = - new JsonCallParameter( - Address.fromHexString("0xdeadbeef00000000000000000000000000000000"), - Address.fromHexString("0x9b8397f1b0fecd3a1a40cdd5e8221fa461898517"), - null, - null, - null, - Wei.fromHexString("0x3B9ACA01"), - null, - Bytes.fromHexString("0x2e64cec1"), - null, - null, - null, - null, - null); + new JsonCallParameter.JsonCallParameterBuilder() + .withFrom(Address.fromHexString("0xdeadbeef00000000000000000000000000000000")) + .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.TRANSACTION_UPFRONT_COST_EXCEEDS_BALANCE); 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 0a3ba1be7f..84447dfc9d 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 @@ -67,20 +67,11 @@ public class EthEstimateGasIntegrationTest { @Test public void shouldReturnExpectedValueForTransfer() { final JsonCallParameter callParameter = - new JsonCallParameter( - Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"), - Address.fromHexString("0x8888f1f195afa192cfee860698584c030f4c9db1"), - null, - null, - null, - null, - Wei.ONE, - null, - null, - null, - null, - null, - null); + new JsonCallParameter.JsonCallParameterBuilder() + .withFrom(Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b")) + .withTo(Address.fromHexString("0x8888f1f195afa192cfee860698584c030f4c9db1")) + .withValue(Wei.ONE) + .build(); final JsonRpcResponse response = method.response(requestWithParams(callParameter)); final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse(null, "0x5208"); @@ -89,22 +80,13 @@ public class EthEstimateGasIntegrationTest { @Test public void shouldReturnExpectedValueForTransfer_WithAccessList() { - final JsonCallParameter callParameter = - new JsonCallParameter( - Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"), - Address.fromHexString("0x8888f1f195afa192cfee860698584c030f4c9db1"), - null, - null, - null, - null, - Wei.ONE, - null, - null, - null, - createAccessList(), - null, - null); + new JsonCallParameter.JsonCallParameterBuilder() + .withFrom(Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b")) + .withTo(Address.fromHexString("0x8888f1f195afa192cfee860698584c030f4c9db1")) + .withValue(Wei.ONE) + .withAccessList(createAccessList()) + .build(); final JsonRpcResponse response = method.response(requestWithParams(callParameter)); final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse(null, "0x62d4"); @@ -114,21 +96,13 @@ public class EthEstimateGasIntegrationTest { @Test public void shouldReturnExpectedValueForContractDeploy() { final JsonCallParameter callParameter = - new JsonCallParameter( - Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"), - null, - null, - null, - null, - null, - null, - Bytes.fromHexString( - "0x608060405234801561001057600080fd5b50610157806100206000396000f30060806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680633bdab8bf146100515780639ae97baa14610068575b600080fd5b34801561005d57600080fd5b5061006661007f565b005b34801561007457600080fd5b5061007d6100b9565b005b7fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60016040518082815260200191505060405180910390a1565b7fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60026040518082815260200191505060405180910390a17fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60036040518082815260200191505060405180910390a15600a165627a7a7230582010ddaa52e73a98c06dbcd22b234b97206c1d7ed64a7c048e10c2043a3d2309cb0029"), - null, - null, - null, - null, - null); + new JsonCallParameter.JsonCallParameterBuilder() + .withFrom(Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b")) + .withInput( + Bytes.fromHexString( + "0x608060405234801561001057600080fd5b50610157806100206000396000f30060806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680633bdab8bf146100515780639ae97baa14610068575b600080fd5b34801561005d57600080fd5b5061006661007f565b005b34801561007457600080fd5b5061007d6100b9565b005b7fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60016040518082815260200191505060405180910390a1565b7fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60026040518082815260200191505060405180910390a17fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60036040518082815260200191505060405180910390a15600a165627a7a7230582010ddaa52e73a98c06dbcd22b234b97206c1d7ed64a7c048e10c2043a3d2309cb0029")) + .build(); + final JsonRpcResponse response = method.response(requestWithParams(callParameter)); final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse(null, "0x1f081"); assertThat(response).usingRecursiveComparison().isEqualTo(expectedResponse); @@ -137,21 +111,13 @@ public class EthEstimateGasIntegrationTest { @Test public void shouldReturnExpectedValueForContractDeploy_WithAccessList() { final JsonCallParameter callParameter = - new JsonCallParameter( - Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"), - null, - null, - null, - null, - null, - null, - Bytes.fromHexString( - "0x608060405234801561001057600080fd5b50610157806100206000396000f30060806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680633bdab8bf146100515780639ae97baa14610068575b600080fd5b34801561005d57600080fd5b5061006661007f565b005b34801561007457600080fd5b5061007d6100b9565b005b7fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60016040518082815260200191505060405180910390a1565b7fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60026040518082815260200191505060405180910390a17fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60036040518082815260200191505060405180910390a15600a165627a7a7230582010ddaa52e73a98c06dbcd22b234b97206c1d7ed64a7c048e10c2043a3d2309cb0029"), - null, - null, - createAccessList(), - null, - null); + new JsonCallParameter.JsonCallParameterBuilder() + .withFrom(Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b")) + .withInput( + Bytes.fromHexString( + "0x608060405234801561001057600080fd5b50610157806100206000396000f30060806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680633bdab8bf146100515780639ae97baa14610068575b600080fd5b34801561005d57600080fd5b5061006661007f565b005b34801561007457600080fd5b5061007d6100b9565b005b7fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60016040518082815260200191505060405180910390a1565b7fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60026040518082815260200191505060405180910390a17fa53887c1eed04528e23301f55ad49a91634ef5021aa83a97d07fd16ed71c039a60036040518082815260200191505060405180910390a15600a165627a7a7230582010ddaa52e73a98c06dbcd22b234b97206c1d7ed64a7c048e10c2043a3d2309cb0029")) + .withAccessList(createAccessList()) + .build(); final JsonRpcResponse response = method.response(requestWithParams(callParameter)); final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse(null, "0x2014d"); 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 237eef2e02..ef8ca5b316 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 @@ -17,7 +17,6 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcErrorConverter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; 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; @@ -94,16 +93,6 @@ public abstract class AbstractEstimateGas implements JsonRpcMethod { return ((long) ((gasUsedByTransaction + gasStipend) * subCallMultiplier)); } - protected JsonCallParameter validateAndGetCallParams(final JsonRpcRequestContext request) { - final JsonCallParameter callParams = request.getRequiredParameter(0, JsonCallParameter.class); - if (callParams.getGasPrice() != null - && (callParams.getMaxFeePerGas().isPresent() - || callParams.getMaxPriorityFeePerGas().isPresent())) { - throw new InvalidJsonRpcParameters("gasPrice cannot be used with baseFee or maxFeePerGas"); - } - return callParams; - } - protected JsonRpcErrorResponse errorResponse( final JsonRpcRequestContext request, final TransactionSimulatorResult result) { diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCreateAccessList.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCreateAccessList.java index b6b9f5171f..2be5047a24 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCreateAccessList.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCreateAccessList.java @@ -14,6 +14,8 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; +import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonCallParameterUtil.validateAndGetCallParams; + import org.hyperledger.besu.datatypes.AccessListEntry; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthEstimateGas.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthEstimateGas.java index c0631bf44c..ca084ba0fb 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthEstimateGas.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthEstimateGas.java @@ -14,6 +14,8 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; +import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonCallParameterUtil.validateAndGetCallParams; + import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonCallParameter; 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 b084ebc913..987b68c2e2 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 @@ -26,68 +26,338 @@ import java.util.List; import java.util.Optional; import com.fasterxml.jackson.annotation.JsonAnySetter; -import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import org.apache.tuweni.bytes.Bytes; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +/** + * This class is used to deserialize JSON parameters for a call to the JSON-RPC method eth_call. It + * extends {@link CallParameter} by adding support for JSON-specific fields such as strict mode, + * access lists, and blob versioned hashes. It also handles unknown JSON properties gracefully. + * + *

To build an instance of this class, use the {@link JsonCallParameterBuilder}: + * + *

{@code
+ * JsonCallParameter param = new JsonCallParameter.JsonCallParameterBuilder()
+ *     .withFrom(Address.fromHexString("0x..."))
+ *     .withTo(Address.fromHexString("0x..."))
+ *     .withGas(21000L)
+ *     .withGasPrice(Wei.of(1000000000L))
+ *     .withValue(Wei.ZERO)
+ *     .withInput(Bytes.fromHexString("0x..."))
+ *     .withStrict(true) // Optional
+ *     .withAccessList(accessList) // Optional
+ *     .withMaxFeePerGas(Wei.of(2)) // Optional
+ *     .withMaxPriorityFeePerGas(Wei.of(1)) // Optional
+ *     .withMaxFeePerBlobGas(Wei.of(3)) // Optional
+ *     .withBlobVersionedHashes(blobVersionedHashes) // Optional
+ *     .build();
+ * }
+ * + *

Note: Only one of 'data' or 'input' should be provided to the builder. If both are provided + * and their values differ, an {@link IllegalArgumentException} is thrown. + * + *

Unknown JSON properties encountered during deserialization are logged but do not affect the + * deserialization process, allowing for flexibility in JSON formats. + */ @JsonIgnoreProperties(ignoreUnknown = true) +@JsonDeserialize(builder = JsonCallParameter.JsonCallParameterBuilder.class) public class JsonCallParameter extends CallParameter { private static final Logger LOG = LoggerFactory.getLogger(JsonCallParameter.class); private final Optional strict; - @JsonCreator - public JsonCallParameter( - @JsonProperty("from") final Address from, - @JsonProperty("to") final Address to, - @JsonDeserialize(using = GasDeserializer.class) @JsonProperty("gas") final Long gasLimit, - @JsonProperty("gasPrice") final Wei gasPrice, - @JsonProperty("maxPriorityFeePerGas") final Wei maxPriorityFeePerGas, - @JsonProperty("maxFeePerGas") final Wei maxFeePerGas, - @JsonProperty("value") final Wei value, - @JsonDeserialize(using = HexStringDeserializer.class) @JsonProperty("data") final Bytes data, - @JsonDeserialize(using = HexStringDeserializer.class) @JsonProperty("input") - final Bytes input, - @JsonProperty("strict") final Boolean strict, - @JsonProperty("accessList") final List accessList, - @JsonProperty("maxFeePerBlobGas") final Wei maxFeePerBlobGas, - @JsonProperty("blobVersionedHashes") final List blobVersionedHashes) { + private JsonCallParameter( + final Address from, + final Address to, + final Long gasLimit, + final Wei gasPrice, + final Optional maxPriorityFeePerGas, + final Optional maxFeePerGas, + final Wei value, + final Bytes payload, + final Optional strict, + final Optional> accessList, + final Optional maxFeePerBlobGas, + final Optional> blobVersionedHashes) { super( from, to, - gasLimit != null ? gasLimit : -1L, + gasLimit, gasPrice, - Optional.ofNullable(maxPriorityFeePerGas), - Optional.ofNullable(maxFeePerGas), + maxPriorityFeePerGas, + maxFeePerGas, value, - Optional.ofNullable(input != null ? input : data).orElse(null), - Optional.ofNullable(accessList), - Optional.ofNullable(maxFeePerBlobGas), - Optional.ofNullable(blobVersionedHashes)); + payload, + accessList, + maxFeePerBlobGas, + blobVersionedHashes); - if (input != null && data != null && !input.equals(data)) { - throw new IllegalArgumentException("Only one of 'input' or 'data' should be provided"); - } - - this.strict = Optional.ofNullable(strict); + this.strict = strict; } + /** + * Returns whether the call should be executed in strict mode. + * + * @return Optional strict mode flag + */ public Optional isMaybeStrict() { return strict; } - @JsonAnySetter - public void logUnknownProperties(final String key, final Object value) { - LOG.debug( - "unknown property - {} with value - {} and type - {} caught during serialization", - key, - value, - value.getClass()); + /** + * Builder for {@link JsonCallParameter}. Used by Jackson to deserialize {@code + * JsonCallParameter}. + */ + public static final class JsonCallParameterBuilder { + private Optional strict = Optional.empty(); + private Address from; + private Address to; + private long gas = -1; + private Optional maxPriorityFeePerGas = Optional.empty(); + private Optional maxFeePerGas = Optional.empty(); + private Optional maxFeePerBlobGas = Optional.empty(); + private Wei gasPrice; + private Wei value; + private Bytes data; + private Bytes input; + private Optional> accessList = Optional.empty(); + private Optional> blobVersionedHashes = Optional.empty(); + + /** Default constructor. */ + public JsonCallParameterBuilder() {} + + /** + * Sets the strict mode for the {@link JsonCallParameter}. If strict mode is enabled, the call + * will be executed with stricter validation rules. This is optional and defaults to not being + * in strict mode if not specified. + * + * @param strict the strict mode flag, can be {@code null} to indicate the absence of a strict + * mode preference + * @return the {@link JsonCallParameterBuilder} instance for chaining + */ + public JsonCallParameterBuilder withStrict(final Boolean strict) { + this.strict = Optional.ofNullable(strict); + return this; + } + + /** + * Sets the "from" address for the {@link JsonCallParameter}. This address represents the sender + * of the call. + * + * @param from the sender's address + * @return the {@link JsonCallParameterBuilder} instance for chaining + */ + public JsonCallParameterBuilder withFrom(final Address from) { + this.from = from; + return this; + } + + /** + * Sets the "to" address for the {@link JsonCallParameter}. This address represents the + * recipient of the call. It can be null for contract creation transactions. + * + * @param to the recipient's address + * @return the {@link JsonCallParameterBuilder} instance for chaining + */ + public JsonCallParameterBuilder withTo(final Address to) { + this.to = to; + return this; + } + + /** + * Sets the gas for the {@link JsonCallParameter} used for transaction execution. eth_call uses + * 0 gas but this parameter may be needed by some executions. By default, if not specified, the + * gas is set to -1, indicating that it is not set. + * + * @param gas the gas limit for the call, can be {@code null} to indicate that the gas limit is + * not set + * @return the {@link JsonCallParameterBuilder} instance for chaining + */ + @JsonDeserialize(using = GasDeserializer.class) + public JsonCallParameterBuilder withGas(final Long gas) { + this.gas = Optional.ofNullable(gas).orElse(-1L); + return this; + } + + /** + * Sets the maximum priority fee per gas for the {@link JsonCallParameter}. This fee is used to + * incentivize miners to include the transaction in a block. It is an optional parameter, and if + * not specified, it defaults to an empty {@link Optional}. + * + * @param maxPriorityFeePerGas the maximum priority fee per gas, can be {@code null} to indicate + * no preference + * @return the {@link JsonCallParameterBuilder} instance for chaining + */ + public JsonCallParameterBuilder withMaxPriorityFeePerGas(final Wei maxPriorityFeePerGas) { + this.maxPriorityFeePerGas = Optional.ofNullable(maxPriorityFeePerGas); + return this; + } + + /** + * Sets the maximum fee per gas for the {@link JsonCallParameter}. This fee represents the + * maximum amount of gas that the sender is willing to pay. It is an optional parameter, and if + * not specified, it defaults to an empty {@link Optional}. + * + * @param maxFeePerGas the maximum fee per gas, can be {@code null} to indicate no preference + * @return the {@link JsonCallParameterBuilder} instance for chaining + */ + public JsonCallParameterBuilder withMaxFeePerGas(final Wei maxFeePerGas) { + this.maxFeePerGas = Optional.ofNullable(maxFeePerGas); + return this; + } + + /** + * Sets the maximum fee per blob gas for the {@link JsonCallParameter}. This fee is specific to + * certain types of transactions and is an optional parameter. If not specified, it defaults to + * an empty {@link Optional}. + * + * @param maxFeePerBlobGas the maximum fee per blob gas, can be {@code null} to indicate no + * preference + * @return the {@link JsonCallParameterBuilder} instance for chaining + */ + public JsonCallParameterBuilder withMaxFeePerBlobGas(final Wei maxFeePerBlobGas) { + this.maxFeePerBlobGas = Optional.ofNullable(maxFeePerBlobGas); + return this; + } + + /** + * Sets the gas price for the {@link JsonCallParameter}. The gas price is used to calculate the + * transaction fee as the product of gas price and gas used. It is an optional parameter, and if + * not specified, it defaults to the network's current gas price. + * + * @param gasPrice the gas price, can be {@code null} to indicate that the network's current gas + * price should be used + * @return the {@link JsonCallParameterBuilder} instance for chaining + */ + public JsonCallParameterBuilder withGasPrice(final Wei gasPrice) { + this.gasPrice = gasPrice; + return this; + } + + /** + * Sets the value to be transferred with the call for the {@link JsonCallParameter}. This value + * is the amount of Wei to be transferred from the sender to the recipient. It is an optional + * parameter, and if not specified, it defaults to 0, indicating that no value is transferred. + * + * @param value the value to be transferred, can be {@code null} to indicate no value is + * transferred + * @return the {@link JsonCallParameterBuilder} instance for chaining + */ + public JsonCallParameterBuilder withValue(final Wei value) { + this.value = value; + return this; + } + + /** + * Sets the data for the {@link JsonCallParameter}. This data represents the payload of the + * call. Note: Only one of 'data' or 'input' should be provided. If both are provided and their + * values differ, an exception will be thrown during the build process. + * + * @param data the payload data + * @return the {@link JsonCallParameterBuilder} instance for chaining + */ + @JsonDeserialize(using = HexStringDeserializer.class) + public JsonCallParameterBuilder withData(final Bytes data) { + this.data = data; + return this; + } + + /** + * Sets the input for the {@link JsonCallParameter}. This input is an alternative representation + * of the payload for the call. Note: Only one of 'input' or 'data' should be provided. If both + * are provided and their values differ, an exception will be thrown during the build process. + * + * @param input the payload input + * @return the {@link JsonCallParameterBuilder} instance for chaining + */ + @JsonDeserialize(using = HexStringDeserializer.class) + public JsonCallParameterBuilder withInput(final Bytes input) { + this.input = input; + return this; + } + + /** + * Sets the access list for the {@link JsonCallParameter}. The access list is a list of + * addresses and storage keys that the transaction plans to access. This is an optional + * parameter, and if not specified, it defaults to an empty {@link Optional}. + * + * @param accessList the access list, can be {@code null} to indicate no access list is provided + * @return the {@link JsonCallParameterBuilder} instance for chaining + */ + public JsonCallParameterBuilder withAccessList(final List accessList) { + this.accessList = Optional.ofNullable(accessList); + return this; + } + + /** + * Sets the blob versioned hashes for the {@link JsonCallParameter}. This is a list of versioned + * hashes related to blob transactions, allowing for more complex transaction types. It is an + * optional parameter, and if not specified, it defaults to an empty {@link Optional}. + * + * @param blobVersionedHashes the list of versioned hashes, can be {@code null} to indicate no + * versioned hashes are provided + * @return the {@link JsonCallParameterBuilder} instance for chaining + */ + public JsonCallParameterBuilder withBlobVersionedHashes( + final List blobVersionedHashes) { + this.blobVersionedHashes = Optional.ofNullable(blobVersionedHashes); + return this; + } + + /** + * Handles unknown JSON properties during deserialization. This method is invoked when an + * unknown property is encountered in the JSON being deserialized into a {@link + * JsonCallParameter} object. It logs the unknown property's key, value, and the value's type if + * the value is not null. This allows for flexibility in JSON formats and aids in debugging + * issues related to unexpected properties. + * + * @param key the key of the unknown property + * @param value the value of the unknown property, which can be any type + */ + @JsonAnySetter + public void withUnknownProperties(final String key, final Object value) { + LOG.debug( + "unknown property - {} with value - {} and type - {} caught during serialization", + key, + value, + value != null ? value.getClass() : "NULL"); + } + + /** + * Builds a {@link JsonCallParameter} instance based on the provided parameters. This method + * also validates that only one of 'input' or 'data' is provided. If both are provided and their + * values differ, an {@link IllegalArgumentException} is thrown. This ensures the integrity of + * the payload data for the call. + * + * @return a new {@link JsonCallParameter} instance with the specified configuration + * @throws IllegalArgumentException if both 'input' and 'data' are provided and their values are + * not equal + */ + public JsonCallParameter build() { + if (input != null && data != null && !input.equals(data)) { + throw new IllegalArgumentException("Only one of 'input' or 'data' should be provided"); + } + + final Bytes payload = input != null ? input : data; + + return new JsonCallParameter( + from, + to, + gas, + gasPrice, + maxPriorityFeePerGas, + maxFeePerGas, + value, + payload, + strict, + accessList, + maxFeePerBlobGas, + blobVersionedHashes); + } } } 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 261f8de505..7570fe342c 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 @@ -115,8 +115,7 @@ public class EthCallTest { @Test public void shouldAcceptRequestWhenMissingOptionalFields() { final JsonCallParameter callParameter = - new JsonCallParameter( - null, null, null, null, null, null, null, null, null, Boolean.FALSE, null, null, null); + new JsonCallParameter.JsonCallParameterBuilder().withStrict(Boolean.FALSE).build(); final JsonRpcRequestContext request = ethCallRequest(callParameter, "latest"); final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse(null, Bytes.of().toString()); @@ -444,20 +443,16 @@ public class EthCallTest { private JsonCallParameter callParameter( final Wei gasPrice, final Wei maxFeesPerGas, final Wei maxPriorityFeesPerGas) { - return new JsonCallParameter( - Address.fromHexString("0x0"), - Address.fromHexString("0x0"), - 0L, - gasPrice, - maxFeesPerGas, - maxPriorityFeesPerGas, - Wei.ZERO, - Bytes.EMPTY, - null, - null, - null, - null, - null); + return new JsonCallParameter.JsonCallParameterBuilder() + .withFrom(Address.fromHexString("0x0")) + .withTo(Address.fromHexString("0x0")) + .withGas(0L) + .withGasPrice(gasPrice) + .withMaxFeePerGas(maxFeesPerGas) + .withMaxPriorityFeePerGas(maxPriorityFeesPerGas) + .withValue(Wei.ZERO) + .withInput(Bytes.EMPTY) + .build(); } private JsonRpcRequestContext ethCallRequest( diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCreateAccessListTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCreateAccessListTest.java index d23c10f23b..8812a1e0a6 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCreateAccessListTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCreateAccessListTest.java @@ -142,7 +142,7 @@ public class EthCreateAccessListTest { Assertions.assertThatThrownBy(() -> method.response(request)) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("gasPrice cannot be used with baseFee or maxFeePerGas"); + .hasMessageContaining("gasPrice cannot be used with maxFeePerGas or maxPriorityFeePerGas"); } @Test @@ -305,20 +305,15 @@ public class EthCreateAccessListTest { } private JsonCallParameter legacyTransactionCallParameter(final Wei gasPrice) { - return new JsonCallParameter( - Address.fromHexString("0x0"), - Address.fromHexString("0x0"), - 0L, - gasPrice, - null, - null, - Wei.ZERO, - Bytes.EMPTY, - null, - false, - null, - null, - null); + return new JsonCallParameter.JsonCallParameterBuilder() + .withFrom(Address.fromHexString("0x0")) + .withTo(Address.fromHexString("0x0")) + .withGas(0L) + .withGasPrice(gasPrice) + .withValue(Wei.ZERO) + .withInput(Bytes.EMPTY) + .withStrict(Boolean.FALSE) + .build(); } private CallParameter eip1559TransactionCallParameter() { @@ -336,20 +331,17 @@ public class EthCreateAccessListTest { private JsonCallParameter eip1559TransactionCallParameter( final Optional gasPrice, final List accessListEntries) { - return new JsonCallParameter( - Address.fromHexString("0x0"), - Address.fromHexString("0x0"), - null, - gasPrice.orElse(null), - Wei.fromHexString("0x10"), - Wei.fromHexString("0x10"), - Wei.ZERO, - Bytes.EMPTY, - null, - false, - accessListEntries, - null, - null); + return new JsonCallParameter.JsonCallParameterBuilder() + .withFrom(Address.fromHexString("0x0")) + .withTo(Address.fromHexString("0x0")) + .withGasPrice(gasPrice.orElse(null)) + .withMaxFeePerGas(Wei.fromHexString("0x10")) + .withMaxPriorityFeePerGas(Wei.fromHexString("0x10")) + .withValue(Wei.ZERO) + .withInput(Bytes.EMPTY) + .withStrict(Boolean.FALSE) + .withAccessList(accessListEntries) + .build(); } private List createAccessList() { diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthEstimateGasTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthEstimateGasTest.java index aa52a31c1f..a6f5008b29 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthEstimateGasTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthEstimateGasTest.java @@ -167,7 +167,7 @@ public class EthEstimateGasTest { mockTransientProcessorResultGasEstimate(1L, false, false); Assertions.assertThatThrownBy(() -> method.response(request)) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("gasPrice cannot be used with baseFee or maxFeePerGas"); + .hasMessageContaining("gasPrice cannot be used with maxFeePerGas or maxPriorityFeePerGas"); } @Test @@ -465,20 +465,15 @@ public class EthEstimateGasTest { private JsonCallParameter legacyTransactionCallParameter( final Wei gasPrice, final boolean isStrict) { - return new JsonCallParameter( - Address.fromHexString("0x0"), - Address.fromHexString("0x0"), - 0L, - gasPrice, - null, - null, - Wei.ZERO, - Bytes.EMPTY, - null, - isStrict, - null, - null, - null); + return new JsonCallParameter.JsonCallParameterBuilder() + .withFrom(Address.fromHexString("0x0")) + .withTo(Address.fromHexString("0x0")) + .withGas(0L) + .withGasPrice(gasPrice) + .withValue(Wei.ZERO) + .withInput(Bytes.EMPTY) + .withStrict(isStrict) + .build(); } private CallParameter modifiedLegacyTransactionCallParameter(final Wei gasPrice) { @@ -499,20 +494,16 @@ public class EthEstimateGasTest { } private JsonCallParameter eip1559TransactionCallParameter(final Optional gasPrice) { - return new JsonCallParameter( - Address.fromHexString("0x0"), - Address.fromHexString("0x0"), - null, - gasPrice.orElse(null), - Wei.fromHexString("0x10"), - Wei.fromHexString("0x10"), - Wei.ZERO, - Bytes.EMPTY, - null, - false, - null, - null, - null); + return new JsonCallParameter.JsonCallParameterBuilder() + .withFrom(Address.fromHexString("0x0")) + .withTo(Address.fromHexString("0x0")) + .withGasPrice(gasPrice.orElse(null)) + .withMaxPriorityFeePerGas(Wei.fromHexString("0x10")) + .withMaxFeePerGas(Wei.fromHexString("0x10")) + .withValue(Wei.ZERO) + .withInput(Bytes.EMPTY) + .withStrict(false) + .build(); } private CallParameter modifiedEip1559TransactionCallParameter() { diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/JsonCallParameterTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/JsonCallParameterTest.java index b74c68f97d..97d7feeeb1 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/JsonCallParameterTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/JsonCallParameterTest.java @@ -15,9 +15,12 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.tuweni.bytes.Bytes; import org.junit.jupiter.api.Test; public class JsonCallParameterTest { @@ -25,7 +28,7 @@ public class JsonCallParameterTest { private final ObjectMapper objectMapper = new ObjectMapper(); @Test - public void acceptsAndCapMaxValueForGasLimit() throws JsonProcessingException { + public void acceptsAndCapMaxValueForGas() throws JsonProcessingException { final String json = """ { @@ -37,4 +40,79 @@ public class JsonCallParameterTest { assertThat(callParameter.getGasLimit()).isEqualTo(Long.MAX_VALUE); } + + @Test + public void dataAsPayLoad() throws JsonProcessingException { + final String json = + """ + { + "data": "0x1234" + } + """; + + final JsonCallParameter callParameter = objectMapper.readValue(json, JsonCallParameter.class); + + assertThat(callParameter.getPayload()).isEqualTo(Bytes.fromHexString("0x1234")); + } + + @Test + public void inputAsPayLoad() throws JsonProcessingException { + final String json = + """ + { + "input": "0x1234" + } + """; + + final JsonCallParameter callParameter = objectMapper.readValue(json, JsonCallParameter.class); + + assertThat(callParameter.getPayload()).isEqualTo(Bytes.fromHexString("0x1234")); + } + + @Test + public void inputAndDataWithSameValueAsPayLoad() throws JsonProcessingException { + final String json = + """ + { + "input": "0x1234", + "data": "0x1234" + } + """; + + final JsonCallParameter callParameter = objectMapper.readValue(json, JsonCallParameter.class); + + assertThat(callParameter.getPayload()).isEqualTo(Bytes.fromHexString("0x1234")); + } + + @Test + public void inputAndDataWithDifferentValueAsPayLoadCauseException() { + final String json = + """ + { + "input": "0x1234", + "data": "0x1235" + } + """; + + assertThatExceptionOfType(JsonMappingException.class) + .isThrownBy(() -> objectMapper.readValue(json, JsonCallParameter.class)) + .withMessageContaining("problem: Only one of 'input' or 'data' should be provided"); + } + + @Test + public void extraParametersAreIgnored() throws JsonProcessingException { + // 0x96 = 150 + final String json = + """ + { + "gas": "0x96", + "gasLimit": "0xfa", + "extraField": "extra" + } + """; + + final JsonCallParameter callParameter = objectMapper.readValue(json, JsonCallParameter.class); + + assertThat(callParameter.getGasLimit()).isEqualTo(150); + } } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCallTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCallTest.java index 8456fa2847..0919ea48e9 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCallTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCallTest.java @@ -75,20 +75,13 @@ public class PrivCallTest { @Test public void shouldThrowInvalidJsonRpcParametersExceptionWhenMissingToField() { final JsonCallParameter callParameter = - new JsonCallParameter( - Address.fromHexString("0x0"), - null, - 0L, - Wei.ZERO, - null, - null, - Wei.ZERO, - Bytes.EMPTY, - null, - null, - null, - null, - null); + new JsonCallParameter.JsonCallParameterBuilder() + .withFrom(Address.fromHexString("0x0")) + .withGas(0L) + .withGasPrice(Wei.ZERO) + .withValue(Wei.ZERO) + .withInput(Bytes.EMPTY) + .build(); final JsonRpcRequestContext request = ethCallRequest(privacyGroupId, callParameter, "latest"); final Throwable thrown = catchThrowable(() -> method.response(request)); @@ -113,20 +106,9 @@ public class PrivCallTest { @Test public void shouldAcceptRequestWhenMissingOptionalFields() { final JsonCallParameter callParameter = - new JsonCallParameter( - null, - Address.fromHexString("0x0"), - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null); + new JsonCallParameter.JsonCallParameterBuilder() + .withTo(Address.fromHexString("0x0")) + .build(); final JsonRpcRequestContext request = ethCallRequest(privacyGroupId, callParameter, "latest"); final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse(null, Bytes.of().toString()); @@ -196,20 +178,14 @@ public class PrivCallTest { } private JsonCallParameter callParameter() { - return new JsonCallParameter( - Address.fromHexString("0x0"), - Address.fromHexString("0x0"), - 0L, - Wei.ZERO, - null, - null, - Wei.ZERO, - Bytes.EMPTY, - null, - null, - null, - null, - null); + return new JsonCallParameter.JsonCallParameterBuilder() + .withFrom(Address.fromHexString("0x0")) + .withTo(Address.fromHexString("0x0")) + .withGas(0L) + .withGasPrice(Wei.ZERO) + .withValue(Wei.ZERO) + .withInput(Bytes.EMPTY) + .build(); } private JsonRpcRequestContext ethCallRequest( From 782553eb039a37eaa097dcf55182c610044864ae Mon Sep 17 00:00:00 2001 From: Fabio Di Fabio Date: Tue, 16 Jul 2024 11:47:16 +0200 Subject: [PATCH 042/259] Stop transaction selection on TX_EVALUATION_TOO_LONG (#7330) Signed-off-by: Fabio Di Fabio --- plugin-api/build.gradle | 2 +- .../besu/plugin/data/TransactionSelectionResult.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugin-api/build.gradle b/plugin-api/build.gradle index 30ab85d37a..dff6cc9098 100644 --- a/plugin-api/build.gradle +++ b/plugin-api/build.gradle @@ -70,7 +70,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 = 'Yv6CY8fh0yrIz3Q8Moy/j1TNGL+O8Mewp4SIgM1JE6M=' + knownHash = 'MOOKIka8Q1D64m0lU29Leq+zf1vcgeLoDVukBVQXhnY=' } check.dependsOn('checkAPIChanges') diff --git a/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/TransactionSelectionResult.java b/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/TransactionSelectionResult.java index 112df57a49..839c4120d0 100644 --- a/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/TransactionSelectionResult.java +++ b/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/TransactionSelectionResult.java @@ -55,7 +55,7 @@ public class TransactionSelectionResult { BLOCK_FULL(true, false), BLOCK_OCCUPANCY_ABOVE_THRESHOLD(true, false), BLOCK_SELECTION_TIMEOUT(true, false), - TX_EVALUATION_TOO_LONG(false, true), + TX_EVALUATION_TOO_LONG(true, true), INVALID_TRANSIENT(false, false), INVALID(false, true); From 465fd1cbe56f1d50c7a2501caea444cec81fca2b Mon Sep 17 00:00:00 2001 From: Fabio Di Fabio Date: Tue, 16 Jul 2024 13:09:10 +0200 Subject: [PATCH 043/259] Fix and restore disabled block creation unit tests (#7331) Signed-off-by: Fabio Di Fabio --- .../AbstractBlockCreatorTest.java | 69 +++++++++++--- ...FeeMarketBlockTransactionSelectorTest.java | 4 - .../blockcreation/PoWBlockCreatorTest.java | 94 ++++++++++++------- ...ock-creation-fixed-difficulty-genesis.json | 34 +++++++ .../resources/block-creation-genesis.json | 32 +++++++ .../vm/TraceTransactionIntegrationTest.java | 5 +- .../resources/genesis-it.json | 13 +++ .../operations/OperationBenchmarkHelper.java | 5 +- .../core/src/jmh/resources/genesis-jmh.json | 13 +++ .../core/ExecutionContextTestFixture.java | 18 ++-- .../AbstractTransactionPoolTest.java | 9 +- .../test/resources/txpool-test-genesis.json | 15 +++ 12 files changed, 246 insertions(+), 65 deletions(-) create mode 100644 ethereum/blockcreation/src/test/resources/block-creation-fixed-difficulty-genesis.json create mode 100644 ethereum/blockcreation/src/test/resources/block-creation-genesis.json create mode 100644 ethereum/core/src/integration-test/resources/genesis-it.json create mode 100644 ethereum/core/src/jmh/resources/genesis-jmh.json create mode 100644 ethereum/eth/src/test/resources/txpool-test-genesis.json 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 68d13987bb..2444d9db7d 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 @@ -26,8 +26,9 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import org.hyperledger.besu.config.GenesisConfigFile; -import org.hyperledger.besu.config.GenesisConfigOptions; import org.hyperledger.besu.crypto.KeyPair; +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; @@ -73,13 +74,18 @@ import org.hyperledger.besu.ethereum.mainnet.BodyValidation; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolScheduleBuilder; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecAdapters; +import org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams; +import org.hyperledger.besu.ethereum.mainnet.TransactionValidator; +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.feemarket.CancunFeeMarket; 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; import org.hyperledger.besu.evm.log.Log; import org.hyperledger.besu.evm.log.LogTopic; @@ -89,13 +95,13 @@ import org.hyperledger.besu.testutil.DeterministicEthScheduler; import java.math.BigInteger; import java.time.Clock; import java.util.List; -import java.util.Map; import java.util.Optional; +import com.google.common.base.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; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; @@ -103,6 +109,17 @@ import org.mockito.junit.jupiter.MockitoExtension; @ExtendWith(MockitoExtension.class) abstract class AbstractBlockCreatorTest { + private static final Supplier SIGNATURE_ALGORITHM = + Suppliers.memoize(SignatureAlgorithmFactory::getInstance); + private static final SECPPrivateKey PRIVATE_KEY1 = + SIGNATURE_ALGORITHM + .get() + .createPrivateKey( + Bytes32.fromHexString( + "8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63")); + private static final KeyPair KEYS1 = + new KeyPair(PRIVATE_KEY1, SIGNATURE_ALGORITHM.get().createPublicKey(PRIVATE_KEY1)); + @Mock private WithdrawalsProcessor withdrawalsProcessor; protected EthScheduler ethScheduler = new DeterministicEthScheduler(); @@ -301,10 +318,8 @@ abstract class AbstractBlockCreatorTest { assertThat(blockCreationResult.getBlock().getBody().getWithdrawals()).isEmpty(); } - @Disabled @Test public void computesGasUsageFromIncludedTransactions() { - final KeyPair senderKeys = SignatureAlgorithmFactory.getInstance().generateKeyPair(); final AbstractBlockCreator blockCreator = blockCreatorWithBlobGasSupport(); BlobTestFixture blobTestFixture = new BlobTestFixture(); BlobsWithCommitments bwc = blobTestFixture.createBlobsWithCommitments(6); @@ -313,13 +328,14 @@ abstract class AbstractBlockCreatorTest { ttf.to(Optional.of(Address.ZERO)) .type(TransactionType.BLOB) .chainId(Optional.of(BigInteger.valueOf(42))) + .gasLimit(21000) .maxFeePerGas(Optional.of(Wei.of(15))) .maxFeePerBlobGas(Optional.of(Wei.of(128))) .maxPriorityFeePerGas(Optional.of(Wei.of(1))) .versionedHashes(Optional.of(bwc.getVersionedHashes())) - .createTransaction(senderKeys); + .blobsWithCommitments(Optional.of(bwc)) + .createTransaction(KEYS1); - ttf.blobsWithCommitments(Optional.of(bwc)); final BlockCreationResult blockCreationResult = blockCreator.createBlock( Optional.of(List.of(fullOfBlobs)), @@ -336,13 +352,17 @@ abstract class AbstractBlockCreatorTest { } private AbstractBlockCreator blockCreatorWithBlobGasSupport() { + final var alwaysValidTransactionValidatorFactory = mock(TransactionValidatorFactory.class); + when(alwaysValidTransactionValidatorFactory.get()) + .thenReturn(new AlwaysValidTransactionValidator()); final ProtocolSpecAdapters protocolSpecAdapters = ProtocolSpecAdapters.create( 0, specBuilder -> { - specBuilder.feeMarket(new CancunFeeMarket(0, Optional.empty())); specBuilder.isReplayProtectionSupported(true); specBuilder.withdrawalsProcessor(withdrawalsProcessor); + specBuilder.transactionValidatorFactoryBuilder( + (evm, gasLimitCalculator, feeMarket) -> alwaysValidTransactionValidatorFactory); return specBuilder; }); return createBlockCreator(protocolSpecAdapters); @@ -356,16 +376,19 @@ abstract class AbstractBlockCreatorTest { } private AbstractBlockCreator blockCreatorWithoutWithdrawalsProcessor() { - return createBlockCreator(new ProtocolSpecAdapters(Map.of())); + final ProtocolSpecAdapters protocolSpecAdapters = + ProtocolSpecAdapters.create(0, specBuilder -> specBuilder.withdrawalsProcessor(null)); + return createBlockCreator(protocolSpecAdapters); } private AbstractBlockCreator createBlockCreator(final ProtocolSpecAdapters protocolSpecAdapters) { - final GenesisConfigOptions genesisConfigOptions = GenesisConfigFile.DEFAULT.getConfigOptions(); + + final var genesisConfigFile = GenesisConfigFile.fromResource("/block-creation-genesis.json"); final ExecutionContextTestFixture executionContextTestFixture = - ExecutionContextTestFixture.builder() + ExecutionContextTestFixture.builder(genesisConfigFile) .protocolSchedule( new ProtocolScheduleBuilder( - genesisConfigOptions, + genesisConfigFile.getConfigOptions(), BigInteger.valueOf(42), protocolSpecAdapters, PrivacyParameters.DEFAULT, @@ -452,4 +475,24 @@ abstract class AbstractBlockCreatorTest { .buildBlockHeader(); } } + + static class AlwaysValidTransactionValidator implements TransactionValidator { + + @Override + public ValidationResult validate( + final Transaction transaction, + final Optional baseFee, + final Optional blobBaseFee, + final TransactionValidationParams transactionValidationParams) { + return ValidationResult.valid(); + } + + @Override + public ValidationResult validateForSender( + final Transaction transaction, + final Account sender, + final TransactionValidationParams validationParams) { + return ValidationResult.valid(); + } + } } diff --git a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/LegacyFeeMarketBlockTransactionSelectorTest.java b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/LegacyFeeMarketBlockTransactionSelectorTest.java index 3b1ae938f7..6206384534 100644 --- a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/LegacyFeeMarketBlockTransactionSelectorTest.java +++ b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/LegacyFeeMarketBlockTransactionSelectorTest.java @@ -42,10 +42,6 @@ import org.hyperledger.besu.util.number.Fraction; import java.time.ZoneId; import java.util.function.Function; -import org.junit.jupiter.api.Disabled; - -@Disabled( - "disabled since it's flaky with a timeout see https://github.com/hyperledger/besu/issues/6850") public class LegacyFeeMarketBlockTransactionSelectorTest extends AbstractBlockTransactionSelectorTest { diff --git a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/PoWBlockCreatorTest.java b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/PoWBlockCreatorTest.java index f7fd4486d1..2cd5bc5e9e 100644 --- a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/PoWBlockCreatorTest.java +++ b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/PoWBlockCreatorTest.java @@ -21,7 +21,6 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import org.hyperledger.besu.config.GenesisConfigFile; -import org.hyperledger.besu.config.GenesisConfigOptions; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.Wei; @@ -38,6 +37,7 @@ import org.hyperledger.besu.ethereum.core.MiningParameters; import org.hyperledger.besu.ethereum.core.MutableWorldState; import org.hyperledger.besu.ethereum.core.PrivacyParameters; import org.hyperledger.besu.ethereum.core.ProcessableBlockHeader; +import org.hyperledger.besu.ethereum.difficulty.fixed.FixedDifficultyCalculators; import org.hyperledger.besu.ethereum.eth.manager.EthContext; import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration; import org.hyperledger.besu.ethereum.eth.transactions.TransactionBroadcaster; @@ -75,6 +75,7 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest { private static final long BLOCK_1_TIMESTAMP = Long.parseUnsignedLong("55ba4224", 16); private static final long BLOCK_1_NONCE = Long.parseLong("539bd4979fef1ec4", 16); + private static final long FIXED_DIFFICULTY_NONCE = 26; private static final Bytes BLOCK_1_EXTRA_DATA = Bytes.fromHexString("0x476574682f76312e302e302f6c696e75782f676f312e342e32"); @@ -82,24 +83,25 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest { @Test void createMainnetBlock1() throws IOException { - final GenesisConfigOptions genesisConfigOptions = GenesisConfigFile.DEFAULT.getConfigOptions(); + final var genesisConfigFile = GenesisConfigFile.mainnet(); + + final MiningParameters miningParameters = createMiningParameters(BLOCK_1_NONCE); + final ExecutionContextTestFixture executionContextTestFixture = - ExecutionContextTestFixture.builder() + ExecutionContextTestFixture.builder(genesisConfigFile) .protocolSchedule( new ProtocolScheduleBuilder( - genesisConfigOptions, + genesisConfigFile.getConfigOptions(), BigInteger.valueOf(42), ProtocolSpecAdapters.create(0, Function.identity()), PrivacyParameters.DEFAULT, false, EvmConfiguration.DEFAULT, - MiningParameters.MINING_DISABLED, + miningParameters, new BadBlockManager()) .createProtocolSchedule()) .build(); - final MiningParameters miningParameters = createMiningParameters(); - final PoWSolver solver = new PoWSolver( miningParameters, @@ -136,26 +138,31 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest { @Test void createMainnetBlock1_fixedDifficulty1() { - final GenesisConfigOptions genesisConfigOptions = - GenesisConfigFile.fromConfig("{\"config\": {\"ethash\": {\"fixeddifficulty\":1}}}") - .getConfigOptions(); + final var genesisConfigFile = + GenesisConfigFile.fromResource("/block-creation-fixed-difficulty-genesis.json"); + + final MiningParameters miningParameters = createMiningParameters(FIXED_DIFFICULTY_NONCE); + final ExecutionContextTestFixture executionContextTestFixture = - ExecutionContextTestFixture.builder() + ExecutionContextTestFixture.builder(genesisConfigFile) .protocolSchedule( new ProtocolScheduleBuilder( - genesisConfigOptions, + genesisConfigFile.getConfigOptions(), BigInteger.valueOf(42), - ProtocolSpecAdapters.create(0, Function.identity()), + ProtocolSpecAdapters.create( + 0, + specBuilder -> + specBuilder.difficultyCalculator( + FixedDifficultyCalculators.calculator( + genesisConfigFile.getConfigOptions()))), PrivacyParameters.DEFAULT, false, EvmConfiguration.DEFAULT, - MiningParameters.MINING_DISABLED, + miningParameters, new BadBlockManager()) .createProtocolSchedule()) .build(); - final MiningParameters miningParameters = createMiningParameters(); - final PoWSolver solver = new PoWSolver( miningParameters, @@ -184,24 +191,31 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest { @Test void rewardBeneficiary_zeroReward_skipZeroRewardsFalse() { - final GenesisConfigOptions genesisConfigOptions = - GenesisConfigFile.fromConfig("{\"config\": {\"ethash\": {\"fixeddifficulty\":1}}}") - .getConfigOptions(); + final var genesisConfigFile = + GenesisConfigFile.fromResource("/block-creation-fixed-difficulty-genesis.json"); + + final MiningParameters miningParameters = createMiningParameters(FIXED_DIFFICULTY_NONCE); + ProtocolSchedule protocolSchedule = new ProtocolScheduleBuilder( - genesisConfigOptions, + genesisConfigFile.getConfigOptions(), BigInteger.valueOf(42), - ProtocolSpecAdapters.create(0, Function.identity()), + ProtocolSpecAdapters.create( + 0, + specBuilder -> + specBuilder.difficultyCalculator( + FixedDifficultyCalculators.calculator( + genesisConfigFile.getConfigOptions()))), PrivacyParameters.DEFAULT, false, EvmConfiguration.DEFAULT, - MiningParameters.MINING_DISABLED, + miningParameters, new BadBlockManager()) .createProtocolSchedule(); final ExecutionContextTestFixture executionContextTestFixture = - ExecutionContextTestFixture.builder().protocolSchedule(protocolSchedule).build(); - - final MiningParameters miningParameters = createMiningParameters(); + ExecutionContextTestFixture.builder(genesisConfigFile) + .protocolSchedule(protocolSchedule) + .build(); final PoWSolver solver = new PoWSolver( @@ -253,24 +267,31 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest { @Test void rewardBeneficiary_zeroReward_skipZeroRewardsTrue() { - final GenesisConfigOptions genesisConfigOptions = - GenesisConfigFile.fromConfig("{\"config\": {\"ethash\": {\"fixeddifficulty\":1}}}") - .getConfigOptions(); + final var genesisConfigFile = + GenesisConfigFile.fromResource("/block-creation-fixed-difficulty-genesis.json"); + + final MiningParameters miningParameters = createMiningParameters(FIXED_DIFFICULTY_NONCE); + ProtocolSchedule protocolSchedule = new ProtocolScheduleBuilder( - genesisConfigOptions, + genesisConfigFile.getConfigOptions(), BigInteger.valueOf(42), - ProtocolSpecAdapters.create(0, Function.identity()), + ProtocolSpecAdapters.create( + 0, + specBuilder -> + specBuilder.difficultyCalculator( + FixedDifficultyCalculators.calculator( + genesisConfigFile.getConfigOptions()))), PrivacyParameters.DEFAULT, false, EvmConfiguration.DEFAULT, - MiningParameters.MINING_DISABLED, + miningParameters, new BadBlockManager()) .createProtocolSchedule(); final ExecutionContextTestFixture executionContextTestFixture = - ExecutionContextTestFixture.builder().protocolSchedule(protocolSchedule).build(); - - final MiningParameters miningParameters = createMiningParameters(); + ExecutionContextTestFixture.builder(genesisConfigFile) + .protocolSchedule(protocolSchedule) + .build(); final PoWSolver solver = new PoWSolver( @@ -348,11 +369,12 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest { return transactionPool; } - private MiningParameters createMiningParameters() { + private MiningParameters createMiningParameters(final long nonce) { return ImmutableMiningParameters.builder() .mutableInitValues( MutableInitValues.builder() - .nonceGenerator(Lists.newArrayList(BLOCK_1_NONCE)) + .nonceGenerator(Lists.newArrayList(nonce)) + // .nonceGenerator(new IncrementingNonceGenerator(0)) .extraData(BLOCK_1_EXTRA_DATA) .minTransactionGasPrice(Wei.ONE) .coinbase(BLOCK_1_COINBASE) diff --git a/ethereum/blockcreation/src/test/resources/block-creation-fixed-difficulty-genesis.json b/ethereum/blockcreation/src/test/resources/block-creation-fixed-difficulty-genesis.json new file mode 100644 index 0000000000..5f9a821a8e --- /dev/null +++ b/ethereum/blockcreation/src/test/resources/block-creation-fixed-difficulty-genesis.json @@ -0,0 +1,34 @@ +{ + "config": { + "chainId": 42, + "frontierBlock": 0, + "ethash": { + "fixeddifficulty":10 + } + }, + "nonce": "0x42", + "timestamp": "0x0", + "extraData": "", + "gasLimit": "0x1fffffffffffff", + "difficulty": "0x1", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "coinbase": "0x0000000000000000000000000000000000000000", + "baseFeePerGas": "0x7", + "alloc": { + "fe3b557e8fb62b89f4916b721be55ceb828dbd73": { + "privateKey": "8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63", + "comment": "private key and this comment are ignored. In a real chain, the private key should NOT be stored", + "balance": "0xad78ebc5ac6200000" + }, + "627306090abaB3A6e1400e9345bC60c78a8BEf57": { + "privateKey": "c87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3", + "comment": "private key and this comment are ignored. In a real chain, the private key should NOT be stored", + "balance": "90000000000000000000000" + }, + "f17f52151EbEF6C7334FAD080c5704D77216b732": { + "privateKey": "ae6ae8e5ccbfb04590405997ee2d52d2b330726137b875053c36d94e974d162f", + "comment": "private key and this comment are ignored. In a real chain, the private key should NOT be stored", + "balance": "90000000000000000000000" + } + } +} diff --git a/ethereum/blockcreation/src/test/resources/block-creation-genesis.json b/ethereum/blockcreation/src/test/resources/block-creation-genesis.json new file mode 100644 index 0000000000..4a26c5ae02 --- /dev/null +++ b/ethereum/blockcreation/src/test/resources/block-creation-genesis.json @@ -0,0 +1,32 @@ +{ + "config": { + "chainId": 42, + "cancunTime": 0, + "terminalTotalDifficulty": 0 + }, + "nonce": "0x42", + "timestamp": "0x0", + "extraData": "", + "gasLimit": "0x1fffffffffffff", + "difficulty": "0x10000", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "coinbase": "0x0000000000000000000000000000000000000000", + "baseFeePerGas": "0x7", + "alloc": { + "fe3b557e8fb62b89f4916b721be55ceb828dbd73": { + "privateKey": "8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63", + "comment": "private key and this comment are ignored. In a real chain, the private key should NOT be stored", + "balance": "0xad78ebc5ac6200000" + }, + "627306090abaB3A6e1400e9345bC60c78a8BEf57": { + "privateKey": "c87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3", + "comment": "private key and this comment are ignored. In a real chain, the private key should NOT be stored", + "balance": "90000000000000000000000" + }, + "f17f52151EbEF6C7334FAD080c5704D77216b732": { + "privateKey": "ae6ae8e5ccbfb04590405997ee2d52d2b330726137b875053c36d94e974d162f", + "comment": "private key and this comment are ignored. In a real chain, the private key should NOT be stored", + "balance": "90000000000000000000000" + } + } +} diff --git a/ethereum/core/src/integration-test/java/org/hyperledger/besu/ethereum/vm/TraceTransactionIntegrationTest.java b/ethereum/core/src/integration-test/java/org/hyperledger/besu/ethereum/vm/TraceTransactionIntegrationTest.java index edae52f35a..a029c4b4a4 100644 --- a/ethereum/core/src/integration-test/java/org/hyperledger/besu/ethereum/vm/TraceTransactionIntegrationTest.java +++ b/ethereum/core/src/integration-test/java/org/hyperledger/besu/ethereum/vm/TraceTransactionIntegrationTest.java @@ -18,6 +18,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.entry; import static org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup; +import org.hyperledger.besu.config.GenesisConfigFile; import org.hyperledger.besu.crypto.KeyPair; import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; import org.hyperledger.besu.datatypes.TransactionType; @@ -68,7 +69,9 @@ public class TraceTransactionIntegrationTest { @BeforeEach public void setUp() { - final ExecutionContextTestFixture contextTestFixture = ExecutionContextTestFixture.create(); + final ExecutionContextTestFixture contextTestFixture = + ExecutionContextTestFixture.builder(GenesisConfigFile.fromResource("/genesis-it.json")) + .build(); genesisBlock = contextTestFixture.getGenesis(); blockchain = contextTestFixture.getBlockchain(); worldStateArchive = contextTestFixture.getStateArchive(); diff --git a/ethereum/core/src/integration-test/resources/genesis-it.json b/ethereum/core/src/integration-test/resources/genesis-it.json new file mode 100644 index 0000000000..70c42b39fe --- /dev/null +++ b/ethereum/core/src/integration-test/resources/genesis-it.json @@ -0,0 +1,13 @@ +{ + "config": { + "petersburgBlock": 0 + }, + "coinbase": "0x0000000000000000000000000000000000000000", + "difficulty": "0x0000001", + "extraData": "", + "gasLimit": "0x2fefd8", + "nonce": "0x0000000000000107", + "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "timestamp": "0x00" +} diff --git a/ethereum/core/src/jmh/java/org/hyperledger/besu/ethereum/vm/operations/OperationBenchmarkHelper.java b/ethereum/core/src/jmh/java/org/hyperledger/besu/ethereum/vm/operations/OperationBenchmarkHelper.java index 8307a8fef4..4289a91a3c 100644 --- a/ethereum/core/src/jmh/java/org/hyperledger/besu/ethereum/vm/operations/OperationBenchmarkHelper.java +++ b/ethereum/core/src/jmh/java/org/hyperledger/besu/ethereum/vm/operations/OperationBenchmarkHelper.java @@ -16,6 +16,7 @@ package org.hyperledger.besu.ethereum.vm.operations; import static java.util.Collections.emptyList; +import org.hyperledger.besu.config.GenesisConfigFile; import org.hyperledger.besu.ethereum.chain.Blockchain; import org.hyperledger.besu.ethereum.chain.MutableBlockchain; import org.hyperledger.besu.ethereum.core.Block; @@ -74,7 +75,9 @@ public class OperationBenchmarkHelper { KeyValueSegmentIdentifier.BLOCKCHAIN, optimisticRocksDBColumnarKeyValueStorage); final ExecutionContextTestFixture executionContext = - ExecutionContextTestFixture.builder().blockchainKeyValueStorage(keyValueStorage).build(); + ExecutionContextTestFixture.builder(GenesisConfigFile.fromResource("/genesis-jmh.json")) + .blockchainKeyValueStorage(keyValueStorage) + .build(); final MutableBlockchain blockchain = executionContext.getBlockchain(); for (int i = 1; i < 256; i++) { diff --git a/ethereum/core/src/jmh/resources/genesis-jmh.json b/ethereum/core/src/jmh/resources/genesis-jmh.json new file mode 100644 index 0000000000..70c42b39fe --- /dev/null +++ b/ethereum/core/src/jmh/resources/genesis-jmh.json @@ -0,0 +1,13 @@ +{ + "config": { + "petersburgBlock": 0 + }, + "coinbase": "0x0000000000000000000000000000000000000000", + "difficulty": "0x0000001", + "extraData": "", + "gasLimit": "0x2fefd8", + "nonce": "0x0000000000000107", + "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "timestamp": "0x00" +} diff --git a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/ExecutionContextTestFixture.java b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/ExecutionContextTestFixture.java index 3aa483e1a9..5aa00d0ed6 100644 --- a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/ExecutionContextTestFixture.java +++ b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/ExecutionContextTestFixture.java @@ -17,7 +17,6 @@ package org.hyperledger.besu.ethereum.core; import static org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider.createInMemoryWorldStateArchive; import org.hyperledger.besu.config.GenesisConfigFile; -import org.hyperledger.besu.config.StubGenesisConfigOptions; import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.chain.BadBlockManager; import org.hyperledger.besu.ethereum.chain.DefaultBlockchain; @@ -48,9 +47,9 @@ public class ExecutionContextTestFixture { private final ProtocolSchedule protocolSchedule; private final ProtocolContext protocolContext; - private static final GenesisConfigFile genesisConfigFile = GenesisConfigFile.mainnet(); private ExecutionContextTestFixture( + final GenesisConfigFile genesisConfigFile, final ProtocolSchedule protocolSchedule, final KeyValueStorage blockchainKeyValueStorage, final KeyValueStorage variablesKeyValueStorage) { @@ -76,11 +75,11 @@ public class ExecutionContextTestFixture { } public static ExecutionContextTestFixture create() { - return new Builder().build(); + return new Builder(GenesisConfigFile.mainnet()).build(); } - public static Builder builder() { - return new Builder(); + public static Builder builder(final GenesisConfigFile genesisConfigFile) { + return new Builder(genesisConfigFile); } public Block getGenesis() { @@ -112,10 +111,15 @@ public class ExecutionContextTestFixture { } public static class Builder { + private final GenesisConfigFile genesisConfigFile; private KeyValueStorage variablesKeyValueStorage; private KeyValueStorage blockchainKeyValueStorage; private ProtocolSchedule protocolSchedule; + public Builder(final GenesisConfigFile genesisConfigFile) { + this.genesisConfigFile = genesisConfigFile; + } + public Builder variablesKeyValueStorage(final KeyValueStorage keyValueStorage) { this.variablesKeyValueStorage = keyValueStorage; return this; @@ -135,7 +139,7 @@ public class ExecutionContextTestFixture { if (protocolSchedule == null) { protocolSchedule = new ProtocolScheduleBuilder( - new StubGenesisConfigOptions().petersburgBlock(0), + genesisConfigFile.getConfigOptions(), BigInteger.valueOf(42), ProtocolSpecAdapters.create(0, Function.identity()), new PrivacyParameters(), @@ -152,7 +156,7 @@ public class ExecutionContextTestFixture { variablesKeyValueStorage = new InMemoryKeyValueStorage(); } return new ExecutionContextTestFixture( - protocolSchedule, variablesKeyValueStorage, blockchainKeyValueStorage); + genesisConfigFile, protocolSchedule, variablesKeyValueStorage, blockchainKeyValueStorage); } } } 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 39b47bf9dd..23eb9d02bf 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 @@ -43,7 +43,7 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; import static org.mockito.quality.Strictness.LENIENT; -import org.hyperledger.besu.config.StubGenesisConfigOptions; +import org.hyperledger.besu.config.GenesisConfigFile; import org.hyperledger.besu.crypto.KeyPair; import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; import org.hyperledger.besu.datatypes.Address; @@ -191,9 +191,10 @@ public abstract class AbstractTransactionPoolTest { protected abstract ExecutionContextTestFixture createExecutionContextTestFixture(); protected static ExecutionContextTestFixture createExecutionContextTestFixtureBaseFeeMarket() { + final var genesisConfigFile = GenesisConfigFile.fromResource("/txpool-test-genesis.json"); final ProtocolSchedule protocolSchedule = new ProtocolScheduleBuilder( - new StubGenesisConfigOptions().londonBlock(0L).baseFeePerGas(10L), + genesisConfigFile.getConfigOptions(), BigInteger.valueOf(1), ProtocolSpecAdapters.create(0, Function.identity()), new PrivacyParameters(), @@ -203,7 +204,9 @@ public abstract class AbstractTransactionPoolTest { new BadBlockManager()) .createProtocolSchedule(); final ExecutionContextTestFixture executionContextTestFixture = - ExecutionContextTestFixture.builder().protocolSchedule(protocolSchedule).build(); + ExecutionContextTestFixture.builder(genesisConfigFile) + .protocolSchedule(protocolSchedule) + .build(); final Block block = new Block( diff --git a/ethereum/eth/src/test/resources/txpool-test-genesis.json b/ethereum/eth/src/test/resources/txpool-test-genesis.json new file mode 100644 index 0000000000..d6a19fe705 --- /dev/null +++ b/ethereum/eth/src/test/resources/txpool-test-genesis.json @@ -0,0 +1,15 @@ +{ + "config": { + "chainId": 1, + "cancunTime": 0, + "terminalTotalDifficulty": 0 + }, + "nonce": "0x42", + "timestamp": "0x0", + "extraData": "", + "gasLimit": "0x1fffffffffffff", + "difficulty": "0x10000", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "coinbase": "0x0000000000000000000000000000000000000000", + "baseFeePerGas": "0xA" +} From 99260fae96cf9d6248a6a112298e943ac323e8cb Mon Sep 17 00:00:00 2001 From: Fabio Di Fabio Date: Tue, 16 Jul 2024 23:50:09 +0200 Subject: [PATCH 044/259] Improve blob size transaction selector (#7312) Signed-off-by: Fabio Di Fabio --- CHANGELOG.md | 1 + .../txselection/BlockTransactionSelector.java | 2 + .../BlobSizeTransactionSelector.java | 95 +++++++++ .../BlockSizeTransactionSelector.java | 9 +- .../BlobSizeTransactionSelectorTest.java | 188 ++++++++++++++++++ plugin-api/build.gradle | 2 +- .../data/TransactionSelectionResult.java | 12 ++ 7 files changed, 300 insertions(+), 9 deletions(-) create mode 100644 ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/BlobSizeTransactionSelector.java create mode 100644 ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/BlobSizeTransactionSelectorTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index bee4620060..e0269472a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ - `privacy-nonce-always-increments` option enables private transactions to always increment the nonce, even if the transaction is invalid [#6593](https://github.com/hyperledger/besu/pull/6593) - Add `block-test` subcommand to the evmtool which runs blockchain reference tests [#7310](https://github.com/hyperledger/besu/pull/7310) - Implement gnark-crypto for eip-2537 [#7316](https://github.com/hyperledger/besu/pull/7316) +- Improve blob size transaction selector [#7312](https://github.com/hyperledger/besu/pull/7312) ### Bug fixes - Fix `eth_call` deserialization to correctly ignore unknown fields in the transaction object. [#7323](https://github.com/hyperledger/besu/pull/7323) diff --git a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/BlockTransactionSelector.java b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/BlockTransactionSelector.java index ab311c3fb3..c106b7aff1 100644 --- a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/BlockTransactionSelector.java +++ b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/BlockTransactionSelector.java @@ -23,6 +23,7 @@ import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.GasLimitCalculator; import org.hyperledger.besu.ethereum.blockcreation.txselection.selectors.AbstractTransactionSelector; import org.hyperledger.besu.ethereum.blockcreation.txselection.selectors.BlobPriceTransactionSelector; +import org.hyperledger.besu.ethereum.blockcreation.txselection.selectors.BlobSizeTransactionSelector; import org.hyperledger.besu.ethereum.blockcreation.txselection.selectors.BlockSizeTransactionSelector; import org.hyperledger.besu.ethereum.blockcreation.txselection.selectors.MinPriorityFeePerGasTransactionSelector; import org.hyperledger.besu.ethereum.blockcreation.txselection.selectors.PriceTransactionSelector; @@ -146,6 +147,7 @@ public class BlockTransactionSelector { final BlockSelectionContext context) { return List.of( new BlockSizeTransactionSelector(context), + new BlobSizeTransactionSelector(context), new PriceTransactionSelector(context), new BlobPriceTransactionSelector(context), new MinPriorityFeePerGasTransactionSelector(context), diff --git a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/BlobSizeTransactionSelector.java b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/BlobSizeTransactionSelector.java new file mode 100644 index 0000000000..9df006722e --- /dev/null +++ b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/BlobSizeTransactionSelector.java @@ -0,0 +1,95 @@ +/* + * 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.blockcreation.txselection.selectors; + +import org.hyperledger.besu.ethereum.blockcreation.txselection.BlockSelectionContext; +import org.hyperledger.besu.ethereum.blockcreation.txselection.TransactionEvaluationContext; +import org.hyperledger.besu.ethereum.blockcreation.txselection.TransactionSelectionResults; +import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult; +import org.hyperledger.besu.plugin.data.TransactionSelectionResult; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This class extends AbstractTransactionSelector and provides a specific implementation for + * evaluating transactions based on blobs size. It checks if a transaction supports blobs, and if + * so, checks that there is enough remaining data gas in the block to fit the blobs of the tx. + */ +public class BlobSizeTransactionSelector extends AbstractTransactionSelector { + private static final Logger LOG = LoggerFactory.getLogger(BlobSizeTransactionSelector.class); + + public BlobSizeTransactionSelector(final BlockSelectionContext context) { + super(context); + } + + /** + * Evaluates a transaction considering other transactions in the same block. If the tx does not + * support blobs, no check is performed, and SELECTED is returned, otherwise SELECTED is returned + * only if there is enough remaining blob gas to fit the blobs of the tx, otherwise a specific not + * selected result is returned, depending on the fact that the block already contains the max + * number of blobs or not. + * + * @param evaluationContext The current selection session data. + * @param transactionSelectionResults The results of other transaction evaluations in the same + * block. + * @return The result of the transaction selection. + */ + @Override + public TransactionSelectionResult evaluateTransactionPreProcessing( + final TransactionEvaluationContext evaluationContext, + final TransactionSelectionResults transactionSelectionResults) { + + final var tx = evaluationContext.getTransaction(); + if (tx.getType().supportsBlob()) { + + final var remainingBlobGas = + context.gasLimitCalculator().currentBlobGasLimit() + - transactionSelectionResults.getCumulativeBlobGasUsed(); + + if (remainingBlobGas == 0) { + LOG.atTrace() + .setMessage("The block already contains the max number of allowed blobs") + .addArgument(evaluationContext.getPendingTransaction()::toTraceLog) + .log(); + return TransactionSelectionResult.BLOBS_FULL; + } + + final long requestedBlobGas = context.gasCalculator().blobGasCost(tx.getBlobCount()); + + if (requestedBlobGas > remainingBlobGas) { + LOG.atTrace() + .setMessage( + "There is not enough blob gas available to fit the blobs of the transaction {} in the block." + + " Available {} / Requested {}") + .addArgument(evaluationContext.getPendingTransaction()::toTraceLog) + .addArgument(remainingBlobGas) + .addArgument(requestedBlobGas) + .log(); + return TransactionSelectionResult.TX_TOO_LARGE_FOR_REMAINING_BLOB_GAS; + } + } + return TransactionSelectionResult.SELECTED; + } + + @Override + public TransactionSelectionResult evaluateTransactionPostProcessing( + final TransactionEvaluationContext evaluationContext, + final TransactionSelectionResults blockTransactionResults, + final TransactionProcessingResult processingResult) { + // All necessary checks were done in the pre-processing method, so nothing to do here. + return TransactionSelectionResult.SELECTED; + } +} diff --git a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/BlockSizeTransactionSelector.java b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/BlockSizeTransactionSelector.java index 7f0b13e8b9..793f3e9384 100644 --- a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/BlockSizeTransactionSelector.java +++ b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/BlockSizeTransactionSelector.java @@ -89,15 +89,8 @@ public class BlockSizeTransactionSelector extends AbstractTransactionSelector { private boolean transactionTooLargeForBlock( final Transaction transaction, final TransactionSelectionResults transactionSelectionResults) { - final long blobGasUsed = context.gasCalculator().blobGasCost(transaction.getBlobCount()); - if (blobGasUsed - > context.gasLimitCalculator().currentBlobGasLimit() - - transactionSelectionResults.getCumulativeBlobGasUsed()) { - return true; - } - - return transaction.getGasLimit() + blobGasUsed + return transaction.getGasLimit() > context.processableBlockHeader().getGasLimit() - transactionSelectionResults.getCumulativeGasUsed(); } diff --git a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/BlobSizeTransactionSelectorTest.java b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/BlobSizeTransactionSelectorTest.java new file mode 100644 index 0000000000..f52a5dfb46 --- /dev/null +++ b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/BlobSizeTransactionSelectorTest.java @@ -0,0 +1,188 @@ +/* + * 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.blockcreation.txselection.selectors; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; +import static org.mockito.Answers.RETURNS_DEEP_STUBS; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; +import static org.mockito.Mockito.when; + +import org.hyperledger.besu.crypto.KeyPair; +import org.hyperledger.besu.crypto.SignatureAlgorithm; +import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; +import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.datatypes.Blob; +import org.hyperledger.besu.datatypes.BlobsWithCommitments; +import org.hyperledger.besu.datatypes.Hash; +import org.hyperledger.besu.datatypes.KZGCommitment; +import org.hyperledger.besu.datatypes.KZGProof; +import org.hyperledger.besu.datatypes.TransactionType; +import org.hyperledger.besu.datatypes.VersionedHash; +import org.hyperledger.besu.datatypes.Wei; +import org.hyperledger.besu.ethereum.blockcreation.txselection.BlockSelectionContext; +import org.hyperledger.besu.ethereum.blockcreation.txselection.TransactionEvaluationContext; +import org.hyperledger.besu.ethereum.blockcreation.txselection.TransactionSelectionResults; +import org.hyperledger.besu.ethereum.core.Transaction; +import org.hyperledger.besu.ethereum.core.TransactionTestFixture; +import org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction; +import org.hyperledger.besu.evm.gascalculator.CancunGasCalculator; +import org.hyperledger.besu.plugin.data.TransactionSelectionResult; + +import java.util.Optional; +import java.util.stream.IntStream; + +import com.google.common.base.Supplier; +import com.google.common.base.Suppliers; +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes48; +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 BlobSizeTransactionSelectorTest { + private static final Supplier SIGNATURE_ALGORITHM = + Suppliers.memoize(SignatureAlgorithmFactory::getInstance); + private static final KeyPair KEYS = SIGNATURE_ALGORITHM.get().generateKeyPair(); + + private static final long BLOB_GAS_PER_BLOB = CancunGasCalculator.BLOB_GAS_PER_BLOB; + private static final int MAX_BLOBS = 6; + private static final long MAX_BLOB_GAS = BLOB_GAS_PER_BLOB * MAX_BLOBS; + + @Mock(answer = RETURNS_DEEP_STUBS) + BlockSelectionContext blockSelectionContext; + + @Mock TransactionSelectionResults selectionResults; + + @Test + void notBlobTransactionsAreSelectedWithoutAnyCheck() { + final var selector = new BlobSizeTransactionSelector(blockSelectionContext); + + final var nonBlobTx = createEIP1559PendingTransaction(); + + final var txEvaluationContext = new TransactionEvaluationContext(nonBlobTx, null, null, null); + + final var result = + selector.evaluateTransactionPreProcessing(txEvaluationContext, selectionResults); + assertThat(result).isEqualTo(TransactionSelectionResult.SELECTED); + verifyNoInteractions(selectionResults); + } + + @Test + void firstBlobTransactionIsSelected() { + when(blockSelectionContext.gasLimitCalculator().currentBlobGasLimit()).thenReturn(MAX_BLOB_GAS); + when(blockSelectionContext.gasCalculator().blobGasCost(anyInt())) + .thenAnswer(iom -> BLOB_GAS_PER_BLOB * iom.getArgument(0, Integer.class)); + + final var selector = new BlobSizeTransactionSelector(blockSelectionContext); + + final var firstBlobTx = createBlobPendingTransaction(MAX_BLOBS); + + final var txEvaluationContext = new TransactionEvaluationContext(firstBlobTx, null, null, null); + + when(selectionResults.getCumulativeBlobGasUsed()).thenReturn(0L); + + final var result = + selector.evaluateTransactionPreProcessing(txEvaluationContext, selectionResults); + assertThat(result).isEqualTo(TransactionSelectionResult.SELECTED); + verify(selectionResults).getCumulativeBlobGasUsed(); + } + + @Test + void returnsBlobsFullWhenMaxNumberOfBlobsAlreadyPresent() { + when(blockSelectionContext.gasLimitCalculator().currentBlobGasLimit()).thenReturn(MAX_BLOB_GAS); + + final var selector = new BlobSizeTransactionSelector(blockSelectionContext); + + final var firstBlobTx = createBlobPendingTransaction(1); + + final var txEvaluationContext = new TransactionEvaluationContext(firstBlobTx, null, null, null); + + when(selectionResults.getCumulativeBlobGasUsed()).thenReturn(MAX_BLOB_GAS); + + final var result = + selector.evaluateTransactionPreProcessing(txEvaluationContext, selectionResults); + assertThat(result).isEqualTo(TransactionSelectionResult.BLOBS_FULL); + verify(selectionResults).getCumulativeBlobGasUsed(); + } + + @Test + void returnsTooLargeForRemainingBlobGas() { + when(blockSelectionContext.gasLimitCalculator().currentBlobGasLimit()).thenReturn(MAX_BLOB_GAS); + when(blockSelectionContext.gasCalculator().blobGasCost(anyInt())) + .thenAnswer(iom -> BLOB_GAS_PER_BLOB * iom.getArgument(0, Integer.class)); + + final var selector = new BlobSizeTransactionSelector(blockSelectionContext); + + final var firstBlobTx = createBlobPendingTransaction(MAX_BLOBS); + + final var txEvaluationContext = new TransactionEvaluationContext(firstBlobTx, null, null, null); + + when(selectionResults.getCumulativeBlobGasUsed()).thenReturn(MAX_BLOB_GAS - 1); + + final var result = + selector.evaluateTransactionPreProcessing(txEvaluationContext, selectionResults); + assertThat(result).isEqualTo(TransactionSelectionResult.TX_TOO_LARGE_FOR_REMAINING_BLOB_GAS); + verify(selectionResults).getCumulativeBlobGasUsed(); + } + + private PendingTransaction createEIP1559PendingTransaction() { + return PendingTransaction.newPendingTransaction( + createTransaction(TransactionType.EIP1559, 0), false, false); + } + + private PendingTransaction createBlobPendingTransaction(final int blobCount) { + return PendingTransaction.newPendingTransaction( + createTransaction(TransactionType.BLOB, blobCount), false, false); + } + + private Transaction createTransaction(final TransactionType type, final int blobCount) { + + var tx = + new TransactionTestFixture() + .to(Optional.of(Address.fromHexString("0x634316eA0EE79c701c6F67C53A4C54cBAfd2316d"))) + .nonce(0) + .type(type); + tx.maxFeePerGas(Optional.of(Wei.of(1000))).maxPriorityFeePerGas(Optional.of(Wei.of(100))); + if (type.supportsBlob()) { + if (blobCount > 0) { + tx.maxFeePerBlobGas(Optional.of(Wei.of(10))); + final var versionHashes = + IntStream.range(0, blobCount) + .mapToObj(i -> new VersionedHash((byte) 1, Hash.ZERO)) + .toList(); + final var kgzCommitments = + IntStream.range(0, blobCount) + .mapToObj(i -> new KZGCommitment(Bytes48.random())) + .toList(); + final var kzgProofs = + IntStream.range(0, blobCount).mapToObj(i -> new KZGProof(Bytes48.random())).toList(); + final var blobs = + IntStream.range(0, blobCount).mapToObj(i -> new Blob(Bytes.random(32 * 4096))).toList(); + tx.versionedHashes(Optional.of(versionHashes)); + final var blobsWithCommitments = + new BlobsWithCommitments(kgzCommitments, blobs, kzgProofs, versionHashes); + tx.blobsWithCommitments(Optional.of(blobsWithCommitments)); + } else { + fail("At least 1 blob is required for blob tx type"); + } + } + return tx.createTransaction(KEYS); + } +} diff --git a/plugin-api/build.gradle b/plugin-api/build.gradle index dff6cc9098..1ea78e7f3a 100644 --- a/plugin-api/build.gradle +++ b/plugin-api/build.gradle @@ -70,7 +70,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 = 'MOOKIka8Q1D64m0lU29Leq+zf1vcgeLoDVukBVQXhnY=' + knownHash = 'vWxI4pduLCvzqU73k5kJsoeK9t7QTqOBC9IxksFuzBs=' } check.dependsOn('checkAPIChanges') diff --git a/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/TransactionSelectionResult.java b/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/TransactionSelectionResult.java index 839c4120d0..b59fb26967 100644 --- a/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/TransactionSelectionResult.java +++ b/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/TransactionSelectionResult.java @@ -53,6 +53,7 @@ public class TransactionSelectionResult { private enum BaseStatus implements Status { SELECTED, BLOCK_FULL(true, false), + BLOBS_FULL(false, false), BLOCK_OCCUPANCY_ABOVE_THRESHOLD(true, false), BLOCK_SELECTION_TIMEOUT(true, false), TX_EVALUATION_TOO_LONG(true, true), @@ -96,6 +97,10 @@ public class TransactionSelectionResult { public static final TransactionSelectionResult BLOCK_FULL = new TransactionSelectionResult(BaseStatus.BLOCK_FULL); + /** The block already contains the max number of allowed blobs. */ + public static final TransactionSelectionResult BLOBS_FULL = + new TransactionSelectionResult(BaseStatus.BLOBS_FULL); + /** There was no more time to add transaction to the block */ public static final TransactionSelectionResult BLOCK_SELECTION_TIMEOUT = new TransactionSelectionResult(BaseStatus.BLOCK_SELECTION_TIMEOUT); @@ -118,6 +123,13 @@ public class TransactionSelectionResult { public static final TransactionSelectionResult TX_TOO_LARGE_FOR_REMAINING_GAS = TransactionSelectionResult.invalidTransient("TX_TOO_LARGE_FOR_REMAINING_GAS"); + /** + * The transaction has not been selected since there is not enough remaining blob gas in the block + * to fit the blobs of the tx, but selection should continue. + */ + public static final TransactionSelectionResult TX_TOO_LARGE_FOR_REMAINING_BLOB_GAS = + TransactionSelectionResult.invalidTransient("TX_TOO_LARGE_FOR_REMAINING_BLOB_GAS"); + /** * The transaction has not been selected since its current price is below the configured min * price, but the selection should continue. From d03c5b68c9715aaf46c5675df19e559b012db55d Mon Sep 17 00:00:00 2001 From: Sally MacFarlane Date: Wed, 17 Jul 2024 11:06:49 +1000 Subject: [PATCH 045/259] adjust text so it succeeds on macOS (#7328) Signed-off-by: Sally MacFarlane --- .../java/org/hyperledger/besu/tests/acceptance/LoggingTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/LoggingTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/LoggingTest.java index aab428eee7..8a231a775d 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/LoggingTest.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/LoggingTest.java @@ -33,6 +33,6 @@ public class LoggingTest extends AcceptanceTestBase { node.verify(net.awaitPeerCount(0)); - assertThat(cluster.getConsoleContents()).contains("| INFO |"); + assertThat(cluster.getConsoleContents()).contains("INFO"); } } From 76a3df704efa1d597976e20a91cb3b532f0f639f Mon Sep 17 00:00:00 2001 From: Sally MacFarlane Date: Wed, 17 Jul 2024 11:52:43 +1000 Subject: [PATCH 046/259] Refactor - replace uses of QbftContext with BftContext (#7333) * refactor to remove QbftContext Signed-off-by: Sally MacFarlane --------- Signed-off-by: Sally MacFarlane --- .../controller/QbftBesuControllerBuilder.java | 3 +- .../qbft/support/TestContextBuilder.java | 3 +- .../test/round/QbftRoundIntegrationTest.java | 4 +- .../besu/consensus/qbft/QbftContext.java | 38 ------------------- ...ockHeaderValidationRulesetFactoryTest.java | 4 +- .../qbft/QbftProtocolScheduleTest.java | 4 +- .../QbftValidatorsValidationRuleTest.java | 10 ++--- .../QbftBlockHeightManagerTest.java | 4 +- .../qbft/statemachine/QbftRoundTest.java | 4 +- .../ProposalPayloadValidatorTest.java | 4 +- .../validation/ProposalValidatorTest.java | 5 +-- .../RoundChangeMessageValidatorTest.java | 5 +-- 12 files changed, 23 insertions(+), 65 deletions(-) delete mode 100644 consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/QbftContext.java 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 4a5f592e23..795136ded5 100644 --- a/besu/src/main/java/org/hyperledger/besu/controller/QbftBesuControllerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/controller/QbftBesuControllerBuilder.java @@ -44,7 +44,6 @@ import org.hyperledger.besu.consensus.common.bft.statemachine.BftFinalState; import org.hyperledger.besu.consensus.common.bft.statemachine.FutureMessageBuffer; import org.hyperledger.besu.consensus.common.validator.ValidatorProvider; import org.hyperledger.besu.consensus.common.validator.blockbased.BlockValidatorProvider; -import org.hyperledger.besu.consensus.qbft.QbftContext; import org.hyperledger.besu.consensus.qbft.QbftExtraDataCodec; import org.hyperledger.besu.consensus.qbft.QbftForksSchedulesFactory; import org.hyperledger.besu.consensus.qbft.QbftGossip; @@ -388,7 +387,7 @@ public class QbftBesuControllerBuilder extends BftBesuControllerBuilder { new ForkingValidatorProvider( blockchain, qbftForksSchedule, blockValidatorProvider, transactionValidatorProvider); - return new QbftContext(validatorProvider, epochManager, bftBlockInterface().get()); + return new BftContext(validatorProvider, epochManager, bftBlockInterface().get()); } private BftValidatorOverrides convertBftForks(final List bftForks) { diff --git a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/TestContextBuilder.java b/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/TestContextBuilder.java index 48b6daad0a..5cf74f9458 100644 --- a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/TestContextBuilder.java +++ b/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/TestContextBuilder.java @@ -62,7 +62,6 @@ import org.hyperledger.besu.consensus.common.bft.statemachine.FutureMessageBuffe import org.hyperledger.besu.consensus.common.validator.ValidatorProvider; import org.hyperledger.besu.consensus.common.validator.blockbased.BlockValidatorProvider; import org.hyperledger.besu.consensus.qbft.MutableQbftConfigOptions; -import org.hyperledger.besu.consensus.qbft.QbftContext; import org.hyperledger.besu.consensus.qbft.QbftExtraDataCodec; import org.hyperledger.besu.consensus.qbft.QbftForksSchedulesFactory; import org.hyperledger.besu.consensus.qbft.QbftGossip; @@ -458,7 +457,7 @@ public class TestContextBuilder { new ProtocolContext( blockChain, worldStateArchive, - new QbftContext(validatorProvider, epochManager, blockInterface), + new BftContext(validatorProvider, epochManager, blockInterface), new BadBlockManager()); final TransactionPoolConfiguration poolConf = diff --git a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/test/round/QbftRoundIntegrationTest.java b/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/test/round/QbftRoundIntegrationTest.java index 52cdfa1ed0..7d57942655 100644 --- a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/test/round/QbftRoundIntegrationTest.java +++ b/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/test/round/QbftRoundIntegrationTest.java @@ -23,6 +23,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoInteractions; import static org.mockito.Mockito.when; +import org.hyperledger.besu.consensus.common.bft.BftContext; import org.hyperledger.besu.consensus.common.bft.BftExtraData; import org.hyperledger.besu.consensus.common.bft.BftExtraDataCodec; import org.hyperledger.besu.consensus.common.bft.BftProtocolSchedule; @@ -30,7 +31,6 @@ import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; import org.hyperledger.besu.consensus.common.bft.RoundTimer; import org.hyperledger.besu.consensus.common.bft.blockcreation.BftBlockCreator; import org.hyperledger.besu.consensus.common.bft.inttest.StubValidatorMulticaster; -import org.hyperledger.besu.consensus.qbft.QbftContext; import org.hyperledger.besu.consensus.qbft.QbftExtraDataCodec; import org.hyperledger.besu.consensus.qbft.network.QbftMessageTransmitter; import org.hyperledger.besu.consensus.qbft.payload.MessageFactory; @@ -129,7 +129,7 @@ public class QbftRoundIntegrationTest { blockChain, worldStateArchive, setupContextWithBftExtraDataEncoder( - QbftContext.class, emptyList(), qbftExtraDataEncoder), + BftContext.class, emptyList(), qbftExtraDataEncoder), new BadBlockManager()); } diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/QbftContext.java b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/QbftContext.java deleted file mode 100644 index 68e8b7f1af..0000000000 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/QbftContext.java +++ /dev/null @@ -1,38 +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.consensus.qbft; - -import org.hyperledger.besu.consensus.common.EpochManager; -import org.hyperledger.besu.consensus.common.bft.BftBlockInterface; -import org.hyperledger.besu.consensus.common.bft.BftContext; -import org.hyperledger.besu.consensus.common.validator.ValidatorProvider; - -/** The Qbft context. */ -public class QbftContext extends BftContext { - - /** - * Instantiates a new Qbft context. - * - * @param validatorProvider the validator provider - * @param epochManager the epoch manager - * @param blockInterface the block interface - */ - public QbftContext( - final ValidatorProvider validatorProvider, - final EpochManager epochManager, - final BftBlockInterface blockInterface) { - super(validatorProvider, epochManager, blockInterface); - } -} diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/QbftBlockHeaderValidationRulesetFactoryTest.java b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/QbftBlockHeaderValidationRulesetFactoryTest.java index 3a09295a99..4771cf91cb 100644 --- a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/QbftBlockHeaderValidationRulesetFactoryTest.java +++ b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/QbftBlockHeaderValidationRulesetFactoryTest.java @@ -19,6 +19,7 @@ import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.assertThat; import static org.hyperledger.besu.consensus.common.bft.BftContextBuilder.setupContextWithBftExtraDataEncoder; +import org.hyperledger.besu.consensus.common.bft.BftContext; import org.hyperledger.besu.cryptoservices.NodeKey; import org.hyperledger.besu.cryptoservices.NodeKeyUtils; import org.hyperledger.besu.datatypes.Address; @@ -45,8 +46,7 @@ public class QbftBlockHeaderValidationRulesetFactoryTest { return new ProtocolContext( null, null, - setupContextWithBftExtraDataEncoder( - QbftContext.class, validators, new QbftExtraDataCodec()), + setupContextWithBftExtraDataEncoder(BftContext.class, validators, new QbftExtraDataCodec()), new BadBlockManager()); } diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/QbftProtocolScheduleTest.java b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/QbftProtocolScheduleTest.java index bdcea4e692..07b3be34b4 100644 --- a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/QbftProtocolScheduleTest.java +++ b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/QbftProtocolScheduleTest.java @@ -26,6 +26,7 @@ import org.hyperledger.besu.config.JsonUtil; import org.hyperledger.besu.config.QbftConfigOptions; import org.hyperledger.besu.consensus.common.ForkSpec; import org.hyperledger.besu.consensus.common.ForksSchedule; +import org.hyperledger.besu.consensus.common.bft.BftContext; import org.hyperledger.besu.consensus.common.bft.BftExtraDataCodec; import org.hyperledger.besu.consensus.common.bft.BftProtocolSchedule; import org.hyperledger.besu.cryptoservices.NodeKey; @@ -58,8 +59,7 @@ public class QbftProtocolScheduleTest { return new ProtocolContext( null, null, - setupContextWithBftExtraDataEncoder( - QbftContext.class, validators, new QbftExtraDataCodec()), + setupContextWithBftExtraDataEncoder(BftContext.class, validators, new QbftExtraDataCodec()), new BadBlockManager()); } diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/QbftValidatorsValidationRuleTest.java b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/QbftValidatorsValidationRuleTest.java index 3e325142c4..28ec8fc3a3 100644 --- a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/QbftValidatorsValidationRuleTest.java +++ b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/QbftValidatorsValidationRuleTest.java @@ -19,9 +19,9 @@ import static org.hyperledger.besu.consensus.common.bft.BftContextBuilder.setupC import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import org.hyperledger.besu.consensus.common.bft.BftContext; import org.hyperledger.besu.consensus.common.bft.BftExtraData; import org.hyperledger.besu.consensus.common.bft.Vote; -import org.hyperledger.besu.consensus.qbft.QbftContext; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.chain.BadBlockManager; @@ -47,7 +47,7 @@ public class QbftValidatorsValidationRuleTest { new ProtocolContext( null, null, - setupContextWithBftExtraData(QbftContext.class, Collections.emptyList(), bftExtraData), + setupContextWithBftExtraData(BftContext.class, Collections.emptyList(), bftExtraData), new BadBlockManager()); when(bftExtraData.getValidators()).thenReturn(Collections.emptyList()); when(bftExtraData.getVote()).thenReturn(Optional.empty()); @@ -66,7 +66,7 @@ public class QbftValidatorsValidationRuleTest { new ProtocolContext( null, null, - setupContextWithBftExtraData(QbftContext.class, validators, bftExtraData), + setupContextWithBftExtraData(BftContext.class, validators, bftExtraData), new BadBlockManager()); when(bftExtraData.getValidators()).thenReturn(validators); assertThat(qbftValidatorsValidationRule.validate(blockHeader, null, context)).isTrue(); @@ -84,7 +84,7 @@ public class QbftValidatorsValidationRuleTest { new ProtocolContext( null, null, - setupContextWithBftExtraData(QbftContext.class, validators, bftExtraData), + setupContextWithBftExtraData(BftContext.class, validators, bftExtraData), new BadBlockManager()); when(bftExtraData.getValidators()).thenReturn(validators); assertThat(qbftValidatorsValidationRule.validate(blockHeader, null, context)).isFalse(); @@ -98,7 +98,7 @@ public class QbftValidatorsValidationRuleTest { new ProtocolContext( null, null, - setupContextWithBftExtraData(QbftContext.class, Collections.emptyList(), bftExtraData), + setupContextWithBftExtraData(BftContext.class, Collections.emptyList(), bftExtraData), new BadBlockManager()); when(bftExtraData.getValidators()).thenReturn(Collections.emptyList()); when(bftExtraData.getVote()).thenReturn(Optional.of(mock(Vote.class))); diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftBlockHeightManagerTest.java b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftBlockHeightManagerTest.java index a047986084..0aa1f7843b 100644 --- a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftBlockHeightManagerTest.java +++ b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftBlockHeightManagerTest.java @@ -32,6 +32,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import org.hyperledger.besu.config.StubGenesisConfigOptions; +import org.hyperledger.besu.consensus.common.bft.BftContext; import org.hyperledger.besu.consensus.common.bft.BftExtraData; import org.hyperledger.besu.consensus.common.bft.BftExtraDataCodec; import org.hyperledger.besu.consensus.common.bft.BftProtocolSchedule; @@ -42,7 +43,6 @@ import org.hyperledger.besu.consensus.common.bft.blockcreation.BftBlockCreator; import org.hyperledger.besu.consensus.common.bft.events.RoundExpiry; import org.hyperledger.besu.consensus.common.bft.network.ValidatorMulticaster; import org.hyperledger.besu.consensus.common.bft.statemachine.BftFinalState; -import org.hyperledger.besu.consensus.qbft.QbftContext; import org.hyperledger.besu.consensus.qbft.QbftExtraDataCodec; import org.hyperledger.besu.consensus.qbft.messagedata.RoundChangeMessageData; import org.hyperledger.besu.consensus.qbft.messagewrappers.Commit; @@ -172,7 +172,7 @@ public class QbftBlockHeightManagerTest { blockchain, null, setupContextWithBftExtraDataEncoder( - QbftContext.class, validators, new QbftExtraDataCodec()), + BftContext.class, validators, new QbftExtraDataCodec()), new BadBlockManager()); final ProtocolScheduleBuilder protocolScheduleBuilder = diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftRoundTest.java b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftRoundTest.java index 838ec71e0d..92e7131476 100644 --- a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftRoundTest.java +++ b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftRoundTest.java @@ -30,6 +30,7 @@ import static org.mockito.Mockito.verifyNoInteractions; import static org.mockito.Mockito.when; import org.hyperledger.besu.consensus.common.bft.BftBlockHashing; +import org.hyperledger.besu.consensus.common.bft.BftContext; import org.hyperledger.besu.consensus.common.bft.BftExtraData; import org.hyperledger.besu.consensus.common.bft.BftExtraDataCodec; import org.hyperledger.besu.consensus.common.bft.BftProtocolSchedule; @@ -37,7 +38,6 @@ import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; import org.hyperledger.besu.consensus.common.bft.RoundTimer; import org.hyperledger.besu.consensus.common.bft.blockcreation.BftBlockCreator; import org.hyperledger.besu.consensus.common.bft.payload.SignedData; -import org.hyperledger.besu.consensus.qbft.QbftContext; import org.hyperledger.besu.consensus.qbft.QbftExtraDataCodec; import org.hyperledger.besu.consensus.qbft.messagewrappers.RoundChange; import org.hyperledger.besu.consensus.qbft.network.QbftMessageTransmitter; @@ -123,7 +123,7 @@ public class QbftRoundTest { blockChain, worldStateArchive, setupContextWithBftExtraDataEncoder( - QbftContext.class, emptyList(), new QbftExtraDataCodec()), + BftContext.class, emptyList(), new QbftExtraDataCodec()), new BadBlockManager()); when(messageValidator.validateProposal(any())).thenReturn(true); diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/validation/ProposalPayloadValidatorTest.java b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/validation/ProposalPayloadValidatorTest.java index 9c9422e108..09e9455d89 100644 --- a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/validation/ProposalPayloadValidatorTest.java +++ b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/validation/ProposalPayloadValidatorTest.java @@ -21,10 +21,10 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; +import org.hyperledger.besu.consensus.common.bft.BftContext; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundHelpers; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; import org.hyperledger.besu.consensus.common.bft.ProposedBlockHelpers; -import org.hyperledger.besu.consensus.qbft.QbftContext; import org.hyperledger.besu.consensus.qbft.QbftExtraDataCodec; import org.hyperledger.besu.consensus.qbft.messagewrappers.Proposal; import org.hyperledger.besu.consensus.qbft.payload.MessageFactory; @@ -74,7 +74,7 @@ public class ProposalPayloadValidatorTest { new ProtocolContext( blockChain, worldStateArchive, - setupContextWithBftExtraDataEncoder(QbftContext.class, emptyList(), bftExtraDataCodec), + setupContextWithBftExtraDataEncoder(BftContext.class, emptyList(), bftExtraDataCodec), new BadBlockManager()); } diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/validation/ProposalValidatorTest.java b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/validation/ProposalValidatorTest.java index c28588a9d5..43afff3501 100644 --- a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/validation/ProposalValidatorTest.java +++ b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/validation/ProposalValidatorTest.java @@ -24,13 +24,13 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.when; +import org.hyperledger.besu.consensus.common.bft.BftContext; import org.hyperledger.besu.consensus.common.bft.BftHelpers; import org.hyperledger.besu.consensus.common.bft.BftProtocolSchedule; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundHelpers; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; import org.hyperledger.besu.consensus.common.bft.ProposedBlockHelpers; import org.hyperledger.besu.consensus.common.bft.payload.SignedData; -import org.hyperledger.besu.consensus.qbft.QbftContext; import org.hyperledger.besu.consensus.qbft.QbftExtraDataCodec; import org.hyperledger.besu.consensus.qbft.messagewrappers.Prepare; import org.hyperledger.besu.consensus.qbft.messagewrappers.Proposal; @@ -102,8 +102,7 @@ public class ProposalValidatorTest { new ProtocolContext( blockChain, worldStateArchive, - setupContextWithBftExtraDataEncoder( - QbftContext.class, emptyList(), bftExtraDataEncoder), + setupContextWithBftExtraDataEncoder(BftContext.class, emptyList(), bftExtraDataEncoder), new BadBlockManager()); // typically tests require the blockValidation to be successful diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/validation/RoundChangeMessageValidatorTest.java b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/validation/RoundChangeMessageValidatorTest.java index b11f2dafc1..82e8fb5c7a 100644 --- a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/validation/RoundChangeMessageValidatorTest.java +++ b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/validation/RoundChangeMessageValidatorTest.java @@ -24,13 +24,13 @@ import static org.mockito.Mockito.any; import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.when; +import org.hyperledger.besu.consensus.common.bft.BftContext; import org.hyperledger.besu.consensus.common.bft.BftHelpers; import org.hyperledger.besu.consensus.common.bft.BftProtocolSchedule; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundHelpers; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; import org.hyperledger.besu.consensus.common.bft.ProposedBlockHelpers; import org.hyperledger.besu.consensus.common.bft.payload.SignedData; -import org.hyperledger.besu.consensus.qbft.QbftContext; import org.hyperledger.besu.consensus.qbft.QbftExtraDataCodec; import org.hyperledger.besu.consensus.qbft.messagewrappers.RoundChange; import org.hyperledger.besu.consensus.qbft.payload.PreparedRoundMetadata; @@ -84,8 +84,7 @@ public class RoundChangeMessageValidatorTest { new ProtocolContext( blockChain, worldStateArchive, - setupContextWithBftExtraDataEncoder( - QbftContext.class, emptyList(), bftExtraDataEncoder), + setupContextWithBftExtraDataEncoder(BftContext.class, emptyList(), bftExtraDataEncoder), new BadBlockManager()); lenient().when(protocolSchedule.getByBlockHeader(any())).thenReturn(protocolSpec); From 895c17d5d2ae140b0d85a6783c9b9f58275b1309 Mon Sep 17 00:00:00 2001 From: daniellehrner Date: Wed, 17 Jul 2024 21:00:48 +0200 Subject: [PATCH 047/259] EIP 7702 (#7237) * EIP 7702 first draft Signed-off-by: Daniel Lehrner * added CHANGELOG.md entry Signed-off-by: Daniel Lehrner * bug fixes, added first tests Signed-off-by: Daniel Lehrner * container verify GitHub workflow (#7239) Container verification step in release process automated with the container verify GitHub workflow. New workflow is triggered at the end of the release workflow which will check the release container images starts successfully. Verification test only checks container starts and reach the Ethereum main loop Signed-off-by: Chaminda Divitotawela Signed-off-by: Daniel Lehrner * Investigate chain halts when syncing (#7162) Fix some reasons for chain download halts when syncing Signed-off-by: stefan.pingel@consensys.net Signed-off-by: Stefan Pingel <16143240+pinges@users.noreply.github.com> Co-authored-by: Sally MacFarlane Signed-off-by: Daniel Lehrner * Check for EOFCreate subcontainer rules (#7232) Check and test for the unused container rule, and only returncontract targets can have truncated data rule. Also test the other subcontainer rules in unit tests. Signed-off-by: Danno Ferrin Signed-off-by: Daniel Lehrner * Remove deprecation message for `--Xp2p-peer-lower-bound` (#7247) Signed-off-by: Gabriel-Trintinalia Signed-off-by: Daniel Lehrner * less invasive code injection approach Signed-off-by: Daniel Lehrner * added missing java doc & fixed test Signed-off-by: Daniel Lehrner * added (currently non-working) acceptance test, some bug fixes in the transaction validation and tx pool logic Signed-off-by: Daniel Lehrner * fix spotless Signed-off-by: Daniel Lehrner * updated acceptance test, still not working, newPayload request seems to be necessary before final fork choice update Signed-off-by: Daniel Lehrner * use correct world state to inject temporary code, inject code in existing accounts as well Signed-off-by: Daniel Lehrner * renamed test service to prague, because the engine versions used are only available in the prague hard fork Signed-off-by: Daniel Lehrner * fixed acceptance test, some bug fixes if authorized account does not yet exist Signed-off-by: Daniel Lehrner * Add build version option to prefix git hash with custom version property (#7222) * Add build version option to prefix git hash with custom version property * Refactor to make appending the git hash a boolean property. Include a commented-out example of how to use the properties in the gradle file Signed-off-by: Matthew Whitehead Signed-off-by: Daniel Lehrner * Handle invalid snap getTrieNode requests with empty paths gracefully (#7221) Signed-off-by: Jason Frame Co-authored-by: Sally MacFarlane Signed-off-by: Daniel Lehrner * fix typos in CHANGELOG (#7226) Signed-off-by: Ties <71668189+TiesD@users.noreply.github.com> Co-authored-by: Matt Nelson <85905982+non-fungible-nelson@users.noreply.github.com> Co-authored-by: Sally MacFarlane Signed-off-by: Daniel Lehrner * feat: Add network option for LUKSO Mainnet (#7223) * Add option for LUKSO network Signed-off-by: Wolmin * Add tests for LUKSO Signed-off-by: Wolmin * Apply spotless Signed-off-by: Wolmin * Add changelog entry Signed-off-by: Wolmin * Fix duplicate func Signed-off-by: Wolmin * Fix changelog Signed-off-by: Wolmin * Add bootnodes to genesis Signed-off-by: Wolmin --------- Signed-off-by: Wolmin Signed-off-by: Wolmin <44748271+Wolmin@users.noreply.github.com> Signed-off-by: Daniel Lehrner * Update Docker base image to Ubuntu 24.04 (#7251) Signed-off-by: Fabio Di Fabio Signed-off-by: Daniel Lehrner * Reconfigure how Protocol Specs are created WRT EVM condiguration (#7245) Make the max code size and max initcode size a part of the EVM configuration. As part of the change we need to move the tasks CodeFactory once handled as a static class and move it into the EVM. This has a nice follow on effect that we don't need to pass in max EOF versions or max code sizes anymore. Signed-off-by: Danno Ferrin Signed-off-by: Daniel Lehrner * Fix the wrong 'Identifier' and 'Synchronizer' usage (#7252) * fix the synchronizer usage Signed-off-by: Leni * fix Identifier usage Signed-off-by: Leni --------- Signed-off-by: Leni Co-authored-by: Sally MacFarlane Signed-off-by: Daniel Lehrner * Fix flaky SECP256R1 test (#7249) Signed-off-by: Daniel Lehrner Co-authored-by: Sally MacFarlane Signed-off-by: Daniel Lehrner * update to work with the new max retries value (#7253) Signed-off-by: Justin Florentine Co-authored-by: Sally MacFarlane Signed-off-by: Daniel Lehrner * Temporary CancunEOF fork for EOF testing. (#7227) Add Genesis ("CancunEOFTime") and reference test ("CancunEOF") support for a temporary Cancun+EOF fork, in anticipation of potential devnets. Signed-off-by: Danno Ferrin Signed-off-by: Daniel Lehrner * fixed bug introduced through merge of main, made acceptance test easier to understand Signed-off-by: Daniel Lehrner * added missing java docs Signed-off-by: Daniel Lehrner * removed unnecessary tag Signed-off-by: Daniel Lehrner * make encodeSingleSetCode public again Signed-off-by: Daniel Lehrner * Snapserver responses to return at least one response (#7190) Signed-off-by: Jason Frame Signed-off-by: Daniel Lehrner * copy setCodeTransactionPayloads as well Signed-off-by: Daniel Lehrner * fixed bug during tests with forrest db Signed-off-by: Daniel Lehrner * Snapserver GetTrieNodes request to handle short hash for storage (#7264) Signed-off-by: Jason Frame Signed-off-by: Daniel Lehrner * javadoc: Adding javadoc for ethstats module (#7269) * javadoc: Adding javadoc for ethstats module --------- Signed-off-by: Usman Saleem Signed-off-by: Daniel Lehrner * Fix javadoc for ethereum:core top level package (#7270) * javadoc - Apply javadoc to ethereum core top level package --------- Signed-off-by: Usman Saleem Signed-off-by: Daniel Lehrner * Disable Flaky tests - permissioning (#7256) * disable some flaky tests Signed-off-by: Sally MacFarlane * correct name for test Signed-off-by: Sally MacFarlane * formatting Signed-off-by: Sally MacFarlane * disable some flaky tests Signed-off-by: Sally MacFarlane --------- Signed-off-by: Sally MacFarlane Co-authored-by: Usman Saleem Signed-off-by: Daniel Lehrner * Add bootnodes to the maintained peer list (#7257) * Add bootnodes to the maintained peer list Signed-off-by: Matthew Whitehead * Update unit tests Signed-off-by: Matthew Whitehead * Add entry in changelog Signed-off-by: Matthew Whitehead * Tweak unit test Signed-off-by: Matthew Whitehead * Refactor to keep common steps the same for both cases Signed-off-by: Matthew Whitehead * Add debug log, call sanitizePeers() only once Signed-off-by: Matthew Whitehead --------- Signed-off-by: Matthew Whitehead Signed-off-by: Daniel Lehrner * Fix javadoc for ethereum api module, graphql package (#7272) * javadoc - Adding missing javadocs ethereum:api graphql package Signed-off-by: Usman Saleem Signed-off-by: Daniel Lehrner * T8n support for isStateTest and empty accounts (#7275) Update t8n executor to support new isStateTest env flag that will disable extra-transactional processing such as block rewards and beacon root. Also, make sure such extra-transactional commits don't create empty accounts. Signed-off-by: Danno Ferrin Co-authored-by: Usman Saleem Signed-off-by: Daniel Lehrner * Promote storage x-trie-log subcommand to trie-log (#7278) Signed-off-by: Simon Dudley Signed-off-by: Daniel Lehrner * Evm tool readme update (#7274) * update paths to binary. update docker build to use java 21 * updated suggested jdk --------- Signed-off-by: Justin Florentine Signed-off-by: Daniel Lehrner * javadoc - Add missing javadoc for evmtool module (#7277) Signed-off-by: Usman Saleem Signed-off-by: Daniel Lehrner * Rename ValidatorPublicKey to ValidatorPubKey (#7280) Adapt to EIP-7002 name change for validator public key in all places. Signed-off-by: Danno Ferrin Signed-off-by: Daniel Lehrner * Add info-level diagnostic logs to aid with resolving stalled BFT chains (#7271) * Add info-level diagnostic logs to aid with resolving stalled BFT chains Signed-off-by: Matthew Whitehead * Add javadoc Signed-off-by: Matthew Whitehead --------- Signed-off-by: Matthew Whitehead Signed-off-by: Matt Whitehead Signed-off-by: Daniel Lehrner * Update EIP-2935 contract (#7281) Use the updated contract and address for EIP-2539. Signed-off-by: Danno Ferrin Signed-off-by: Daniel Lehrner * add evmtool compability, fixing bugs related to sender recovery of 7702 txs and handling authorizations to empty accounts Signed-off-by: Daniel Lehrner * Deeper tracing of self-destructed accounts (#7284) Consider previously self-destructed accounts when creating accounts. Signed-off-by: Danno Ferrin Signed-off-by: Daniel Lehrner * next release version after 24.7.0 (#7285) Signed-off-by: garyschulte Signed-off-by: Daniel Lehrner * Add experimental `--Xsnapsync-bft-enabled` which enables snap sync for BFT chains (#7140) * Create a BFT-specific pivot block handler Signed-off-by: Matthew Whitehead * Change visibility Signed-off-by: Matthew Whitehead * Refactor sync-peer-count internal variable to match name, add experimental flag to enabled snap + BFT Signed-off-by: Matthew Whitehead * Merge with main Signed-off-by: Matthew Whitehead * Fix uppercase Signed-off-by: Matthew Whitehead * Address synchronization issue with trie pruning. Create BFT-specific account range handler. Add pipeline name and logs Signed-off-by: Matthew Whitehead * Remove debug log Signed-off-by: Matthew Whitehead * fixing snapsync for empty state Signed-off-by: Karim Taam * Don't queue up events we can't handle Signed-off-by: Matthew Whitehead * Fix timing window where a validator with an empty data dir sometimes falls back to full sync if peer status isn't received quickly enough Signed-off-by: Matthew Whitehead * Remove BFT-specific account request class. Not needed Signed-off-by: Matthew Whitehead * Refactor some more 'fast' sync variables that are common to all pivot-based sync types Signed-off-by: Matthew Whitehead * In FULL sync mode, disable bonsai-limit-trie-logs-enabled instead of failing to start Signed-off-by: Matthew Whitehead * Add javadoc comments, clarify overriding bonsai-limit-trie-logs-enabled Signed-off-by: Matthew Whitehead * Add BFT pivot block selector tests Signed-off-by: Matthew Whitehead * Fix failure error message Signed-off-by: Matthew Whitehead * Remove the unnamed Pipe constructor and update tests to set a pipe name Signed-off-by: Matthew Whitehead * Revert some info logs back to debug given the feedback on noise in the logs syncing with holesky Signed-off-by: Matthew Whitehead * Refactor fastSyncPivotDistance to syncPivotDistance Signed-off-by: Matthew Whitehead * Incomplete refactoring Signed-off-by: Matthew Whitehead * Update BFT event queueing tests Signed-off-by: Matthew Whitehead * Event queue test fixes Signed-off-by: Matthew Whitehead * Remove automatic setting of bonsai-limit-trie-logs-enabled to false if sync-mode = FULL (moving to another PR) Signed-off-by: Matthew Whitehead --------- Signed-off-by: Matthew Whitehead Signed-off-by: Karim Taam Signed-off-by: Matt Whitehead Co-authored-by: Karim Taam Signed-off-by: Daniel Lehrner * Turn off CicleCI for Besu (#7291) All the CI jobs run in GitHub actions and Circle CI it no longer needed in Besu project Signed-off-by: Chaminda Divitotawela Signed-off-by: Daniel Lehrner * Check for snap server (#6609) * EthPeer add isServingSnap to be able to make sure that we have enough snap servers connected when we are snap syncing Signed-off-by: stefan.pingel@consensys.net Signed-off-by: Sally MacFarlane Co-authored-by: Sally MacFarlane Signed-off-by: Daniel Lehrner * Implement System Calls (#7263) Signed-off-by: Gabriel-Trintinalia Signed-off-by: Daniel Lehrner * wrap WorldUpdater inside a WorldUpdaterService to inject the authorized code whenever needed Signed-off-by: Daniel Lehrner * Update limit trie logs validation message for sync-mode=FULL (#7279) Signed-off-by: Simon Dudley Co-authored-by: Sally MacFarlane Signed-off-by: Daniel Lehrner * Execute requests before block persist (#7295) Signed-off-by: Gabriel-Trintinalia Signed-off-by: Daniel Lehrner * fixed MainnetTransactionProcessor retrieval of correctn `to` account with injected code, fixed code injection Signed-off-by: Daniel Lehrner * only first authorization is accepted, all the following ones are ignored Signed-off-by: Daniel Lehrner * don't cache account with empty code Signed-off-by: Daniel Lehrner * revert wrapping of world updater, as its `updater()` method creates a type of nesting that is not compatible with wrapping it. Instead a service is injected in the world updater to inject the code into the authorized accounts Signed-off-by: Daniel Lehrner * Fixed outdated tech redirect link. (#7297) * fix wiki link Signed-off-by: Snazzy * fix format Signed-off-by: Snazzy * change knownHash Signed-off-by: Snazzy --------- Signed-off-by: Snazzy Signed-off-by: Daniel Lehrner * Increment private nonce even if transaction failed. (#6593) Increment private nonce even if transaction failed Signed-off-by: George Tebrean Signed-off-by: stefan.pingel@consensys.net Co-authored-by: stefan.pingel@consensys.net Co-authored-by: Stefan Pingel <16143240+pinges@users.noreply.github.com> Signed-off-by: Daniel Lehrner * feat: Enhance --profile to load external profiles (#7292) * feat: --profile can load external profiles * fix external profile name method * fix ProfilesCompletionCandidate * test: Add unit tests * changelog: Update changelog * test: Fix TomlConfigurationDefaultProviderTest * test: Fix BesuCommandTest --------- Signed-off-by: Usman Saleem Signed-off-by: Daniel Lehrner * Fix status badge for documentation (#7304) Documentation has been moved to GitHub pages and no longer use readthedocs. Updated the README status badge for docs with correct link Signed-off-by: Chaminda Divitotawela Signed-off-by: Daniel Lehrner * [MINOR] Fixed some typos (#7299) * typos Signed-off-by: Sally MacFarlane --------- Signed-off-by: Sally MacFarlane Signed-off-by: Daniel Lehrner * refactored to share one AuthorizedAccountService between the different instances of the world updater, renamed some classes Signed-off-by: Daniel Lehrner * spotless Signed-off-by: Daniel Lehrner * load code for authorization at the beginning of the transaction Signed-off-by: Daniel Lehrner * ignore authorization if chain id doesn't match Signed-off-by: Daniel Lehrner * cache authority address, evmtool: do not fail if sender address is wrong Signed-off-by: Daniel Lehrner * Add evmtool block-test subcommand (#7293) * Add evmtool block-test subcommand Add an evmtool subcommand that will run non-hive blockchain tests. Signed-off-by: Danno Ferrin Signed-off-by: Daniel Lehrner * Make the retrying snap tasks switching (#7307) * make snap tasks switching Signed-off-by: stefan.pingel@consensys.net Signed-off-by: Daniel Lehrner * 6612: Remove deprecated sync modes and related helper methods (#7309) * 6612: Remove deprecated sync modes and related helper methods Signed-off-by: Matilda-Clerke Signed-off-by: Daniel Lehrner * EOF Reference Test Fixes (#7306) Fix a number of issues found in reference tests and evmone tests. - Be tolerant of more nulls in json - Support ContainerKind in reference tests - re-order EXTCALL oeprands - correct return value for REVERT in EXT*CALL - re-order EOFCREATE code validation Signed-off-by: Danno Ferrin Signed-off-by: Daniel Lehrner * test template refactor, bump besu-native to 0.9.2 (#7315) Signed-off-by: garyschulte Signed-off-by: Daniel Lehrner * Feature/use gnark-crypto for eip-2537 (#7316) * use gnark-crypto for bls precompiles Signed-off-by: garyschulte Signed-off-by: Daniel Lehrner * 6612 update changelog with removed syncmodes (#7320) * 6612: Update changelog with removal of deprecated sync modes Signed-off-by: Matilda Clerke * 6612: Update changelog with removal of deprecated sync modes Signed-off-by: Matilda Clerke * 6612: Update changelog with removal of deprecated sync modes Signed-off-by: Matilda Clerke --------- Signed-off-by: Matilda Clerke Signed-off-by: Daniel Lehrner * Update datacopy (#7319) Check for OOG earlier in DataCopy. Add unit tests to cover operation branches. Signed-off-by: Danno Ferrin Signed-off-by: Daniel Lehrner * disable flaky test (#7308) * disable flaky test Signed-off-by: Sally MacFarlane * disable flaky test Signed-off-by: Sally MacFarlane --------- Signed-off-by: Sally MacFarlane Signed-off-by: Daniel Lehrner * Update unit test (#7317) * Update parameterized unit tests so the enumerate with --dry-run * Update the prague-withdrawal.json unit test to handle current code Signed-off-by: Danno Ferrin Co-authored-by: Sally MacFarlane Signed-off-by: Daniel Lehrner * persist accounts that have storage updates, but no nonce, balance nor code Signed-off-by: Daniel Lehrner * Revert "persist accounts that have storage updates, but no nonce, balance nor code" This reverts commit 9c9121a115ecb09f1c3add1fff4da3b102f8b429. Signed-off-by: Daniel Lehrner * removed PKI backed QBFT (#7310) * removed PKI backed QBFT Signed-off-by: Sally MacFarlane * changelog Signed-off-by: Sally MacFarlane --------- Signed-off-by: Sally MacFarlane Signed-off-by: Daniel Lehrner * EIP-7251 add consolidation request type (#7266) * add request type for consolidations, encoder, decoder and tests * added raw tx for consolidation * add consolidation reqs to EngineGetPayloadResultV4 * set storage slot value to 0 initially and value for tx * updates plugin api Signed-off-by: Justin Florentine Signed-off-by: Sally MacFarlane --------- Signed-off-by: Sally MacFarlane Signed-off-by: Justin Florentine Co-authored-by: Justin Florentine Signed-off-by: Daniel Lehrner * fix: `eth_call` deserialization to correctly ignore unknown fields in the transaction object (#7323) * fix: Use Builder for JsonCallParameter * changelog * add additional unit tests * fix: Update builder to withGas to match the json eth_call --------- Signed-off-by: Usman Saleem Signed-off-by: Daniel Lehrner * Stop transaction selection on TX_EVALUATION_TOO_LONG (#7330) Signed-off-by: Fabio Di Fabio Signed-off-by: Daniel Lehrner * message frame buider will create AuthorizedCodeService by itsef if it isn't set Signed-off-by: Daniel Lehrner * get correct nonce for authorization Signed-off-by: Daniel Lehrner * nonce only returns a vaid nonce, new method nonceList returns all the nonces Signed-off-by: Daniel Lehrner * plugs leaky abstraction Signed-off-by: Justin Florentine * some renaming, acceptance tests checks for exact balance of tx sponsor at the end. Signed-off-by: Daniel Lehrner * inject the 7702 code into DiffBasedWorldStateUpdateAccumulator.createAccount Signed-off-by: Daniel Lehrner * spotless Signed-off-by: Justin Florentine * spotless fix, removed todos Signed-off-by: Daniel Lehrner * make AuthorityProcessor & chain id for it optional Signed-off-by: Daniel Lehrner --------- Signed-off-by: Daniel Lehrner Signed-off-by: Chaminda Divitotawela Signed-off-by: stefan.pingel@consensys.net Signed-off-by: Stefan Pingel <16143240+pinges@users.noreply.github.com> Signed-off-by: Danno Ferrin Signed-off-by: Gabriel-Trintinalia Signed-off-by: Matthew Whitehead Signed-off-by: Jason Frame Signed-off-by: Ties <71668189+TiesD@users.noreply.github.com> Signed-off-by: Wolmin Signed-off-by: Wolmin <44748271+Wolmin@users.noreply.github.com> Signed-off-by: Fabio Di Fabio Signed-off-by: Leni Signed-off-by: Justin Florentine Signed-off-by: Usman Saleem Signed-off-by: Sally MacFarlane Signed-off-by: Simon Dudley Signed-off-by: Matt Whitehead Signed-off-by: garyschulte Signed-off-by: Karim Taam Signed-off-by: Snazzy Signed-off-by: George Tebrean Signed-off-by: Matilda-Clerke Signed-off-by: Matilda Clerke Co-authored-by: Chaminda Divitotawela Co-authored-by: Stefan Pingel <16143240+pinges@users.noreply.github.com> Co-authored-by: Sally MacFarlane Co-authored-by: Danno Ferrin Co-authored-by: Gabriel-Trintinalia Co-authored-by: Matt Whitehead Co-authored-by: Jason Frame Co-authored-by: Ties <71668189+TiesD@users.noreply.github.com> Co-authored-by: Matt Nelson <85905982+non-fungible-nelson@users.noreply.github.com> Co-authored-by: Wolmin <44748271+Wolmin@users.noreply.github.com> Co-authored-by: Fabio Di Fabio Co-authored-by: leniram159 Co-authored-by: Justin Florentine Co-authored-by: Usman Saleem Co-authored-by: Simon Dudley Co-authored-by: garyschulte Co-authored-by: Karim Taam Co-authored-by: gringsam Co-authored-by: George Tebrean <99179176+gtebrean@users.noreply.github.com> Co-authored-by: stefan.pingel@consensys.net Co-authored-by: Matilda-Clerke --- CHANGELOG.md | 1 + .../ethereum/PragueAcceptanceTestHelper.java | 193 +++++++++++++ .../SetCodeTransactionAcceptanceTest.java | 125 +++++++++ .../src/test/resources/dev/dev_prague.json | 112 ++++++++ .../options/TransactionPoolOptionsTest.java | 2 +- .../besu/datatypes/SetCodeAuthorization.java | 82 ++++++ .../besu/datatypes/Transaction.java | 14 + .../besu/datatypes/TransactionType.java | 18 +- .../engine/EngineForkchoiceUpdatedV3.java | 14 +- .../results/EnginePayloadStatusResult.java | 9 +- .../results/TransactionCompleteResult.java | 14 +- .../ethereum/core/SetCodeAuthorization.java | 260 ++++++++++++++++++ .../besu/ethereum/core/Transaction.java | 89 +++++- .../encoding/SetCodeTransactionDecoder.java | 116 ++++++++ .../encoding/SetCodeTransactionEncoder.java | 89 ++++++ .../core/encoding/TransactionDecoder.java | 4 +- .../core/encoding/TransactionEncoder.java | 4 +- .../ethereum/mainnet/AuthorityProcessor.java | 88 ++++++ .../mainnet/MainnetProtocolSpecs.java | 20 +- .../mainnet/MainnetTransactionProcessor.java | 52 +++- .../mainnet/MainnetTransactionValidator.java | 3 +- .../PrivateMutableWorldStateUpdater.java | 20 +- .../DiffBasedWorldStateUpdateAccumulator.java | 6 +- .../ethereum/core/BlockDataGenerator.java | 1 + .../ethereum/core/TransactionTestFixture.java | 2 + .../SetCodeTransactionDecoderTest.java | 120 ++++++++ .../SetCodeTransactionEncoderTest.java | 122 ++++++++ .../MainnetTransactionProcessorTest.java | 4 +- .../eth/transactions/PendingTransaction.java | 5 + .../layered/BaseTransactionPoolTest.java | 2 +- .../eth/transactions/layered/LayersTest.java | 1 + .../hyperledger/besu/evmtool/T8nExecutor.java | 69 ++++- .../evm/account/AuthorizedCodeAccount.java | 100 +++++++ .../account/MutableAuthorizedCodeAccount.java | 138 ++++++++++ .../besu/evm/fluent/SimpleWorld.java | 23 +- .../besu/evm/frame/MessageFrame.java | 39 ++- .../besu/evm/gascalculator/GasCalculator.java | 10 + .../gascalculator/PragueGasCalculator.java | 7 + .../evm/operation/AbstractCallOperation.java | 1 + .../operation/AbstractCreateOperation.java | 1 + .../operation/AbstractExtCallOperation.java | 1 + .../evm/worldstate/AbstractWorldUpdater.java | 22 +- .../evm/worldstate/AuthorizedCodeService.java | 116 ++++++++ .../besu/evm/worldstate/JournaledUpdater.java | 22 +- .../besu/evm/worldstate/WorldUpdater.java | 8 + .../hyperledger/besu/evm/toy/ToyWorld.java | 22 +- 46 files changed, 2108 insertions(+), 63 deletions(-) create mode 100644 acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/ethereum/PragueAcceptanceTestHelper.java create mode 100644 acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/ethereum/SetCodeTransactionAcceptanceTest.java create mode 100644 acceptance-tests/tests/src/test/resources/dev/dev_prague.json create mode 100644 datatypes/src/main/java/org/hyperledger/besu/datatypes/SetCodeAuthorization.java create mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/SetCodeAuthorization.java create mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/SetCodeTransactionDecoder.java create mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/SetCodeTransactionEncoder.java create mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/AuthorityProcessor.java create mode 100644 ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/SetCodeTransactionDecoderTest.java create mode 100644 ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/SetCodeTransactionEncoderTest.java create mode 100644 evm/src/main/java/org/hyperledger/besu/evm/account/AuthorizedCodeAccount.java create mode 100644 evm/src/main/java/org/hyperledger/besu/evm/account/MutableAuthorizedCodeAccount.java create mode 100644 evm/src/main/java/org/hyperledger/besu/evm/worldstate/AuthorizedCodeService.java diff --git a/CHANGELOG.md b/CHANGELOG.md index e0269472a5..a6b28d0a5c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ - Add `block-test` subcommand to the evmtool which runs blockchain reference tests [#7310](https://github.com/hyperledger/besu/pull/7310) - Implement gnark-crypto for eip-2537 [#7316](https://github.com/hyperledger/besu/pull/7316) - Improve blob size transaction selector [#7312](https://github.com/hyperledger/besu/pull/7312) +- Added EIP-7702 [#7237](https://github.com/hyperledger/besu/pull/7237) ### Bug fixes - Fix `eth_call` deserialization to correctly ignore unknown fields in the transaction object. [#7323](https://github.com/hyperledger/besu/pull/7323) 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 new file mode 100644 index 0000000000..fa190f3de1 --- /dev/null +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/ethereum/PragueAcceptanceTestHelper.java @@ -0,0 +1,193 @@ +/* + * 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.ethereum; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + +import org.hyperledger.besu.tests.acceptance.dsl.node.BesuNode; +import org.hyperledger.besu.tests.acceptance.dsl.transaction.eth.EthTransactions; + +import java.io.IOException; +import java.util.Optional; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import okhttp3.Call; +import okhttp3.MediaType; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; +import org.web3j.protocol.core.methods.response.EthBlock; + +public class PragueAcceptanceTestHelper { + protected static final MediaType MEDIA_TYPE_JSON = + MediaType.parse("application/json; charset=utf-8"); + + private final OkHttpClient httpClient; + private final ObjectMapper mapper; + private final BesuNode besuNode; + private final EthTransactions ethTransactions; + + private long blockTimeStamp = 0; + + PragueAcceptanceTestHelper(final BesuNode besuNode, final EthTransactions ethTransactions) { + this.besuNode = besuNode; + this.ethTransactions = ethTransactions; + httpClient = new OkHttpClient(); + mapper = new ObjectMapper(); + } + + public void buildNewBlock() throws IOException { + final EthBlock.Block block = besuNode.execute(ethTransactions.block()); + + blockTimeStamp += 1; + final Call buildBlockRequest = + createEngineCall(createForkChoiceRequest(block.getHash(), blockTimeStamp)); + + final String payloadId; + try (final Response buildBlockResponse = buildBlockRequest.execute()) { + payloadId = + mapper + .readTree(buildBlockResponse.body().string()) + .get("result") + .get("payloadId") + .asText(); + + assertThat(payloadId).isNotEmpty(); + } + + waitFor(500); + + final Call getPayloadRequest = createEngineCall(createGetPayloadRequest(payloadId)); + + final ObjectNode executionPayload; + 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"); + + newBlockHash = executionPayload.get("blockHash").asText(); + parentBeaconBlockRoot = executionPayload.remove("parentBeaconBlockRoot").asText(); + + assertThat(newBlockHash).isNotEmpty(); + } + + final Call newPayloadRequest = + createEngineCall( + createNewPayloadRequest(executionPayload.toString(), parentBeaconBlockRoot)); + try (final Response newPayloadResponse = newPayloadRequest.execute()) { + assertThat(newPayloadResponse.code()).isEqualTo(200); + } + + final Call moveChainAheadRequest = createEngineCall(createForkChoiceRequest(newBlockHash)); + + try (final Response moveChainAheadResponse = moveChainAheadRequest.execute()) { + assertThat(moveChainAheadResponse.code()).isEqualTo(200); + } + } + + private Call createEngineCall(final String request) { + return httpClient.newCall( + new Request.Builder() + .url(besuNode.engineRpcUrl().get()) + .post(RequestBody.create(request, MEDIA_TYPE_JSON)) + .build()); + } + + private String createForkChoiceRequest(final String blockHash) { + return createForkChoiceRequest(blockHash, null); + } + + private String createForkChoiceRequest(final String parentBlockHash, final Long timeStamp) { + final Optional maybeTimeStamp = Optional.ofNullable(timeStamp); + + String forkChoiceRequest = + "{" + + " \"jsonrpc\": \"2.0\"," + + " \"method\": \"engine_forkchoiceUpdatedV3\"," + + " \"params\": [" + + " {" + + " \"headBlockHash\": \"" + + parentBlockHash + + "\"," + + " \"safeBlockHash\": \"" + + parentBlockHash + + "\"," + + " \"finalizedBlockHash\": \"" + + parentBlockHash + + "\"" + + " }"; + + if (maybeTimeStamp.isPresent()) { + forkChoiceRequest += + " ,{" + + " \"timestamp\": \"" + + Long.toHexString(maybeTimeStamp.get()) + + "\"," + + " \"prevRandao\": \"0x0000000000000000000000000000000000000000000000000000000000000000\"," + + " \"suggestedFeeRecipient\": \"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b\"," + + " \"withdrawals\": []," + + " \"parentBeaconBlockRoot\": \"0x0000000000000000000000000000000000000000000000000000000000000000\"" + + " }"; + } + + forkChoiceRequest += " ]," + " \"id\": 67" + "}"; + + return forkChoiceRequest; + } + + private String createGetPayloadRequest(final String payloadId) { + return "{" + + " \"jsonrpc\": \"2.0\"," + + " \"method\": \"engine_getPayloadV4\"," + + " \"params\": [\"" + + payloadId + + "\"]," + + " \"id\": 67" + + "}"; + } + + private String createNewPayloadRequest( + final String executionPayload, final String parentBeaconBlockRoot) { + return "{" + + " \"jsonrpc\": \"2.0\"," + + " \"method\": \"engine_newPayloadV4\"," + + " \"params\": [" + + executionPayload + + ",[]," + + "\"" + + parentBeaconBlockRoot + + "\"" + + "]," + + " \"id\": 67" + + "}"; + } + + private static void waitFor(final long durationMilliSeconds) { + try { + Thread.sleep(durationMilliSeconds); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } +} diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/ethereum/SetCodeTransactionAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/ethereum/SetCodeTransactionAcceptanceTest.java new file mode 100644 index 0000000000..f1b2558a97 --- /dev/null +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/ethereum/SetCodeTransactionAcceptanceTest.java @@ -0,0 +1,125 @@ +/* + * 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.ethereum; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.hyperledger.besu.crypto.SECP256K1; +import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.datatypes.TransactionType; +import org.hyperledger.besu.datatypes.Wei; +import org.hyperledger.besu.ethereum.core.SetCodeAuthorization; +import org.hyperledger.besu.ethereum.core.Transaction; +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; + +import java.io.IOException; +import java.math.BigInteger; +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; +import org.web3j.protocol.core.methods.response.TransactionReceipt; + +public class SetCodeTransactionAcceptanceTest extends AcceptanceTestBase { + private static final String GENESIS_FILE = "/dev/dev_prague.json"; + private static final SECP256K1 secp256k1 = new SECP256K1(); + + public static final Address SEND_ALL_ETH_CONTRACT_ADDRESS = + Address.fromHexStringStrict("0000000000000000000000000000000000009999"); + + private final Account authorizer = + accounts.createAccount( + Address.fromHexStringStrict("8da48afC965480220a3dB9244771bd3afcB5d895")); + public static final Bytes AUTHORIZER_PRIVATE_KEY = + Bytes.fromHexString("11f2e7b6a734ab03fa682450e0d4681d18a944f8b83c99bf7b9b4de6c0f35ea1"); + + private final Account transactionSponsor = + accounts.createAccount( + Address.fromHexStringStrict("a05b21E5186Ce93d2a226722b85D6e550Ac7D6E3")); + public static final Bytes TRANSACTION_SPONSOR_PRIVATE_KEY = + Bytes.fromHexString("3a4ff6d22d7502ef2452368165422861c01a0f72f851793b372b87888dc3c453"); + + private BesuNode besuNode; + private PragueAcceptanceTestHelper testHelper; + + @BeforeEach + void setUp() throws IOException { + besuNode = besu.createExecutionEngineGenesisNode("besuNode", GENESIS_FILE); + cluster.start(besuNode); + + testHelper = new PragueAcceptanceTestHelper(besuNode, ethTransactions); + } + + /** + * At the beginning of the test both the authorizer and the transaction sponsor have a balance of + * 90000 ETH. The authorizer creates an authorization for a contract that send all its ETH to any + * given address. The transaction sponsor created a 7702 transaction with it and sends all the ETH + * from the authorizer to itself. The authorizer balance should be 0 and the transaction sponsor + * balance should be 180000 ETH minus the transaction costs. + */ + @Test + public void shouldTransferAllEthOfAuthorizerToSponsor() throws IOException { + + // 7702 transaction + final org.hyperledger.besu.datatypes.SetCodeAuthorization authorization = + SetCodeAuthorization.builder() + .chainId(BigInteger.valueOf(20211)) + .address(SEND_ALL_ETH_CONTRACT_ADDRESS) + .signAndBuild( + secp256k1.createKeyPair( + secp256k1.createPrivateKey(AUTHORIZER_PRIVATE_KEY.toUnsignedBigInteger()))); + + final Transaction tx = + Transaction.builder() + .type(TransactionType.SET_CODE) + .chainId(BigInteger.valueOf(20211)) + .nonce(0) + .maxPriorityFeePerGas(Wei.of(1000000000)) + .maxFeePerGas(Wei.fromHexString("0x02540BE400")) + .gasLimit(1000000) + .to(Address.fromHexStringStrict(authorizer.getAddress())) + .value(Wei.ZERO) + .payload(Bytes32.leftPad(Bytes.fromHexString(transactionSponsor.getAddress()))) + .accessList(List.of()) + .setCodeTransactionPayloads(List.of(authorization)) + .signAndBuild( + secp256k1.createKeyPair( + secp256k1.createPrivateKey( + TRANSACTION_SPONSOR_PRIVATE_KEY.toUnsignedBigInteger()))); + + final String txHash = + besuNode.execute(ethTransactions.sendRawTransaction(tx.encoded().toHexString())); + testHelper.buildNewBlock(); + + Optional maybeTransactionReceipt = + besuNode.execute(ethTransactions.getTransactionReceipt(txHash)); + assertThat(maybeTransactionReceipt).isPresent(); + + cluster.verify(authorizer.balanceEquals(0)); + + final String gasPriceWithout0x = + maybeTransactionReceipt.get().getEffectiveGasPrice().substring(2); + final BigInteger txCost = + maybeTransactionReceipt.get().getGasUsed().multiply(new BigInteger(gasPriceWithout0x, 16)); + BigInteger expectedSponsorBalance = new BigInteger("180000000000000000000000").subtract(txCost); + cluster.verify(transactionSponsor.balanceEquals(Amount.wei(expectedSponsorBalance))); + } +} diff --git a/acceptance-tests/tests/src/test/resources/dev/dev_prague.json b/acceptance-tests/tests/src/test/resources/dev/dev_prague.json new file mode 100644 index 0000000000..26e59992d1 --- /dev/null +++ b/acceptance-tests/tests/src/test/resources/dev/dev_prague.json @@ -0,0 +1,112 @@ +{ + "config": { + "chainId":20211, + "homesteadBlock":0, + "eip150Block":0, + "eip155Block":0, + "eip158Block":0, + "byzantiumBlock":0, + "constantinopleBlock":0, + "petersburgBlock":0, + "istanbulBlock":0, + "muirGlacierBlock":0, + "berlinBlock":0, + "londonBlock":0, + "terminalTotalDifficulty":0, + "cancunTime":0, + "pragueTime":0, + "clique": { + "period": 5, + "epoch": 30000 + }, + "depositContractAddress": "0x4242424242424242424242424242424242424242" + }, + "nonce":"0x42", + "timestamp":"0x0", + "extraData":"0x0000000000000000000000000000000000000000000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "gasLimit":"0x1C9C380", + "difficulty":"0x400000000", + "mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000", + "coinbase":"0x0000000000000000000000000000000000000000", + "alloc":{ + "a05b21E5186Ce93d2a226722b85D6e550Ac7D6E3": { + "privateKey": "3a4ff6d22d7502ef2452368165422861c01a0f72f851793b372b87888dc3c453", + "balance": "90000000000000000000000" + }, + "8da48afC965480220a3dB9244771bd3afcB5d895": { + "comment": "This account has signed a authorization for contract 0x0000000000000000000000000000000000009999 to send a 7702 transaction", + "privateKey": "11f2e7b6a734ab03fa682450e0d4681d18a944f8b83c99bf7b9b4de6c0f35ea1", + "balance": "90000000000000000000000" + }, + "0x0000000000000000000000000000000000009999": { + "comment": "Contract sends all its Ether to the address provided as a call data.", + "balance": "0", + "code": "5F5F5F5F475F355AF100", + "codeDecompiled": "PUSH0 PUSH0 PUSH0 PUSH0 SELFBALANCE PUSH0 CALLDATALOAD GAS CALL STOP", + "storage": {} + }, + "0xa4664C40AACeBD82A2Db79f0ea36C06Bc6A19Adb": { + "balance": "1000000000000000000000000000" + }, + "0x23618e81E3f5cdF7f54C3d65f7FBc0aBf5B21E8f": { + "comment": "This is the account used to sign the transaction that creates a validator exit", + "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", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000000": "0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000001": "0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000002": "0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000003": "0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000004": "000000000000000000000000a4664C40AACeBD82A2Db79f0ea36C06Bc6A19Adb", + "0x0000000000000000000000000000000000000000000000000000000000000005": "b10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee9922355", + "0x0000000000000000000000000000000000000000000000000000000000000006": "5d8601f0cb3bcc4ce1af9864779a416e00000000000000000000000000000000" + } + }, + "0x4242424242424242424242424242424242424242": { + "comment": "The deposit contract", + "balance": "0", + "code": "0x60806040526004361061003f5760003560e01c806301ffc9a71461004457806322895118146100a4578063621fd130146101ba578063c5f2892f14610244575b600080fd5b34801561005057600080fd5b506100906004803603602081101561006757600080fd5b50357fffffffff000000000000000000000000000000000000000000000000000000001661026b565b604080519115158252519081900360200190f35b6101b8600480360360808110156100ba57600080fd5b8101906020810181356401000000008111156100d557600080fd5b8201836020820111156100e757600080fd5b8035906020019184600183028401116401000000008311171561010957600080fd5b91939092909160208101903564010000000081111561012757600080fd5b82018360208201111561013957600080fd5b8035906020019184600183028401116401000000008311171561015b57600080fd5b91939092909160208101903564010000000081111561017957600080fd5b82018360208201111561018b57600080fd5b803590602001918460018302840111640100000000831117156101ad57600080fd5b919350915035610304565b005b3480156101c657600080fd5b506101cf6110b5565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102095781810151838201526020016101f1565b50505050905090810190601f1680156102365780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561025057600080fd5b506102596110c7565b60408051918252519081900360200190f35b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a70000000000000000000000000000000000000000000000000000000014806102fe57507fffffffff0000000000000000000000000000000000000000000000000000000082167f8564090700000000000000000000000000000000000000000000000000000000145b92915050565b6030861461035d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118056026913960400191505060405180910390fd5b602084146103b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603681526020018061179c6036913960400191505060405180910390fd5b6060821461040f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260298152602001806118786029913960400191505060405180910390fd5b670de0b6b3a7640000341015610470576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118526026913960400191505060405180910390fd5b633b9aca003406156104cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260338152602001806117d26033913960400191505060405180910390fd5b633b9aca00340467ffffffffffffffff811115610535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602781526020018061182b6027913960400191505060405180910390fd5b6060610540826114ba565b90507f649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c589898989858a8a6105756020546114ba565b6040805160a0808252810189905290819060208201908201606083016080840160c085018e8e80828437600083820152601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690910187810386528c815260200190508c8c808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690920188810386528c5181528c51602091820193918e019250908190849084905b83811015610648578181015183820152602001610630565b50505050905090810190601f1680156106755780820380516001836020036101000a031916815260200191505b5086810383528881526020018989808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169092018881038452895181528951602091820193918b019250908190849084905b838110156106ef5781810151838201526020016106d7565b50505050905090810190601f16801561071c5780820380516001836020036101000a031916815260200191505b509d505050505050505050505050505060405180910390a1600060028a8a600060801b604051602001808484808284377fffffffffffffffffffffffffffffffff0000000000000000000000000000000090941691909301908152604080517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0818403018152601090920190819052815191955093508392506020850191508083835b602083106107fc57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016107bf565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610859573d6000803e3d6000fd5b5050506040513d602081101561086e57600080fd5b5051905060006002806108846040848a8c6116fe565b6040516020018083838082843780830192505050925050506040516020818303038152906040526040518082805190602001908083835b602083106108f857805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016108bb565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610955573d6000803e3d6000fd5b5050506040513d602081101561096a57600080fd5b5051600261097b896040818d6116fe565b60405160009060200180848480828437919091019283525050604080518083038152602092830191829052805190945090925082918401908083835b602083106109f457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016109b7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610a51573d6000803e3d6000fd5b5050506040513d6020811015610a6657600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610ada57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610a9d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610b37573d6000803e3d6000fd5b5050506040513d6020811015610b4c57600080fd5b50516040805160208101858152929350600092600292839287928f928f92018383808284378083019250505093505050506040516020818303038152906040526040518082805190602001908083835b60208310610bd957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610b9c565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610c36573d6000803e3d6000fd5b5050506040513d6020811015610c4b57600080fd5b50516040518651600291889160009188916020918201918291908601908083835b60208310610ca957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610c6c565b6001836020036101000a0380198251168184511680821785525050505050509050018367ffffffffffffffff191667ffffffffffffffff1916815260180182815260200193505050506040516020818303038152906040526040518082805190602001908083835b60208310610d4e57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610d11565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610dab573d6000803e3d6000fd5b5050506040513d6020811015610dc057600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610e3457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610df7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610e91573d6000803e3d6000fd5b5050506040513d6020811015610ea657600080fd5b50519050858114610f02576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260548152602001806117486054913960600191505060405180910390fd5b60205463ffffffff11610f60576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806117276021913960400191505060405180910390fd5b602080546001019081905560005b60208110156110a9578160011660011415610fa0578260008260208110610f9157fe5b0155506110ac95505050505050565b600260008260208110610faf57fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061102557805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610fe8565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015611082573d6000803e3d6000fd5b5050506040513d602081101561109757600080fd5b50519250600282049150600101610f6e565b50fe5b50505050505050565b60606110c26020546114ba565b905090565b6020546000908190815b60208110156112f05781600116600114156111e6576002600082602081106110f557fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061116b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161112e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156111c8573d6000803e3d6000fd5b5050506040513d60208110156111dd57600080fd5b505192506112e2565b600283602183602081106111f657fe5b015460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061126b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161122e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156112c8573d6000803e3d6000fd5b5050506040513d60208110156112dd57600080fd5b505192505b6002820491506001016110d1565b506002826112ff6020546114ba565b600060401b6040516020018084815260200183805190602001908083835b6020831061135a57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161131d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790527fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000095909516920191825250604080518083037ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8018152601890920190819052815191955093508392850191508083835b6020831061143f57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611402565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa15801561149c573d6000803e3d6000fd5b5050506040513d60208110156114b157600080fd5b50519250505090565b60408051600880825281830190925260609160208201818036833701905050905060c082901b8060071a60f81b826000815181106114f457fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060061a60f81b8260018151811061153757fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060051a60f81b8260028151811061157a57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060041a60f81b826003815181106115bd57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060031a60f81b8260048151811061160057fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060021a60f81b8260058151811061164357fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060011a60f81b8260068151811061168657fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060001a60f81b826007815181106116c957fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535050919050565b6000808585111561170d578182fd5b83861115611719578182fd5b505082019391909203915056fe4465706f736974436f6e74726163743a206d65726b6c6520747265652066756c6c4465706f736974436f6e74726163743a207265636f6e7374727563746564204465706f7369744461746120646f6573206e6f74206d6174636820737570706c696564206465706f7369745f646174615f726f6f744465706f736974436f6e74726163743a20696e76616c6964207769746864726177616c5f63726564656e7469616c73206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c7565206e6f74206d756c7469706c65206f6620677765694465706f736974436f6e74726163743a20696e76616c6964207075626b6579206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f20686967684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f206c6f774465706f736974436f6e74726163743a20696e76616c6964207369676e6174757265206c656e677468a26469706673582212201dd26f37a621703009abf16e77e69c93dc50c79db7f6cc37543e3e0e3decdc9764736f6c634300060b0033", + "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" + } + } + }, + "number":"0x0", + "gasUsed":"0x0", + "parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000", + "baseFeePerGas":"0x7" +} \ No newline at end of file diff --git a/besu/src/test/java/org/hyperledger/besu/cli/options/TransactionPoolOptionsTest.java b/besu/src/test/java/org/hyperledger/besu/cli/options/TransactionPoolOptionsTest.java index c029983a33..4ee34295f4 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/options/TransactionPoolOptionsTest.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/options/TransactionPoolOptionsTest.java @@ -413,7 +413,7 @@ public class TransactionPoolOptionsTest @Test public void maxPrioritizedTxsPerTypeWrongTxType() { internalTestFailure( - "Invalid value for option '--tx-pool-max-prioritized-by-type' (MAP): expected one of [FRONTIER, ACCESS_LIST, EIP1559, BLOB] (case-insensitive) but was 'WRONG_TYPE'", + "Invalid value for option '--tx-pool-max-prioritized-by-type' (MAP): expected one of [FRONTIER, ACCESS_LIST, EIP1559, BLOB, SET_CODE] (case-insensitive) but was 'WRONG_TYPE'", "--tx-pool-max-prioritized-by-type", "WRONG_TYPE=1"); } diff --git a/datatypes/src/main/java/org/hyperledger/besu/datatypes/SetCodeAuthorization.java b/datatypes/src/main/java/org/hyperledger/besu/datatypes/SetCodeAuthorization.java new file mode 100644 index 0000000000..b12e65de41 --- /dev/null +++ b/datatypes/src/main/java/org/hyperledger/besu/datatypes/SetCodeAuthorization.java @@ -0,0 +1,82 @@ +/* + * 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.datatypes; + +import org.hyperledger.besu.crypto.SECPSignature; + +import java.math.BigInteger; +import java.util.Optional; + +/** + * SetCodeAuthorization is a data structure that represents the authorization to set code on a EOA + * account. + */ +public interface SetCodeAuthorization { + /** + * Return the chain id. + * + * @return chain id + */ + BigInteger chainId(); + + /** + * Return the address of the account which code will be used. + * + * @return address + */ + Address address(); + + /** + * Return the signature. + * + * @return signature + */ + SECPSignature signature(); + + /** + * Return the authorizer address. + * + * @return authorizer address of the EOA which will load the code into its account + */ + Optional

authorizer(); + + /** + * Return a valid nonce or empty otherwise. A nonce is valid if the size of the list is exactly 1 + * + * @return all the optional nonce + */ + Optional nonce(); + + /** + * Return the recovery id. + * + * @return byte + */ + byte v(); + + /** + * Return the r value of the signature. + * + * @return r value + */ + BigInteger r(); + + /** + * Return the s value of the signature. + * + * @return s value + */ + BigInteger s(); +} diff --git a/datatypes/src/main/java/org/hyperledger/besu/datatypes/Transaction.java b/datatypes/src/main/java/org/hyperledger/besu/datatypes/Transaction.java index 4a77a898de..d6751852bc 100644 --- a/datatypes/src/main/java/org/hyperledger/besu/datatypes/Transaction.java +++ b/datatypes/src/main/java/org/hyperledger/besu/datatypes/Transaction.java @@ -234,4 +234,18 @@ public interface Transaction { * @return the size in bytes of the encoded transaction. */ int getSize(); + + /** + * Returns the set code transaction payload if this transaction is a 7702 transaction. + * + * @return the set code transaction payloads + */ + Optional> getAuthorizationList(); + + /** + * Returns the size of the authorization list. + * + * @return the size of the authorization list + */ + int authorizationListSize(); } diff --git a/datatypes/src/main/java/org/hyperledger/besu/datatypes/TransactionType.java b/datatypes/src/main/java/org/hyperledger/besu/datatypes/TransactionType.java index 984a4cc746..df4a07193b 100644 --- a/datatypes/src/main/java/org/hyperledger/besu/datatypes/TransactionType.java +++ b/datatypes/src/main/java/org/hyperledger/besu/datatypes/TransactionType.java @@ -27,10 +27,12 @@ public enum TransactionType { /** Eip1559 transaction type. */ EIP1559(0x02), /** Blob transaction type. */ - BLOB(0x03); + BLOB(0x03), + /** Eip7702 transaction type. */ + SET_CODE(0x04); private static final Set ACCESS_LIST_SUPPORTED_TRANSACTION_TYPES = - Set.of(ACCESS_LIST, EIP1559, BLOB); + Set.of(ACCESS_LIST, EIP1559, BLOB, SET_CODE); private static final EnumSet LEGACY_FEE_MARKET_TRANSACTION_TYPES = EnumSet.of(TransactionType.FRONTIER, TransactionType.ACCESS_LIST); @@ -83,7 +85,8 @@ public enum TransactionType { TransactionType.FRONTIER, TransactionType.ACCESS_LIST, TransactionType.EIP1559, - TransactionType.BLOB + TransactionType.BLOB, + TransactionType.SET_CODE }) .filter(transactionType -> transactionType.typeValue == serializedTypeValue) .findFirst() @@ -128,4 +131,13 @@ public enum TransactionType { public boolean supportsBlob() { return this.equals(BLOB); } + + /** + * Does transaction type require code. + * + * @return the boolean + */ + public boolean requiresSetCode() { + return this.equals(SET_CODE); + } } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineForkchoiceUpdatedV3.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineForkchoiceUpdatedV3.java index 60ba8990a1..b5aebf4f5d 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineForkchoiceUpdatedV3.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineForkchoiceUpdatedV3.java @@ -33,7 +33,7 @@ import org.slf4j.LoggerFactory; public class EngineForkchoiceUpdatedV3 extends AbstractEngineForkchoiceUpdated { - private final Optional cancun; + private final Optional supportedHardFork; private static final Logger LOG = LoggerFactory.getLogger(EngineForkchoiceUpdatedV3.class); public EngineForkchoiceUpdatedV3( @@ -43,7 +43,11 @@ public class EngineForkchoiceUpdatedV3 extends AbstractEngineForkchoiceUpdated { final MergeMiningCoordinator mergeCoordinator, final EngineCallListener engineCallListener) { super(vertx, protocolSchedule, protocolContext, mergeCoordinator, engineCallListener); - this.cancun = protocolSchedule.hardforkFor(s -> s.fork().name().equalsIgnoreCase("Cancun")); + this.supportedHardFork = + protocolSchedule.hardforkFor( + s -> + s.fork().name().equalsIgnoreCase("Cancun") + || s.fork().name().equalsIgnoreCase("Prague")); } @Override @@ -77,12 +81,12 @@ public class EngineForkchoiceUpdatedV3 extends AbstractEngineForkchoiceUpdated { @Override protected ValidationResult validateForkSupported(final long blockTimestamp) { if (protocolSchedule.isPresent()) { - if (cancun.isPresent() && blockTimestamp >= cancun.get().milestone()) { + if (supportedHardFork.isPresent() && blockTimestamp >= supportedHardFork.get().milestone()) { return ValidationResult.valid(); } else { return ValidationResult.invalid( RpcErrorType.UNSUPPORTED_FORK, - "Cancun configured to start at timestamp: " + cancun.get().milestone()); + "Cancun configured to start at timestamp: " + supportedHardFork.get().milestone()); } } else { return ValidationResult.invalid( @@ -99,7 +103,7 @@ public class EngineForkchoiceUpdatedV3 extends AbstractEngineForkchoiceUpdated { return Optional.of(new JsonRpcErrorResponse(requestId, getInvalidPayloadAttributesError())); } else if (payloadAttributes.getTimestamp().longValue() == 0) { return Optional.of(new JsonRpcErrorResponse(requestId, getInvalidPayloadAttributesError())); - } else if (payloadAttributes.getTimestamp() < cancun.get().milestone()) { + } else if (payloadAttributes.getTimestamp() < supportedHardFork.get().milestone()) { return Optional.of(new JsonRpcErrorResponse(requestId, RpcErrorType.UNSUPPORTED_FORK)); } else { return Optional.empty(); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/EnginePayloadStatusResult.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/EnginePayloadStatusResult.java index 4912f81e49..a9b9a17018 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/EnginePayloadStatusResult.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/EnginePayloadStatusResult.java @@ -19,7 +19,9 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngin import java.util.Optional; +import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonGetter; +import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; @JsonPropertyOrder({"status", "latestValidHash", "validationError"}) @@ -28,10 +30,11 @@ public class EnginePayloadStatusResult { Optional latestValidHash; Optional validationError; + @JsonCreator public EnginePayloadStatusResult( - final EngineStatus status, - final Hash latestValidHash, - final Optional validationError) { + @JsonProperty("status") final EngineStatus status, + @JsonProperty("latestValidHash") final Hash latestValidHash, + @JsonProperty("errorMessage") final Optional validationError) { this.status = status; this.latestValidHash = Optional.ofNullable(latestValidHash); this.validationError = validationError; diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/TransactionCompleteResult.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/TransactionCompleteResult.java index c8260d090c..05b323cacb 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/TransactionCompleteResult.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/TransactionCompleteResult.java @@ -15,6 +15,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.results; import org.hyperledger.besu.datatypes.AccessListEntry; +import org.hyperledger.besu.datatypes.SetCodeAuthorization; import org.hyperledger.besu.datatypes.TransactionType; import org.hyperledger.besu.datatypes.VersionedHash; import org.hyperledger.besu.datatypes.Wei; @@ -30,6 +31,7 @@ import org.apache.tuweni.bytes.Bytes; @JsonPropertyOrder({ "accessList", + "authorizationList", "blockHash", "blockNumber", "chainId", @@ -91,6 +93,9 @@ public class TransactionCompleteResult implements TransactionResult { @JsonInclude(JsonInclude.Include.NON_NULL) private final List versionedHashes; + @JsonInclude(JsonInclude.Include.NON_NULL) + private final List authorizationList; + public TransactionCompleteResult(final TransactionWithMetadata tx) { final Transaction transaction = tx.getTransaction(); final TransactionType transactionType = transaction.getType(); @@ -125,7 +130,8 @@ public class TransactionCompleteResult implements TransactionResult { this.yParity = Quantity.create(transaction.getYParity()); this.v = (transactionType == TransactionType.ACCESS_LIST - || transactionType == TransactionType.EIP1559) + || transactionType == TransactionType.EIP1559) + || transactionType == TransactionType.SET_CODE ? Quantity.create(transaction.getYParity()) : null; } @@ -133,6 +139,7 @@ public class TransactionCompleteResult implements TransactionResult { this.r = Quantity.create(transaction.getR()); this.s = Quantity.create(transaction.getS()); this.versionedHashes = transaction.getVersionedHashes().orElse(null); + this.authorizationList = transaction.getAuthorizationList().orElse(null); } @JsonGetter(value = "accessList") @@ -246,4 +253,9 @@ public class TransactionCompleteResult implements TransactionResult { public List getVersionedHashes() { return versionedHashes; } + + @JsonGetter(value = "authorizationList") + public List getAuthorizationList() { + return authorizationList; + } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/SetCodeAuthorization.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/SetCodeAuthorization.java new file mode 100644 index 0000000000..ea9cae2fcb --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/SetCodeAuthorization.java @@ -0,0 +1,260 @@ +/* + * 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.crypto.KeyPair; +import org.hyperledger.besu.crypto.SECPSignature; +import org.hyperledger.besu.crypto.SignatureAlgorithm; +import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; +import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.datatypes.Hash; +import org.hyperledger.besu.ethereum.core.encoding.SetCodeTransactionEncoder; +import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; + +import java.math.BigInteger; +import java.util.List; +import java.util.Optional; +import java.util.function.Supplier; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.common.base.Suppliers; +import org.apache.tuweni.bytes.Bytes; + +public class SetCodeAuthorization implements org.hyperledger.besu.datatypes.SetCodeAuthorization { + private static final Supplier SIGNATURE_ALGORITHM = + Suppliers.memoize(SignatureAlgorithmFactory::getInstance); + + public static final Bytes MAGIC = Bytes.fromHexString("05"); + + private final BigInteger chainId; + private final Address address; + private final Optional nonce; + private final SECPSignature signature; + private Optional
authorizer = Optional.empty(); + private boolean isAuthorityComputed = false; + + /** + * An access list entry as defined in EIP-7702 + * + * @param chainId can be either the current chain id or zero + * @param address the address from which the code will be set into the EOA account + * @param nonce an optional nonce after which this auth expires + * @param signature the signature of the EOA account which will be used to set the code + */ + public SetCodeAuthorization( + final BigInteger chainId, + final Address address, + final Optional nonce, + final SECPSignature signature) { + this.chainId = chainId; + this.address = address; + this.nonce = nonce; + this.signature = signature; + } + + /** + * Create access list entry. + * + * @param chainId can be either the current chain id or zero + * @param address the address from which the code will be set into the EOA account + * @param nonces the list of nonces + * @param v the recovery id + * @param r the r value of the signature + * @param s the s value of the signature + * @return SetCodeTransactionEntry + */ + @JsonCreator + public static org.hyperledger.besu.datatypes.SetCodeAuthorization createSetCodeAuthorizationEntry( + @JsonProperty("chainId") final BigInteger chainId, + @JsonProperty("address") final Address address, + @JsonProperty("nonce") final List nonces, + @JsonProperty("v") final byte v, + @JsonProperty("r") final BigInteger r, + @JsonProperty("s") final BigInteger s) { + return new SetCodeAuthorization( + chainId, + address, + Optional.ofNullable(nonces.get(0)), + SIGNATURE_ALGORITHM.get().createSignature(r, s, v)); + } + + @JsonProperty("chainId") + @Override + public BigInteger chainId() { + return chainId; + } + + @JsonProperty("address") + @Override + public Address address() { + return address; + } + + @JsonProperty("signature") + @Override + public SECPSignature signature() { + return signature; + } + + @Override + public Optional
authorizer() { + if (!isAuthorityComputed) { + authorizer = computeAuthority(); + isAuthorityComputed = true; + } + + return authorizer; + } + + @Override + public Optional nonce() { + return nonce; + } + + @JsonProperty("v") + @Override + public byte v() { + return signature.getRecId(); + } + + @JsonProperty("r") + @Override + public BigInteger r() { + return signature.getR(); + } + + @JsonProperty("s") + @Override + public BigInteger s() { + return signature.getS(); + } + + private Optional
computeAuthority() { + BytesValueRLPOutput rlpOutput = new BytesValueRLPOutput(); + SetCodeTransactionEncoder.encodeSingleSetCodeWithoutSignature(this, rlpOutput); + + final Hash hash = Hash.hash(Bytes.concatenate(MAGIC, rlpOutput.encoded())); + + return SIGNATURE_ALGORITHM + .get() + .recoverPublicKeyFromSignature(hash, signature) + .map(Address::extract); + } + + /** + * Create set code authorization with a builder. + * + * @return SetCodeAuthorization.Builder + */ + public static Builder builder() { + return new Builder(); + } + + /** Builder for SetCodeAuthorization. */ + public static class Builder { + private BigInteger chainId = BigInteger.ZERO; + private Address address; + private Optional nonce = Optional.empty(); + private SECPSignature signature; + + /** Create a new builder. */ + protected Builder() {} + + /** + * Set the optional chain id. + * + * @param chainId the chain id + * @return this builder + */ + public Builder chainId(final BigInteger chainId) { + this.chainId = chainId; + return this; + } + + /** + * Set the address of the authorized smart contract. + * + * @param address the address + * @return this builder + */ + public Builder address(final Address address) { + this.address = address; + return this; + } + + /** + * Set the optional nonce. + * + * @param nonce the optional nonce. + * @return this builder + */ + public Builder nonces(final Optional nonce) { + this.nonce = nonce; + return this; + } + + /** + * Set the signature of the authorizer account. + * + * @param signature the signature + * @return this builder + */ + public Builder signature(final SECPSignature signature) { + this.signature = signature; + return this; + } + + /** + * Sign the authorization with the given key pair and return the authorization. + * + * @param keyPair the key pair + * @return SetCodeAuthorization + */ + public org.hyperledger.besu.datatypes.SetCodeAuthorization signAndBuild(final KeyPair keyPair) { + final BytesValueRLPOutput output = new BytesValueRLPOutput(); + output.startList(); + output.writeBigIntegerScalar(chainId); + output.writeBytes(address); + output.startList(); + nonce.ifPresent(output::writeLongScalar); + output.endList(); + output.endList(); + + signature( + SIGNATURE_ALGORITHM + .get() + .sign(Hash.hash(Bytes.concatenate(MAGIC, output.encoded())), keyPair)); + return build(); + } + + /** + * Build the authorization. + * + * @return SetCodeAuthorization + */ + public org.hyperledger.besu.datatypes.SetCodeAuthorization build() { + if (address == null) { + throw new IllegalStateException("Address must be set"); + } + + if (signature == null) { + throw new IllegalStateException("Signature must be set"); + } + + return new SetCodeAuthorization(chainId, address, nonce, signature); + } + } +} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Transaction.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Transaction.java index 7ca349721f..513cfb8319 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Transaction.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Transaction.java @@ -31,6 +31,7 @@ import org.hyperledger.besu.datatypes.BlobsWithCommitments; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.KZGCommitment; import org.hyperledger.besu.datatypes.KZGProof; +import org.hyperledger.besu.datatypes.SetCodeAuthorization; import org.hyperledger.besu.datatypes.Sha256Hash; import org.hyperledger.besu.datatypes.TransactionType; import org.hyperledger.besu.datatypes.VersionedHash; @@ -38,6 +39,7 @@ import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.core.encoding.AccessListTransactionEncoder; import org.hyperledger.besu.ethereum.core.encoding.BlobTransactionEncoder; import org.hyperledger.besu.ethereum.core.encoding.EncodingContext; +import org.hyperledger.besu.ethereum.core.encoding.SetCodeTransactionEncoder; import org.hyperledger.besu.ethereum.core.encoding.TransactionDecoder; import org.hyperledger.besu.ethereum.core.encoding.TransactionEncoder; import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; @@ -122,6 +124,7 @@ public class Transaction private final Optional> versionedHashes; private final Optional blobsWithCommitments; + private final Optional> maybeAuthorizationList; public static Builder builder() { return new Builder(); @@ -177,7 +180,8 @@ public class Transaction final Address sender, final Optional chainId, final Optional> versionedHashes, - final Optional blobsWithCommitments) { + final Optional blobsWithCommitments, + final Optional> maybeAuthorizationList) { if (!forCopy) { if (transactionType.requiresChainId()) { @@ -213,6 +217,12 @@ public class Transaction checkArgument( maxFeePerBlobGas.isPresent(), "Must specify max fee per blob gas for blob transaction"); } + + if (transactionType.requiresSetCode()) { + checkArgument( + maybeAuthorizationList.isPresent(), + "Must specify set code transaction payload for set code transaction"); + } } this.transactionType = transactionType; @@ -231,6 +241,7 @@ public class Transaction this.chainId = chainId; this.versionedHashes = versionedHashes; this.blobsWithCommitments = blobsWithCommitments; + this.maybeAuthorizationList = maybeAuthorizationList; } /** @@ -462,6 +473,7 @@ public class Transaction payload, maybeAccessList, versionedHashes.orElse(null), + maybeAuthorizationList, chainId); } return hashNoSignature; @@ -668,6 +680,16 @@ public class Transaction return blobsWithCommitments; } + @Override + public Optional> getAuthorizationList() { + return maybeAuthorizationList; + } + + @Override + public int authorizationListSize() { + return maybeAuthorizationList.map(List::size).orElse(0); + } + /** * Return the list of transaction hashes extracted from the collection of Transaction passed as * argument @@ -692,6 +714,7 @@ public class Transaction final Bytes payload, final Optional> accessList, final List versionedHashes, + final Optional> authorizationList, final Optional chainId) { if (transactionType.requiresChainId()) { checkArgument(chainId.isPresent(), "Transaction type %s requires chainId", transactionType); @@ -736,6 +759,21 @@ public class Transaction new IllegalStateException( "Developer error: the transaction should be guaranteed to have an access list here")), chainId); + case SET_CODE -> + setCodePreimage( + nonce, + maxPriorityFeePerGas, + maxFeePerGas, + gasLimit, + to, + value, + payload, + chainId, + accessList, + authorizationList.orElseThrow( + () -> + new IllegalStateException( + "Developer error: the transaction should be guaranteed to have a set code payload here"))); }; return keccak256(preimage); } @@ -873,6 +911,38 @@ public class Transaction return Bytes.concatenate(Bytes.of(TransactionType.ACCESS_LIST.getSerializedType()), encode); } + private static Bytes setCodePreimage( + final long nonce, + final Wei maxPriorityFeePerGas, + final Wei maxFeePerGas, + final long gasLimit, + final Optional
to, + final Wei value, + final Bytes payload, + final Optional chainId, + final Optional> accessList, + final List authorizationList) { + final Bytes encoded = + RLP.encode( + rlpOutput -> { + rlpOutput.startList(); + eip1559PreimageFields( + nonce, + maxPriorityFeePerGas, + maxFeePerGas, + gasLimit, + to, + value, + payload, + chainId, + accessList, + rlpOutput); + SetCodeTransactionEncoder.encodeSetCodeInner(authorizationList, rlpOutput); + rlpOutput.endList(); + }); + return Bytes.concatenate(Bytes.of(TransactionType.SET_CODE.getSerializedType()), encoded); + } + @Override public boolean equals(final Object other) { if (!(other instanceof Transaction that)) { @@ -1040,7 +1110,8 @@ public class Transaction sender, chainId, detachedVersionedHashes, - detachedBlobsWithCommitments); + detachedBlobsWithCommitments, + maybeAuthorizationList); // copy also the computed fields, to avoid to recompute them copiedTx.sender = this.sender; @@ -1108,6 +1179,7 @@ public class Transaction protected Optional v = Optional.empty(); protected List versionedHashes = null; private BlobsWithCommitments blobsWithCommitments; + protected Optional> setCodeTransactionPayloads = Optional.empty(); public Builder copiedFrom(final Transaction toCopy) { this.transactionType = toCopy.transactionType; @@ -1126,6 +1198,7 @@ public class Transaction this.chainId = toCopy.chainId; this.versionedHashes = toCopy.versionedHashes.orElse(null); this.blobsWithCommitments = toCopy.blobsWithCommitments.orElse(null); + this.setCodeTransactionPayloads = toCopy.maybeAuthorizationList; return this; } @@ -1219,6 +1292,8 @@ public class Transaction transactionType = TransactionType.EIP1559; } else if (accessList.isPresent()) { transactionType = TransactionType.ACCESS_LIST; + } else if (setCodeTransactionPayloads.isPresent()) { + transactionType = TransactionType.SET_CODE; } else { transactionType = TransactionType.FRONTIER; } @@ -1248,7 +1323,8 @@ public class Transaction sender, chainId, Optional.ofNullable(versionedHashes), - Optional.ofNullable(blobsWithCommitments)); + Optional.ofNullable(blobsWithCommitments), + setCodeTransactionPayloads); } public Transaction signAndBuild(final KeyPair keys) { @@ -1275,6 +1351,7 @@ public class Transaction payload, accessList, versionedHashes, + setCodeTransactionPayloads, chainId), keys); } @@ -1298,5 +1375,11 @@ public class Transaction this.blobsWithCommitments = blobsWithCommitments; return this; } + + public Builder setCodeTransactionPayloads( + final List setCodeTransactionEntries) { + this.setCodeTransactionPayloads = Optional.ofNullable(setCodeTransactionEntries); + return this; + } } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/SetCodeTransactionDecoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/SetCodeTransactionDecoder.java new file mode 100644 index 0000000000..80d59de83b --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/SetCodeTransactionDecoder.java @@ -0,0 +1,116 @@ +/* + * 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.crypto.SECPSignature; +import org.hyperledger.besu.crypto.SignatureAlgorithm; +import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; +import org.hyperledger.besu.datatypes.AccessListEntry; +import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.datatypes.TransactionType; +import org.hyperledger.besu.datatypes.Wei; +import org.hyperledger.besu.ethereum.core.SetCodeAuthorization; +import org.hyperledger.besu.ethereum.core.Transaction; +import org.hyperledger.besu.ethereum.rlp.RLPInput; + +import java.math.BigInteger; +import java.util.Optional; +import java.util.function.Supplier; + +import com.google.common.base.Suppliers; + +public class SetCodeTransactionDecoder { + private static final Supplier SIGNATURE_ALGORITHM = + Suppliers.memoize(SignatureAlgorithmFactory::getInstance); + + private SetCodeTransactionDecoder() { + // private constructor + } + + public static Transaction decode(final RLPInput input) { + input.enterList(); + final BigInteger chainId = input.readBigIntegerScalar(); + final Transaction.Builder builder = + Transaction.builder() + .type(TransactionType.SET_CODE) + .chainId(chainId) + .nonce(input.readLongScalar()) + .maxPriorityFeePerGas(Wei.of(input.readUInt256Scalar())) + .maxFeePerGas(Wei.of(input.readUInt256Scalar())) + .gasLimit(input.readLongScalar()) + .to(input.readBytes(v -> v.isEmpty() ? null : Address.wrap(v))) + .value(Wei.of(input.readUInt256Scalar())) + .payload(input.readBytes()) + .accessList( + input.readList( + accessListEntryRLPInput -> { + accessListEntryRLPInput.enterList(); + final AccessListEntry accessListEntry = + new AccessListEntry( + Address.wrap(accessListEntryRLPInput.readBytes()), + accessListEntryRLPInput.readList(RLPInput::readBytes32)); + accessListEntryRLPInput.leaveList(); + return accessListEntry; + })) + .setCodeTransactionPayloads( + input.readList( + setCodeTransactionPayloadsRLPInput -> + decodeInnerPayload(setCodeTransactionPayloadsRLPInput))); + + final byte recId = (byte) input.readUnsignedByteScalar(); + final BigInteger r = input.readUInt256Scalar().toUnsignedBigInteger(); + final BigInteger s = input.readUInt256Scalar().toUnsignedBigInteger(); + + input.leaveList(); + + final Transaction transaction = + builder.signature(SIGNATURE_ALGORITHM.get().createSignature(r, s, recId)).build(); + + return transaction; + } + + public static org.hyperledger.besu.datatypes.SetCodeAuthorization decodeInnerPayload( + final RLPInput input) { + input.enterList(); + final BigInteger chainId = input.readBigIntegerScalar(); + final Address address = Address.wrap(input.readBytes()); + + Optional nonce = Optional.empty(); + + if (!input.nextIsList()) { + throw new IllegalArgumentException("Optional nonce must be an list, but isn't"); + } + + final long noncesSize = input.nextSize(); + + input.enterList(); + if (noncesSize == 1) { + nonce = Optional.ofNullable(input.readLongScalar()); + } else if (noncesSize > 1) { + throw new IllegalArgumentException("Nonce list may only have 1 member, if any"); + } + input.leaveList(); + + final byte yParity = (byte) input.readUnsignedByteScalar(); + final BigInteger r = input.readUInt256Scalar().toUnsignedBigInteger(); + final BigInteger s = input.readUInt256Scalar().toUnsignedBigInteger(); + + input.leaveList(); + + final SECPSignature signature = SIGNATURE_ALGORITHM.get().createSignature(r, s, yParity); + + return new SetCodeAuthorization(chainId, address, nonce, signature); + } +} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/SetCodeTransactionEncoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/SetCodeTransactionEncoder.java new file mode 100644 index 0000000000..05808f3129 --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/SetCodeTransactionEncoder.java @@ -0,0 +1,89 @@ +/* + * 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.hyperledger.besu.ethereum.core.encoding.AccessListTransactionEncoder.writeAccessList; +import static org.hyperledger.besu.ethereum.core.encoding.TransactionEncoder.writeSignatureAndRecoveryId; + +import org.hyperledger.besu.datatypes.SetCodeAuthorization; +import org.hyperledger.besu.ethereum.core.Transaction; +import org.hyperledger.besu.ethereum.rlp.RLPOutput; + +import java.util.List; + +import org.apache.tuweni.bytes.Bytes; + +public class SetCodeTransactionEncoder { + + private SetCodeTransactionEncoder() { + // private constructor + } + + public static void encodeSetCodeInner( + final List payloads, final RLPOutput rlpOutput) { + rlpOutput.startList(); + payloads.forEach(payload -> encodeSingleSetCode(payload, rlpOutput)); + rlpOutput.endList(); + } + + public static void encodeSingleSetCodeWithoutSignature( + final SetCodeAuthorization payload, final RLPOutput rlpOutput) { + rlpOutput.startList(); + encodeAuthorizationDetails(payload, rlpOutput); + rlpOutput.endList(); + } + + public static void encodeSingleSetCode( + final SetCodeAuthorization payload, final RLPOutput rlpOutput) { + rlpOutput.startList(); + encodeAuthorizationDetails(payload, rlpOutput); + rlpOutput.writeIntScalar(payload.signature().getRecId()); + rlpOutput.writeBigIntegerScalar(payload.signature().getR()); + rlpOutput.writeBigIntegerScalar(payload.signature().getS()); + rlpOutput.endList(); + } + + private static void encodeAuthorizationDetails( + final SetCodeAuthorization payload, final RLPOutput rlpOutput) { + rlpOutput.writeBigIntegerScalar(payload.chainId()); + rlpOutput.writeBytes(payload.address().copy()); + rlpOutput.startList(); + payload.nonce().ifPresent(rlpOutput::writeLongScalar); + rlpOutput.endList(); + } + + public static void encode(final Transaction transaction, final RLPOutput out) { + out.startList(); + out.writeBigIntegerScalar(transaction.getChainId().orElseThrow()); + out.writeLongScalar(transaction.getNonce()); + out.writeUInt256Scalar(transaction.getMaxPriorityFeePerGas().orElseThrow()); + out.writeUInt256Scalar(transaction.getMaxFeePerGas().orElseThrow()); + out.writeLongScalar(transaction.getGasLimit()); + out.writeBytes(transaction.getTo().map(Bytes::copy).orElse(Bytes.EMPTY)); + out.writeUInt256Scalar(transaction.getValue()); + out.writeBytes(transaction.getPayload()); + writeAccessList(out, transaction.getAccessList()); + encodeSetCodeInner( + transaction + .getAuthorizationList() + .orElseThrow( + () -> + new IllegalStateException( + "Developer error: the transaction should be guaranteed to have a set code payload here")), + out); + writeSignatureAndRecoveryId(transaction, out); + out.endList(); + } +} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/TransactionDecoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/TransactionDecoder.java index fe6687cdb5..2a63d8f24b 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/TransactionDecoder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/TransactionDecoder.java @@ -40,7 +40,9 @@ public class TransactionDecoder { TransactionType.EIP1559, EIP1559TransactionDecoder::decode, TransactionType.BLOB, - BlobTransactionDecoder::decode); + BlobTransactionDecoder::decode, + TransactionType.SET_CODE, + SetCodeTransactionDecoder::decode); private static final ImmutableMap POOLED_TRANSACTION_DECODERS = ImmutableMap.of(TransactionType.BLOB, BlobPooledTransactionDecoder::decode); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/TransactionEncoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/TransactionEncoder.java index 20fe75885e..4995975621 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/TransactionEncoder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/TransactionEncoder.java @@ -39,7 +39,9 @@ public class TransactionEncoder { TransactionType.EIP1559, EIP1559TransactionEncoder::encode, TransactionType.BLOB, - BlobTransactionEncoder::encode); + BlobTransactionEncoder::encode, + TransactionType.SET_CODE, + SetCodeTransactionEncoder::encode); private static final ImmutableMap POOLED_TRANSACTION_ENCODERS = ImmutableMap.of(TransactionType.BLOB, BlobPooledTransactionEncoder::encode); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/AuthorityProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/AuthorityProcessor.java new file mode 100644 index 0000000000..f79e2c98e3 --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/AuthorityProcessor.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.mainnet; + +import org.hyperledger.besu.ethereum.core.Transaction; +import org.hyperledger.besu.evm.account.Account; +import org.hyperledger.besu.evm.account.AccountState; +import org.hyperledger.besu.evm.account.MutableAccount; +import org.hyperledger.besu.evm.worldstate.AuthorizedCodeService; +import org.hyperledger.besu.evm.worldstate.WorldUpdater; + +import java.math.BigInteger; +import java.util.Optional; + +import org.apache.tuweni.bytes.Bytes; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class AuthorityProcessor { + private static final Logger LOG = LoggerFactory.getLogger(AuthorityProcessor.class); + + private final Optional maybeChainId; + + public AuthorityProcessor(final Optional maybeChainId) { + this.maybeChainId = maybeChainId; + } + + public void addContractToAuthority( + final WorldUpdater worldUpdater, + final AuthorizedCodeService authorizedCodeService, + final Transaction transaction) { + + transaction + .getAuthorizationList() + .get() + .forEach( + payload -> + payload + .authorizer() + .ifPresent( + authorityAddress -> { + LOG.trace("Set code authority: {}", authorityAddress); + + if (maybeChainId.isPresent() + && !payload.chainId().equals(BigInteger.ZERO) + && !maybeChainId.get().equals(payload.chainId())) { + return; + } + + final Optional maybeAccount = + Optional.ofNullable(worldUpdater.getAccount(authorityAddress)); + final long accountNonce = + maybeAccount.map(AccountState::getNonce).orElse(0L); + + if (payload.nonce().isPresent() + && !payload.nonce().get().equals(accountNonce)) { + return; + } + + if (authorizedCodeService.hasAuthorizedCode(authorityAddress)) { + return; + } + + Optional codeAccount = + Optional.ofNullable(worldUpdater.get(payload.address())); + final Bytes code; + if (codeAccount.isPresent()) { + code = codeAccount.get().getCode(); + } else { + code = Bytes.EMPTY; + } + + authorizedCodeService.addAuthorizedCode(authorityAddress, code); + })); + } +} 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 4ae30f8de9..6f09df923e 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 @@ -595,7 +595,8 @@ public abstract class MainnetProtocolSpecs { true, evmConfiguration.evmStackSize(), feeMarket, - CoinbaseFeePriceCalculator.eip1559())) + CoinbaseFeePriceCalculator.eip1559(), + new AuthorityProcessor(chainId))) // change to check for max blob gas per block for EIP-4844 .transactionValidatorFactoryBuilder( (evm, gasLimitCalculator, feeMarket) -> @@ -658,6 +659,23 @@ public abstract class MainnetProtocolSpecs { // EIP-7002 Withdrawals / EIP-6610 Deposits / EIP-7685 Requests .requestProcessorCoordinator(pragueRequestsProcessors(depositContractAddress)) + // change to accept EIP-7702 transactions + .transactionValidatorFactoryBuilder( + (evm, gasLimitCalculator, feeMarket) -> + new TransactionValidatorFactory( + evm.getGasCalculator(), + gasLimitCalculator, + feeMarket, + true, + chainId, + Set.of( + TransactionType.FRONTIER, + TransactionType.ACCESS_LIST, + TransactionType.EIP1559, + TransactionType.BLOB, + TransactionType.SET_CODE), + evm.getEvmVersion().getMaxInitcodeSize())) + // EIP-2935 Blockhash processor .blockHashProcessor(new PragueBlockHashProcessor()) .name("Prague"); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java index 53801d14cd..9ad1db7d89 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java @@ -42,6 +42,7 @@ import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.gascalculator.GasCalculator; import org.hyperledger.besu.evm.processor.AbstractMessageProcessor; import org.hyperledger.besu.evm.tracing.OperationTracer; +import org.hyperledger.besu.evm.worldstate.AuthorizedCodeService; import org.hyperledger.besu.evm.worldstate.WorldUpdater; import java.util.Deque; @@ -80,6 +81,8 @@ public class MainnetTransactionProcessor { protected final FeeMarket feeMarket; private final CoinbaseFeePriceCalculator coinbaseFeePriceCalculator; + private final Optional maybeAuthorityProcessor; + public MainnetTransactionProcessor( final GasCalculator gasCalculator, final TransactionValidatorFactory transactionValidatorFactory, @@ -90,6 +93,30 @@ public class MainnetTransactionProcessor { final int maxStackSize, final FeeMarket feeMarket, final CoinbaseFeePriceCalculator coinbaseFeePriceCalculator) { + this( + gasCalculator, + transactionValidatorFactory, + contractCreationProcessor, + messageCallProcessor, + clearEmptyAccounts, + warmCoinbase, + maxStackSize, + feeMarket, + coinbaseFeePriceCalculator, + null); + } + + public MainnetTransactionProcessor( + final GasCalculator gasCalculator, + final TransactionValidatorFactory transactionValidatorFactory, + final AbstractMessageProcessor contractCreationProcessor, + final AbstractMessageProcessor messageCallProcessor, + final boolean clearEmptyAccounts, + final boolean warmCoinbase, + final int maxStackSize, + final FeeMarket feeMarket, + final CoinbaseFeePriceCalculator coinbaseFeePriceCalculator, + final AuthorityProcessor maybeAuthorityProcessor) { this.gasCalculator = gasCalculator; this.transactionValidatorFactory = transactionValidatorFactory; this.contractCreationProcessor = contractCreationProcessor; @@ -99,6 +126,7 @@ public class MainnetTransactionProcessor { this.maxStackSize = maxStackSize; this.feeMarket = feeMarket; this.coinbaseFeePriceCalculator = coinbaseFeePriceCalculator; + this.maybeAuthorityProcessor = Optional.ofNullable(maybeAuthorityProcessor); } /** @@ -259,6 +287,8 @@ public class MainnetTransactionProcessor { final PrivateMetadataUpdater privateMetadataUpdater, final Wei blobGasPrice) { try { + final AuthorizedCodeService authorizedCodeService = new AuthorizedCodeService(); + worldState.setAuthorizedCodeService(authorizedCodeService); final var transactionValidator = transactionValidatorFactory.get(); LOG.trace("Starting execution of {}", transaction); ValidationResult validationResult = @@ -332,15 +362,19 @@ public class MainnetTransactionProcessor { transaction.getPayload(), transaction.isContractCreation()); final long accessListGas = gasCalculator.accessListGasCost(accessListEntries.size(), accessListStorageCount); - final long gasAvailable = transaction.getGasLimit() - intrinsicGas - accessListGas; + final long setCodeGas = gasCalculator.setCodeListGasCost(transaction.authorizationListSize()); + final long gasAvailable = + transaction.getGasLimit() - intrinsicGas - accessListGas - setCodeGas; LOG.trace( - "Gas available for execution {} = {} - {} - {} (limit - intrinsic - accessList)", + "Gas available for execution {} = {} - {} - {} - {} (limit - intrinsic - accessList - setCode)", gasAvailable, transaction.getGasLimit(), intrinsicGas, - accessListGas); + accessListGas, + setCodeGas); final WorldUpdater worldUpdater = worldState.updater(); + worldUpdater.setAuthorizedCodeService(authorizedCodeService); final ImmutableMap.Builder contextVariablesBuilder = ImmutableMap.builder() .put(KEY_IS_PERSISTING_PRIVATE_STATE, isPersistingPrivateState) @@ -374,6 +408,15 @@ public class MainnetTransactionProcessor { if (transaction.getVersionedHashes().isPresent()) { commonMessageFrameBuilder.versionedHashes( Optional.of(transaction.getVersionedHashes().get().stream().toList())); + } else if (transaction.getAuthorizationList().isPresent()) { + if (maybeAuthorityProcessor.isEmpty()) { + throw new RuntimeException("Authority processor is required for 7702 transactions"); + } + + maybeAuthorityProcessor + .get() + .addContractToAuthority(worldUpdater, authorizedCodeService, transaction); + addressList.addAll(authorizedCodeService.getAuthorities()); } else { commonMessageFrameBuilder.versionedHashes(Optional.empty()); } @@ -392,6 +435,7 @@ public class MainnetTransactionProcessor { .contract(contractAddress) .inputData(initCodeBytes.slice(code.getSize())) .code(code) + .authorizedCodeService(authorizedCodeService) .build(); } else { @SuppressWarnings("OptionalGetWithoutIsPresent") // isContractCall tests isPresent @@ -407,6 +451,7 @@ public class MainnetTransactionProcessor { maybeContract .map(c -> messageCallProcessor.getCodeFromEVM(c.getCodeHash(), c.getCode())) .orElse(CodeV0.EMPTY_CODE)) + .authorizedCodeService(authorizedCodeService) .build(); } Deque messageFrameStack = initialFrame.getMessageFrameStack(); @@ -485,6 +530,7 @@ public class MainnetTransactionProcessor { coinbaseCalculator.price(usedGas, transactionGasPrice, blockHeader.getBaseFee()); coinbase.incrementBalance(coinbaseWeiDelta); + authorizedCodeService.resetAuthorities(); operationTracer.traceEndTransaction( worldUpdater, diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionValidator.java index 9d90a409a5..481ce70e05 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionValidator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionValidator.java @@ -189,7 +189,8 @@ public class MainnetTransactionValidator implements TransactionValidator { final long intrinsicGasCost = gasCalculator.transactionIntrinsicGasCost( transaction.getPayload(), transaction.isContractCreation()) - + (transaction.getAccessList().map(gasCalculator::accessListGasCost).orElse(0L)); + + (transaction.getAccessList().map(gasCalculator::accessListGasCost).orElse(0L)) + + gasCalculator.setCodeListGasCost(transaction.authorizationListSize()); if (Long.compareUnsigned(intrinsicGasCost, transaction.getGasLimit()) > 0) { return ValidationResult.invalid( TransactionInvalidReason.INTRINSIC_GAS_EXCEEDS_GAS_LIMIT, diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateMutableWorldStateUpdater.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateMutableWorldStateUpdater.java index fc20db7f81..b4e8e28561 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateMutableWorldStateUpdater.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateMutableWorldStateUpdater.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.evm.account.Account; import org.hyperledger.besu.evm.account.MutableAccount; +import org.hyperledger.besu.evm.worldstate.AuthorizedCodeService; import org.hyperledger.besu.evm.worldstate.WorldUpdater; import java.util.Collection; @@ -30,35 +31,39 @@ public class PrivateMutableWorldStateUpdater implements WorldUpdater { protected final WorldUpdater publicWorldUpdater; protected final WorldUpdater privateWorldUpdater; + private AuthorizedCodeService authorizedCodeService; public PrivateMutableWorldStateUpdater( final WorldUpdater publicWorldUpdater, final WorldUpdater privateWorldUpdater) { this.publicWorldUpdater = publicWorldUpdater; this.privateWorldUpdater = privateWorldUpdater; + this.authorizedCodeService = new AuthorizedCodeService(); } @Override public MutableAccount createAccount(final Address address, final long nonce, final Wei balance) { - return privateWorldUpdater.createAccount(address, nonce, balance); + return authorizedCodeService.processMutableAccount( + this, privateWorldUpdater.createAccount(address, nonce, balance), address); } @Override public MutableAccount createAccount(final Address address) { - return privateWorldUpdater.createAccount(address); + return authorizedCodeService.processMutableAccount( + this, privateWorldUpdater.createAccount(address), address); } @Override public MutableAccount getAccount(final Address address) { final MutableAccount privateAccount = privateWorldUpdater.getAccount(address); if (privateAccount != null && !privateAccount.isEmpty()) { - return privateAccount; + return authorizedCodeService.processMutableAccount(this, privateAccount, address); } final MutableAccount publicAccount = publicWorldUpdater.getAccount(address); if (publicAccount != null && !publicAccount.isEmpty()) { publicAccount.becomeImmutable(); - return publicAccount; + return authorizedCodeService.processMutableAccount(this, publicAccount, address); } - return privateAccount; + return authorizedCodeService.processMutableAccount(this, privateAccount, address); } @Override @@ -104,4 +109,9 @@ public class PrivateMutableWorldStateUpdater implements WorldUpdater { public Optional parentUpdater() { return privateWorldUpdater.parentUpdater(); } + + @Override + public void setAuthorizedCodeService(final AuthorizedCodeService authorizedCodeService) { + this.authorizedCodeService = authorizedCodeService; + } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/worldview/accumulator/DiffBasedWorldStateUpdateAccumulator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/worldview/accumulator/DiffBasedWorldStateUpdateAccumulator.java index 149cefbe54..b5bae0aed9 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/worldview/accumulator/DiffBasedWorldStateUpdateAccumulator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/worldview/accumulator/DiffBasedWorldStateUpdateAccumulator.java @@ -136,7 +136,8 @@ public abstract class DiffBasedWorldStateUpdateAccumulator(diffBasedValue.getUpdated())); + return authorizedCodeService.processMutableAccount( + this, track(new UpdateTrackingAccount<>(diffBasedValue.getUpdated())), address); } else { throw new IllegalStateException("Cannot create an account when one already exists"); } @@ -153,7 +154,8 @@ public abstract class DiffBasedWorldStateUpdateAccumulator(newAccount)); + return authorizedCodeService.processMutableAccount( + this, track(new UpdateTrackingAccount<>(newAccount)), address); } @Override 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 c5b797403a..2709b94e29 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 @@ -376,6 +376,7 @@ public class BlockDataGenerator { case EIP1559 -> eip1559Transaction(payload, to); case ACCESS_LIST -> accessListTransaction(payload, to); case BLOB -> blobTransaction(payload, to); + case SET_CODE -> null; // no default, all types accounted for. }; } diff --git a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/TransactionTestFixture.java b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/TransactionTestFixture.java index d016b7f4e5..3f7049be39 100644 --- a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/TransactionTestFixture.java +++ b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/TransactionTestFixture.java @@ -92,6 +92,8 @@ public class TransactionTestFixture { builder.versionedHashes(versionedHashes.get()); } break; + case SET_CODE: + break; } to.ifPresent(builder::to); diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/SetCodeTransactionDecoderTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/SetCodeTransactionDecoderTest.java new file mode 100644 index 0000000000..610b5906f5 --- /dev/null +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/SetCodeTransactionDecoderTest.java @@ -0,0 +1,120 @@ +/* + * 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.AssertionsForClassTypes.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.hyperledger.besu.crypto.SECPSignature; +import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.datatypes.SetCodeAuthorization; +import org.hyperledger.besu.ethereum.rlp.BytesValueRLPInput; + +import java.math.BigInteger; + +import org.apache.tuweni.bytes.Bytes; +import org.junit.jupiter.api.Test; + +class SetCodeTransactionDecoderTest { + + @Test + void shouldDecodeInnerPayloadWithNonce() { + // "0xd80194633688abc3ccf8b0c03088d2d1c6ae4958c2fa56c105" + + final BytesValueRLPInput input = + new BytesValueRLPInput( + Bytes.fromHexString( + "0xf85b0194633688abc3ccf8b0c03088d2d1c6ae4958c2fa56c18080a0840798fa67118e034c1eb7e42fe89e28d7cd5006dc813d5729e5f75b0d1a7ec5a03b1dbace38ceb862a65bf2eac0637693b5c3493bcb2a022dd614c0a74cce0b99"), + true); + final SetCodeAuthorization authorization = SetCodeTransactionDecoder.decodeInnerPayload(input); + + assertThat(authorization.chainId()).isEqualTo(BigInteger.ONE); + assertThat(authorization.address()) + .isEqualTo(Address.fromHexStringStrict("0x633688abc3cCf8B0C03088D2d1C6ae4958c2fA56")); + assertThat(authorization.nonce().get()).isEqualTo(0L); + + final SECPSignature signature = authorization.signature(); + assertThat(signature.getRecId()).isEqualTo((byte) 0); + assertThat(signature.getR().toString(16)) + .isEqualTo("840798fa67118e034c1eb7e42fe89e28d7cd5006dc813d5729e5f75b0d1a7ec5"); + assertThat(signature.getS().toString(16)) + .isEqualTo("3b1dbace38ceb862a65bf2eac0637693b5c3493bcb2a022dd614c0a74cce0b99"); + } + + @Test + void shouldDecodeInnerPayloadWithoutNonce() { + // "0xd70194633688abc3ccf8b0c03088d2d1c6ae4958c2fa56c5" + + final BytesValueRLPInput input = + new BytesValueRLPInput( + Bytes.fromHexString( + "0xf85a0194633688abc3ccf8b0c03088d2d1c6ae4958c2fa56c001a0dd6b24048be1b7d7fe5bbbb73ffc37eb2ce1997ecb4ae5b6096532ef19363148a025b58a1ff8ad00bddbbfa1d5c2411961cbb6d08dcdc8ae88303db3c6cf983031"), + true); + final SetCodeAuthorization authorization = SetCodeTransactionDecoder.decodeInnerPayload(input); + + assertThat(authorization.chainId()).isEqualTo(BigInteger.ONE); + assertThat(authorization.address()) + .isEqualTo(Address.fromHexStringStrict("0x633688abc3cCf8B0C03088D2d1C6ae4958c2fA56")); + assertThat(authorization.nonce()).isEmpty(); + + final SECPSignature signature = authorization.signature(); + assertThat(signature.getRecId()).isEqualTo((byte) 1); + assertThat(signature.getR().toString(16)) + .isEqualTo("dd6b24048be1b7d7fe5bbbb73ffc37eb2ce1997ecb4ae5b6096532ef19363148"); + assertThat(signature.getS().toString(16)) + .isEqualTo("25b58a1ff8ad00bddbbfa1d5c2411961cbb6d08dcdc8ae88303db3c6cf983031"); + } + + @Test + void shouldThrowInnerPayloadWithMultipleNonces() { + // "d90194633688abc3ccf8b0c03088d2d1c6ae4958c2fa56c20107" + + final BytesValueRLPInput input = + new BytesValueRLPInput( + Bytes.fromHexString( + "0xf85c0194633688abc3ccf8b0c03088d2d1c6ae4958c2fa56c2010201a0401b5d4ebe88306448115d1a46a30e5ad1136f2818b4ebb0733d9c4efffd135aa0753ff1dbce6db504ecb9635a64d8c4506ff887e2d2a0d2b7175baf94c849eccc"), + true); + + assertThrows( + IllegalArgumentException.class, + () -> { + SetCodeTransactionDecoder.decodeInnerPayload(input); + }); + } + + @Test + void shouldDecodeInnerPayloadWithoutNonceAndChainIdZero() { + // "d70094633688abc3ccf8b0c03088d2d1c6ae4958c2fa56c5" + + final BytesValueRLPInput input = + new BytesValueRLPInput( + Bytes.fromHexString( + "0xf85a0094633688abc3ccf8b0c03088d2d1c6ae4958c2fa56c001a0025c1240d7ffec0daeedb752d3357aff2e3cd58468f0c2d43ee0ee999e02ace2a03c8a25b2becd6e666f69803d1ae3322f2e137b7745c2c7f19da80f993ffde4df"), + true); + final SetCodeAuthorization authorization = SetCodeTransactionDecoder.decodeInnerPayload(input); + + assertThat(authorization.chainId()).isEqualTo(BigInteger.ZERO); + assertThat(authorization.address()) + .isEqualTo(Address.fromHexStringStrict("0x633688abc3cCf8B0C03088D2d1C6ae4958c2fA56")); + assertThat(authorization.nonce().isEmpty()).isTrue(); + + final SECPSignature signature = authorization.signature(); + assertThat(signature.getRecId()).isEqualTo((byte) 1); + assertThat(signature.getR().toString(16)) + .isEqualTo("25c1240d7ffec0daeedb752d3357aff2e3cd58468f0c2d43ee0ee999e02ace2"); + assertThat(signature.getS().toString(16)) + .isEqualTo("3c8a25b2becd6e666f69803d1ae3322f2e137b7745c2c7f19da80f993ffde4df"); + } +} diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/SetCodeTransactionEncoderTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/SetCodeTransactionEncoderTest.java new file mode 100644 index 0000000000..89211f4ba3 --- /dev/null +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/SetCodeTransactionEncoderTest.java @@ -0,0 +1,122 @@ +/* + * 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.AssertionsForClassTypes.assertThat; + +import org.hyperledger.besu.crypto.SignatureAlgorithm; +import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; +import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.ethereum.core.SetCodeAuthorization; +import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; + +import java.math.BigInteger; +import java.util.Optional; +import java.util.function.Supplier; + +import com.google.common.base.Suppliers; +import org.apache.tuweni.bytes.Bytes; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class SetCodeTransactionEncoderTest { + private static final Supplier SIGNATURE_ALGORITHM = + Suppliers.memoize(SignatureAlgorithmFactory::getInstance); + + BytesValueRLPOutput output; + + @BeforeEach + void setUp() { + output = new BytesValueRLPOutput(); + } + + @Test + void shouldEncodeSingleSetCodeWithNonce() { + // "0xd80194633688abc3ccf8b0c03088d2d1c6ae4958c2fa56c105" + + final SetCodeAuthorization authorization = + new SetCodeAuthorization( + BigInteger.ONE, + Address.fromHexString("0x633688abc3cCf8B0C03088D2d1C6ae4958c2fA56"), + Optional.of(0L), + SIGNATURE_ALGORITHM + .get() + .createSignature( + new BigInteger( + "840798fa67118e034c1eb7e42fe89e28d7cd5006dc813d5729e5f75b0d1a7ec5", 16), + new BigInteger( + "3b1dbace38ceb862a65bf2eac0637693b5c3493bcb2a022dd614c0a74cce0b99", 16), + (byte) 0)); + + SetCodeTransactionEncoder.encodeSingleSetCode(authorization, output); + + assertThat(output.encoded()) + .isEqualTo( + Bytes.fromHexString( + "0xf85b0194633688abc3ccf8b0c03088d2d1c6ae4958c2fa56c18080a0840798fa67118e034c1eb7e42fe89e28d7cd5006dc813d5729e5f75b0d1a7ec5a03b1dbace38ceb862a65bf2eac0637693b5c3493bcb2a022dd614c0a74cce0b99")); + } + + @Test + void shouldEncodeSingleSetCodeWithoutNonce() { + // "0xd70194633688abc3ccf8b0c03088d2d1c6ae4958c2fa56c5" + + final SetCodeAuthorization authorization = + new SetCodeAuthorization( + BigInteger.ONE, + Address.fromHexString("0x633688abc3cCf8B0C03088D2d1C6ae4958c2fA56"), + Optional.empty(), + SIGNATURE_ALGORITHM + .get() + .createSignature( + new BigInteger( + "dd6b24048be1b7d7fe5bbbb73ffc37eb2ce1997ecb4ae5b6096532ef19363148", 16), + new BigInteger( + "25b58a1ff8ad00bddbbfa1d5c2411961cbb6d08dcdc8ae88303db3c6cf983031", 16), + (byte) 1)); + + SetCodeTransactionEncoder.encodeSingleSetCode(authorization, output); + + assertThat(output.encoded()) + .isEqualTo( + Bytes.fromHexString( + "0xf85a0194633688abc3ccf8b0c03088d2d1c6ae4958c2fa56c001a0dd6b24048be1b7d7fe5bbbb73ffc37eb2ce1997ecb4ae5b6096532ef19363148a025b58a1ff8ad00bddbbfa1d5c2411961cbb6d08dcdc8ae88303db3c6cf983031")); + } + + @Test + void shouldEncodeSingleSetCodeWithoutNonceAndChainIdZero() { + // "d70094633688abc3ccf8b0c03088d2d1c6ae4958c2fa56c5" + + final SetCodeAuthorization authorization = + new SetCodeAuthorization( + BigInteger.ZERO, + Address.fromHexString("0x633688abc3cCf8B0C03088D2d1C6ae4958c2fA56"), + Optional.empty(), + SIGNATURE_ALGORITHM + .get() + .createSignature( + new BigInteger( + "25c1240d7ffec0daeedb752d3357aff2e3cd58468f0c2d43ee0ee999e02ace2", 16), + new BigInteger( + "3c8a25b2becd6e666f69803d1ae3322f2e137b7745c2c7f19da80f993ffde4df", 16), + (byte) 1)); + + SetCodeTransactionEncoder.encodeSingleSetCode(authorization, output); + + assertThat(output.encoded()) + .isEqualTo( + Bytes.fromHexString( + "0xf85a8094633688abc3ccf8b0c03088d2d1c6ae4958c2fa56c001a0025c1240d7ffec0daeedb752d3357aff2e3cd58468f0c2d43ee0ee999e02ace2a03c8a25b2becd6e666f69803d1ae3322f2e137b7745c2c7f19da80f993ffde4df")); + } +} diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessorTest.java index d541cbd99a..b2f5718dad 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessorTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessorTest.java @@ -39,6 +39,7 @@ import org.hyperledger.besu.evm.tracing.OperationTracer; import org.hyperledger.besu.evm.worldstate.WorldUpdater; import org.hyperledger.besu.evm.worldstate.WorldView; +import java.math.BigInteger; import java.util.List; import java.util.Optional; import java.util.Set; @@ -87,7 +88,8 @@ class MainnetTransactionProcessorTest { warmCoinbase, MAX_STACK_SIZE, FeeMarket.legacy(), - CoinbaseFeePriceCalculator.frontier()); + CoinbaseFeePriceCalculator.frontier(), + new AuthorityProcessor(Optional.of(BigInteger.ONE))); } @Test diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/PendingTransaction.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/PendingTransaction.java index 79e8c368e0..6ce8f47a7a 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/PendingTransaction.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/PendingTransaction.java @@ -131,6 +131,7 @@ public abstract class PendingTransaction case ACCESS_LIST -> computeAccessListMemorySize(); case EIP1559 -> computeEIP1559MemorySize(); case BLOB -> computeBlobMemorySize(); + case SET_CODE -> computeSetCodeMemorySize(); } + PENDING_TRANSACTION_MEMORY_SIZE; } @@ -164,6 +165,10 @@ public abstract class PendingTransaction + computeBlobWithCommitmentsMemorySize(); } + private int computeSetCodeMemorySize() { + return 0; + } + private int computeBlobWithCommitmentsMemorySize() { final int blobCount = transaction.getBlobCount(); diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/BaseTransactionPoolTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/BaseTransactionPoolTest.java index e717adbed1..bbd4e7322f 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/BaseTransactionPoolTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/BaseTransactionPoolTest.java @@ -128,7 +128,7 @@ public class BaseTransactionPoolTest { final TransactionType txType = TransactionType.values()[randomizeTxType.nextInt(4)]; return switch (txType) { - case FRONTIER, ACCESS_LIST, EIP1559 -> + case FRONTIER, ACCESS_LIST, EIP1559, SET_CODE -> createTransaction(txType, nonce, maxGasPrice, payloadSize, keys); case BLOB -> createTransaction( 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 a56222345c..c5c2bdcf97 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 @@ -1377,6 +1377,7 @@ public class LayersTest extends BaseTransactionPoolTest { case ACCESS_LIST -> createAccessListPendingTransaction(sender, n); case EIP1559 -> createEIP1559PendingTransaction(sender, n); case BLOB -> createBlobPendingTransaction(sender, n); + case SET_CODE -> throw new UnsupportedOperationException(); }); } 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 ee6c5d5f70..6f222166b3 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 @@ -35,6 +35,7 @@ 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.SetCodeAuthorization; import org.hyperledger.besu.ethereum.core.Transaction; import org.hyperledger.besu.ethereum.core.TransactionReceipt; import org.hyperledger.besu.ethereum.core.WithdrawalRequest; @@ -212,6 +213,69 @@ public class T8nExecutor { builder.accessList(entries); } + if (txNode.has("authorizationList")) { + JsonNode authorizationList = txNode.get("authorizationList"); + + if (!authorizationList.isArray()) { + out.printf( + "TX json node unparseable: expected authorizationList to be an array - %s%n", + txNode); + continue; + } + + List authorizations = + new ArrayList<>(authorizationList.size()); + for (JsonNode entryAsJson : authorizationList) { + final BigInteger authorizationChainId = + Bytes.fromHexStringLenient(entryAsJson.get("chainId").textValue()) + .toUnsignedBigInteger(); + final Address authorizationAddress = + Address.fromHexString(entryAsJson.get("address").textValue()); + + JsonNode nonces = entryAsJson.get("nonce"); + + if (nonces == null) { + out.printf( + "TX json node unparseable: expected nonce field to be provided - %s%n", + txNode); + continue; + } + + List authorizationNonces; + if (nonces.isArray()) { + authorizationNonces = new ArrayList<>(nonces.size()); + for (JsonNode nonceAsJson : nonces) { + authorizationNonces.add( + Bytes.fromHexStringLenient(nonceAsJson.textValue()).toLong()); + } + } else { + authorizationNonces = + List.of(Bytes.fromHexStringLenient(nonces.textValue()).toLong()); + } + + final byte authorizationV = + Bytes.fromHexStringLenient(entryAsJson.get("v").textValue()) + .toUnsignedBigInteger() + .byteValueExact(); + final BigInteger authorizationR = + Bytes.fromHexStringLenient(entryAsJson.get("r").textValue()) + .toUnsignedBigInteger(); + final BigInteger authorizationS = + Bytes.fromHexStringLenient(entryAsJson.get("s").textValue()) + .toUnsignedBigInteger(); + + authorizations.add( + SetCodeAuthorization.createSetCodeAuthorizationEntry( + authorizationChainId, + authorizationAddress, + authorizationNonces, + authorizationV, + authorizationR, + authorizationS)); + } + builder.setCodeTransactionPayloads(authorizations); + } + if (txNode.has("blobVersionedHashes")) { JsonNode blobVersionedHashes = txNode.get("blobVersionedHashes"); if (!blobVersionedHashes.isArray()) { @@ -255,7 +319,10 @@ public class T8nExecutor { Bytes.fromHexStringLenient(txNode.get("s").textValue()) .toUnsignedBigInteger(), v.byteValueExact())); - transactions.add(builder.build()); + + final Transaction tx = builder.build(); + + transactions.add(tx); } } } else { diff --git a/evm/src/main/java/org/hyperledger/besu/evm/account/AuthorizedCodeAccount.java b/evm/src/main/java/org/hyperledger/besu/evm/account/AuthorizedCodeAccount.java new file mode 100644 index 0000000000..46acac74f9 --- /dev/null +++ b/evm/src/main/java/org/hyperledger/besu/evm/account/AuthorizedCodeAccount.java @@ -0,0 +1,100 @@ +/* + * Copyright contributors to Hyperledger Besu. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.evm.account; + +import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.datatypes.Hash; +import org.hyperledger.besu.datatypes.Wei; + +import java.util.NavigableMap; + +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; +import org.apache.tuweni.units.bigints.UInt256; + +/** Wraps an EOA account and includes authorized code to be run on behalf of it. */ +public class AuthorizedCodeAccount implements Account { + private final Account wrappedAccount; + private final Bytes authorizedCode; + + /** The hash of the authorized code. */ + protected Hash codeHash = null; + + /** + * Creates a new AuthorizedCodeAccount. + * + * @param wrappedAccount the account that has authorized code to be loaded into it. + * @param authorizedCode the authorized code. + */ + public AuthorizedCodeAccount(final Account wrappedAccount, final Bytes authorizedCode) { + this.wrappedAccount = wrappedAccount; + this.authorizedCode = authorizedCode; + } + + @Override + public Address getAddress() { + return wrappedAccount.getAddress(); + } + + @Override + public boolean isStorageEmpty() { + return wrappedAccount.isStorageEmpty(); + } + + @Override + public Hash getAddressHash() { + return wrappedAccount.getAddressHash(); + } + + @Override + public long getNonce() { + return wrappedAccount.getNonce(); + } + + @Override + public Wei getBalance() { + return wrappedAccount.getBalance(); + } + + @Override + public Bytes getCode() { + return authorizedCode; + } + + @Override + public Hash getCodeHash() { + if (codeHash == null) { + codeHash = authorizedCode.equals(Bytes.EMPTY) ? Hash.EMPTY : Hash.hash(authorizedCode); + } + + return codeHash; + } + + @Override + public UInt256 getStorageValue(final UInt256 key) { + return wrappedAccount.getStorageValue(key); + } + + @Override + public UInt256 getOriginalStorageValue(final UInt256 key) { + return wrappedAccount.getOriginalStorageValue(key); + } + + @Override + public NavigableMap storageEntriesFrom( + final Bytes32 startKeyHash, final int limit) { + return wrappedAccount.storageEntriesFrom(startKeyHash, limit); + } +} diff --git a/evm/src/main/java/org/hyperledger/besu/evm/account/MutableAuthorizedCodeAccount.java b/evm/src/main/java/org/hyperledger/besu/evm/account/MutableAuthorizedCodeAccount.java new file mode 100644 index 0000000000..6d4e30a9c2 --- /dev/null +++ b/evm/src/main/java/org/hyperledger/besu/evm/account/MutableAuthorizedCodeAccount.java @@ -0,0 +1,138 @@ +/* + * Copyright contributors to Hyperledger Besu. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.evm.account; + +import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.datatypes.Hash; +import org.hyperledger.besu.datatypes.Wei; + +import java.util.Map; +import java.util.NavigableMap; + +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; +import org.apache.tuweni.units.bigints.UInt256; + +/** Wraps a mutable EOA account and includes authorized code to be run on behalf of it. */ +public class MutableAuthorizedCodeAccount implements MutableAccount { + + private final MutableAccount wrappedAccount; + private final Bytes authorizedCode; + + /** The hash of the authorized code. */ + protected Hash codeHash = null; + + /** + * Creates a new MutableAuthorizedCodeAccount. + * + * @param wrappedAccount the account that has authorized code to be loaded into it. + * @param authorizedCode the authorized code. + */ + public MutableAuthorizedCodeAccount( + final MutableAccount wrappedAccount, final Bytes authorizedCode) { + this.wrappedAccount = wrappedAccount; + this.authorizedCode = authorizedCode; + } + + @Override + public Address getAddress() { + return wrappedAccount.getAddress(); + } + + @Override + public boolean isStorageEmpty() { + return wrappedAccount.isStorageEmpty(); + } + + @Override + public Hash getAddressHash() { + return wrappedAccount.getAddressHash(); + } + + @Override + public long getNonce() { + return wrappedAccount.getNonce(); + } + + @Override + public Wei getBalance() { + return wrappedAccount.getBalance(); + } + + @Override + public Bytes getCode() { + return authorizedCode; + } + + @Override + public Hash getCodeHash() { + if (codeHash == null) { + codeHash = authorizedCode.equals(Bytes.EMPTY) ? Hash.EMPTY : Hash.hash(authorizedCode); + } + + return codeHash; + } + + @Override + public UInt256 getStorageValue(final UInt256 key) { + return wrappedAccount.getStorageValue(key); + } + + @Override + public UInt256 getOriginalStorageValue(final UInt256 key) { + return wrappedAccount.getOriginalStorageValue(key); + } + + @Override + public NavigableMap storageEntriesFrom( + final Bytes32 startKeyHash, final int limit) { + return wrappedAccount.storageEntriesFrom(startKeyHash, limit); + } + + @Override + public void setNonce(final long value) { + wrappedAccount.setNonce(value); + } + + @Override + public void setBalance(final Wei value) { + wrappedAccount.setBalance(value); + } + + @Override + public void setCode(final Bytes code) { + throw new RuntimeException("Cannot set code on an AuthorizedCodeAccount"); + } + + @Override + public void setStorageValue(final UInt256 key, final UInt256 value) { + wrappedAccount.setStorageValue(key, value); + } + + @Override + public void clearStorage() { + wrappedAccount.clearStorage(); + } + + @Override + public Map getUpdatedStorage() { + return wrappedAccount.getUpdatedStorage(); + } + + @Override + public void becomeImmutable() { + wrappedAccount.becomeImmutable(); + } +} diff --git a/evm/src/main/java/org/hyperledger/besu/evm/fluent/SimpleWorld.java b/evm/src/main/java/org/hyperledger/besu/evm/fluent/SimpleWorld.java index f52e788bab..c64ca3744f 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/fluent/SimpleWorld.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/fluent/SimpleWorld.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.evm.account.Account; import org.hyperledger.besu.evm.account.MutableAccount; +import org.hyperledger.besu.evm.worldstate.AuthorizedCodeService; import org.hyperledger.besu.evm.worldstate.WorldUpdater; import java.util.Collection; @@ -34,6 +35,8 @@ public class SimpleWorld implements WorldUpdater { /** The Accounts. */ Map accounts = new HashMap<>(); + private AuthorizedCodeService authorizedCodeService; + /** Instantiates a new Simple world. */ public SimpleWorld() { this(null); @@ -46,6 +49,7 @@ public class SimpleWorld implements WorldUpdater { */ public SimpleWorld(final SimpleWorld parent) { this.parent = parent; + this.authorizedCodeService = new AuthorizedCodeService(); } @Override @@ -56,11 +60,11 @@ public class SimpleWorld implements WorldUpdater { @Override public Account get(final Address address) { if (accounts.containsKey(address)) { - return accounts.get(address); + return authorizedCodeService.processAccount(this, accounts.get(address), address); } else if (parent != null) { - return parent.get(address); + return authorizedCodeService.processAccount(this, parent.get(address), address); } else { - return null; + return authorizedCodeService.processAccount(this, null, address); } } @@ -71,14 +75,14 @@ public class SimpleWorld implements WorldUpdater { } SimpleAccount account = new SimpleAccount(address, nonce, balance); accounts.put(address, account); - return account; + return authorizedCodeService.processMutableAccount(this, account, address); } @Override public MutableAccount getAccount(final Address address) { SimpleAccount account = accounts.get(address); if (account != null) { - return account; + return authorizedCodeService.processMutableAccount(this, account, address); } Account parentAccount = parent == null ? null : parent.getAccount(address); if (parentAccount != null) { @@ -90,9 +94,9 @@ public class SimpleWorld implements WorldUpdater { parentAccount.getBalance(), parentAccount.getCode()); accounts.put(address, account); - return account; + return authorizedCodeService.processMutableAccount(this, account, address); } - return null; + return authorizedCodeService.processMutableAccount(this, null, address); } @Override @@ -132,4 +136,9 @@ public class SimpleWorld implements WorldUpdater { public Optional parentUpdater() { return Optional.ofNullable(parent); } + + @Override + public void setAuthorizedCodeService(final AuthorizedCodeService authorizedCodeService) { + this.authorizedCodeService = authorizedCodeService; + } } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/frame/MessageFrame.java b/evm/src/main/java/org/hyperledger/besu/evm/frame/MessageFrame.java index e01c915510..cf77619229 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/frame/MessageFrame.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/frame/MessageFrame.java @@ -33,6 +33,7 @@ import org.hyperledger.besu.evm.internal.UnderflowException; import org.hyperledger.besu.evm.log.Log; import org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup; import org.hyperledger.besu.evm.operation.Operation; +import org.hyperledger.besu.evm.worldstate.AuthorizedCodeService; import org.hyperledger.besu.evm.worldstate.WorldUpdater; import java.util.ArrayDeque; @@ -201,6 +202,7 @@ public class MessageFrame { // Global data fields. private final WorldUpdater worldUpdater; + private final AuthorizedCodeService authorizedCodeService; // Metadata fields. private final Type type; @@ -270,7 +272,8 @@ public class MessageFrame { final Consumer completer, final Map contextVariables, final Optional revertReason, - final TxValues txValues) { + final TxValues txValues, + final AuthorizedCodeService authorizedCodeService) { this.txValues = txValues; this.type = type; @@ -290,6 +293,7 @@ public class MessageFrame { this.completer = completer; this.contextVariables = contextVariables; this.revertReason = revertReason; + this.authorizedCodeService = authorizedCodeService; this.undoMark = txValues.transientStorage().mark(); } @@ -423,6 +427,15 @@ public class MessageFrame { return returnData; } + /** + * Return the authorized account service. + * + * @return the authorized account service + */ + public AuthorizedCodeService getAuthorizedCodeService() { + return authorizedCodeService; + } + /** * Set the return data. * @@ -1347,6 +1360,7 @@ public class MessageFrame { private Optional reason = Optional.empty(); private Set
accessListWarmAddresses = emptySet(); private Multimap accessListWarmStorage = HashMultimap.create(); + private AuthorizedCodeService authorizedCodeService; private Optional> versionedHashes = Optional.empty(); @@ -1631,6 +1645,17 @@ public class MessageFrame { return this; } + /** + * Sets authorized account service. + * + * @param authorizedCodeService the authorized account service + * @return the builder + */ + public Builder authorizedCodeService(final AuthorizedCodeService authorizedCodeService) { + this.authorizedCodeService = authorizedCodeService; + return this; + } + private void validate() { if (parentMessageFrame == null) { checkState(worldUpdater != null, "Missing message frame world updater"); @@ -1664,6 +1689,11 @@ public class MessageFrame { WorldUpdater updater; boolean newStatic; TxValues newTxValues; + + if (authorizedCodeService == null) { + authorizedCodeService = new AuthorizedCodeService(); + } + if (parentMessageFrame == null) { newTxValues = new TxValues( @@ -1686,10 +1716,12 @@ public class MessageFrame { newStatic = isStatic; } else { newTxValues = parentMessageFrame.txValues; - updater = parentMessageFrame.worldUpdater.updater(); + updater = parentMessageFrame.getWorldUpdater().updater(); newStatic = isStatic || parentMessageFrame.isStatic; } + updater.setAuthorizedCodeService(authorizedCodeService); + MessageFrame messageFrame = new MessageFrame( type, @@ -1706,7 +1738,8 @@ public class MessageFrame { completer, contextVariables == null ? Map.of() : contextVariables, reason, - newTxValues); + newTxValues, + authorizedCodeService); newTxValues.messageFrameStack().addFirst(messageFrame); messageFrame.warmUpAddress(sender); messageFrame.warmUpAddress(contract); diff --git a/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/GasCalculator.java b/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/GasCalculator.java index 2e1728b234..0af023851c 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/GasCalculator.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/GasCalculator.java @@ -645,4 +645,14 @@ public interface GasCalculator { default long computeExcessBlobGas(final long parentExcessBlobGas, final long blobGasUsed) { return 0L; } + + /** + * Returns the upfront gas cost for EIP 7702 operation. + * + * @param authorizationListLength The length of the authorization list + * @return the gas cost + */ + default long setCodeListGasCost(final int authorizationListLength) { + return 0L; + } } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/PragueGasCalculator.java b/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/PragueGasCalculator.java index e2789bba33..0c223d780b 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/PragueGasCalculator.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/PragueGasCalculator.java @@ -28,6 +28,8 @@ import static org.hyperledger.besu.datatypes.Address.BLS12_MAP_FP2_TO_G2; */ public class PragueGasCalculator extends CancunGasCalculator { + static final long PER_CONTRACT_CODE_BASE_COST = 2500L; + /** Instantiates a new Prague Gas Calculator. */ public PragueGasCalculator() { this(BLS12_MAP_FP2_TO_G2.toArrayUnsafe()[19]); @@ -41,4 +43,9 @@ public class PragueGasCalculator extends CancunGasCalculator { protected PragueGasCalculator(final int maxPrecompile) { super(maxPrecompile); } + + @Override + public long setCodeListGasCost(final int authorizationListLength) { + return PER_CONTRACT_CODE_BASE_COST * authorizationListLength; + } } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCallOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCallOperation.java index 8a82262204..762030bf3b 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCallOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCallOperation.java @@ -230,6 +230,7 @@ public abstract class AbstractCallOperation extends AbstractOperation { .code(code) .isStatic(isStatic(frame)) .completer(child -> complete(frame, child)) + .authorizedCodeService(frame.getAuthorizedCodeService()) .build(); // see note in stack depth check about incrementing cost frame.incrementRemainingGas(cost); diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCreateOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCreateOperation.java index f20c2914a0..16ea218f9c 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCreateOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCreateOperation.java @@ -195,6 +195,7 @@ public abstract class AbstractCreateOperation extends AbstractOperation { .apparentValue(value) .code(code) .completer(child -> complete(parent, child, evm)) + .authorizedCodeService(parent.getAuthorizedCodeService()) .build(); parent.setState(MessageFrame.State.CODE_SUSPENDED); 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 43d7e343ff..e19b6cd8a2 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 @@ -180,6 +180,7 @@ public abstract class AbstractExtCallOperation extends AbstractCallOperation { .code(code) .isStatic(isStatic(frame)) .completer(child -> complete(frame, child)) + .authorizedCodeService(frame.getAuthorizedCodeService()) .build(); frame.setState(MessageFrame.State.CODE_SUSPENDED); diff --git a/evm/src/main/java/org/hyperledger/besu/evm/worldstate/AbstractWorldUpdater.java b/evm/src/main/java/org/hyperledger/besu/evm/worldstate/AbstractWorldUpdater.java index 9623eaf89e..00cd67ddb8 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/worldstate/AbstractWorldUpdater.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/worldstate/AbstractWorldUpdater.java @@ -43,6 +43,9 @@ public abstract class AbstractWorldUpdater> updatedAccounts = new ConcurrentHashMap<>(); @@ -59,6 +62,7 @@ public abstract class AbstractWorldUpdater account = new UpdateTrackingAccount<>(address); account.setNonce(nonce); account.setBalance(balance); - return track(account); + return authorizedCodeService.processMutableAccount(this, track(account), address); } @Override @@ -95,12 +99,12 @@ public abstract class AbstractWorldUpdater(origin)); + return authorizedCodeService.processMutableAccount( + this, track(new UpdateTrackingAccount<>(origin)), address); } } @@ -165,6 +170,11 @@ public abstract class AbstractWorldUpdater authorizedCode = new HashMap<>(); + + /** Creates a new AuthorizedCodeService. */ + public AuthorizedCodeService() {} + + /** + * Authorizes to load the code of authorizedCode into the authorizer account. + * + * @param authorizer the address that gives the authorization. + * @param authorizedCode the code which will be loaded. + */ + public void addAuthorizedCode(final Address authorizer, final Bytes authorizedCode) { + this.authorizedCode.put(authorizer, authorizedCode); + } + + /** + * Return all the authorities that have given their authorization to load the code of another + * account. + * + * @return the set of authorities. + */ + public Set
getAuthorities() { + return authorizedCode.keySet(); + } + + /** Resets all the authorized accounts. */ + public void resetAuthorities() { + authorizedCode.clear(); + } + + /** + * Checks if the provided address has set an authorized to load code into an EOA account. + * + * @param authority the address to check. + * @return {@code true} if the address has been authorized, {@code false} otherwise. + */ + public boolean hasAuthorizedCode(final Address authority) { + return authorizedCode.containsKey(authority); + } + + /** + * Processes the provided account, injecting the authorized code if authorized. + * + * @param worldUpdater the world updater to retrieve the code account. + * @param originalAccount the account to process. + * @param address the address of the account in case the provided account is null + * @return the processed account, containing the authorized code if authorized. + */ + public Account processAccount( + final WorldUpdater worldUpdater, final Account originalAccount, final Address address) { + if (!authorizedCode.containsKey(address)) { + return originalAccount; + } + + Account account = originalAccount; + if (account == null) { + account = worldUpdater.createAccount(address); + } + + return new AuthorizedCodeAccount(account, authorizedCode.get(address)); + } + + /** + * Processes the provided mutable account, injecting the authorized code if authorized. + * + * @param worldUpdater the world updater to retrieve the code account. + * @param originalAccount the mutable account to process. + * @param address the address of the account in case the provided account is null + * @return the processed mutable account, containing the authorized code if authorized. + */ + public MutableAccount processMutableAccount( + final WorldUpdater worldUpdater, + final MutableAccount originalAccount, + final Address address) { + if (!authorizedCode.containsKey(address)) { + return originalAccount; + } + + MutableAccount account = originalAccount; + if (account == null) { + account = worldUpdater.createAccount(address); + } + + return new MutableAuthorizedCodeAccount(account, authorizedCode.get(address)); + } +} diff --git a/evm/src/main/java/org/hyperledger/besu/evm/worldstate/JournaledUpdater.java b/evm/src/main/java/org/hyperledger/besu/evm/worldstate/JournaledUpdater.java index 9987a5be75..2497ed348d 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/worldstate/JournaledUpdater.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/worldstate/JournaledUpdater.java @@ -41,6 +41,7 @@ public class JournaledUpdater implements WorldUpdater { final UndoMap accounts; final UndoSet
deleted; final long undoMark; + private AuthorizedCodeService authorizedCodeService; /** * Instantiates a new Stacked updater. @@ -66,6 +67,7 @@ public class JournaledUpdater implements WorldUpdater { "WorldUpdater must be a JournaledWorldUpdater or an AbstractWorldUpdater"); } undoMark = accounts.mark(); + this.authorizedCodeService = new AuthorizedCodeService(); } /** @@ -126,12 +128,18 @@ public class JournaledUpdater implements WorldUpdater { accounts.values().forEach(JournaledAccount::markTransactionBoundary); } + @Override + public void setAuthorizedCodeService(final AuthorizedCodeService authorizedCodeService) { + this.authorizedCodeService = authorizedCodeService; + } + @Override public MutableAccount createAccount(final Address address, final long nonce, final Wei balance) { JournaledAccount journaledAccount = new JournaledAccount(rootWorld.createAccount(address, nonce, balance)); accounts.put(address, journaledAccount); - return new JournaledAccount(journaledAccount); + return authorizedCodeService.processMutableAccount( + this, new JournaledAccount(journaledAccount), address); } @Override @@ -139,7 +147,7 @@ public class JournaledUpdater implements WorldUpdater { // We may have updated it already, so check that first. final JournaledAccount existing = accounts.get(address); if (existing != null) { - return existing; + return authorizedCodeService.processMutableAccount(this, existing, address); } if (deleted.contains(address)) { return null; @@ -148,11 +156,11 @@ public class JournaledUpdater implements WorldUpdater { // Otherwise, get it from our wrapped view and create a new update tracker. final MutableAccount origin = rootWorld.getAccount(address); if (origin == null) { - return null; + return authorizedCodeService.processMutableAccount(this, null, address); } else { var newAccount = new JournaledAccount(origin); accounts.put(address, newAccount); - return newAccount; + return authorizedCodeService.processMutableAccount(this, newAccount, address); } } @@ -169,12 +177,12 @@ public class JournaledUpdater implements WorldUpdater { public Account get(final Address address) { final MutableAccount existing = accounts.get(address); if (existing != null) { - return existing; + return authorizedCodeService.processAccount(this, existing, address); } if (deleted.contains(address)) { - return null; + return authorizedCodeService.processAccount(this, null, address); } - return rootWorld.get(address); + return authorizedCodeService.processAccount(this, rootWorld.get(address), address); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/worldstate/WorldUpdater.java b/evm/src/main/java/org/hyperledger/besu/evm/worldstate/WorldUpdater.java index 4cbda73279..5144176e79 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/worldstate/WorldUpdater.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/worldstate/WorldUpdater.java @@ -179,4 +179,12 @@ public interface WorldUpdater extends MutableWorldView { default void markTransactionBoundary() { // default is to ignore } + + /** + * Sets the {@link AuthorizedCodeService} associated with this {@link WorldUpdater}. + * + * @param authorizedCodeService the {@link AuthorizedCodeService} to associate with this {@link + * WorldUpdater} + */ + void setAuthorizedCodeService(AuthorizedCodeService authorizedCodeService); } diff --git a/evm/src/test/java/org/hyperledger/besu/evm/toy/ToyWorld.java b/evm/src/test/java/org/hyperledger/besu/evm/toy/ToyWorld.java index e1e9c4c3ad..479376a8fe 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/toy/ToyWorld.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/toy/ToyWorld.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.evm.account.Account; import org.hyperledger.besu.evm.account.MutableAccount; +import org.hyperledger.besu.evm.worldstate.AuthorizedCodeService; import org.hyperledger.besu.evm.worldstate.WorldUpdater; import java.util.Collection; @@ -32,6 +33,7 @@ public class ToyWorld implements WorldUpdater { ToyWorld parent; Map accounts = new HashMap<>(); + private AuthorizedCodeService authorizedCodeService; public ToyWorld() { this(null); @@ -39,6 +41,7 @@ public class ToyWorld implements WorldUpdater { public ToyWorld(final ToyWorld parent) { this.parent = parent; + this.authorizedCodeService = new AuthorizedCodeService(); } @Override @@ -49,11 +52,11 @@ public class ToyWorld implements WorldUpdater { @Override public Account get(final Address address) { if (accounts.containsKey(address)) { - return accounts.get(address); + return authorizedCodeService.processAccount(this, accounts.get(address), address); } else if (parent != null) { - return parent.get(address); + return authorizedCodeService.processAccount(this, parent.get(address), address); } else { - return null; + return authorizedCodeService.processAccount(this, null, address); } } @@ -70,17 +73,17 @@ public class ToyWorld implements WorldUpdater { final Bytes code) { ToyAccount account = new ToyAccount(parentAccount, address, nonce, balance, code); accounts.put(address, account); - return account; + return authorizedCodeService.processMutableAccount(this, account, address); } @Override public MutableAccount getAccount(final Address address) { if (accounts.containsKey(address)) { - return accounts.get(address); + return authorizedCodeService.processMutableAccount(this, accounts.get(address), address); } else if (parent != null) { Account parentAccount = parent.getAccount(address); if (parentAccount == null) { - return null; + return authorizedCodeService.processMutableAccount(this, null, address); } else { return createAccount( parentAccount, @@ -90,7 +93,7 @@ public class ToyWorld implements WorldUpdater { parentAccount.getCode()); } } else { - return null; + return authorizedCodeService.processMutableAccount(this, null, address); } } @@ -128,4 +131,9 @@ public class ToyWorld implements WorldUpdater { public Optional parentUpdater() { return Optional.empty(); } + + @Override + public void setAuthorizedCodeService(final AuthorizedCodeService authorizedCodeService) { + this.authorizedCodeService = authorizedCodeService; + } } From 8eef2df494ccd9bf3d6a69caf828ebb226acfb88 Mon Sep 17 00:00:00 2001 From: garyschulte Date: Wed, 17 Jul 2024 13:45:40 -0700 Subject: [PATCH 048/259] Feature/use gnark-crypto for eip-196 precompiles (#7262) * squash commit, use gnark-crypto for eip-196 * use besu-native 0.9.3 Signed-off-by: garyschulte --- CHANGELOG.md | 4 +- .../AbstractAltBnPrecompiledContract.java | 23 +++--- .../AltBN128AddPrecompiledContract.java | 4 +- .../AltBN128MulPrecompiledContract.java | 4 +- .../AltBN128PairingPrecompiledContract.java | 4 +- gradle/verification-metadata.xml | 70 +++++++++---------- gradle/versions.gradle | 2 +- 7 files changed, 57 insertions(+), 54 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a6b28d0a5c..5fb35c2e0b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,10 +10,12 @@ - `--Xsnapsync-bft-enabled` option enables experimental support for snap sync with IBFT/QBFT permissioned Bonsai-DB chains [#7140](https://github.com/hyperledger/besu/pull/7140) - Add support to load external profiles using `--profile` [#7265](https://github.com/hyperledger/besu/issues/7265) - `privacy-nonce-always-increments` option enables private transactions to always increment the nonce, even if the transaction is invalid [#6593](https://github.com/hyperledger/besu/pull/6593) -- Add `block-test` subcommand to the evmtool which runs blockchain reference tests [#7310](https://github.com/hyperledger/besu/pull/7310) +- Added `block-test` subcommand to the evmtool which runs blockchain reference tests [#7293](https://github.com/hyperledger/besu/pull/7293) +- removed PKI backed QBFT [#7310](https://github.com/hyperledger/besu/pull/7310) - Implement gnark-crypto for eip-2537 [#7316](https://github.com/hyperledger/besu/pull/7316) - Improve blob size transaction selector [#7312](https://github.com/hyperledger/besu/pull/7312) - Added EIP-7702 [#7237](https://github.com/hyperledger/besu/pull/7237) +- implement gnark-crypto for eip-196 [#7262](https://github.com/hyperledger/besu/pull/7262) ### Bug fixes - Fix `eth_call` deserialization to correctly ignore unknown fields in the transaction object. [#7323](https://github.com/hyperledger/besu/pull/7323) diff --git a/evm/src/main/java/org/hyperledger/besu/evm/precompile/AbstractAltBnPrecompiledContract.java b/evm/src/main/java/org/hyperledger/besu/evm/precompile/AbstractAltBnPrecompiledContract.java index 84ce6c6cf9..5f8e4b0a8c 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/precompile/AbstractAltBnPrecompiledContract.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/precompile/AbstractAltBnPrecompiledContract.java @@ -19,7 +19,7 @@ import static java.nio.charset.StandardCharsets.UTF_8; 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.nativelib.bls12_381.LibEthPairings; +import org.hyperledger.besu.nativelib.gnark.LibGnarkEIP196; import java.util.Optional; import javax.annotation.Nonnull; @@ -49,7 +49,7 @@ public abstract class AbstractAltBnPrecompiledContract extends AbstractPrecompil */ public static boolean maybeEnableNative() { try { - useNative = LibEthPairings.ENABLED; + useNative = LibGnarkEIP196.ENABLED; } catch (UnsatisfiedLinkError | NoClassDefFoundError ule) { LOG.info("altbn128 native precompile not available: {}", ule.getMessage()); useNative = false; @@ -72,7 +72,7 @@ public abstract class AbstractAltBnPrecompiledContract extends AbstractPrecompil } private final byte operationId; - private final int inputLen; + private final int inputLimit; /** * Instantiates a new Abstract alt bn precompiled contract. @@ -89,9 +89,9 @@ public abstract class AbstractAltBnPrecompiledContract extends AbstractPrecompil final int inputLen) { super(name, gasCalculator); this.operationId = operationId; - this.inputLen = inputLen + 1; + this.inputLimit = inputLen + 1; - if (!LibEthPairings.ENABLED) { + if (!LibGnarkEIP196.ENABLED) { LOG.info("Native alt bn128 not available"); } } @@ -106,16 +106,16 @@ public abstract class AbstractAltBnPrecompiledContract extends AbstractPrecompil @Nonnull public PrecompileContractResult computeNative( final @Nonnull Bytes input, final MessageFrame messageFrame) { - final byte[] result = new byte[LibEthPairings.EIP196_PREALLOCATE_FOR_RESULT_BYTES]; - final byte[] error = new byte[LibEthPairings.EIP2537_PREALLOCATE_FOR_ERROR_BYTES]; + final byte[] result = new byte[LibGnarkEIP196.EIP196_PREALLOCATE_FOR_RESULT_BYTES]; + final byte[] error = new byte[LibGnarkEIP196.EIP196_PREALLOCATE_FOR_ERROR_BYTES]; final IntByReference o_len = - new IntByReference(LibEthPairings.EIP196_PREALLOCATE_FOR_RESULT_BYTES); + new IntByReference(LibGnarkEIP196.EIP196_PREALLOCATE_FOR_RESULT_BYTES); final IntByReference err_len = - new IntByReference(LibEthPairings.EIP2537_PREALLOCATE_FOR_ERROR_BYTES); - final int inputSize = Math.min(inputLen, input.size()); + new IntByReference(LibGnarkEIP196.EIP196_PREALLOCATE_FOR_ERROR_BYTES); + final int inputSize = Math.min(inputLimit, input.size()); final int errorNo = - LibEthPairings.eip196_perform_operation( + LibGnarkEIP196.eip196_perform_operation( operationId, input.slice(0, inputSize).toArrayUnsafe(), inputSize, @@ -123,6 +123,7 @@ public abstract class AbstractAltBnPrecompiledContract extends AbstractPrecompil o_len, error, err_len); + if (errorNo == 0) { return PrecompileContractResult.success(Bytes.wrap(result, 0, o_len.getValue())); } else { diff --git a/evm/src/main/java/org/hyperledger/besu/evm/precompile/AltBN128AddPrecompiledContract.java b/evm/src/main/java/org/hyperledger/besu/evm/precompile/AltBN128AddPrecompiledContract.java index 026a78c4a2..8aaa276586 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/precompile/AltBN128AddPrecompiledContract.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/precompile/AltBN128AddPrecompiledContract.java @@ -19,7 +19,7 @@ import org.hyperledger.besu.crypto.altbn128.Fq; 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.nativelib.bls12_381.LibEthPairings; +import org.hyperledger.besu.nativelib.gnark.LibGnarkEIP196; import java.math.BigInteger; import java.util.Arrays; @@ -40,7 +40,7 @@ public class AltBN128AddPrecompiledContract extends AbstractAltBnPrecompiledCont super( "AltBN128Add", gasCalculator, - LibEthPairings.EIP196_ADD_OPERATION_RAW_VALUE, + LibGnarkEIP196.EIP196_ADD_OPERATION_RAW_VALUE, PARAMETER_LENGTH); this.gasCost = gasCost; } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/precompile/AltBN128MulPrecompiledContract.java b/evm/src/main/java/org/hyperledger/besu/evm/precompile/AltBN128MulPrecompiledContract.java index 73b824f763..25399d9e71 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/precompile/AltBN128MulPrecompiledContract.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/precompile/AltBN128MulPrecompiledContract.java @@ -19,7 +19,7 @@ import org.hyperledger.besu.crypto.altbn128.Fq; 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.nativelib.bls12_381.LibEthPairings; +import org.hyperledger.besu.nativelib.gnark.LibGnarkEIP196; import java.math.BigInteger; import java.util.Arrays; @@ -44,7 +44,7 @@ public class AltBN128MulPrecompiledContract extends AbstractAltBnPrecompiledCont super( "AltBN128Mul", gasCalculator, - LibEthPairings.EIP196_MUL_OPERATION_RAW_VALUE, + LibGnarkEIP196.EIP196_MUL_OPERATION_RAW_VALUE, PARAMETER_LENGTH); this.gasCost = gasCost; } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/precompile/AltBN128PairingPrecompiledContract.java b/evm/src/main/java/org/hyperledger/besu/evm/precompile/AltBN128PairingPrecompiledContract.java index 82496d4e31..e6cd892233 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/precompile/AltBN128PairingPrecompiledContract.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/precompile/AltBN128PairingPrecompiledContract.java @@ -23,7 +23,7 @@ import org.hyperledger.besu.crypto.altbn128.Fq2; 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.nativelib.bls12_381.LibEthPairings; +import org.hyperledger.besu.nativelib.gnark.LibGnarkEIP196; import java.math.BigInteger; import java.util.ArrayList; @@ -56,7 +56,7 @@ public class AltBN128PairingPrecompiledContract extends AbstractAltBnPrecompiled super( "AltBN128Pairing", gasCalculator, - LibEthPairings.EIP196_PAIR_OPERATION_RAW_VALUE, + LibGnarkEIP196.EIP196_PAIR_OPERATION_RAW_VALUE, Integer.MAX_VALUE / PARAMETER_LENGTH * PARAMETER_LENGTH); this.pairingGasCost = pairingGasCost; this.baseGasCost = baseGasCost; diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index bd437c3a4e..7cdf7ce080 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -4632,12 +4632,12 @@ - - - + + + - - + + @@ -4648,52 +4648,52 @@ - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + diff --git a/gradle/versions.gradle b/gradle/versions.gradle index 0c2289233d..6d176ba7e3 100644 --- a/gradle/versions.gradle +++ b/gradle/versions.gradle @@ -156,7 +156,7 @@ dependencyManagement { dependency 'org.openjdk.jol:jol-core:0.17' dependency 'tech.pegasys:jc-kzg-4844:1.0.0' - dependencySet(group: 'org.hyperledger.besu', version: '0.9.2') { + dependencySet(group: 'org.hyperledger.besu', version: '0.9.3') { entry 'arithmetic' entry 'ipa-multipoint' entry 'bls12-381' From 3925ee4a80add4e0f4353b47b52f2b9d01442882 Mon Sep 17 00:00:00 2001 From: Sally MacFarlane Date: Thu, 18 Jul 2024 10:04:48 +1000 Subject: [PATCH 049/259] exclude permissioning test from default ATs run on PRs (#7327) * exclude permissioning test from default ATs run on PRs Signed-off-by: Sally MacFarlane --------- Signed-off-by: Sally MacFarlane --- acceptance-tests/tests/build.gradle | 32 ++--------------------------- 1 file changed, 2 insertions(+), 30 deletions(-) diff --git a/acceptance-tests/tests/build.gradle b/acceptance-tests/tests/build.gradle index 1bc0e55567..953d1859e8 100644 --- a/acceptance-tests/tests/build.gradle +++ b/acceptance-tests/tests/build.gradle @@ -122,39 +122,11 @@ task acceptanceTest(type: Test) { doFirst { mkdir "${buildDir}/jvmErrorLogs" } } -task acceptanceTestMainnet(type: Test) { - inputs.property "integration.date", LocalTime.now() // so it runs at every invocation - exclude '**/bft/**' - exclude '**/clique/**' - exclude '**/permissioning/**' - exclude '**/privacy/**' - - useJUnitPlatform {} - - dependsOn(rootProject.installDist) - setSystemProperties(test.getSystemProperties()) - systemProperty 'acctests.runBesuAsProcess', 'true' - systemProperty 'java.security.properties', "${buildDir}/resources/test/acceptanceTesting.security" - mustRunAfter rootProject.subprojects*.test - description = 'Runs MAINNET Besu acceptance tests (excluding permissioning, privacy and some other stable features).' - group = 'verification' - - jvmArgs "-XX:ErrorFile=${buildDir}/jvmErrorLogs/java_err_pid%p.log" - - testLogging { - exceptionFormat = 'full' - showStackTraces = true - showStandardStreams = Boolean.getBoolean('acctests.showStandardStreams') - showExceptions = true - showCauses = true - } - - doFirst { mkdir "${buildDir}/jvmErrorLogs" } -} task acceptanceTestNotPrivacy(type: Test) { inputs.property "integration.date", LocalTime.now() // so it runs at every invocation exclude '**/privacy/**' + exclude '**/permissioning/**' exclude '**/bftsoak/**' useJUnitPlatform {} @@ -164,7 +136,7 @@ task acceptanceTestNotPrivacy(type: Test) { systemProperty 'acctests.runBesuAsProcess', 'true' systemProperty 'java.security.properties', "${buildDir}/resources/test/acceptanceTesting.security" mustRunAfter rootProject.subprojects*.test - description = 'Runs MAINNET Besu acceptance tests (excluding privacy since they run nightly, and are being refactored).' + description = 'Runs MAINNET Besu acceptance tests (excluding specific non-mainnet suites).' group = 'verification' jvmArgs "-XX:ErrorFile=${buildDir}/jvmErrorLogs/java_err_pid%p.log" From cee973d429e41391927eb611b93b046eeba1c540 Mon Sep 17 00:00:00 2001 From: Gabriel-Trintinalia Date: Thu, 18 Jul 2024 10:28:29 +1000 Subject: [PATCH 050/259] [minor] Remove redundant info from plugin summary (#7339) Signed-off-by: Gabriel-Trintinalia --- .../besu/services/BesuPluginContextImpl.java | 18 ++++++++---------- plugin-api/build.gradle | 2 +- .../hyperledger/besu/plugin/BesuPlugin.java | 2 +- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/besu/src/main/java/org/hyperledger/besu/services/BesuPluginContextImpl.java b/besu/src/main/java/org/hyperledger/besu/services/BesuPluginContextImpl.java index 6aa64ac510..ddf6940292 100644 --- a/besu/src/main/java/org/hyperledger/besu/services/BesuPluginContextImpl.java +++ b/besu/src/main/java/org/hyperledger/besu/services/BesuPluginContextImpl.java @@ -379,22 +379,20 @@ public class BesuPluginContextImpl implements BesuContext, PluginVersionsProvide plugin -> summary.add( String.format( - " - %s (Version: %s)", - plugin.getClass().getSimpleName(), plugin.getVersion()))); + " - %s (%s)", plugin.getClass().getSimpleName(), plugin.getVersion()))); } // Identify and log detected but not registered (skipped) plugins - List skippedPlugins = - detectedPlugins.stream() - .filter(plugin -> !registeredPlugins.contains(plugin)) - .map(plugin -> plugin.getClass().getSimpleName()) - .toList(); + List skippedPlugins = + detectedPlugins.stream().filter(plugin -> !registeredPlugins.contains(plugin)).toList(); if (!skippedPlugins.isEmpty()) { - summary.add("Skipped Plugins:"); + summary.add("Detected but not registered:"); skippedPlugins.forEach( - pluginName -> - summary.add(String.format(" - %s (Detected but not registered)", pluginName))); + plugin -> + summary.add( + String.format( + " - %s (%s)", plugin.getClass().getSimpleName(), plugin.getVersion()))); } summary.add( String.format( diff --git a/plugin-api/build.gradle b/plugin-api/build.gradle index 1ea78e7f3a..58c241509e 100644 --- a/plugin-api/build.gradle +++ b/plugin-api/build.gradle @@ -70,7 +70,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 = 'vWxI4pduLCvzqU73k5kJsoeK9t7QTqOBC9IxksFuzBs=' + knownHash = 'F07ix5Mkvycb2W2luprKmcMyrWcSLB4Xtou5Id10DW0=' } check.dependsOn('checkAPIChanges') diff --git a/plugin-api/src/main/java/org/hyperledger/besu/plugin/BesuPlugin.java b/plugin-api/src/main/java/org/hyperledger/besu/plugin/BesuPlugin.java index 952f1fb074..1d7acf3a3e 100644 --- a/plugin-api/src/main/java/org/hyperledger/besu/plugin/BesuPlugin.java +++ b/plugin-api/src/main/java/org/hyperledger/besu/plugin/BesuPlugin.java @@ -105,6 +105,6 @@ public interface BesuPlugin { Optional.ofNullable(pluginPackage.getImplementationVersion()) .filter(version -> !version.isBlank()) .orElse(""); - return implTitle + "/v" + implVersion; + return implTitle + "/" + implVersion; } } From 39e276fd10b0c2c28e1893efc6303f4857d40218 Mon Sep 17 00:00:00 2001 From: Sally MacFarlane Date: Thu, 18 Jul 2024 11:29:17 +1000 Subject: [PATCH 051/259] Refactor - eliminate non-constant string concatenation from debug and trace (#7336) * eliminate non-constant string concatenation from debug and trace Signed-off-by: Sally MacFarlane * adjustments Signed-off-by: Sally MacFarlane --------- Signed-off-by: Sally MacFarlane --- besu/src/main/java/org/hyperledger/besu/Runner.java | 2 +- .../besu/ethereum/chain/ChainDataPruner.java | 2 +- .../common/DiffBasedWorldStateProvider.java | 12 ++++++------ .../besu/ethereum/eth/manager/EthPeer.java | 6 +++++- .../besu/ethereum/eth/manager/EthScheduler.java | 7 +++++-- .../eth/manager/snap/SnapProtocolManager.java | 9 +++++---- .../hyperledger/besu/nat/upnp/UpnpNatManager.java | 5 ++++- 7 files changed, 27 insertions(+), 16 deletions(-) diff --git a/besu/src/main/java/org/hyperledger/besu/Runner.java b/besu/src/main/java/org/hyperledger/besu/Runner.java index 4444f7acf7..eed35a03a9 100644 --- a/besu/src/main/java/org/hyperledger/besu/Runner.java +++ b/besu/src/main/java/org/hyperledger/besu/Runner.java @@ -253,7 +253,7 @@ public class Runner implements AutoCloseable { try { shutdown.await(); } catch (final InterruptedException e) { - LOG.debug("Interrupted while waiting for service " + serviceName + " to stop", e); + LOG.debug("Interrupted while waiting for service {} to stop {}", serviceName, e); Thread.currentThread().interrupt(); } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/chain/ChainDataPruner.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/chain/ChainDataPruner.java index 11a1500e4e..37025feca7 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/chain/ChainDataPruner.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/chain/ChainDataPruner.java @@ -76,7 +76,7 @@ public class ChainDataPruner implements BlockAddedObserver { if (event.isNewCanonicalHead() && blocksToBePruned >= pruningFrequency) { long currentRetainedBlock = blockNumber - currentPruningMark + 1; while (currentRetainedBlock > blocksToRetain) { - LOG.debug("Pruning chain data with block height of " + currentPruningMark); + LOG.debug("Pruning chain data with block height of {}", currentPruningMark); pruneChainDataAtBlock(pruningTransaction, currentPruningMark); currentPruningMark++; currentRetainedBlock = blockNumber - currentPruningMark; diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/DiffBasedWorldStateProvider.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/DiffBasedWorldStateProvider.java index 857ec0b079..75b370c1cd 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/DiffBasedWorldStateProvider.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/DiffBasedWorldStateProvider.java @@ -230,12 +230,12 @@ public abstract class DiffBasedWorldStateProvider implements WorldStateArchive { } catch (final Exception e) { // if we fail we must clean up the updater diffBasedUpdater.reset(); - LOG.debug( - "State rolling failed on " - + mutableState.getWorldStateStorage().getClass().getSimpleName() - + " for block hash " - + blockHash, - e); + LOG.atDebug() + .setMessage("State rolling failed on {} for block hash {}") + .addArgument(mutableState.getWorldStateStorage().getClass().getSimpleName()) + .addArgument(blockHash) + .addArgument(e) + .log(); return Optional.empty(); } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/EthPeer.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/EthPeer.java index 8cc907d686..755283b080 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/EthPeer.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/EthPeer.java @@ -710,7 +710,11 @@ public class EthPeer implements Comparable { } } // Otherwise, keep older connection - LOG.trace("comparing timestamps " + a.getInitiatedAt() + " with " + b.getInitiatedAt()); + LOG.atTrace() + .setMessage("comparing timestamps {} with {}") + .addArgument(a.getInitiatedAt()) + .addArgument(b.getInitiatedAt()) + .log(); return a.getInitiatedAt() < b.getInitiatedAt() ? -1 : 1; } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/EthScheduler.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/EthScheduler.java index dcb6669666..1e2f3eb6ab 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/EthScheduler.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/EthScheduler.java @@ -243,7 +243,7 @@ public class EthScheduler { public void stop() { if (stopped.compareAndSet(false, true)) { - LOG.trace("Stopping " + getClass().getSimpleName()); + LOG.atTrace().setMessage("Stopping {}").addArgument(getClass().getSimpleName()).log(); syncWorkerExecutor.shutdownNow(); txWorkerExecutor.shutdownNow(); scheduler.shutdownNow(); @@ -251,7 +251,10 @@ public class EthScheduler { computationExecutor.shutdownNow(); shutdown.countDown(); } else { - LOG.trace("Attempted to stop already stopped " + getClass().getSimpleName()); + LOG.atTrace() + .setMessage("Attempted to stop already stopped {}") + .addArgument(getClass().getSimpleName()) + .log(); } } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/SnapProtocolManager.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/SnapProtocolManager.java index c65a1c6b0c..ce639a7a9a 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/SnapProtocolManager.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/SnapProtocolManager.java @@ -97,7 +97,7 @@ public class SnapProtocolManager implements ProtocolManager { final EthPeer ethPeer = ethPeers.peer(message.getConnection()); if (ethPeer == null) { LOG.debug( - "Ignoring message received from unknown peer connection: " + message.getConnection()); + "Ignoring message received from unknown peer connection: {}", message.getConnection()); return; } final EthMessage ethMessage = new EthMessage(ethPeer, messageData); @@ -132,9 +132,10 @@ public class SnapProtocolManager implements ProtocolManager { try { ethPeer.send(responseData, getSupportedProtocol()); } catch (final PeerConnection.PeerNotConnected error) { - // Peer disconnected before we could respond - nothing to do - LOG.trace( - "Peer disconnected before we could respond - nothing to do " + error.getMessage()); + LOG.atTrace() + .setMessage("Peer disconnected before we could respond - nothing to do {}") + .addArgument(error.getMessage()) + .log(); } }); } diff --git a/nat/src/main/java/org/hyperledger/besu/nat/upnp/UpnpNatManager.java b/nat/src/main/java/org/hyperledger/besu/nat/upnp/UpnpNatManager.java index a7386d7f78..292fb0b007 100644 --- a/nat/src/main/java/org/hyperledger/besu/nat/upnp/UpnpNatManager.java +++ b/nat/src/main/java/org/hyperledger/besu/nat/upnp/UpnpNatManager.java @@ -101,7 +101,10 @@ public class UpnpNatManager extends AbstractNatManager { new BesuUpnpRegistryListener() { @Override public void remoteDeviceAdded(final Registry registry, final RemoteDevice device) { - LOG.debug("UPnP Device discovered: " + device.getDetails().getFriendlyName()); + LOG.atDebug() + .setMessage("UPnP Device discovered: {}") + .addArgument(device.getDetails().getFriendlyName()) + .log(); inspectDeviceRecursive(device, recognizedServices.keySet()); } }; From 592acb7b5054a7a30cf460e12335c716e2c6ab81 Mon Sep 17 00:00:00 2001 From: Simon Dudley Date: Thu, 18 Jul 2024 14:09:41 +1000 Subject: [PATCH 052/259] Update release checklist (#7329) Signed-off-by: Simon Dudley --- .github/ISSUE_TEMPLATE/release-checklist.md | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/release-checklist.md b/.github/ISSUE_TEMPLATE/release-checklist.md index f484b7a590..9840a3fa49 100644 --- a/.github/ISSUE_TEMPLATE/release-checklist.md +++ b/.github/ISSUE_TEMPLATE/release-checklist.md @@ -8,8 +8,8 @@ assignees: '' --- - [ ] Confirm anything outstanding for release with other maintainers on #besu-release in Discord +- [ ] Update changelog if necessary, and merge a PR for it to main - [ ] Notify maintainers about updating changelog for in-flight PRs - - [ ] Update changelog if necessary, and merge a PR for it to main - [ ] Optional: for hotfixes, create a release branch and cherry-pick, e.g. `release--hotfix` - [ ] Optional: 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` @@ -18,18 +18,14 @@ assignees: '' - [ ] Sign off burn-in; convey burn-in results in #besu-release in Discord - [ ] 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: - - makes the release "latest" in github - 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 -- [ ] Draft homebrew PR -- [ ] Draft documentation release -- [ ] Ensure binary SHAs are correct on the release page -- [ ] Docker release startup test: - - `docker run hyperledger/besu:` - - `docker run hyperledger/besu:-arm64` - - `docker run --platform linux/amd64 hyperledger/besu:-amd64` - - `docker run --pull=always hyperledger/besu:latest` (check version is ) -- [ ] Merge homebrew PR -- [ ] Publish Docs Release +- [ ] Check binary SHAs are correct on the release page +- [ ] Check "Container Verify" GitHub workflow has run successfully +- [ ] Create homebrew release - run https://github.com/hyperledger/homebrew-besu/actions/workflows/update-version.yml +- [ ] Create besu-docs release - https://github.com/hyperledger/besu-docs/releases/new + - Copy release notes from besu + - If publishing the release in github doesn't automatically trigger this workflow, then manually run https://github.com/hyperledger/besu-docs/actions/workflows/update-version.yml - [ ] Social announcements From 7a905f8b0a4266809c6789060490df538e350d5c Mon Sep 17 00:00:00 2001 From: Simon Dudley Date: Fri, 19 Jul 2024 03:21:08 +1000 Subject: [PATCH 053/259] Add metrics for trie log pruner (#7352) --------- Signed-off-by: Simon Dudley --- CHANGELOG.md | 9 ++++- .../controller/BesuControllerBuilder.java | 3 +- .../common/trielog/TrieLogPruner.java | 23 ++++++++++++- .../bonsai/trielog/TrieLogPrunerTest.java | 34 +++++++++++++++---- 4 files changed, 60 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5fb35c2e0b..7710f8e7b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ ## Next release +### Upcoming Breaking Changes +- Receipt compaction will be enabled by default in a future version of Besu. After this change it will not be possible to downgrade to the previous Besu version. +- --Xbonsai-limit-trie-logs-enabled is deprecated, use --bonsai-limit-trie-logs-enabled instead +- --Xbonsai-trie-logs-pruning-window-size is deprecated, use --bonsai-trie-logs-pruning-window-size instead +- `besu storage x-trie-log` subcommand is deprecated, use `besu storage trie-log` instead + ### Breaking Changes - Remove deprecated sync modes (X_SNAP and X_CHECKPOINT). Use SNAP and CHECKPOINT instead [#7309](https://github.com/hyperledger/besu/pull/7309) - Remove PKI-backed QBFT (deprecated in 24.5.1) Other forms of QBFT remain unchanged. [#7293](https://github.com/hyperledger/besu/pull/7293) @@ -15,7 +21,8 @@ - Implement gnark-crypto for eip-2537 [#7316](https://github.com/hyperledger/besu/pull/7316) - Improve blob size transaction selector [#7312](https://github.com/hyperledger/besu/pull/7312) - Added EIP-7702 [#7237](https://github.com/hyperledger/besu/pull/7237) -- implement gnark-crypto for eip-196 [#7262](https://github.com/hyperledger/besu/pull/7262) +- Implement gnark-crypto for eip-196 [#7262](https://github.com/hyperledger/besu/pull/7262) +- Add trie log pruner metrics [#7352](https://github.com/hyperledger/besu/pull/7352) ### Bug fixes - Fix `eth_call` deserialization to correctly ignore unknown fields in the transaction object. [#7323](https://github.com/hyperledger/besu/pull/7323) 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 8f26909a51..20f3ca8ef6 100644 --- a/besu/src/main/java/org/hyperledger/besu/controller/BesuControllerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/controller/BesuControllerBuilder.java @@ -793,7 +793,8 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides scheduler::executeServiceTask, dataStorageConfiguration.getBonsaiMaxLayersToLoad(), dataStorageConfiguration.getBonsaiTrieLogPruningWindowSize(), - isProofOfStake); + isProofOfStake, + metricsSystem); trieLogPruner.initialize(); return trieLogPruner; diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/trielog/TrieLogPruner.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/trielog/TrieLogPruner.java index 6f347be033..cea5c1a327 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/trielog/TrieLogPruner.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/trielog/TrieLogPruner.java @@ -19,6 +19,9 @@ import org.hyperledger.besu.ethereum.chain.Blockchain; import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.ProcessableBlockHeader; import org.hyperledger.besu.ethereum.trie.diffbased.common.storage.DiffBasedWorldStateKeyValueStorage; +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.trielogs.TrieLogEvent; import java.util.Comparator; @@ -45,6 +48,9 @@ public class TrieLogPruner implements TrieLogEvent.TrieLogObserver { private final Consumer executeAsync; private final long numBlocksToRetain; private final boolean requireFinalizedBlock; + private final Counter addedToPruneQueueCounter; + private final Counter prunedFromQueueCounter; + private final Counter prunedOrphanCounter; private final Multimap trieLogBlocksAndForksByDescendingBlockNumber = TreeMultimap.create(Comparator.reverseOrder(), Comparator.naturalOrder()); @@ -55,7 +61,8 @@ public class TrieLogPruner implements TrieLogEvent.TrieLogObserver { final Consumer executeAsync, final long numBlocksToRetain, final int pruningLimit, - final boolean requireFinalizedBlock) { + final boolean requireFinalizedBlock, + final MetricsSystem metricsSystem) { this.rootWorldStateStorage = rootWorldStateStorage; this.blockchain = blockchain; this.executeAsync = executeAsync; @@ -63,6 +70,17 @@ public class TrieLogPruner implements TrieLogEvent.TrieLogObserver { this.pruningLimit = pruningLimit; this.loadingLimit = pruningLimit; // same as pruningLimit for now this.requireFinalizedBlock = requireFinalizedBlock; + this.addedToPruneQueueCounter = + metricsSystem.createCounter( + BesuMetricCategory.PRUNER, + "trie_log_added_to_prune_queue", + "trie log added to prune queue"); + this.prunedFromQueueCounter = + metricsSystem.createCounter( + BesuMetricCategory.PRUNER, "trie_log_pruned_from_queue", "trie log pruned from queue"); + this.prunedOrphanCounter = + metricsSystem.createCounter( + BesuMetricCategory.PRUNER, "trie_log_pruned_orphan", "trie log pruned orphan"); } public int initialize() { @@ -88,6 +106,7 @@ public class TrieLogPruner implements TrieLogEvent.TrieLogObserver { // prune orphaned blocks (sometimes created during block production) rootWorldStateStorage.pruneTrieLog(blockHash); orphansPruned.getAndIncrement(); + prunedOrphanCounter.inc(); } }); LOG.atDebug().log("Pruned {} orphaned trie logs from database...", orphansPruned.intValue()); @@ -106,6 +125,7 @@ public class TrieLogPruner implements TrieLogEvent.TrieLogObserver { .addArgument(blockHash) .log(); trieLogBlocksAndForksByDescendingBlockNumber.put(blockNumber, blockHash); + addedToPruneQueueCounter.inc(); } public synchronized int pruneFromQueue() { @@ -155,6 +175,7 @@ public class TrieLogPruner implements TrieLogEvent.TrieLogObserver { }); wasPruned.keySet().forEach(trieLogBlocksAndForksByDescendingBlockNumber::removeAll); + prunedFromQueueCounter.inc(wasPruned.size()); LOG.atTrace() .setMessage("pruned {} trie logs for blocks {}") diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/trielog/TrieLogPrunerTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/trielog/TrieLogPrunerTest.java index bca954a493..621e73711a 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/trielog/TrieLogPrunerTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/trielog/TrieLogPrunerTest.java @@ -29,6 +29,7 @@ import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.BonsaiWorldSt import org.hyperledger.besu.ethereum.trie.diffbased.common.trielog.TrieLogAddedEvent; import org.hyperledger.besu.ethereum.trie.diffbased.common.trielog.TrieLogLayer; import org.hyperledger.besu.ethereum.trie.diffbased.common.trielog.TrieLogPruner; +import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import java.util.Optional; import java.util.function.Consumer; @@ -72,7 +73,8 @@ public class TrieLogPrunerTest { // When TrieLogPruner trieLogPruner = - new TrieLogPruner(worldState, blockchain, executeAsync, 3, loadingLimit, false); + new TrieLogPruner( + worldState, blockchain, executeAsync, 3, loadingLimit, false, new NoOpMetricsSystem()); trieLogPruner.initialize(); // Then @@ -92,7 +94,13 @@ public class TrieLogPrunerTest { // requireFinalizedBlock = false means this is not a PoS chain TrieLogPruner trieLogPruner = new TrieLogPruner( - worldState, blockchain, executeAsync, blocksToRetain, pruningWindowSize, false); + worldState, + blockchain, + executeAsync, + blocksToRetain, + pruningWindowSize, + false, + new NoOpMetricsSystem()); trieLogPruner.addToPruneQueue(0, key(0)); // older block outside prune window trieLogPruner.addToPruneQueue(1, key(1)); // block inside the prune window @@ -201,7 +209,13 @@ public class TrieLogPrunerTest { when(blockchain.getChainHeadBlockNumber()).thenReturn(chainHeight); TrieLogPruner trieLogPruner = new TrieLogPruner( - worldState, blockchain, executeAsync, blocksToRetain, pruningWindowSize, true); + worldState, + blockchain, + executeAsync, + blocksToRetain, + pruningWindowSize, + true, + new NoOpMetricsSystem()); trieLogPruner.addToPruneQueue(1, key(1)); trieLogPruner.addToPruneQueue(2, key(2)); @@ -240,7 +254,8 @@ public class TrieLogPrunerTest { // Given final TriggerableConsumer triggerableConsumer = new TriggerableConsumer(); TrieLogPruner trieLogPruner = - new TrieLogPruner(worldState, blockchain, triggerableConsumer, 0, 1, false); + new TrieLogPruner( + worldState, blockchain, triggerableConsumer, 0, 1, false, new NoOpMetricsSystem()); assertThat(trieLogPruner.pruneFromQueue()).isEqualTo(0); final TrieLogLayer layer = new TrieLogLayer(); @@ -261,7 +276,8 @@ public class TrieLogPrunerTest { public void onTrieLogAdded_should_not_prune_when_no_blockNumber() { // Given TrieLogPruner trieLogPruner = - new TrieLogPruner(worldState, blockchain, executeAsync, 0, 1, false); + new TrieLogPruner( + worldState, blockchain, executeAsync, 0, 1, false, new NoOpMetricsSystem()); assertThat(trieLogPruner.pruneFromQueue()).isEqualTo(0); final TrieLogLayer layer = new TrieLogLayer(); @@ -289,7 +305,13 @@ public class TrieLogPrunerTest { when(blockchain.getChainHeadBlockNumber()).thenReturn(chainHeight); TrieLogPruner trieLogPruner = new TrieLogPruner( - worldState, blockchain, executeAsync, blocksToRetain, pruningWindowSize, true); + worldState, + blockchain, + executeAsync, + blocksToRetain, + pruningWindowSize, + true, + new NoOpMetricsSystem()); trieLogPruner.addToPruneQueue(1, key(1)); trieLogPruner.addToPruneQueue(2, key(2)); From 30c96c7a1d6e379854d91f3f43914b5d564f3381 Mon Sep 17 00:00:00 2001 From: Karim Taam Date: Fri, 19 Jul 2024 18:11:30 +0200 Subject: [PATCH 054/259] Optimistic parallelization of transactions to improve performance (#7296) Optimistic transaction parallelization execution during block processing to improve the performances. This feature can enabled with a flag --Xbonsai-parallel-tx-processing-enabled=true Signed-off-by: Karim Taam Co-authored-by: Ameziane H Co-authored-by: garyschulte --- CHANGELOG.md | 1 + .../org/hyperledger/besu/cli/BesuCommand.java | 2 + .../options/stable/DataStorageOptions.java | 81 +++-- .../controller/BesuControllerBuilder.java | 17 + .../CliqueBesuControllerBuilder.java | 4 +- ...onsensusScheduleBesuControllerBuilder.java | 9 + .../controller/IbftBesuControllerBuilder.java | 4 +- .../MainnetBesuControllerBuilder.java | 4 +- .../MergeBesuControllerBuilder.java | 4 +- .../controller/QbftBesuControllerBuilder.java | 4 +- .../TransitionBesuControllerBuilder.java | 7 + .../besu/ForkIdsNetworkConfigTest.java | 14 +- .../besu/cli/CommandTestAbstract.java | 2 + .../clique/CliqueProtocolSchedule.java | 23 +- .../clique/CliqueProtocolScheduleTest.java | 21 +- .../blockcreation/CliqueBlockCreatorTest.java | 4 +- .../CliqueMinerExecutorTest.java | 4 +- .../bft/BaseBftProtocolScheduleBuilder.java | 12 +- .../CombinedProtocolScheduleFactoryTest.java | 5 +- .../BaseBftProtocolScheduleBuilderTest.java | 5 +- .../ibft/support/TestContextBuilder.java | 4 +- .../ibft/IbftProtocolScheduleBuilder.java | 23 +- .../ibft/IbftProtocolScheduleTest.java | 5 +- .../blockcreation/BftBlockCreatorTest.java | 4 +- .../IbftBlockHeightManagerTest.java | 5 +- .../merge/MergeProtocolSchedule.java | 19 +- .../merge/TransitionProtocolSchedule.java | 20 +- .../merge/MergeProtocolScheduleTest.java | 33 +- .../MergeGenesisConfigHelper.java | 5 +- .../qbft/support/TestContextBuilder.java | 4 +- .../qbft/QbftProtocolScheduleBuilder.java | 34 +- .../qbft/QbftProtocolScheduleTest.java | 5 +- .../QbftBlockHeightManagerTest.java | 5 +- .../besu/crypto/Blake2bfMessageDigest.java | 30 +- .../crypto/Blake2bfMessageDigestTest.java | 50 +++ .../besu/datatypes/StorageSlotKey.java | 2 +- .../api/jsonrpc/BlockchainImporter.java | 5 +- .../JsonRpcHttpServiceHostAllowlistTest.java | 4 +- .../jsonrpc/JsonRpcHttpServiceLoginTest.java | 6 +- .../jsonrpc/JsonRpcHttpServiceTestBase.java | 4 +- .../JsonRpcHttpServiceTlsClientAuthTest.java | 4 +- ...RpcHttpServiceTlsMisconfigurationTest.java | 4 +- .../jsonrpc/JsonRpcHttpServiceTlsTest.java | 4 +- .../websocket/WebSocketServiceLoginTest.java | 4 +- .../AbstractBlockCreatorTest.java | 4 +- .../AbstractBlockTransactionSelectorTest.java | 4 +- ...FeeMarketBlockTransactionSelectorTest.java | 5 +- ...FeeMarketBlockTransactionSelectorTest.java | 5 +- .../blockcreation/PoWBlockCreatorTest.java | 24 +- .../FixedDifficultyProtocolSchedule.java | 25 +- .../mainnet/AbstractBlockProcessor.java | 119 ++++--- .../mainnet/ClassicProtocolSpecs.java | 125 ++++++-- .../mainnet/MainnetProtocolSchedule.java | 42 ++- .../mainnet/MainnetProtocolSpecFactory.java | 209 +++++++++++-- .../mainnet/MainnetProtocolSpecs.java | 268 ++++++++++++---- .../mainnet/MainnetTransactionProcessor.java | 4 +- .../mainnet/ProtocolScheduleBuilder.java | 32 +- .../ethereum/mainnet/ProtocolSpecBuilder.java | 3 + .../MainnetParallelBlockProcessor.java | 199 ++++++++++++ ...lelizedConcurrentTransactionProcessor.java | 268 ++++++++++++++++ .../ParallelizedTransactionContext.java | 133 ++++++++ .../TransactionCollisionDetector.java | 114 +++++++ .../NoopBonsaiCachedMerkleTrieLoader.java | 44 +++ .../bonsai/worldview/BonsaiWorldState.java | 12 + .../DiffBasedWorldStateUpdateAccumulator.java | 126 +++++++- .../worldstate/DataStorageConfiguration.java | 7 + .../ethereum/core/BlockchainSetupUtil.java | 4 +- .../core/ExecutionContextTestFixture.java | 4 +- .../core/ProtocolScheduleFixture.java | 5 +- .../BlockImportExceptionHandlingTest.java | 6 + .../fixed/FixedProtocolScheduleTest.java | 5 +- .../mainnet/DefaultProtocolScheduleTest.java | 5 +- .../mainnet/MainnetProtocolScheduleTest.java | 13 +- .../mainnet/ProtocolScheduleBuilderTest.java | 9 +- ...zedConcurrentTransactionProcessorTest.java | 213 +++++++++++++ .../TransactionCollisionDetectorTest.java | 290 ++++++++++++++++++ .../bonsai/AbstractIsolationTests.java | 4 +- .../eth/messages/BlockBodiesMessageTest.java | 5 +- .../eth/messages/BlockHeadersMessageTest.java | 5 +- .../eth/sync/ChainHeadTrackerTest.java | 4 +- .../backwardsync/BackwardSyncContextTest.java | 7 +- .../backwardsync/BackwardSyncStepTest.java | 7 +- .../backwardsync/ForwardSyncStepTest.java | 7 +- .../AbstractTransactionPoolTest.java | 4 +- .../ethereum/eth/transactions/TestNode.java | 4 +- .../TransactionPoolFactoryTest.java | 4 +- .../evmtool/MainnetGenesisFileModule.java | 12 +- ethereum/referencetests/build.gradle | 1 + .../ReferenceTestProtocolSchedules.java | 5 +- .../mainnet/DifficultyCalculatorTests.java | 30 +- .../ethereum/retesteth/RetestethContext.java | 7 +- .../besu/evm/tracing/OperationTracer.java | 12 + .../besu/metrics/BesuMetricCategory.java | 4 +- 93 files changed, 2629 insertions(+), 329 deletions(-) create mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/parallelization/MainnetParallelBlockProcessor.java create mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/parallelization/ParallelizedConcurrentTransactionProcessor.java create mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/parallelization/ParallelizedTransactionContext.java create mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/parallelization/TransactionCollisionDetector.java create mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/cache/NoopBonsaiCachedMerkleTrieLoader.java create mode 100644 ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/parallelization/ParallelizedConcurrentTransactionProcessorTest.java create mode 100644 ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/parallelization/TransactionCollisionDetectorTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 7710f8e7b9..9c6cb373ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ - Added EIP-7702 [#7237](https://github.com/hyperledger/besu/pull/7237) - Implement gnark-crypto for eip-196 [#7262](https://github.com/hyperledger/besu/pull/7262) - Add trie log pruner metrics [#7352](https://github.com/hyperledger/besu/pull/7352) +- `--Xbonsai-parallel-tx-processing-enabled` option enables executing transactions in parallel during block processing for Bonsai nodes ### Bug fixes - Fix `eth_call` deserialization to correctly ignore unknown fields in the transaction object. [#7323](https://github.com/hyperledger/besu/pull/7323) 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 7216d9ebd6..198c26fe2a 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java @@ -1901,6 +1901,8 @@ public class BesuCommand implements DefaultCommandValues, Runnable { .privacyParameters(privacyParameters()) .clock(Clock.systemUTC()) .isRevertReasonEnabled(isRevertReasonEnabled) + .isParallelTxProcessingEnabled( + dataStorageConfiguration.getUnstable().isParallelTxProcessingEnabled()) .storageProvider(storageProvider) .gasLimitCalculator( miningParametersSupplier.get().getTargetGasLimit().isPresent() 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 index 69cf819cb4..fc92a7e5dd 100644 --- 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 @@ -122,6 +122,14 @@ public class DataStorageOptions implements CLIOptions "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() {} } @@ -142,40 +150,48 @@ public class DataStorageOptions implements CLIOptions * @param syncMode the sync mode */ public void validate(final CommandLine commandLine, final SyncMode syncMode) { - if (DataStorageFormat.BONSAI == dataStorageFormat && bonsaiLimitTrieLogsEnabled) { - if (SyncMode.FULL == syncMode) { - throw new CommandLine.ParameterException( - commandLine, - String.format( - "Cannot enable %s with sync-mode %s. You must set %s or use a different sync-mode", - BONSAI_LIMIT_TRIE_LOGS_ENABLED, - SyncMode.FULL, - BONSAI_LIMIT_TRIE_LOGS_ENABLED + "=false")); - } - 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 (DataStorageFormat.BONSAI == dataStorageFormat) { + if (bonsaiLimitTrieLogsEnabled) { + if (SyncMode.FULL == syncMode) { + throw new CommandLine.ParameterException( + commandLine, + String.format( + "Cannot enable %s with sync-mode %s. You must set %s or use a different sync-mode", + BONSAI_LIMIT_TRIE_LOGS_ENABLED, + SyncMode.FULL, + BONSAI_LIMIT_TRIE_LOGS_ENABLED + "=false")); + } + 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)); + } } - if (bonsaiTrieLogPruningWindowSize <= bonsaiMaxLayersToLoad) { + } else { + if (unstableOptions.isParallelTxProcessingEnabled) { 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)); + "Transaction parallelization is not supported unless operating in a 'diffbased' mode, such as Bonsai."); } } } @@ -198,6 +214,8 @@ public class DataStorageOptions implements CLIOptions domainObject.getUnstable().getBonsaiFullFlatDbEnabled(); dataStorageOptions.unstableOptions.bonsaiCodeUsingCodeHashEnabled = domainObject.getUnstable().getBonsaiCodeStoredByCodeHashEnabled(); + dataStorageOptions.unstableOptions.isParallelTxProcessingEnabled = + domainObject.getUnstable().isParallelTxProcessingEnabled(); return dataStorageOptions; } @@ -214,6 +232,7 @@ public class DataStorageOptions implements CLIOptions ImmutableDataStorageConfiguration.Unstable.builder() .bonsaiFullFlatDbEnabled(unstableOptions.bonsaiFullFlatDbEnabled) .bonsaiCodeStoredByCodeHashEnabled(unstableOptions.bonsaiCodeUsingCodeHashEnabled) + .isParallelTxProcessingEnabled(unstableOptions.isParallelTxProcessingEnabled) .build()) .build(); } 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 20f3ca8ef6..ddb75fcded 100644 --- a/besu/src/main/java/org/hyperledger/besu/controller/BesuControllerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/controller/BesuControllerBuilder.java @@ -203,6 +203,9 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides private int numberOfBlocksToCache = 0; + /** whether parallel transaction processing is enabled or not */ + protected boolean isParallelTxProcessingEnabled; + /** Instantiates a new Besu controller builder. */ protected BesuControllerBuilder() {} @@ -512,6 +515,20 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides return this; } + /** + * Sets whether parallel transaction processing is enabled. When parallel transaction processing + * is enabled, transactions within a block can be processed in parallel and potentially improving + * performance + * + * @param isParallelTxProcessingEnabled true to enable parallel transaction + * @return the besu controller + */ + public BesuControllerBuilder isParallelTxProcessingEnabled( + final boolean isParallelTxProcessingEnabled) { + this.isParallelTxProcessingEnabled = isParallelTxProcessingEnabled; + return this; + } + /** * Build besu controller. * diff --git a/besu/src/main/java/org/hyperledger/besu/controller/CliqueBesuControllerBuilder.java b/besu/src/main/java/org/hyperledger/besu/controller/CliqueBesuControllerBuilder.java index c127424069..b4ada60549 100644 --- a/besu/src/main/java/org/hyperledger/besu/controller/CliqueBesuControllerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/controller/CliqueBesuControllerBuilder.java @@ -136,7 +136,9 @@ public class CliqueBesuControllerBuilder extends BesuControllerBuilder { isRevertReasonEnabled, evmConfiguration, miningParameters, - badBlockManager); + badBlockManager, + isParallelTxProcessingEnabled, + metricsSystem); } @Override diff --git a/besu/src/main/java/org/hyperledger/besu/controller/ConsensusScheduleBesuControllerBuilder.java b/besu/src/main/java/org/hyperledger/besu/controller/ConsensusScheduleBesuControllerBuilder.java index f669332202..0d0f8d2fd8 100644 --- a/besu/src/main/java/org/hyperledger/besu/controller/ConsensusScheduleBesuControllerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/controller/ConsensusScheduleBesuControllerBuilder.java @@ -358,6 +358,15 @@ public class ConsensusScheduleBesuControllerBuilder extends BesuControllerBuilde return super.isRevertReasonEnabled(isRevertReasonEnabled); } + @Override + public BesuControllerBuilder isParallelTxProcessingEnabled( + final boolean isParallelTxProcessingEnabled) { + besuControllerBuilderSchedule + .values() + .forEach(b -> b.isParallelTxProcessingEnabled(isParallelTxProcessingEnabled)); + return super.isParallelTxProcessingEnabled(isParallelTxProcessingEnabled); + } + @Override public BesuControllerBuilder gasLimitCalculator(final GasLimitCalculator gasLimitCalculator) { besuControllerBuilderSchedule.values().forEach(b -> b.gasLimitCalculator(gasLimitCalculator)); 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 473549e0bd..b8d4d2645e 100644 --- a/besu/src/main/java/org/hyperledger/besu/controller/IbftBesuControllerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/controller/IbftBesuControllerBuilder.java @@ -291,7 +291,9 @@ public class IbftBesuControllerBuilder extends BftBesuControllerBuilder { bftExtraDataCodec().get(), evmConfiguration, miningParameters, - badBlockManager); + badBlockManager, + isParallelTxProcessingEnabled, + metricsSystem); } @Override diff --git a/besu/src/main/java/org/hyperledger/besu/controller/MainnetBesuControllerBuilder.java b/besu/src/main/java/org/hyperledger/besu/controller/MainnetBesuControllerBuilder.java index 27570483c1..e0fbed608a 100644 --- a/besu/src/main/java/org/hyperledger/besu/controller/MainnetBesuControllerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/controller/MainnetBesuControllerBuilder.java @@ -99,7 +99,9 @@ public class MainnetBesuControllerBuilder extends BesuControllerBuilder { isRevertReasonEnabled, evmConfiguration, miningParameters, - badBlockManager); + badBlockManager, + isParallelTxProcessingEnabled, + metricsSystem); } @Override diff --git a/besu/src/main/java/org/hyperledger/besu/controller/MergeBesuControllerBuilder.java b/besu/src/main/java/org/hyperledger/besu/controller/MergeBesuControllerBuilder.java index cdd46ea5b9..f5fc75959e 100644 --- a/besu/src/main/java/org/hyperledger/besu/controller/MergeBesuControllerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/controller/MergeBesuControllerBuilder.java @@ -177,7 +177,9 @@ public class MergeBesuControllerBuilder extends BesuControllerBuilder { privacyParameters, isRevertReasonEnabled, miningParameters, - badBlockManager); + badBlockManager, + isParallelTxProcessingEnabled, + metricsSystem); } @Override 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 795136ded5..ab2dbce3f1 100644 --- a/besu/src/main/java/org/hyperledger/besu/controller/QbftBesuControllerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/controller/QbftBesuControllerBuilder.java @@ -329,7 +329,9 @@ public class QbftBesuControllerBuilder extends BftBesuControllerBuilder { bftExtraDataCodec().get(), evmConfiguration, miningParameters, - badBlockManager); + badBlockManager, + isParallelTxProcessingEnabled, + metricsSystem); } @Override diff --git a/besu/src/main/java/org/hyperledger/besu/controller/TransitionBesuControllerBuilder.java b/besu/src/main/java/org/hyperledger/besu/controller/TransitionBesuControllerBuilder.java index cdf5413fff..d7b701b4c5 100644 --- a/besu/src/main/java/org/hyperledger/besu/controller/TransitionBesuControllerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/controller/TransitionBesuControllerBuilder.java @@ -374,6 +374,13 @@ public class TransitionBesuControllerBuilder extends BesuControllerBuilder { return propagateConfig(z -> z.isRevertReasonEnabled(isRevertReasonEnabled)); } + @Override + public BesuControllerBuilder isParallelTxProcessingEnabled( + final boolean isParallelTxProcessingEnabled) { + super.isParallelTxProcessingEnabled(isParallelTxProcessingEnabled); + return propagateConfig(z -> z.isParallelTxProcessingEnabled(isParallelTxProcessingEnabled)); + } + @Override public BesuControllerBuilder gasLimitCalculator(final GasLimitCalculator gasLimitCalculator) { super.gasLimitCalculator(gasLimitCalculator); diff --git a/besu/src/test/java/org/hyperledger/besu/ForkIdsNetworkConfigTest.java b/besu/src/test/java/org/hyperledger/besu/ForkIdsNetworkConfigTest.java index fe5077acc6..28d4c77036 100644 --- a/besu/src/test/java/org/hyperledger/besu/ForkIdsNetworkConfigTest.java +++ b/besu/src/test/java/org/hyperledger/besu/ForkIdsNetworkConfigTest.java @@ -35,6 +35,7 @@ import org.hyperledger.besu.ethereum.forkid.ForkId; import org.hyperledger.besu.ethereum.forkid.ForkIdManager; import org.hyperledger.besu.ethereum.mainnet.DefaultProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.MainnetProtocolSchedule; +import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import java.util.Collection; import java.util.List; @@ -177,12 +178,21 @@ public class ForkIdsNetworkConfigTest { new MilestoneStreamingProtocolSchedule( (DefaultProtocolSchedule) MainnetProtocolSchedule.fromConfig( - configOptions, MiningParameters.MINING_DISABLED, new BadBlockManager())); + configOptions, + MiningParameters.MINING_DISABLED, + new BadBlockManager(), + false, + new NoOpMetricsSystem())); MilestoneStreamingProtocolSchedule postMergeProtocolSchedule = new MilestoneStreamingProtocolSchedule( (DefaultProtocolSchedule) MergeProtocolSchedule.create( - configOptions, false, MiningParameters.MINING_DISABLED, new BadBlockManager())); + configOptions, + false, + MiningParameters.MINING_DISABLED, + new BadBlockManager(), + false, + new NoOpMetricsSystem())); final MilestoneStreamingTransitionProtocolSchedule schedule = new MilestoneStreamingTransitionProtocolSchedule( preMergeProtocolSchedule, postMergeProtocolSchedule); 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 c92a3a5bda..8a6a578119 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/CommandTestAbstract.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/CommandTestAbstract.java @@ -276,6 +276,8 @@ public abstract class CommandTestAbstract { when(mockControllerBuilder.privacyParameters(any())).thenReturn(mockControllerBuilder); when(mockControllerBuilder.clock(any())).thenReturn(mockControllerBuilder); when(mockControllerBuilder.isRevertReasonEnabled(false)).thenReturn(mockControllerBuilder); + when(mockControllerBuilder.isParallelTxProcessingEnabled(false)) + .thenReturn(mockControllerBuilder); when(mockControllerBuilder.storageProvider(any())).thenReturn(mockControllerBuilder); when(mockControllerBuilder.gasLimitCalculator(any())).thenReturn(mockControllerBuilder); when(mockControllerBuilder.requiredBlocks(any())).thenReturn(mockControllerBuilder); diff --git a/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/CliqueProtocolSchedule.java b/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/CliqueProtocolSchedule.java index 91013ab97c..cd19755638 100644 --- a/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/CliqueProtocolSchedule.java +++ b/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/CliqueProtocolSchedule.java @@ -36,6 +36,7 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecBuilder; import org.hyperledger.besu.ethereum.mainnet.feemarket.BaseFeeMarket; import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; import org.hyperledger.besu.evm.internal.EvmConfiguration; +import org.hyperledger.besu.plugin.services.MetricsSystem; import java.math.BigInteger; import java.util.HashMap; @@ -64,6 +65,9 @@ public class CliqueProtocolSchedule { * @param evmConfiguration the evm configuration * @param miningParameters the mining parameters * @param badBlockManager the cache to use to keep invalid blocks + * @param isParallelTxProcessingEnabled indicates whether parallel transaction is enabled + * @param metricsSystem A metricSystem instance to be able to expose metrics in the underlying + * calls * @return the protocol schedule */ public static ProtocolSchedule create( @@ -74,7 +78,9 @@ public class CliqueProtocolSchedule { final boolean isRevertReasonEnabled, final EvmConfiguration evmConfiguration, final MiningParameters miningParameters, - final BadBlockManager badBlockManager) { + final BadBlockManager badBlockManager, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { final CliqueConfigOptions cliqueConfig = config.getCliqueConfigOptions(); @@ -110,7 +116,9 @@ public class CliqueProtocolSchedule { isRevertReasonEnabled, evmConfiguration, miningParameters, - badBlockManager) + badBlockManager, + isParallelTxProcessingEnabled, + metricsSystem) .createProtocolSchedule(); } @@ -124,6 +132,9 @@ public class CliqueProtocolSchedule { * @param evmConfiguration the evm configuration * @param miningParameters the mining parameters * @param badBlockManager the cache to use to keep invalid blocks + * @param isParallelTxProcessingEnabled indicates whether parallel transaction is enabled + * @param metricsSystem A metricSystem instance to be able to expose metrics in the underlying + * calls * @return the protocol schedule */ @VisibleForTesting @@ -134,7 +145,9 @@ public class CliqueProtocolSchedule { final boolean isRevertReasonEnabled, final EvmConfiguration evmConfiguration, final MiningParameters miningParameters, - final BadBlockManager badBlockManager) { + final BadBlockManager badBlockManager, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { return create( config, forksSchedule, @@ -143,7 +156,9 @@ public class CliqueProtocolSchedule { isRevertReasonEnabled, evmConfiguration, miningParameters, - badBlockManager); + badBlockManager, + isParallelTxProcessingEnabled, + metricsSystem); } private static ProtocolSpecBuilder applyCliqueSpecificModifications( diff --git a/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/CliqueProtocolScheduleTest.java b/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/CliqueProtocolScheduleTest.java index 35f959e45b..5cbdbb6d06 100644 --- a/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/CliqueProtocolScheduleTest.java +++ b/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/CliqueProtocolScheduleTest.java @@ -37,6 +37,7 @@ import org.hyperledger.besu.ethereum.mainnet.HeaderValidationMode; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; import org.hyperledger.besu.evm.internal.EvmConfiguration; +import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import java.time.Instant; import java.util.List; @@ -68,7 +69,9 @@ public class CliqueProtocolScheduleTest { false, EvmConfiguration.DEFAULT, MiningParameters.MINING_DISABLED, - new BadBlockManager()); + new BadBlockManager(), + false, + new NoOpMetricsSystem()); final ProtocolSpec homesteadSpec = protocolSchedule.getByBlockHeader(blockHeader(1)); final ProtocolSpec tangerineWhistleSpec = protocolSchedule.getByBlockHeader(blockHeader(2)); @@ -92,7 +95,9 @@ public class CliqueProtocolScheduleTest { false, EvmConfiguration.DEFAULT, MiningParameters.MINING_DISABLED, - new BadBlockManager()) + new BadBlockManager(), + false, + new NoOpMetricsSystem()) .getByBlockHeader(blockHeader(0)); assertThat(homestead.getName()).isEqualTo("Frontier"); @@ -116,7 +121,9 @@ public class CliqueProtocolScheduleTest { false, EvmConfiguration.DEFAULT, MiningParameters.MINING_DISABLED, - new BadBlockManager())) + new BadBlockManager(), + false, + new NoOpMetricsSystem())) .isInstanceOf(IllegalArgumentException.class) .hasMessage("Epoch length in config must be greater than zero"); } @@ -136,7 +143,9 @@ public class CliqueProtocolScheduleTest { false, EvmConfiguration.DEFAULT, MiningParameters.MINING_DISABLED, - new BadBlockManager())) + new BadBlockManager(), + false, + new NoOpMetricsSystem())) .isInstanceOf(IllegalArgumentException.class) .hasMessage("Epoch length in config must be greater than zero"); } @@ -160,7 +169,9 @@ public class CliqueProtocolScheduleTest { false, EvmConfiguration.DEFAULT, MiningParameters.MINING_DISABLED, - new BadBlockManager()); + new BadBlockManager(), + false, + new NoOpMetricsSystem()); BlockHeader emptyFrontierParent = headerBuilder diff --git a/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueBlockCreatorTest.java b/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueBlockCreatorTest.java index 485b2aff79..ec10630df9 100644 --- a/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueBlockCreatorTest.java +++ b/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueBlockCreatorTest.java @@ -106,7 +106,9 @@ public class CliqueBlockCreatorTest { false, EvmConfiguration.DEFAULT, MiningParameters.MINING_DISABLED, - new BadBlockManager()); + new BadBlockManager(), + false, + new NoOpMetricsSystem()); final Address otherAddress = Util.publicKeyToAddress(otherKeyPair.getPublicKey()); validatorList.add(otherAddress); diff --git a/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueMinerExecutorTest.java b/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueMinerExecutorTest.java index bb69aaff48..9502d00a19 100644 --- a/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueMinerExecutorTest.java +++ b/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueMinerExecutorTest.java @@ -105,7 +105,9 @@ public class CliqueMinerExecutorTest { false, EvmConfiguration.DEFAULT, MiningParameters.MINING_DISABLED, - new BadBlockManager()); + new BadBlockManager(), + false, + new NoOpMetricsSystem()); cliqueEthContext = mock(EthContext.class, RETURNS_DEEP_STUBS); blockHeaderBuilder = new BlockHeaderTestFixture(); } diff --git a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BaseBftProtocolScheduleBuilder.java b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BaseBftProtocolScheduleBuilder.java index da81ce80b7..311bf30fae 100644 --- a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BaseBftProtocolScheduleBuilder.java +++ b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BaseBftProtocolScheduleBuilder.java @@ -33,6 +33,7 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecBuilder; import org.hyperledger.besu.ethereum.mainnet.WithdrawalsValidator; import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; import org.hyperledger.besu.evm.internal.EvmConfiguration; +import org.hyperledger.besu.plugin.services.MetricsSystem; import java.math.BigInteger; import java.util.HashMap; @@ -58,6 +59,9 @@ public abstract class BaseBftProtocolScheduleBuilder { * @param evmConfiguration the evm configuration * @param miningParameters the mining parameters * @param badBlockManager the cache to use to keep invalid blocks + * @param isParallelTxProcessingEnabled indicates whether parallel transaction is enabled. + * @param metricsSystem metricsSystem A metricSystem instance to be able to expose metrics in the + * underlying calls * @return the protocol schedule */ public BftProtocolSchedule createProtocolSchedule( @@ -68,7 +72,9 @@ public abstract class BaseBftProtocolScheduleBuilder { final BftExtraDataCodec bftExtraDataCodec, final EvmConfiguration evmConfiguration, final MiningParameters miningParameters, - final BadBlockManager badBlockManager) { + final BadBlockManager badBlockManager, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { final Map> specMap = new HashMap<>(); forksSchedule @@ -90,7 +96,9 @@ public abstract class BaseBftProtocolScheduleBuilder { isRevertReasonEnabled, evmConfiguration, miningParameters, - badBlockManager) + badBlockManager, + isParallelTxProcessingEnabled, + metricsSystem) .createProtocolSchedule(); return new BftProtocolSchedule((DefaultProtocolSchedule) protocolSchedule); } diff --git a/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/CombinedProtocolScheduleFactoryTest.java b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/CombinedProtocolScheduleFactoryTest.java index 4e3cab78e7..02689d52af 100644 --- a/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/CombinedProtocolScheduleFactoryTest.java +++ b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/CombinedProtocolScheduleFactoryTest.java @@ -28,6 +28,7 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolScheduleBuilder; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecAdapters; import org.hyperledger.besu.evm.internal.EvmConfiguration; +import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import java.math.BigInteger; import java.util.List; @@ -177,7 +178,9 @@ public class CombinedProtocolScheduleFactoryTest { false, EvmConfiguration.DEFAULT, MiningParameters.MINING_DISABLED, - new BadBlockManager()); + new BadBlockManager(), + false, + new NoOpMetricsSystem()); return new BftProtocolSchedule( (DefaultProtocolSchedule) protocolScheduleBuilder.createProtocolSchedule()); diff --git a/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/BaseBftProtocolScheduleBuilderTest.java b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/BaseBftProtocolScheduleBuilderTest.java index 9b05bd7a36..e23664fd8d 100644 --- a/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/BaseBftProtocolScheduleBuilderTest.java +++ b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/BaseBftProtocolScheduleBuilderTest.java @@ -39,6 +39,7 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; import org.hyperledger.besu.evm.internal.EvmConfiguration; +import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import java.math.BigInteger; import java.util.List; @@ -245,7 +246,9 @@ public class BaseBftProtocolScheduleBuilderTest { bftExtraDataCodec, EvmConfiguration.DEFAULT, MiningParameters.MINING_DISABLED, - new BadBlockManager()); + new BadBlockManager(), + false, + new NoOpMetricsSystem()); } private BftConfigOptions createBftConfig(final BigInteger blockReward) { diff --git a/consensus/ibft/src/integration-test/java/org/hyperledger/besu/consensus/ibft/support/TestContextBuilder.java b/consensus/ibft/src/integration-test/java/org/hyperledger/besu/consensus/ibft/support/TestContextBuilder.java index 55a2f3551a..2d620c5632 100644 --- a/consensus/ibft/src/integration-test/java/org/hyperledger/besu/consensus/ibft/support/TestContextBuilder.java +++ b/consensus/ibft/src/integration-test/java/org/hyperledger/besu/consensus/ibft/support/TestContextBuilder.java @@ -333,7 +333,9 @@ public class TestContextBuilder { IBFT_EXTRA_DATA_ENCODER, EvmConfiguration.DEFAULT, MiningParameters.MINING_DISABLED, - new BadBlockManager()); + new BadBlockManager(), + false, + new NoOpMetricsSystem()); ///////////////////////////////////////////////////////////////////////////////////// // From here down is BASICALLY taken from IbftBesuController diff --git a/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/IbftProtocolScheduleBuilder.java b/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/IbftProtocolScheduleBuilder.java index 5cad697c53..0789f2e898 100644 --- a/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/IbftProtocolScheduleBuilder.java +++ b/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/IbftProtocolScheduleBuilder.java @@ -27,6 +27,7 @@ import org.hyperledger.besu.ethereum.mainnet.BlockHeaderValidator; import org.hyperledger.besu.ethereum.mainnet.feemarket.BaseFeeMarket; import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; import org.hyperledger.besu.evm.internal.EvmConfiguration; +import org.hyperledger.besu.plugin.services.MetricsSystem; import java.util.Optional; @@ -46,6 +47,9 @@ public class IbftProtocolScheduleBuilder extends BaseBftProtocolScheduleBuilder * @param evmConfiguration the evm configuration * @param miningParameters the mining parameters * @param badBlockManager the cache to use to keep invalid blocks + * @param isParallelTxProcessingEnabled indicates whether parallel transaction is enabled + * @param metricsSystem A metricSystem instance to be able to expose metrics in the underlying + * calls * @return the protocol schedule */ public static BftProtocolSchedule create( @@ -56,7 +60,9 @@ public class IbftProtocolScheduleBuilder extends BaseBftProtocolScheduleBuilder final BftExtraDataCodec bftExtraDataCodec, final EvmConfiguration evmConfiguration, final MiningParameters miningParameters, - final BadBlockManager badBlockManager) { + final BadBlockManager badBlockManager, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { return new IbftProtocolScheduleBuilder() .createProtocolSchedule( config, @@ -66,7 +72,9 @@ public class IbftProtocolScheduleBuilder extends BaseBftProtocolScheduleBuilder bftExtraDataCodec, evmConfiguration, miningParameters, - badBlockManager); + badBlockManager, + isParallelTxProcessingEnabled, + metricsSystem); } /** @@ -78,6 +86,9 @@ public class IbftProtocolScheduleBuilder extends BaseBftProtocolScheduleBuilder * @param evmConfiguration the evm configuration * @param miningParameters the mining parameters * @param badBlockManager the cache to use to keep invalid blocks + * @param isParallelTxProcessingEnabled indicates whether parallel transaction is enabled. + * @param metricsSystem A metricSystem instance to be able to expose metrics in the underlying + * calls * @return the protocol schedule */ public static BftProtocolSchedule create( @@ -86,7 +97,9 @@ public class IbftProtocolScheduleBuilder extends BaseBftProtocolScheduleBuilder final BftExtraDataCodec bftExtraDataCodec, final EvmConfiguration evmConfiguration, final MiningParameters miningParameters, - final BadBlockManager badBlockManager) { + final BadBlockManager badBlockManager, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { return create( config, forksSchedule, @@ -95,7 +108,9 @@ public class IbftProtocolScheduleBuilder extends BaseBftProtocolScheduleBuilder bftExtraDataCodec, evmConfiguration, miningParameters, - badBlockManager); + badBlockManager, + isParallelTxProcessingEnabled, + metricsSystem); } @Override diff --git a/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/IbftProtocolScheduleTest.java b/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/IbftProtocolScheduleTest.java index 611399fd55..e5551ff3f3 100644 --- a/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/IbftProtocolScheduleTest.java +++ b/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/IbftProtocolScheduleTest.java @@ -45,6 +45,7 @@ import org.hyperledger.besu.ethereum.core.PrivacyParameters; import org.hyperledger.besu.ethereum.core.Util; import org.hyperledger.besu.ethereum.mainnet.HeaderValidationMode; import org.hyperledger.besu.evm.internal.EvmConfiguration; +import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import java.math.BigInteger; import java.util.Collection; @@ -103,7 +104,9 @@ public class IbftProtocolScheduleTest { bftExtraDataCodec, EvmConfiguration.DEFAULT, MiningParameters.MINING_DISABLED, - new BadBlockManager()); + new BadBlockManager(), + false, + new NoOpMetricsSystem()); } private boolean validateHeader( diff --git a/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/blockcreation/BftBlockCreatorTest.java b/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/blockcreation/BftBlockCreatorTest.java index 25c5c1d10b..1b86896f36 100644 --- a/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/blockcreation/BftBlockCreatorTest.java +++ b/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/blockcreation/BftBlockCreatorTest.java @@ -121,7 +121,9 @@ public class BftBlockCreatorTest { bftExtraDataEncoder, EvmConfiguration.DEFAULT, MiningParameters.MINING_DISABLED, - new BadBlockManager()); + new BadBlockManager(), + false, + new NoOpMetricsSystem()); final ProtocolContext protContext = new ProtocolContext( blockchain, diff --git a/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/statemachine/IbftBlockHeightManagerTest.java b/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/statemachine/IbftBlockHeightManagerTest.java index 68e0ee5efe..b388b80a3f 100644 --- a/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/statemachine/IbftBlockHeightManagerTest.java +++ b/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/statemachine/IbftBlockHeightManagerTest.java @@ -79,6 +79,7 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolScheduleBuilder; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecAdapters; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.MessageData; import org.hyperledger.besu.evm.internal.EvmConfiguration; +import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import org.hyperledger.besu.util.Subscribers; import java.math.BigInteger; @@ -184,7 +185,9 @@ public class IbftBlockHeightManagerTest { false, EvmConfiguration.DEFAULT, MiningParameters.MINING_DISABLED, - new BadBlockManager()); + new BadBlockManager(), + false, + new NoOpMetricsSystem()); ProtocolSchedule protocolSchedule = new BftProtocolSchedule( diff --git a/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/MergeProtocolSchedule.java b/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/MergeProtocolSchedule.java index ff92319ae3..abbc3b130a 100644 --- a/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/MergeProtocolSchedule.java +++ b/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/MergeProtocolSchedule.java @@ -27,6 +27,7 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecBuilder; import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; import org.hyperledger.besu.evm.MainnetEVMs; import org.hyperledger.besu.evm.internal.EvmConfiguration; +import org.hyperledger.besu.plugin.services.MetricsSystem; import java.math.BigInteger; import java.util.HashMap; @@ -49,19 +50,24 @@ public class MergeProtocolSchedule { * @param isRevertReasonEnabled the is revert reason enabled * @param miningParameters the mining parameters * @param badBlockManager the cache to use to keep invalid blocks + * @param isParallelTxProcessingEnabled indicates whether parallel transaction is enabled. * @return the protocol schedule */ public static ProtocolSchedule create( final GenesisConfigOptions config, final boolean isRevertReasonEnabled, final MiningParameters miningParameters, - final BadBlockManager badBlockManager) { + final BadBlockManager badBlockManager, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { return create( config, PrivacyParameters.DEFAULT, isRevertReasonEnabled, miningParameters, - badBlockManager); + badBlockManager, + isParallelTxProcessingEnabled, + metricsSystem); } /** @@ -72,6 +78,7 @@ public class MergeProtocolSchedule { * @param isRevertReasonEnabled the is revert reason enabled * @param miningParameters the mining parameters * @param badBlockManager the cache to use to keep invalid blocks + * @param isParallelTxProcessingEnabled indicates whether parallel transaction is enabled. * @return the protocol schedule */ public static ProtocolSchedule create( @@ -79,7 +86,9 @@ public class MergeProtocolSchedule { final PrivacyParameters privacyParameters, final boolean isRevertReasonEnabled, final MiningParameters miningParameters, - final BadBlockManager badBlockManager) { + final BadBlockManager badBlockManager, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { Map> postMergeModifications = new HashMap<>(); @@ -98,7 +107,9 @@ public class MergeProtocolSchedule { isRevertReasonEnabled, EvmConfiguration.DEFAULT, miningParameters, - badBlockManager) + badBlockManager, + isParallelTxProcessingEnabled, + metricsSystem) .createProtocolSchedule(); } diff --git a/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/TransitionProtocolSchedule.java b/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/TransitionProtocolSchedule.java index faab15dac4..8600344cef 100644 --- a/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/TransitionProtocolSchedule.java +++ b/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/TransitionProtocolSchedule.java @@ -27,6 +27,7 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; import org.hyperledger.besu.ethereum.mainnet.ScheduledProtocolSpec; import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; +import org.hyperledger.besu.plugin.services.MetricsSystem; import java.math.BigInteger; import java.util.Optional; @@ -65,17 +66,30 @@ public class TransitionProtocolSchedule implements ProtocolSchedule { * milestone starting points * @param miningParameters the mining parameters * @param badBlockManager the cache to use to keep invalid blocks + * @param isParallelTxProcessingEnabled indicates whether parallel transaction is enabled. * @return an initialised TransitionProtocolSchedule using post-merge defaults */ public static TransitionProtocolSchedule fromConfig( final GenesisConfigOptions genesisConfigOptions, final MiningParameters miningParameters, - final BadBlockManager badBlockManager) { + final BadBlockManager badBlockManager, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { ProtocolSchedule preMergeProtocolSchedule = - MainnetProtocolSchedule.fromConfig(genesisConfigOptions, miningParameters, badBlockManager); + MainnetProtocolSchedule.fromConfig( + genesisConfigOptions, + miningParameters, + badBlockManager, + isParallelTxProcessingEnabled, + metricsSystem); ProtocolSchedule postMergeProtocolSchedule = MergeProtocolSchedule.create( - genesisConfigOptions, false, miningParameters, badBlockManager); + genesisConfigOptions, + false, + miningParameters, + badBlockManager, + isParallelTxProcessingEnabled, + metricsSystem); return new TransitionProtocolSchedule( preMergeProtocolSchedule, postMergeProtocolSchedule, PostMergeContext.get()); } diff --git a/consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/MergeProtocolScheduleTest.java b/consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/MergeProtocolScheduleTest.java index b1f7414e45..0d4aede3a1 100644 --- a/consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/MergeProtocolScheduleTest.java +++ b/consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/MergeProtocolScheduleTest.java @@ -29,6 +29,7 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; import org.hyperledger.besu.evm.operation.InvalidOperation; import org.hyperledger.besu.evm.operation.PrevRanDaoOperation; import org.hyperledger.besu.evm.operation.Push0Operation; +import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import java.math.BigInteger; @@ -48,7 +49,12 @@ public class MergeProtocolScheduleTest { final GenesisConfigOptions config = GenesisConfigFile.fromConfig(jsonInput).getConfigOptions(); final ProtocolSchedule protocolSchedule = MergeProtocolSchedule.create( - config, false, MiningParameters.MINING_DISABLED, new BadBlockManager()); + config, + false, + MiningParameters.MINING_DISABLED, + new BadBlockManager(), + false, + new NoOpMetricsSystem()); final ProtocolSpec homesteadSpec = protocolSchedule.getByBlockHeader(blockHeader(1)); final ProtocolSpec londonSpec = protocolSchedule.getByBlockHeader(blockHeader(1559)); @@ -64,7 +70,12 @@ public class MergeProtocolScheduleTest { final GenesisConfigOptions config = GenesisConfigFile.mainnet().getConfigOptions(); final ProtocolSchedule protocolSchedule = MergeProtocolSchedule.create( - config, false, MiningParameters.MINING_DISABLED, new BadBlockManager()); + config, + false, + MiningParameters.MINING_DISABLED, + new BadBlockManager(), + false, + new NoOpMetricsSystem()); final long lastParisBlockNumber = 17034869L; final ProtocolSpec parisSpec = @@ -100,7 +111,12 @@ public class MergeProtocolScheduleTest { final GenesisConfigOptions config = GenesisConfigFile.fromConfig(jsonInput).getConfigOptions(); final ProtocolSchedule protocolSchedule = MergeProtocolSchedule.create( - config, false, MiningParameters.MINING_DISABLED, new BadBlockManager()); + config, + false, + MiningParameters.MINING_DISABLED, + new BadBlockManager(), + false, + new NoOpMetricsSystem()); final ProtocolSpec parisSpec = protocolSchedule.getByBlockHeader( @@ -128,7 +144,12 @@ public class MergeProtocolScheduleTest { final GenesisConfigOptions config = GenesisConfigFile.mainnet().getConfigOptions(); final ProtocolSchedule protocolSchedule = MergeProtocolSchedule.create( - config, false, MiningParameters.MINING_DISABLED, new BadBlockManager()); + config, + false, + MiningParameters.MINING_DISABLED, + new BadBlockManager(), + false, + new NoOpMetricsSystem()); final long lastParisBlockNumber = 17034869L; final ProtocolSpec parisSpec = @@ -160,7 +181,9 @@ public class MergeProtocolScheduleTest { GenesisConfigFile.DEFAULT.getConfigOptions(), false, MiningParameters.MINING_DISABLED, - new BadBlockManager()) + new BadBlockManager(), + false, + new NoOpMetricsSystem()) .getByBlockHeader(blockHeader(0)); assertThat(london.getName()).isEqualTo("Paris"); diff --git a/consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeGenesisConfigHelper.java b/consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeGenesisConfigHelper.java index 54099f868c..dcfe5f98e3 100644 --- a/consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeGenesisConfigHelper.java +++ b/consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeGenesisConfigHelper.java @@ -21,6 +21,7 @@ import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.ethereum.chain.BadBlockManager; import org.hyperledger.besu.ethereum.core.MiningParameters; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; +import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import java.io.IOException; import java.net.URI; @@ -56,6 +57,8 @@ public interface MergeGenesisConfigHelper { getPosGenesisConfigFile().getConfigOptions(), false, MiningParameters.MINING_DISABLED, - new BadBlockManager()); + new BadBlockManager(), + false, + new NoOpMetricsSystem()); } } diff --git a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/TestContextBuilder.java b/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/TestContextBuilder.java index 5cf74f9458..3467dce9fb 100644 --- a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/TestContextBuilder.java +++ b/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/TestContextBuilder.java @@ -437,7 +437,9 @@ public class TestContextBuilder { BFT_EXTRA_DATA_ENCODER, EvmConfiguration.DEFAULT, MiningParameters.MINING_DISABLED, - new BadBlockManager()); + new BadBlockManager(), + false, + new NoOpMetricsSystem()); final BftValidatorOverrides validatorOverrides = convertBftForks(qbftForks); final TransactionSimulator transactionSimulator = diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/QbftProtocolScheduleBuilder.java b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/QbftProtocolScheduleBuilder.java index 58a50efa26..44c7ddfba8 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/QbftProtocolScheduleBuilder.java +++ b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/QbftProtocolScheduleBuilder.java @@ -31,6 +31,7 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.feemarket.BaseFeeMarket; import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; import org.hyperledger.besu.evm.internal.EvmConfiguration; +import org.hyperledger.besu.plugin.services.MetricsSystem; import java.util.Optional; @@ -50,6 +51,9 @@ public class QbftProtocolScheduleBuilder extends BaseBftProtocolScheduleBuilder * @param evmConfiguration the evm configuration * @param miningParameters The mining parameters * @param badBlockManager the cache to use to keep invalid blocks + * @param isParallelTxProcessingEnabled indicates whether parallel transaction is enabled. + * @param metricsSystem A metricSystem instance to be able to expose metrics in the underlying + * calls * @return the protocol schedule */ public static BftProtocolSchedule create( @@ -60,7 +64,9 @@ public class QbftProtocolScheduleBuilder extends BaseBftProtocolScheduleBuilder final BftExtraDataCodec bftExtraDataCodec, final EvmConfiguration evmConfiguration, final MiningParameters miningParameters, - final BadBlockManager badBlockManager) { + final BadBlockManager badBlockManager, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { return new QbftProtocolScheduleBuilder() .createProtocolSchedule( config, @@ -70,7 +76,9 @@ public class QbftProtocolScheduleBuilder extends BaseBftProtocolScheduleBuilder bftExtraDataCodec, evmConfiguration, miningParameters, - badBlockManager); + badBlockManager, + isParallelTxProcessingEnabled, + metricsSystem); } /** @@ -82,6 +90,9 @@ public class QbftProtocolScheduleBuilder extends BaseBftProtocolScheduleBuilder * @param evmConfiguration the evm configuration * @param miningParameters The mining parameters * @param badBlockManager the cache to use to keep invalid blocks + * @param isParallelTxProcessingEnabled indicates whether parallel transaction is enabled. + * @param metricsSystem A metricSystem instance to be able to expose metrics in the underlying + * calls * @return the protocol schedule */ public static BftProtocolSchedule create( @@ -90,7 +101,9 @@ public class QbftProtocolScheduleBuilder extends BaseBftProtocolScheduleBuilder final BftExtraDataCodec bftExtraDataCodec, final EvmConfiguration evmConfiguration, final MiningParameters miningParameters, - final BadBlockManager badBlockManager) { + final BadBlockManager badBlockManager, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { return create( config, qbftForksSchedule, @@ -99,7 +112,9 @@ public class QbftProtocolScheduleBuilder extends BaseBftProtocolScheduleBuilder bftExtraDataCodec, evmConfiguration, miningParameters, - badBlockManager); + badBlockManager, + isParallelTxProcessingEnabled, + metricsSystem); } /** @@ -111,6 +126,9 @@ public class QbftProtocolScheduleBuilder extends BaseBftProtocolScheduleBuilder * @param bftExtraDataCodec the bft extra data codec * @param miningParameters The mining parameters * @param badBlockManager the cache to use to keep invalid blocks + * @param isParallelTxProcessingEnabled indicates whether parallel transaction is enabled. + * @param metricsSystem A metricSystem instance to be able to expose metrics in the underlying + * calls * @return the protocol schedule */ public static ProtocolSchedule create( @@ -119,7 +137,9 @@ public class QbftProtocolScheduleBuilder extends BaseBftProtocolScheduleBuilder final boolean isRevertReasonEnabled, final BftExtraDataCodec bftExtraDataCodec, final MiningParameters miningParameters, - final BadBlockManager badBlockManager) { + final BadBlockManager badBlockManager, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { return create( config, qbftForksSchedule, @@ -128,7 +148,9 @@ public class QbftProtocolScheduleBuilder extends BaseBftProtocolScheduleBuilder bftExtraDataCodec, EvmConfiguration.DEFAULT, miningParameters, - badBlockManager); + badBlockManager, + isParallelTxProcessingEnabled, + metricsSystem); } @Override diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/QbftProtocolScheduleTest.java b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/QbftProtocolScheduleTest.java index 07b3be34b4..020d6e0e5a 100644 --- a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/QbftProtocolScheduleTest.java +++ b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/QbftProtocolScheduleTest.java @@ -41,6 +41,7 @@ import org.hyperledger.besu.ethereum.core.PrivacyParameters; import org.hyperledger.besu.ethereum.core.Util; import org.hyperledger.besu.ethereum.mainnet.HeaderValidationMode; import org.hyperledger.besu.evm.internal.EvmConfiguration; +import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import java.math.BigInteger; import java.util.Collection; @@ -138,7 +139,9 @@ public class QbftProtocolScheduleTest { bftExtraDataCodec, EvmConfiguration.DEFAULT, MiningParameters.MINING_DISABLED, - new BadBlockManager()); + new BadBlockManager(), + false, + new NoOpMetricsSystem()); } private boolean validateHeader( diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftBlockHeightManagerTest.java b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftBlockHeightManagerTest.java index 0aa1f7843b..71ea4131a3 100644 --- a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftBlockHeightManagerTest.java +++ b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftBlockHeightManagerTest.java @@ -78,6 +78,7 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolScheduleBuilder; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecAdapters; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.MessageData; import org.hyperledger.besu.evm.internal.EvmConfiguration; +import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import org.hyperledger.besu.util.Subscribers; import java.math.BigInteger; @@ -184,7 +185,9 @@ public class QbftBlockHeightManagerTest { false, EvmConfiguration.DEFAULT, MiningParameters.MINING_DISABLED, - new BadBlockManager()); + new BadBlockManager(), + false, + new NoOpMetricsSystem()); ProtocolSchedule protocolSchedule = new BftProtocolSchedule( diff --git a/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/Blake2bfMessageDigest.java b/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/Blake2bfMessageDigest.java index 63449d74b5..ad4fe7ddb1 100644 --- a/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/Blake2bfMessageDigest.java +++ b/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/Blake2bfMessageDigest.java @@ -34,6 +34,13 @@ public class Blake2bfMessageDigest extends BCMessageDigest implements Cloneable super(new Blake2bfDigest()); } + @Override + public Blake2bfMessageDigest clone() throws CloneNotSupportedException { + Blake2bfMessageDigest cloned = (Blake2bfMessageDigest) super.clone(); + cloned.digest = ((Blake2bfDigest) this.digest).clone(); + return cloned; + } + /** * Implementation of the `F` compression function of the Blake2b cryptographic hash function. * @@ -43,7 +50,7 @@ public class Blake2bfMessageDigest extends BCMessageDigest implements Cloneable * *

Optimized for 64-bit platforms */ - public static class Blake2bfDigest implements Digest { + public static class Blake2bfDigest implements Digest, Cloneable { /** The constant MESSAGE_LENGTH_BYTES. */ public static final int MESSAGE_LENGTH_BYTES = 213; @@ -71,18 +78,18 @@ public class Blake2bfMessageDigest extends BCMessageDigest implements Cloneable // buffer which holds serialized input for this compression function // [ 4 bytes for rounds ][ 64 bytes for h ][ 128 bytes for m ] // [ 8 bytes for t_0 ][ 8 bytes for t_1 ][ 1 byte for f ] - private final byte[] buffer; + private byte[] buffer; private int bufferPos; // deserialized inputs for f compression - private final long[] h; - private final long[] m; - private final long[] t; + private long[] h; + private long[] m; + private long[] t; private boolean f; private long rounds; // unsigned integer represented as long - private final long[] v; + private long[] v; private static boolean useNative; static { @@ -112,6 +119,17 @@ public class Blake2bfMessageDigest extends BCMessageDigest implements Cloneable v = new long[16]; } + @Override + public Blake2bfDigest clone() throws CloneNotSupportedException { + Blake2bfDigest cloned = (Blake2bfDigest) super.clone(); + cloned.buffer = this.buffer.clone(); + cloned.h = this.h.clone(); + cloned.m = this.m.clone(); + cloned.t = this.t.clone(); + cloned.v = this.v.clone(); + return cloned; + } + /** Disable native. */ public static void disableNative() { useNative = false; diff --git a/crypto/algorithms/src/test/java/org/hyperledger/besu/crypto/Blake2bfMessageDigestTest.java b/crypto/algorithms/src/test/java/org/hyperledger/besu/crypto/Blake2bfMessageDigestTest.java index bd00dc7dae..390d7d4143 100644 --- a/crypto/algorithms/src/test/java/org/hyperledger/besu/crypto/Blake2bfMessageDigestTest.java +++ b/crypto/algorithms/src/test/java/org/hyperledger/besu/crypto/Blake2bfMessageDigestTest.java @@ -17,6 +17,13 @@ package org.hyperledger.besu.crypto; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.stream.IntStream; + import org.bouncycastle.util.Pack; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -29,6 +36,16 @@ import org.junit.jupiter.params.provider.CsvFileSource; */ public class Blake2bfMessageDigestTest { + private static final SecureRandom SECURE_RANDOM; + + static { + try { + SECURE_RANDOM = SecureRandom.getInstanceStrong(); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException(e); + } + } + private Blake2bfMessageDigest messageDigest; // output when input is all 0 @@ -124,6 +141,39 @@ public class Blake2bfMessageDigestTest { .isInstanceOf(IllegalArgumentException.class); } + @SuppressWarnings("unchecked") + @Test + public void testDigestThreadSafety() throws ExecutionException, InterruptedException { + final byte[] input = new byte[213]; + ; + SECURE_RANDOM.nextBytes(input); + int numberOfHashes = 10; + + CompletableFuture[] futures = + IntStream.range(0, numberOfHashes) + .mapToObj( + i -> + CompletableFuture.supplyAsync( + () -> { + try { + MessageDigest clonedDigest = messageDigest.clone(); + clonedDigest.update(input); + byte[] digest = clonedDigest.digest(); + return digest; + } catch (CloneNotSupportedException e) { + throw new RuntimeException(e); + } + })) + .toArray(CompletableFuture[]::new); + + CompletableFuture.allOf(futures).get(); + + byte[] expectedHash = futures[0].get(); + for (CompletableFuture future : futures) { + assertThat(expectedHash).isEqualTo(future.get()); + } + } + @ParameterizedTest @CsvFileSource(resources = "eip152TestCases.csv", numLinesToSkip = 1) public void eip152TestCases(final String hexIn, final String hexExpected) { diff --git a/datatypes/src/main/java/org/hyperledger/besu/datatypes/StorageSlotKey.java b/datatypes/src/main/java/org/hyperledger/besu/datatypes/StorageSlotKey.java index a8bf7c9afd..8404453cf1 100644 --- a/datatypes/src/main/java/org/hyperledger/besu/datatypes/StorageSlotKey.java +++ b/datatypes/src/main/java/org/hyperledger/besu/datatypes/StorageSlotKey.java @@ -94,7 +94,7 @@ public class StorageSlotKey implements Comparable { @Override public int hashCode() { - return Objects.hash(slotHash.hashCode()); + return slotHash.hashCode(); } @Override diff --git a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/BlockchainImporter.java b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/BlockchainImporter.java index 2a62331d33..3e261abf6d 100644 --- a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/BlockchainImporter.java +++ b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/BlockchainImporter.java @@ -24,6 +24,7 @@ import org.hyperledger.besu.ethereum.mainnet.MainnetProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ScheduleBasedBlockHeaderFunctions; import org.hyperledger.besu.ethereum.util.RawBlockIterator; +import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import java.net.URL; import java.nio.file.Paths; @@ -46,7 +47,9 @@ public class BlockchainImporter { MainnetProtocolSchedule.fromConfig( GenesisConfigFile.fromConfig(genesisJson).getConfigOptions(), MiningParameters.newDefault(), - new BadBlockManager()); + new BadBlockManager(), + false, + new NoOpMetricsSystem()); final BlockHeaderFunctions blockHeaderFunctions = ScheduleBasedBlockHeaderFunctions.create(protocolSchedule); blocks = new ArrayList<>(); diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceHostAllowlistTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceHostAllowlistTest.java index af5228dc06..80626ef2fc 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceHostAllowlistTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceHostAllowlistTest.java @@ -109,7 +109,9 @@ public class JsonRpcHttpServiceHostAllowlistTest { MainnetProtocolSchedule.fromConfig( new StubGenesisConfigOptions().constantinopleBlock(0).chainId(CHAIN_ID), MiningParameters.MINING_DISABLED, - new BadBlockManager()), + new BadBlockManager(), + false, + new NoOpMetricsSystem()), mock(ProtocolContext.class), mock(FilterManager.class), mock(TransactionPool.class), diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceLoginTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceLoginTest.java index 6ae5d37a0f..0fb55fdf34 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceLoginTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceLoginTest.java @@ -138,7 +138,11 @@ public class JsonRpcHttpServiceLoginTest { blockchainQueries, synchronizer, MainnetProtocolSchedule.fromConfig( - genesisConfigOptions, MiningParameters.MINING_DISABLED, new BadBlockManager()), + genesisConfigOptions, + MiningParameters.MINING_DISABLED, + new BadBlockManager(), + false, + new NoOpMetricsSystem()), mock(ProtocolContext.class), mock(FilterManager.class), mock(TransactionPool.class), diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTestBase.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTestBase.java index f8c9dbc18f..a2a856333e 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTestBase.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTestBase.java @@ -118,7 +118,9 @@ public class JsonRpcHttpServiceTestBase { new StubGenesisConfigOptions().constantinopleBlock(0).chainId(CHAIN_ID), EvmConfiguration.DEFAULT, MiningParameters.MINING_DISABLED, - new BadBlockManager()), + new BadBlockManager(), + false, + new NoOpMetricsSystem()), mock(ProtocolContext.class), mock(FilterManager.class), mock(TransactionPool.class), diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsClientAuthTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsClientAuthTest.java index 2f62e490be..1d3a3a087a 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsClientAuthTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsClientAuthTest.java @@ -123,7 +123,9 @@ public class JsonRpcHttpServiceTlsClientAuthTest { MainnetProtocolSchedule.fromConfig( new StubGenesisConfigOptions().constantinopleBlock(0).chainId(CHAIN_ID), MiningParameters.MINING_DISABLED, - new BadBlockManager()), + new BadBlockManager(), + false, + new NoOpMetricsSystem()), mock(ProtocolContext.class), mock(FilterManager.class), mock(TransactionPool.class), diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsMisconfigurationTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsMisconfigurationTest.java index 2ff0833bc6..684f843d2f 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsMisconfigurationTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsMisconfigurationTest.java @@ -111,7 +111,9 @@ class JsonRpcHttpServiceTlsMisconfigurationTest { MainnetProtocolSchedule.fromConfig( new StubGenesisConfigOptions().constantinopleBlock(0).chainId(CHAIN_ID), MiningParameters.MINING_DISABLED, - new BadBlockManager()), + new BadBlockManager(), + false, + new NoOpMetricsSystem()), mock(ProtocolContext.class), mock(FilterManager.class), mock(TransactionPool.class), diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsTest.java index e650f9d490..b6d7fa67f8 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsTest.java @@ -112,7 +112,9 @@ public class JsonRpcHttpServiceTlsTest { MainnetProtocolSchedule.fromConfig( new StubGenesisConfigOptions().constantinopleBlock(0).chainId(CHAIN_ID), MiningParameters.MINING_DISABLED, - new BadBlockManager()), + new BadBlockManager(), + false, + new NoOpMetricsSystem()), mock(ProtocolContext.class), mock(FilterManager.class), mock(TransactionPool.class), diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/WebSocketServiceLoginTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/WebSocketServiceLoginTest.java index 5fa137e312..75927c4513 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/WebSocketServiceLoginTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/WebSocketServiceLoginTest.java @@ -176,7 +176,9 @@ public class WebSocketServiceLoginTest { MainnetProtocolSchedule.fromConfig( genesisConfigOptions, MiningParameters.MINING_DISABLED, - new BadBlockManager()), + new BadBlockManager(), + false, + new NoOpMetricsSystem()), mock(ProtocolContext.class), mock(FilterManager.class), mock(TransactionPool.class), 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 2444d9db7d..946d4ab09d 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 @@ -395,7 +395,9 @@ abstract class AbstractBlockCreatorTest { false, EvmConfiguration.DEFAULT, MiningParameters.MINING_DISABLED, - new BadBlockManager()) + new BadBlockManager(), + false, + new NoOpMetricsSystem()) .createProtocolSchedule()) .build(); diff --git a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockTransactionSelectorTest.java b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockTransactionSelectorTest.java index d70589ae83..c6ee454241 100644 --- a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockTransactionSelectorTest.java +++ b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockTransactionSelectorTest.java @@ -223,7 +223,9 @@ public abstract class AbstractBlockTransactionSelectorTest { GenesisConfigFile.fromResource("/dev.json").getConfigOptions(), EvmConfiguration.DEFAULT, MiningParameters.MINING_DISABLED, - new BadBlockManager()); + new BadBlockManager(), + false, + new NoOpMetricsSystem()); final MainnetTransactionProcessor mainnetTransactionProcessor = protocolSchedule.getByBlockHeader(blockHeader(0)).getTransactionProcessor(); diff --git a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/LegacyFeeMarketBlockTransactionSelectorTest.java b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/LegacyFeeMarketBlockTransactionSelectorTest.java index 6206384534..416e5fd234 100644 --- a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/LegacyFeeMarketBlockTransactionSelectorTest.java +++ b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/LegacyFeeMarketBlockTransactionSelectorTest.java @@ -36,6 +36,7 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolScheduleBuilder; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecAdapters; import org.hyperledger.besu.evm.internal.EvmConfiguration; +import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import org.hyperledger.besu.testutil.TestClock; import org.hyperledger.besu.util.number.Fraction; @@ -60,7 +61,9 @@ public class LegacyFeeMarketBlockTransactionSelectorTest false, EvmConfiguration.DEFAULT, MiningParameters.MINING_DISABLED, - new BadBlockManager()) + new BadBlockManager(), + false, + new NoOpMetricsSystem()) .createProtocolSchedule(); } diff --git a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/LondonFeeMarketBlockTransactionSelectorTest.java b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/LondonFeeMarketBlockTransactionSelectorTest.java index e9bfcfb762..a59841d4f4 100644 --- a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/LondonFeeMarketBlockTransactionSelectorTest.java +++ b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/LondonFeeMarketBlockTransactionSelectorTest.java @@ -43,6 +43,7 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolScheduleBuilder; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecAdapters; import org.hyperledger.besu.ethereum.mainnet.ValidationResult; import org.hyperledger.besu.evm.internal.EvmConfiguration; +import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import org.hyperledger.besu.plugin.data.TransactionSelectionResult; import org.hyperledger.besu.testutil.TestClock; import org.hyperledger.besu.util.number.Fraction; @@ -71,7 +72,9 @@ public class LondonFeeMarketBlockTransactionSelectorTest false, EvmConfiguration.DEFAULT, MiningParameters.MINING_DISABLED, - new BadBlockManager()) + new BadBlockManager(), + false, + new NoOpMetricsSystem()) .createProtocolSchedule(); } diff --git a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/PoWBlockCreatorTest.java b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/PoWBlockCreatorTest.java index 2cd5bc5e9e..7e3c01200c 100644 --- a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/PoWBlockCreatorTest.java +++ b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/PoWBlockCreatorTest.java @@ -97,8 +97,10 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest { PrivacyParameters.DEFAULT, false, EvmConfiguration.DEFAULT, - miningParameters, - new BadBlockManager()) + MiningParameters.MINING_DISABLED, + new BadBlockManager(), + false, + new NoOpMetricsSystem()) .createProtocolSchedule()) .build(); @@ -158,8 +160,10 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest { PrivacyParameters.DEFAULT, false, EvmConfiguration.DEFAULT, - miningParameters, - new BadBlockManager()) + MiningParameters.MINING_DISABLED, + new BadBlockManager(), + false, + new NoOpMetricsSystem()) .createProtocolSchedule()) .build(); @@ -209,8 +213,10 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest { PrivacyParameters.DEFAULT, false, EvmConfiguration.DEFAULT, - miningParameters, - new BadBlockManager()) + MiningParameters.MINING_DISABLED, + new BadBlockManager(), + false, + new NoOpMetricsSystem()) .createProtocolSchedule(); final ExecutionContextTestFixture executionContextTestFixture = ExecutionContextTestFixture.builder(genesisConfigFile) @@ -285,8 +291,10 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest { PrivacyParameters.DEFAULT, false, EvmConfiguration.DEFAULT, - miningParameters, - new BadBlockManager()) + MiningParameters.MINING_DISABLED, + new BadBlockManager(), + false, + new NoOpMetricsSystem()) .createProtocolSchedule(); final ExecutionContextTestFixture executionContextTestFixture = ExecutionContextTestFixture.builder(genesisConfigFile) diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/difficulty/fixed/FixedDifficultyProtocolSchedule.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/difficulty/fixed/FixedDifficultyProtocolSchedule.java index b7f8395d92..b86b2b0de2 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/difficulty/fixed/FixedDifficultyProtocolSchedule.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/difficulty/fixed/FixedDifficultyProtocolSchedule.java @@ -22,6 +22,7 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolScheduleBuilder; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecAdapters; import org.hyperledger.besu.evm.internal.EvmConfiguration; +import org.hyperledger.besu.plugin.services.MetricsSystem; /** A ProtocolSchedule which behaves similarly to MainNet, but with a much reduced difficulty. */ public class FixedDifficultyProtocolSchedule { @@ -32,7 +33,9 @@ public class FixedDifficultyProtocolSchedule { final boolean isRevertReasonEnabled, final EvmConfiguration evmConfiguration, final MiningParameters miningParameters, - final BadBlockManager badBlockManager) { + final BadBlockManager badBlockManager, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { return new ProtocolScheduleBuilder( config, ProtocolSpecAdapters.create( @@ -43,7 +46,9 @@ public class FixedDifficultyProtocolSchedule { isRevertReasonEnabled, evmConfiguration, miningParameters, - badBlockManager) + badBlockManager, + isParallelTxProcessingEnabled, + metricsSystem) .createProtocolSchedule(); } @@ -52,27 +57,35 @@ public class FixedDifficultyProtocolSchedule { final boolean isRevertReasonEnabled, final EvmConfiguration evmConfiguration, final MiningParameters miningParameters, - final BadBlockManager badBlockManager) { + final BadBlockManager badBlockManager, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { return create( config, PrivacyParameters.DEFAULT, isRevertReasonEnabled, evmConfiguration, miningParameters, - badBlockManager); + badBlockManager, + isParallelTxProcessingEnabled, + metricsSystem); } public static ProtocolSchedule create( final GenesisConfigOptions config, final EvmConfiguration evmConfiguration, final MiningParameters miningParameters, - final BadBlockManager badBlockManager) { + final BadBlockManager badBlockManager, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { return create( config, PrivacyParameters.DEFAULT, false, evmConfiguration, miningParameters, - badBlockManager); + badBlockManager, + isParallelTxProcessingEnabled, + metricsSystem); } } 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 8ecfa453d9..480a1d8d7a 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 @@ -38,6 +38,7 @@ import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.worldview.BonsaiWorld import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.worldview.BonsaiWorldStateUpdateAccumulator; import org.hyperledger.besu.ethereum.vm.CachingBlockHashLookup; import org.hyperledger.besu.evm.gascalculator.CancunGasCalculator; +import org.hyperledger.besu.evm.operation.BlockHashOperation; import org.hyperledger.besu.evm.tracing.OperationTracer; import org.hyperledger.besu.evm.worldstate.WorldState; import org.hyperledger.besu.evm.worldstate.WorldUpdater; @@ -110,57 +111,67 @@ public abstract class AbstractBlockProcessor implements BlockProcessor { protocolSpec.getBlockHashProcessor().processBlockHashes(blockchain, worldState, blockHeader); final BlockHashLookup blockHashLookup = new CachingBlockHashLookup(blockHeader, blockchain); - for (final Transaction transaction : transactions) { + final Address miningBeneficiary = miningBeneficiaryCalculator.calculateBeneficiary(blockHeader); + + Optional maybeParentHeader = + blockchain.getBlockHeader(blockHeader.getParentHash()); + + Wei blobGasPrice = + maybeParentHeader + .map( + parentHeader -> + protocolSpec + .getFeeMarket() + .blobGasPricePerGas( + calculateExcessBlobGasForParent(protocolSpec, parentHeader))) + .orElse(Wei.ZERO); + + final Optional preProcessingContext = + runBlockPreProcessing( + worldState, + privateMetadataUpdater, + blockHeader, + transactions, + miningBeneficiary, + blockHashLookup, + blobGasPrice); + + for (int i = 0; i < transactions.size(); i++) { + final Transaction transaction = transactions.get(i); if (!hasAvailableBlockBudget(blockHeader, transaction, currentGasUsed)) { return new BlockProcessingResult(Optional.empty(), "provided gas insufficient"); } + final WorldUpdater blockUpdater = worldState.updater(); - final WorldUpdater worldStateUpdater = worldState.updater(); - - final Address miningBeneficiary = - miningBeneficiaryCalculator.calculateBeneficiary(blockHeader); - - Optional maybeParentHeader = - blockchain.getBlockHeader(blockHeader.getParentHash()); - - Wei blobGasPrice = - maybeParentHeader - .map( - parentHeader -> - protocolSpec - .getFeeMarket() - .blobGasPricePerGas( - calculateExcessBlobGasForParent(protocolSpec, parentHeader))) - .orElse(Wei.ZERO); - - final TransactionProcessingResult result = - transactionProcessor.processTransaction( - worldStateUpdater, + TransactionProcessingResult transactionProcessingResult = + getTransactionProcessingResult( + preProcessingContext, + worldState, + blockUpdater, + privateMetadataUpdater, blockHeader, - transaction, + blobGasPrice, miningBeneficiary, - OperationTracer.NO_TRACING, - blockHashLookup, - true, - TransactionValidationParams.processingBlock(), - privateMetadataUpdater, - blobGasPrice); - if (result.isInvalid()) { + transaction, + i, + blockHashLookup); + if (transactionProcessingResult.isInvalid()) { String errorMessage = MessageFormat.format( "Block processing error: transaction invalid {0}. Block {1} Transaction {2}", - result.getValidationResult().getErrorMessage(), + transactionProcessingResult.getValidationResult().getErrorMessage(), blockHeader.getHash().toHexString(), transaction.getHash().toHexString()); LOG.info(errorMessage); if (worldState instanceof BonsaiWorldState) { - ((BonsaiWorldStateUpdateAccumulator) worldStateUpdater).reset(); + ((BonsaiWorldStateUpdateAccumulator) blockUpdater).reset(); } return new BlockProcessingResult(Optional.empty(), errorMessage); } - worldStateUpdater.commit(); - currentGasUsed += transaction.getGasLimit() - result.getGasRemaining(); + blockUpdater.commit(); + + currentGasUsed += transaction.getGasLimit() - transactionProcessingResult.getGasRemaining(); if (transaction.getVersionedHashes().isPresent()) { currentBlobGasUsed += (transaction.getVersionedHashes().get().size() * CancunGasCalculator.BLOB_GAS_PER_BLOB); @@ -168,7 +179,7 @@ public abstract class AbstractBlockProcessor implements BlockProcessor { final TransactionReceipt transactionReceipt = transactionReceiptFactory.create( - transaction.getType(), result, worldState, currentGasUsed); + transaction.getType(), transactionProcessingResult, worldState, currentGasUsed); receipts.add(transactionReceipt); } if (blockHeader.getBlobGasUsed().isPresent() @@ -235,6 +246,41 @@ public abstract class AbstractBlockProcessor implements BlockProcessor { Optional.of(new BlockProcessingOutputs(worldState, receipts, maybeRequests))); } + protected Optional runBlockPreProcessing( + final MutableWorldState worldState, + final PrivateMetadataUpdater privateMetadataUpdater, + final BlockHeader blockHeader, + final List transactions, + final Address miningBeneficiary, + final BlockHashOperation.BlockHashLookup blockHashLookup, + final Wei blobGasPrice) { + return Optional.empty(); + } + + protected TransactionProcessingResult getTransactionProcessingResult( + final Optional preProcessingContext, + final MutableWorldState worldState, + final WorldUpdater blockUpdater, + final PrivateMetadataUpdater privateMetadataUpdater, + final BlockHeader blockHeader, + final Wei blobGasPrice, + final Address miningBeneficiary, + final Transaction transaction, + final int location, + final BlockHashLookup blockHashLookup) { + return transactionProcessor.processTransaction( + blockUpdater, + blockHeader, + transaction, + miningBeneficiary, + OperationTracer.NO_TRACING, + blockHashLookup, + true, + TransactionValidationParams.processingBlock(), + privateMetadataUpdater, + blobGasPrice); + } + protected boolean hasAvailableBlockBudget( final BlockHeader blockHeader, final Transaction transaction, final long currentGasUsed) { final long remainingGasBudget = blockHeader.getGasLimit() - currentGasUsed; @@ -261,4 +307,7 @@ public abstract class AbstractBlockProcessor implements BlockProcessor { final BlockHeader header, final List ommers, final boolean skipZeroBlockRewards); + + public interface PreprocessingContext {} + ; } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ClassicProtocolSpecs.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ClassicProtocolSpecs.java index aec844894f..47c1747dc9 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ClassicProtocolSpecs.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ClassicProtocolSpecs.java @@ -38,6 +38,7 @@ import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.evm.processor.ContractCreationProcessor; import org.hyperledger.besu.evm.processor.MessageCallProcessor; import org.hyperledger.besu.evm.worldstate.WorldState; +import org.hyperledger.besu.plugin.services.MetricsSystem; import java.math.BigInteger; import java.util.Collections; @@ -54,16 +55,23 @@ public class ClassicProtocolSpecs { } public static ProtocolSpecBuilder classicRecoveryInitDefinition( - final EvmConfiguration evmConfiguration) { - return MainnetProtocolSpecs.homesteadDefinition(evmConfiguration) + final EvmConfiguration evmConfiguration, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { + return MainnetProtocolSpecs.homesteadDefinition( + evmConfiguration, isParallelTxProcessingEnabled, metricsSystem) .blockHeaderValidatorBuilder( feeMarket -> MainnetBlockHeaderValidator.createClassicValidator()) .name("ClassicRecoveryInit"); } public static ProtocolSpecBuilder tangerineWhistleDefinition( - final Optional chainId, final EvmConfiguration evmConfiguration) { - return MainnetProtocolSpecs.homesteadDefinition(evmConfiguration) + final Optional chainId, + final EvmConfiguration evmConfiguration, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { + return MainnetProtocolSpecs.homesteadDefinition( + evmConfiguration, isParallelTxProcessingEnabled, metricsSystem) .isReplayProtectionSupported(true) .gasCalculator(TangerineWhistleGasCalculator::new) .transactionValidatorFactoryBuilder( @@ -74,8 +82,12 @@ public class ClassicProtocolSpecs { } public static ProtocolSpecBuilder dieHardDefinition( - final Optional chainId, final EvmConfiguration evmConfiguration) { - return tangerineWhistleDefinition(chainId, evmConfiguration) + final Optional chainId, + final EvmConfiguration evmConfiguration, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { + return tangerineWhistleDefinition( + chainId, evmConfiguration, isParallelTxProcessingEnabled, metricsSystem) .gasCalculator(DieHardGasCalculator::new) .difficultyCalculator(ClassicDifficultyCalculators.DIFFICULTY_BOMB_PAUSED) .name("DieHard"); @@ -84,8 +96,11 @@ public class ClassicProtocolSpecs { public static ProtocolSpecBuilder gothamDefinition( final Optional chainId, final OptionalLong ecip1017EraRounds, - final EvmConfiguration evmConfiguration) { - return dieHardDefinition(chainId, evmConfiguration) + final EvmConfiguration evmConfiguration, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { + return dieHardDefinition( + chainId, evmConfiguration, isParallelTxProcessingEnabled, metricsSystem) .blockReward(MAX_BLOCK_REWARD) .difficultyCalculator(ClassicDifficultyCalculators.DIFFICULTY_BOMB_DELAYED) .blockProcessorBuilder( @@ -109,8 +124,15 @@ public class ClassicProtocolSpecs { public static ProtocolSpecBuilder defuseDifficultyBombDefinition( final Optional chainId, final OptionalLong ecip1017EraRounds, - final EvmConfiguration evmConfiguration) { - return gothamDefinition(chainId, ecip1017EraRounds, evmConfiguration) + final EvmConfiguration evmConfiguration, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { + return gothamDefinition( + chainId, + ecip1017EraRounds, + evmConfiguration, + isParallelTxProcessingEnabled, + metricsSystem) .difficultyCalculator(ClassicDifficultyCalculators.DIFFICULTY_BOMB_REMOVED) .transactionValidatorFactoryBuilder( (evm, gasLimitCalculator, feeMarket) -> @@ -123,8 +145,15 @@ public class ClassicProtocolSpecs { final Optional chainId, final boolean enableRevertReason, final OptionalLong ecip1017EraRounds, - final EvmConfiguration evmConfiguration) { - return gothamDefinition(chainId, ecip1017EraRounds, evmConfiguration) + final EvmConfiguration evmConfiguration, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { + return gothamDefinition( + chainId, + ecip1017EraRounds, + evmConfiguration, + isParallelTxProcessingEnabled, + metricsSystem) .evmBuilder(MainnetEVMs::byzantium) .evmConfiguration(evmConfiguration) .gasCalculator(SpuriousDragonGasCalculator::new) @@ -163,8 +192,16 @@ public class ClassicProtocolSpecs { final Optional chainId, final boolean enableRevertReason, final OptionalLong ecip1017EraRounds, - final EvmConfiguration evmConfiguration) { - return atlantisDefinition(chainId, enableRevertReason, ecip1017EraRounds, evmConfiguration) + final EvmConfiguration evmConfiguration, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { + return atlantisDefinition( + chainId, + enableRevertReason, + ecip1017EraRounds, + evmConfiguration, + isParallelTxProcessingEnabled, + metricsSystem) .evmBuilder(MainnetEVMs::constantinople) .gasCalculator(PetersburgGasCalculator::new) .evmBuilder(MainnetEVMs::constantinople) @@ -176,8 +213,16 @@ public class ClassicProtocolSpecs { final Optional chainId, final boolean enableRevertReason, final OptionalLong ecip1017EraRounds, - final EvmConfiguration evmConfiguration) { - return aghartaDefinition(chainId, enableRevertReason, ecip1017EraRounds, evmConfiguration) + final EvmConfiguration evmConfiguration, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { + return aghartaDefinition( + chainId, + enableRevertReason, + ecip1017EraRounds, + evmConfiguration, + isParallelTxProcessingEnabled, + metricsSystem) .gasCalculator(IstanbulGasCalculator::new) .evmBuilder( (gasCalculator, evmConfig) -> @@ -191,8 +236,16 @@ public class ClassicProtocolSpecs { final Optional chainId, final boolean enableRevertReason, final OptionalLong ecip1017EraRounds, - final EvmConfiguration evmConfiguration) { - return phoenixDefinition(chainId, enableRevertReason, ecip1017EraRounds, evmConfiguration) + final EvmConfiguration evmConfiguration, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { + return phoenixDefinition( + chainId, + enableRevertReason, + ecip1017EraRounds, + evmConfiguration, + isParallelTxProcessingEnabled, + metricsSystem) .blockHeaderValidatorBuilder( feeMarket -> MainnetBlockHeaderValidator.createPgaBlockHeaderValidator( @@ -228,8 +281,16 @@ public class ClassicProtocolSpecs { final Optional chainId, final boolean enableRevertReason, final OptionalLong ecip1017EraRounds, - final EvmConfiguration evmConfiguration) { - return thanosDefinition(chainId, enableRevertReason, ecip1017EraRounds, evmConfiguration) + final EvmConfiguration evmConfiguration, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { + return thanosDefinition( + chainId, + enableRevertReason, + ecip1017EraRounds, + evmConfiguration, + isParallelTxProcessingEnabled, + metricsSystem) .gasCalculator(BerlinGasCalculator::new) .transactionValidatorFactoryBuilder( (evm, gasLimitCalculator, feeMarket) -> @@ -250,8 +311,16 @@ public class ClassicProtocolSpecs { final Optional chainId, final boolean enableRevertReason, final OptionalLong ecip1017EraRounds, - final EvmConfiguration evmConfiguration) { - return magnetoDefinition(chainId, enableRevertReason, ecip1017EraRounds, evmConfiguration) + final EvmConfiguration evmConfiguration, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { + return magnetoDefinition( + chainId, + enableRevertReason, + ecip1017EraRounds, + evmConfiguration, + isParallelTxProcessingEnabled, + metricsSystem) .gasCalculator(LondonGasCalculator::new) .contractCreationProcessorBuilder( evm -> @@ -264,8 +333,16 @@ public class ClassicProtocolSpecs { final Optional chainId, final boolean enableRevertReason, final OptionalLong ecip1017EraRounds, - final EvmConfiguration evmConfiguration) { - return mystiqueDefinition(chainId, enableRevertReason, ecip1017EraRounds, evmConfiguration) + final EvmConfiguration evmConfiguration, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { + return mystiqueDefinition( + chainId, + enableRevertReason, + ecip1017EraRounds, + evmConfiguration, + isParallelTxProcessingEnabled, + metricsSystem) // EIP-3860 .gasCalculator(ShanghaiGasCalculator::new) // EIP-3855 diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSchedule.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSchedule.java index 794f96cfb3..88b6a5ae1b 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSchedule.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSchedule.java @@ -21,6 +21,7 @@ import org.hyperledger.besu.ethereum.core.PrivacyParameters; import org.hyperledger.besu.ethereum.difficulty.fixed.FixedDifficultyCalculators; import org.hyperledger.besu.ethereum.difficulty.fixed.FixedDifficultyProtocolSchedule; import org.hyperledger.besu.evm.internal.EvmConfiguration; +import org.hyperledger.besu.plugin.services.MetricsSystem; import java.math.BigInteger; import java.util.function.Function; @@ -40,6 +41,8 @@ public class MainnetProtocolSchedule { * @param evmConfiguration how to configure the EVMs jumpdest cache * @param miningParameters the mining parameters * @param badBlockManager the cache to use to keep invalid blocks + * @param isParallelTxProcessingEnabled indicates whether parallel transaction is enabled + * @param metricsSystem A metricSystem instance to expose metrics in the underlying calls * @return A configured mainnet protocol schedule */ public static ProtocolSchedule fromConfig( @@ -48,7 +51,9 @@ public class MainnetProtocolSchedule { final boolean isRevertReasonEnabled, final EvmConfiguration evmConfiguration, final MiningParameters miningParameters, - final BadBlockManager badBlockManager) { + final BadBlockManager badBlockManager, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { if (FixedDifficultyCalculators.isFixedDifficultyInConfig(config)) { return FixedDifficultyProtocolSchedule.create( config, @@ -56,7 +61,9 @@ public class MainnetProtocolSchedule { isRevertReasonEnabled, evmConfiguration, miningParameters, - badBlockManager); + badBlockManager, + isParallelTxProcessingEnabled, + metricsSystem); } return new ProtocolScheduleBuilder( config, @@ -66,7 +73,9 @@ public class MainnetProtocolSchedule { isRevertReasonEnabled, evmConfiguration, miningParameters, - badBlockManager) + badBlockManager, + isParallelTxProcessingEnabled, + metricsSystem) .createProtocolSchedule(); } @@ -79,6 +88,7 @@ public class MainnetProtocolSchedule { * @param evmConfiguration how to configure the EVMs jumpdest cache * @param miningParameters the mining parameters * @param badBlockManager the cache to use to keep invalid blocks + * @param isParallelTxProcessingEnabled indicates whether parallel transaction is enabled. * @return A configured mainnet protocol schedule */ public static ProtocolSchedule fromConfig( @@ -86,14 +96,18 @@ public class MainnetProtocolSchedule { final boolean isRevertReasonEnabled, final EvmConfiguration evmConfiguration, final MiningParameters miningParameters, - final BadBlockManager badBlockManager) { + final BadBlockManager badBlockManager, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { return fromConfig( config, PrivacyParameters.DEFAULT, isRevertReasonEnabled, evmConfiguration, miningParameters, - badBlockManager); + badBlockManager, + isParallelTxProcessingEnabled, + metricsSystem); } /** @@ -104,20 +118,25 @@ public class MainnetProtocolSchedule { * @param evmConfiguration size of * @param miningParameters the mining parameters * @param badBlockManager the cache to use to keep invalid blocks + * @param isParallelTxProcessingEnabled indicates whether parallel transaction is enabled. * @return A configured mainnet protocol schedule */ public static ProtocolSchedule fromConfig( final GenesisConfigOptions config, final EvmConfiguration evmConfiguration, final MiningParameters miningParameters, - final BadBlockManager badBlockManager) { + final BadBlockManager badBlockManager, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { return fromConfig( config, PrivacyParameters.DEFAULT, false, evmConfiguration, miningParameters, - badBlockManager); + badBlockManager, + isParallelTxProcessingEnabled, + metricsSystem); } /** @@ -127,18 +146,23 @@ public class MainnetProtocolSchedule { * starting points * @param miningParameters the mining parameters * @param badBlockManager the cache to use to keep invalid blocks + * @param isParallelTxProcessingEnabled indicates whether parallel transaction is enabled. * @return A configured mainnet protocol schedule */ public static ProtocolSchedule fromConfig( final GenesisConfigOptions config, final MiningParameters miningParameters, - final BadBlockManager badBlockManager) { + final BadBlockManager badBlockManager, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { return fromConfig( config, PrivacyParameters.DEFAULT, false, EvmConfiguration.DEFAULT, miningParameters, - badBlockManager); + badBlockManager, + isParallelTxProcessingEnabled, + metricsSystem); } } 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 aa9bae6c7e..55bfb363ba 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 @@ -17,6 +17,7 @@ package org.hyperledger.besu.ethereum.mainnet; import org.hyperledger.besu.config.GenesisConfigOptions; import org.hyperledger.besu.ethereum.core.MiningParameters; import org.hyperledger.besu.evm.internal.EvmConfiguration; +import org.hyperledger.besu.plugin.services.MetricsSystem; import java.math.BigInteger; import java.util.Optional; @@ -29,118 +30,209 @@ public class MainnetProtocolSpecFactory { private final OptionalLong ecip1017EraRounds; private final EvmConfiguration evmConfiguration; private final MiningParameters miningParameters; + private final boolean isParallelTxProcessingEnabled; + private final MetricsSystem metricsSystem; public MainnetProtocolSpecFactory( final Optional chainId, final boolean isRevertReasonEnabled, final OptionalLong ecip1017EraRounds, final EvmConfiguration evmConfiguration, - final MiningParameters miningParameters) { + final MiningParameters miningParameters, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { this.chainId = chainId; this.isRevertReasonEnabled = isRevertReasonEnabled; this.ecip1017EraRounds = ecip1017EraRounds; this.evmConfiguration = evmConfiguration; this.miningParameters = miningParameters; + this.isParallelTxProcessingEnabled = isParallelTxProcessingEnabled; + this.metricsSystem = metricsSystem; } public ProtocolSpecBuilder frontierDefinition() { - return MainnetProtocolSpecs.frontierDefinition(evmConfiguration); + return MainnetProtocolSpecs.frontierDefinition( + evmConfiguration, isParallelTxProcessingEnabled, metricsSystem); } public ProtocolSpecBuilder homesteadDefinition() { - return MainnetProtocolSpecs.homesteadDefinition(evmConfiguration); + return MainnetProtocolSpecs.homesteadDefinition( + evmConfiguration, isParallelTxProcessingEnabled, metricsSystem); } public ProtocolSpecBuilder daoRecoveryInitDefinition() { - return MainnetProtocolSpecs.daoRecoveryInitDefinition(evmConfiguration); + return MainnetProtocolSpecs.daoRecoveryInitDefinition( + evmConfiguration, isParallelTxProcessingEnabled, metricsSystem); } public ProtocolSpecBuilder daoRecoveryTransitionDefinition() { - return MainnetProtocolSpecs.daoRecoveryTransitionDefinition(evmConfiguration); + return MainnetProtocolSpecs.daoRecoveryTransitionDefinition( + evmConfiguration, isParallelTxProcessingEnabled, metricsSystem); } public ProtocolSpecBuilder tangerineWhistleDefinition() { - return MainnetProtocolSpecs.tangerineWhistleDefinition(evmConfiguration); + return MainnetProtocolSpecs.tangerineWhistleDefinition( + evmConfiguration, isParallelTxProcessingEnabled, metricsSystem); } public ProtocolSpecBuilder spuriousDragonDefinition() { - return MainnetProtocolSpecs.spuriousDragonDefinition(chainId, evmConfiguration); + return MainnetProtocolSpecs.spuriousDragonDefinition( + chainId, evmConfiguration, isParallelTxProcessingEnabled, metricsSystem); } public ProtocolSpecBuilder byzantiumDefinition() { return MainnetProtocolSpecs.byzantiumDefinition( - chainId, isRevertReasonEnabled, evmConfiguration); + chainId, + isRevertReasonEnabled, + evmConfiguration, + isParallelTxProcessingEnabled, + metricsSystem); } public ProtocolSpecBuilder constantinopleDefinition() { return MainnetProtocolSpecs.constantinopleDefinition( - chainId, isRevertReasonEnabled, evmConfiguration); + chainId, + isRevertReasonEnabled, + evmConfiguration, + isParallelTxProcessingEnabled, + metricsSystem); } public ProtocolSpecBuilder petersburgDefinition() { return MainnetProtocolSpecs.petersburgDefinition( - chainId, isRevertReasonEnabled, evmConfiguration); + chainId, + isRevertReasonEnabled, + evmConfiguration, + isParallelTxProcessingEnabled, + metricsSystem); } public ProtocolSpecBuilder istanbulDefinition() { return MainnetProtocolSpecs.istanbulDefinition( - chainId, isRevertReasonEnabled, evmConfiguration); + chainId, + isRevertReasonEnabled, + evmConfiguration, + isParallelTxProcessingEnabled, + metricsSystem); } public ProtocolSpecBuilder muirGlacierDefinition() { return MainnetProtocolSpecs.muirGlacierDefinition( - chainId, isRevertReasonEnabled, evmConfiguration); + chainId, + isRevertReasonEnabled, + evmConfiguration, + isParallelTxProcessingEnabled, + metricsSystem); } public ProtocolSpecBuilder berlinDefinition() { - return MainnetProtocolSpecs.berlinDefinition(chainId, isRevertReasonEnabled, evmConfiguration); + return MainnetProtocolSpecs.berlinDefinition( + chainId, + isRevertReasonEnabled, + evmConfiguration, + isParallelTxProcessingEnabled, + metricsSystem); } public ProtocolSpecBuilder londonDefinition(final GenesisConfigOptions genesisConfigOptions) { return MainnetProtocolSpecs.londonDefinition( - chainId, isRevertReasonEnabled, genesisConfigOptions, evmConfiguration, miningParameters); + chainId, + isRevertReasonEnabled, + genesisConfigOptions, + evmConfiguration, + miningParameters, + isParallelTxProcessingEnabled, + metricsSystem); } public ProtocolSpecBuilder arrowGlacierDefinition( final GenesisConfigOptions genesisConfigOptions) { return MainnetProtocolSpecs.arrowGlacierDefinition( - chainId, isRevertReasonEnabled, genesisConfigOptions, evmConfiguration, miningParameters); + chainId, + isRevertReasonEnabled, + genesisConfigOptions, + evmConfiguration, + miningParameters, + isParallelTxProcessingEnabled, + metricsSystem); } public ProtocolSpecBuilder grayGlacierDefinition( final GenesisConfigOptions genesisConfigOptions) { return MainnetProtocolSpecs.grayGlacierDefinition( - chainId, isRevertReasonEnabled, genesisConfigOptions, evmConfiguration, miningParameters); + chainId, + isRevertReasonEnabled, + genesisConfigOptions, + evmConfiguration, + miningParameters, + isParallelTxProcessingEnabled, + metricsSystem); } public ProtocolSpecBuilder parisDefinition(final GenesisConfigOptions genesisConfigOptions) { return MainnetProtocolSpecs.parisDefinition( - chainId, isRevertReasonEnabled, genesisConfigOptions, evmConfiguration, miningParameters); + chainId, + isRevertReasonEnabled, + genesisConfigOptions, + evmConfiguration, + miningParameters, + isParallelTxProcessingEnabled, + metricsSystem); } public ProtocolSpecBuilder shanghaiDefinition(final GenesisConfigOptions genesisConfigOptions) { return MainnetProtocolSpecs.shanghaiDefinition( - chainId, isRevertReasonEnabled, genesisConfigOptions, evmConfiguration, miningParameters); + chainId, + isRevertReasonEnabled, + genesisConfigOptions, + evmConfiguration, + miningParameters, + isParallelTxProcessingEnabled, + metricsSystem); } public ProtocolSpecBuilder cancunDefinition(final GenesisConfigOptions genesisConfigOptions) { return MainnetProtocolSpecs.cancunDefinition( - chainId, isRevertReasonEnabled, genesisConfigOptions, evmConfiguration, miningParameters); + chainId, + isRevertReasonEnabled, + genesisConfigOptions, + evmConfiguration, + miningParameters, + isParallelTxProcessingEnabled, + metricsSystem); } public ProtocolSpecBuilder cancunEOFDefinition(final GenesisConfigOptions genesisConfigOptions) { return MainnetProtocolSpecs.cancunEOFDefinition( - chainId, isRevertReasonEnabled, genesisConfigOptions, evmConfiguration, miningParameters); + chainId, + isRevertReasonEnabled, + genesisConfigOptions, + evmConfiguration, + miningParameters, + isParallelTxProcessingEnabled, + metricsSystem); } public ProtocolSpecBuilder pragueDefinition(final GenesisConfigOptions genesisConfigOptions) { return MainnetProtocolSpecs.pragueDefinition( - chainId, isRevertReasonEnabled, genesisConfigOptions, evmConfiguration, miningParameters); + chainId, + isRevertReasonEnabled, + genesisConfigOptions, + evmConfiguration, + miningParameters, + isParallelTxProcessingEnabled, + metricsSystem); } public ProtocolSpecBuilder pragueEOFDefinition(final GenesisConfigOptions genesisConfigOptions) { return MainnetProtocolSpecs.pragueEOFDefinition( - chainId, isRevertReasonEnabled, genesisConfigOptions, evmConfiguration, miningParameters); + chainId, + isRevertReasonEnabled, + genesisConfigOptions, + evmConfiguration, + miningParameters, + isParallelTxProcessingEnabled, + metricsSystem); } /** @@ -156,7 +248,13 @@ public class MainnetProtocolSpecFactory { */ public ProtocolSpecBuilder futureEipsDefinition(final GenesisConfigOptions genesisConfigOptions) { return MainnetProtocolSpecs.futureEipsDefinition( - chainId, isRevertReasonEnabled, genesisConfigOptions, evmConfiguration, miningParameters); + chainId, + isRevertReasonEnabled, + genesisConfigOptions, + evmConfiguration, + miningParameters, + isParallelTxProcessingEnabled, + metricsSystem); } /** @@ -172,57 +270,100 @@ public class MainnetProtocolSpecFactory { public ProtocolSpecBuilder experimentalEipsDefinition( final GenesisConfigOptions genesisConfigOptions) { return MainnetProtocolSpecs.experimentalEipsDefinition( - chainId, isRevertReasonEnabled, genesisConfigOptions, evmConfiguration, miningParameters); + chainId, + isRevertReasonEnabled, + genesisConfigOptions, + evmConfiguration, + miningParameters, + isParallelTxProcessingEnabled, + metricsSystem); } //////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////// // Classic Protocol Specs public ProtocolSpecBuilder dieHardDefinition() { - return ClassicProtocolSpecs.dieHardDefinition(chainId, evmConfiguration); + return ClassicProtocolSpecs.dieHardDefinition( + chainId, evmConfiguration, isParallelTxProcessingEnabled, metricsSystem); } public ProtocolSpecBuilder gothamDefinition() { - return ClassicProtocolSpecs.gothamDefinition(chainId, ecip1017EraRounds, evmConfiguration); + return ClassicProtocolSpecs.gothamDefinition( + chainId, ecip1017EraRounds, evmConfiguration, isParallelTxProcessingEnabled, metricsSystem); } public ProtocolSpecBuilder defuseDifficultyBombDefinition() { return ClassicProtocolSpecs.defuseDifficultyBombDefinition( - chainId, ecip1017EraRounds, evmConfiguration); + chainId, ecip1017EraRounds, evmConfiguration, isParallelTxProcessingEnabled, metricsSystem); } public ProtocolSpecBuilder atlantisDefinition() { return ClassicProtocolSpecs.atlantisDefinition( - chainId, isRevertReasonEnabled, ecip1017EraRounds, evmConfiguration); + chainId, + isRevertReasonEnabled, + ecip1017EraRounds, + evmConfiguration, + isParallelTxProcessingEnabled, + metricsSystem); } public ProtocolSpecBuilder aghartaDefinition() { return ClassicProtocolSpecs.aghartaDefinition( - chainId, isRevertReasonEnabled, ecip1017EraRounds, evmConfiguration); + chainId, + isRevertReasonEnabled, + ecip1017EraRounds, + evmConfiguration, + isParallelTxProcessingEnabled, + metricsSystem); } public ProtocolSpecBuilder phoenixDefinition() { return ClassicProtocolSpecs.phoenixDefinition( - chainId, isRevertReasonEnabled, ecip1017EraRounds, evmConfiguration); + chainId, + isRevertReasonEnabled, + ecip1017EraRounds, + evmConfiguration, + isParallelTxProcessingEnabled, + metricsSystem); } public ProtocolSpecBuilder thanosDefinition() { return ClassicProtocolSpecs.thanosDefinition( - chainId, isRevertReasonEnabled, ecip1017EraRounds, evmConfiguration); + chainId, + isRevertReasonEnabled, + ecip1017EraRounds, + evmConfiguration, + isParallelTxProcessingEnabled, + metricsSystem); } public ProtocolSpecBuilder magnetoDefinition() { return ClassicProtocolSpecs.magnetoDefinition( - chainId, isRevertReasonEnabled, ecip1017EraRounds, evmConfiguration); + chainId, + isRevertReasonEnabled, + ecip1017EraRounds, + evmConfiguration, + isParallelTxProcessingEnabled, + metricsSystem); } public ProtocolSpecBuilder mystiqueDefinition() { return ClassicProtocolSpecs.mystiqueDefinition( - chainId, isRevertReasonEnabled, ecip1017EraRounds, evmConfiguration); + chainId, + isRevertReasonEnabled, + ecip1017EraRounds, + evmConfiguration, + isParallelTxProcessingEnabled, + metricsSystem); } public ProtocolSpecBuilder spiralDefinition() { return ClassicProtocolSpecs.spiralDefinition( - chainId, isRevertReasonEnabled, ecip1017EraRounds, evmConfiguration); + chainId, + isRevertReasonEnabled, + ecip1017EraRounds, + evmConfiguration, + isParallelTxProcessingEnabled, + metricsSystem); } } 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 6f09df923e..36d8257ffb 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 @@ -39,6 +39,7 @@ import org.hyperledger.besu.ethereum.mainnet.blockhash.FrontierBlockHashProcesso import org.hyperledger.besu.ethereum.mainnet.blockhash.PragueBlockHashProcessor; import org.hyperledger.besu.ethereum.mainnet.feemarket.BaseFeeMarket; import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; +import org.hyperledger.besu.ethereum.mainnet.parallelization.MainnetParallelBlockProcessor; import org.hyperledger.besu.ethereum.privacy.PrivateTransactionProcessor; import org.hyperledger.besu.ethereum.privacy.PrivateTransactionValidator; import org.hyperledger.besu.ethereum.privacy.storage.PrivateMetadataUpdater; @@ -67,6 +68,7 @@ import org.hyperledger.besu.evm.processor.ContractCreationProcessor; import org.hyperledger.besu.evm.processor.MessageCallProcessor; import org.hyperledger.besu.evm.worldstate.WorldState; import org.hyperledger.besu.evm.worldstate.WorldUpdater; +import org.hyperledger.besu.plugin.services.MetricsSystem; import java.io.IOException; import java.math.BigInteger; @@ -101,7 +103,10 @@ public abstract class MainnetProtocolSpecs { private MainnetProtocolSpecs() {} - public static ProtocolSpecBuilder frontierDefinition(final EvmConfiguration evmConfiguration) { + public static ProtocolSpecBuilder frontierDefinition( + final EvmConfiguration evmConfiguration, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { return new ProtocolSpecBuilder() .gasCalculator(FrontierGasCalculator::new) .gasLimitCalculatorBuilder(feeMarket -> new FrontierTargetingGasLimitCalculator()) @@ -152,7 +157,10 @@ public abstract class MainnetProtocolSpecs { .transactionReceiptFactory(MainnetProtocolSpecs::frontierTransactionReceiptFactory) .blockReward(FRONTIER_BLOCK_REWARD) .skipZeroBlockRewards(false) - .blockProcessorBuilder(MainnetBlockProcessor::new) + .blockProcessorBuilder( + isParallelTxProcessingEnabled + ? new MainnetParallelBlockProcessor.ParallelBlockProcessorBuilder(metricsSystem) + : MainnetBlockProcessor::new) .blockValidatorBuilder(MainnetProtocolSpecs.blockValidatorBuilder()) .blockImporterBuilder(MainnetBlockImporter::new) .blockHeaderFunctions(new MainnetBlockHeaderFunctions()) @@ -173,8 +181,11 @@ public abstract class MainnetProtocolSpecs { return MainnetBlockValidator::new; } - public static ProtocolSpecBuilder homesteadDefinition(final EvmConfiguration evmConfiguration) { - return frontierDefinition(evmConfiguration) + public static ProtocolSpecBuilder homesteadDefinition( + final EvmConfiguration evmConfiguration, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { + return frontierDefinition(evmConfiguration, isParallelTxProcessingEnabled, metricsSystem) .gasCalculator(HomesteadGasCalculator::new) .evmBuilder(MainnetEVMs::homestead) .contractCreationProcessorBuilder( @@ -190,8 +201,10 @@ public abstract class MainnetProtocolSpecs { } public static ProtocolSpecBuilder daoRecoveryInitDefinition( - final EvmConfiguration evmConfiguration) { - return homesteadDefinition(evmConfiguration) + final EvmConfiguration evmConfiguration, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { + return homesteadDefinition(evmConfiguration, isParallelTxProcessingEnabled, metricsSystem) .blockHeaderValidatorBuilder(feeMarket -> MainnetBlockHeaderValidator.createDaoValidator()) .blockProcessorBuilder( (transactionProcessor, @@ -201,33 +214,53 @@ public abstract class MainnetProtocolSpecs { skipZeroBlockRewards, protocolSchedule) -> new DaoBlockProcessor( - new MainnetBlockProcessor( - transactionProcessor, - transactionReceiptFactory, - blockReward, - miningBeneficiaryCalculator, - skipZeroBlockRewards, - protocolSchedule))) + isParallelTxProcessingEnabled + ? new MainnetParallelBlockProcessor( + transactionProcessor, + transactionReceiptFactory, + blockReward, + miningBeneficiaryCalculator, + skipZeroBlockRewards, + protocolSchedule, + metricsSystem) + : new MainnetBlockProcessor( + transactionProcessor, + transactionReceiptFactory, + blockReward, + miningBeneficiaryCalculator, + skipZeroBlockRewards, + protocolSchedule))) .name("DaoRecoveryInit"); } public static ProtocolSpecBuilder daoRecoveryTransitionDefinition( - final EvmConfiguration evmConfiguration) { - return daoRecoveryInitDefinition(evmConfiguration) - .blockProcessorBuilder(MainnetBlockProcessor::new) + final EvmConfiguration evmConfiguration, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { + return daoRecoveryInitDefinition(evmConfiguration, isParallelTxProcessingEnabled, metricsSystem) + .blockProcessorBuilder( + isParallelTxProcessingEnabled + ? new MainnetParallelBlockProcessor.ParallelBlockProcessorBuilder(metricsSystem) + : MainnetBlockProcessor::new) .name("DaoRecoveryTransition"); } public static ProtocolSpecBuilder tangerineWhistleDefinition( - final EvmConfiguration evmConfiguration) { - return homesteadDefinition(evmConfiguration) + final EvmConfiguration evmConfiguration, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { + return homesteadDefinition(evmConfiguration, isParallelTxProcessingEnabled, metricsSystem) .gasCalculator(TangerineWhistleGasCalculator::new) .name("TangerineWhistle"); } public static ProtocolSpecBuilder spuriousDragonDefinition( - final Optional chainId, final EvmConfiguration evmConfiguration) { - return tangerineWhistleDefinition(evmConfiguration) + final Optional chainId, + final EvmConfiguration evmConfiguration, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { + return tangerineWhistleDefinition( + evmConfiguration, isParallelTxProcessingEnabled, metricsSystem) .isReplayProtectionSupported(true) .gasCalculator(SpuriousDragonGasCalculator::new) .skipZeroBlockRewards(true) @@ -271,8 +304,11 @@ public abstract class MainnetProtocolSpecs { public static ProtocolSpecBuilder byzantiumDefinition( final Optional chainId, final boolean enableRevertReason, - final EvmConfiguration evmConfiguration) { - return spuriousDragonDefinition(chainId, evmConfiguration) + final EvmConfiguration evmConfiguration, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { + return spuriousDragonDefinition( + chainId, evmConfiguration, isParallelTxProcessingEnabled, metricsSystem) .gasCalculator(ByzantiumGasCalculator::new) .evmBuilder(MainnetEVMs::byzantium) .precompileContractRegistryBuilder(MainnetPrecompiledContractRegistries::byzantium) @@ -301,8 +337,15 @@ public abstract class MainnetProtocolSpecs { public static ProtocolSpecBuilder constantinopleDefinition( final Optional chainId, final boolean enableRevertReason, - final EvmConfiguration evmConfiguration) { - return byzantiumDefinition(chainId, enableRevertReason, evmConfiguration) + final EvmConfiguration evmConfiguration, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { + return byzantiumDefinition( + chainId, + enableRevertReason, + evmConfiguration, + isParallelTxProcessingEnabled, + metricsSystem) .difficultyCalculator(MainnetDifficultyCalculators.CONSTANTINOPLE) .gasCalculator(ConstantinopleGasCalculator::new) .evmBuilder(MainnetEVMs::constantinople) @@ -313,8 +356,15 @@ public abstract class MainnetProtocolSpecs { public static ProtocolSpecBuilder petersburgDefinition( final Optional chainId, final boolean enableRevertReason, - final EvmConfiguration evmConfiguration) { - return constantinopleDefinition(chainId, enableRevertReason, evmConfiguration) + final EvmConfiguration evmConfiguration, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { + return constantinopleDefinition( + chainId, + enableRevertReason, + evmConfiguration, + isParallelTxProcessingEnabled, + metricsSystem) .gasCalculator(PetersburgGasCalculator::new) .name("Petersburg"); } @@ -322,8 +372,15 @@ public abstract class MainnetProtocolSpecs { public static ProtocolSpecBuilder istanbulDefinition( final Optional chainId, final boolean enableRevertReason, - final EvmConfiguration evmConfiguration) { - return petersburgDefinition(chainId, enableRevertReason, evmConfiguration) + final EvmConfiguration evmConfiguration, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { + return petersburgDefinition( + chainId, + enableRevertReason, + evmConfiguration, + isParallelTxProcessingEnabled, + metricsSystem) .gasCalculator(IstanbulGasCalculator::new) .evmBuilder( (gasCalculator, jdCacheConfig) -> @@ -344,8 +401,15 @@ public abstract class MainnetProtocolSpecs { static ProtocolSpecBuilder muirGlacierDefinition( final Optional chainId, final boolean enableRevertReason, - final EvmConfiguration evmConfiguration) { - return istanbulDefinition(chainId, enableRevertReason, evmConfiguration) + final EvmConfiguration evmConfiguration, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { + return istanbulDefinition( + chainId, + enableRevertReason, + evmConfiguration, + isParallelTxProcessingEnabled, + metricsSystem) .difficultyCalculator(MainnetDifficultyCalculators.MUIR_GLACIER) .name("MuirGlacier"); } @@ -353,8 +417,15 @@ public abstract class MainnetProtocolSpecs { static ProtocolSpecBuilder berlinDefinition( final Optional chainId, final boolean enableRevertReason, - final EvmConfiguration evmConfiguration) { - return muirGlacierDefinition(chainId, enableRevertReason, evmConfiguration) + final EvmConfiguration evmConfiguration, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { + return muirGlacierDefinition( + chainId, + enableRevertReason, + evmConfiguration, + isParallelTxProcessingEnabled, + metricsSystem) .gasCalculator(BerlinGasCalculator::new) .transactionValidatorFactoryBuilder( (evm, gasLimitCalculator, feeMarket) -> @@ -376,7 +447,9 @@ public abstract class MainnetProtocolSpecs { final boolean enableRevertReason, final GenesisConfigOptions genesisConfigOptions, final EvmConfiguration evmConfiguration, - final MiningParameters miningParameters) { + final MiningParameters miningParameters, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { final long londonForkBlockNumber = genesisConfigOptions.getLondonBlockNumber().orElse(Long.MAX_VALUE); final BaseFeeMarket londonFeeMarket; @@ -390,7 +463,12 @@ public abstract class MainnetProtocolSpecs { londonFeeMarket = FeeMarket.london(londonForkBlockNumber, genesisConfigOptions.getBaseFeePerGas()); } - return berlinDefinition(chainId, enableRevertReason, evmConfiguration) + return berlinDefinition( + chainId, + enableRevertReason, + evmConfiguration, + isParallelTxProcessingEnabled, + metricsSystem) .feeMarket(londonFeeMarket) .gasCalculator(LondonGasCalculator::new) .gasLimitCalculatorBuilder( @@ -455,9 +533,17 @@ public abstract class MainnetProtocolSpecs { final boolean enableRevertReason, final GenesisConfigOptions genesisConfigOptions, final EvmConfiguration evmConfiguration, - final MiningParameters miningParameters) { + final MiningParameters miningParameters, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { return londonDefinition( - chainId, enableRevertReason, genesisConfigOptions, evmConfiguration, miningParameters) + chainId, + enableRevertReason, + genesisConfigOptions, + evmConfiguration, + miningParameters, + isParallelTxProcessingEnabled, + metricsSystem) .difficultyCalculator(MainnetDifficultyCalculators.ARROW_GLACIER) .name("ArrowGlacier"); } @@ -467,9 +553,17 @@ public abstract class MainnetProtocolSpecs { final boolean enableRevertReason, final GenesisConfigOptions genesisConfigOptions, final EvmConfiguration evmConfiguration, - final MiningParameters miningParameters) { + final MiningParameters miningParameters, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { return arrowGlacierDefinition( - chainId, enableRevertReason, genesisConfigOptions, evmConfiguration, miningParameters) + chainId, + enableRevertReason, + genesisConfigOptions, + evmConfiguration, + miningParameters, + isParallelTxProcessingEnabled, + metricsSystem) .difficultyCalculator(MainnetDifficultyCalculators.GRAY_GLACIER) .name("GrayGlacier"); } @@ -479,10 +573,18 @@ public abstract class MainnetProtocolSpecs { final boolean enableRevertReason, final GenesisConfigOptions genesisConfigOptions, final EvmConfiguration evmConfiguration, - final MiningParameters miningParameters) { + final MiningParameters miningParameters, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { return grayGlacierDefinition( - chainId, enableRevertReason, genesisConfigOptions, evmConfiguration, miningParameters) + chainId, + enableRevertReason, + genesisConfigOptions, + evmConfiguration, + miningParameters, + isParallelTxProcessingEnabled, + metricsSystem) .evmBuilder( (gasCalculator, jdCacheConfig) -> MainnetEVMs.paris(gasCalculator, chainId.orElse(BigInteger.ZERO), evmConfiguration)) @@ -499,9 +601,17 @@ public abstract class MainnetProtocolSpecs { final boolean enableRevertReason, final GenesisConfigOptions genesisConfigOptions, final EvmConfiguration evmConfiguration, - final MiningParameters miningParameters) { + final MiningParameters miningParameters, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { return parisDefinition( - chainId, enableRevertReason, genesisConfigOptions, evmConfiguration, miningParameters) + chainId, + enableRevertReason, + genesisConfigOptions, + evmConfiguration, + miningParameters, + isParallelTxProcessingEnabled, + metricsSystem) // gas calculator has new code to support EIP-3860 limit and meter initcode .gasCalculator(ShanghaiGasCalculator::new) // EVM has a new operation for EIP-3855 PUSH0 instruction @@ -550,7 +660,9 @@ public abstract class MainnetProtocolSpecs { final boolean enableRevertReason, final GenesisConfigOptions genesisConfigOptions, final EvmConfiguration evmConfiguration, - final MiningParameters miningParameters) { + final MiningParameters miningParameters, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { final long londonForkBlockNumber = genesisConfigOptions.getLondonBlockNumber().orElse(0L); final BaseFeeMarket cancunFeeMarket; if (genesisConfigOptions.isZeroBaseFee()) { @@ -565,7 +677,13 @@ public abstract class MainnetProtocolSpecs { } return shanghaiDefinition( - chainId, enableRevertReason, genesisConfigOptions, evmConfiguration, miningParameters) + chainId, + enableRevertReason, + genesisConfigOptions, + evmConfiguration, + miningParameters, + isParallelTxProcessingEnabled, + metricsSystem) .feeMarket(cancunFeeMarket) // gas calculator for EIP-4844 blob gas .gasCalculator(CancunGasCalculator::new) @@ -623,11 +741,19 @@ public abstract class MainnetProtocolSpecs { final boolean enableRevertReason, final GenesisConfigOptions genesisConfigOptions, final EvmConfiguration evmConfiguration, - final MiningParameters miningParameters) { + final MiningParameters miningParameters, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { ProtocolSpecBuilder protocolSpecBuilder = cancunDefinition( - chainId, enableRevertReason, genesisConfigOptions, evmConfiguration, miningParameters); + chainId, + enableRevertReason, + genesisConfigOptions, + evmConfiguration, + miningParameters, + isParallelTxProcessingEnabled, + metricsSystem); return addEOF(chainId, evmConfiguration, protocolSpecBuilder).name("CancunEOF"); } @@ -636,14 +762,22 @@ public abstract class MainnetProtocolSpecs { final boolean enableRevertReason, final GenesisConfigOptions genesisConfigOptions, final EvmConfiguration evmConfiguration, - final MiningParameters miningParameters) { + final MiningParameters miningParameters, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { final Address depositContractAddress = genesisConfigOptions.getDepositContractAddress().orElse(DEFAULT_DEPOSIT_CONTRACT_ADDRESS); return cancunDefinition( - chainId, enableRevertReason, genesisConfigOptions, evmConfiguration, miningParameters) - // EIP-3074 AUTH and AUTHCALL gas + chainId, + enableRevertReason, + genesisConfigOptions, + evmConfiguration, + miningParameters, + isParallelTxProcessingEnabled, + metricsSystem) + // EIP-3074 AUTH and AUTCALL gas .gasCalculator(PragueGasCalculator::new) // EIP-3074 AUTH and AUTHCALL .evmBuilder( @@ -686,11 +820,19 @@ public abstract class MainnetProtocolSpecs { final boolean enableRevertReason, final GenesisConfigOptions genesisConfigOptions, final EvmConfiguration evmConfiguration, - final MiningParameters miningParameters) { + final MiningParameters miningParameters, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { ProtocolSpecBuilder protocolSpecBuilder = pragueDefinition( - chainId, enableRevertReason, genesisConfigOptions, evmConfiguration, miningParameters); + chainId, + enableRevertReason, + genesisConfigOptions, + evmConfiguration, + miningParameters, + isParallelTxProcessingEnabled, + metricsSystem); return addEOF(chainId, evmConfiguration, protocolSpecBuilder).name("PragueEOF"); } @@ -722,9 +864,17 @@ public abstract class MainnetProtocolSpecs { final boolean enableRevertReason, final GenesisConfigOptions genesisConfigOptions, final EvmConfiguration evmConfiguration, - final MiningParameters miningParameters) { + final MiningParameters miningParameters, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { return pragueEOFDefinition( - chainId, enableRevertReason, genesisConfigOptions, evmConfiguration, miningParameters) + chainId, + enableRevertReason, + genesisConfigOptions, + evmConfiguration, + miningParameters, + isParallelTxProcessingEnabled, + metricsSystem) // Use Future EIP configured EVM .evmBuilder( (gasCalculator, jdCacheConfig) -> @@ -749,10 +899,18 @@ public abstract class MainnetProtocolSpecs { final boolean enableRevertReason, final GenesisConfigOptions genesisConfigOptions, final EvmConfiguration evmConfiguration, - final MiningParameters miningParameters) { + final MiningParameters miningParameters, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { return futureEipsDefinition( - chainId, enableRevertReason, genesisConfigOptions, evmConfiguration, miningParameters) + chainId, + enableRevertReason, + genesisConfigOptions, + evmConfiguration, + miningParameters, + isParallelTxProcessingEnabled, + metricsSystem) .evmBuilder( (gasCalculator, jdCacheConfig) -> MainnetEVMs.experimentalEips( diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java index 9ad1db7d89..5fa2b119f1 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java @@ -507,7 +507,6 @@ public class MainnetTransactionProcessor { final long gasUsedByTransaction = transaction.getGasLimit() - initialFrame.getRemainingGas(); // update the coinbase - final var coinbase = worldState.getOrCreate(miningBeneficiary); final long usedGas = transaction.getGasLimit() - refundedGas; final CoinbaseFeePriceCalculator coinbaseCalculator; if (blockHeader.getBaseFee().isPresent()) { @@ -529,6 +528,9 @@ public class MainnetTransactionProcessor { final Wei coinbaseWeiDelta = coinbaseCalculator.price(usedGas, transactionGasPrice, blockHeader.getBaseFee()); + operationTracer.traceBeforeRewardTransaction(worldUpdater, transaction, coinbaseWeiDelta); + + final var coinbase = worldState.getOrCreate(miningBeneficiary); coinbase.incrementBalance(coinbaseWeiDelta); authorizedCodeService.resetAuthorities(); 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 649442f88c..1cb3a5cb3c 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 @@ -20,6 +20,7 @@ import org.hyperledger.besu.ethereum.core.MiningParameters; import org.hyperledger.besu.ethereum.core.PrivacyParameters; import org.hyperledger.besu.ethereum.privacy.PrivateTransactionValidator; import org.hyperledger.besu.evm.internal.EvmConfiguration; +import org.hyperledger.besu.plugin.services.MetricsSystem; import java.math.BigInteger; import java.util.NavigableMap; @@ -45,6 +46,8 @@ public class ProtocolScheduleBuilder { private final EvmConfiguration evmConfiguration; private final MiningParameters miningParameters; private final BadBlockManager badBlockManager; + private final boolean isParallelTxProcessingEnabled; + private final MetricsSystem metricsSystem; public ProtocolScheduleBuilder( final GenesisConfigOptions config, @@ -54,7 +57,9 @@ public class ProtocolScheduleBuilder { final boolean isRevertReasonEnabled, final EvmConfiguration evmConfiguration, final MiningParameters miningParameters, - final BadBlockManager badBlockManager) { + final BadBlockManager badBlockManager, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { this( config, Optional.of(defaultChainId), @@ -63,7 +68,9 @@ public class ProtocolScheduleBuilder { isRevertReasonEnabled, evmConfiguration, miningParameters, - badBlockManager); + badBlockManager, + isParallelTxProcessingEnabled, + metricsSystem); } public ProtocolScheduleBuilder( @@ -73,7 +80,9 @@ public class ProtocolScheduleBuilder { final boolean isRevertReasonEnabled, final EvmConfiguration evmConfiguration, final MiningParameters miningParameters, - final BadBlockManager badBlockManager) { + final BadBlockManager badBlockManager, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { this( config, Optional.empty(), @@ -82,7 +91,9 @@ public class ProtocolScheduleBuilder { isRevertReasonEnabled, evmConfiguration, miningParameters, - badBlockManager); + badBlockManager, + isParallelTxProcessingEnabled, + metricsSystem); } private ProtocolScheduleBuilder( @@ -93,7 +104,9 @@ public class ProtocolScheduleBuilder { final boolean isRevertReasonEnabled, final EvmConfiguration evmConfiguration, final MiningParameters miningParameters, - final BadBlockManager badBlockManager) { + final BadBlockManager badBlockManager, + final boolean isParallelTxProcessingEnabled, + final MetricsSystem metricsSystem) { this.config = config; this.protocolSpecAdapters = protocolSpecAdapters; this.privacyParameters = privacyParameters; @@ -102,6 +115,8 @@ public class ProtocolScheduleBuilder { this.defaultChainId = defaultChainId; this.miningParameters = miningParameters; this.badBlockManager = badBlockManager; + this.isParallelTxProcessingEnabled = isParallelTxProcessingEnabled; + this.metricsSystem = metricsSystem; } public ProtocolSchedule createProtocolSchedule() { @@ -121,7 +136,9 @@ public class ProtocolScheduleBuilder { config.getEcip1017EraRounds(), evmConfiguration.overrides( config.getContractSizeLimit(), OptionalInt.empty(), config.getEvmStackSize()), - miningParameters); + miningParameters, + isParallelTxProcessingEnabled, + metricsSystem); validateForkOrdering(); @@ -203,7 +220,8 @@ public class ProtocolScheduleBuilder { protocolSchedule, BuilderMapEntry.MilestoneType.BLOCK_NUMBER, classicBlockNumber, - ClassicProtocolSpecs.classicRecoveryInitDefinition(evmConfiguration), + ClassicProtocolSpecs.classicRecoveryInitDefinition( + evmConfiguration, isParallelTxProcessingEnabled, metricsSystem), Function.identity()); protocolSchedule.putBlockNumberMilestone( classicBlockNumber + 1, originalProtocolSpec); 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 cd886b6c84..0d792b7870 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 @@ -51,6 +51,7 @@ public class ProtocolSpecBuilder { private Function gasLimitCalculatorBuilder; private Wei blockReward; private boolean skipZeroBlockRewards; + private BlockHeaderFunctions blockHeaderFunctions; private AbstractBlockProcessor.TransactionReceiptFactory transactionReceiptFactory; private DifficultyCalculator difficultyCalculator; @@ -66,9 +67,11 @@ public class ProtocolSpecBuilder { private BiFunction messageCallProcessorBuilder; private TransactionProcessorBuilder transactionProcessorBuilder; + private BlockProcessorBuilder blockProcessorBuilder; private BlockValidatorBuilder blockValidatorBuilder; private BlockImporterBuilder blockImporterBuilder; + private String name; private MiningBeneficiaryCalculator miningBeneficiaryCalculator; private PrivacyParameters privacyParameters; diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/parallelization/MainnetParallelBlockProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/parallelization/MainnetParallelBlockProcessor.java new file mode 100644 index 0000000000..d1f0d9c512 --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/parallelization/MainnetParallelBlockProcessor.java @@ -0,0 +1,199 @@ +/* + * Copyright contributors to Hyperledger Besu. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.mainnet.parallelization; + +import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.datatypes.Wei; +import org.hyperledger.besu.ethereum.core.BlockHeader; +import org.hyperledger.besu.ethereum.core.MutableWorldState; +import org.hyperledger.besu.ethereum.core.Transaction; +import org.hyperledger.besu.ethereum.mainnet.BlockProcessor; +import org.hyperledger.besu.ethereum.mainnet.MainnetBlockProcessor; +import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor; +import org.hyperledger.besu.ethereum.mainnet.MiningBeneficiaryCalculator; +import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; +import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecBuilder; +import org.hyperledger.besu.ethereum.privacy.storage.PrivateMetadataUpdater; +import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult; +import org.hyperledger.besu.ethereum.trie.diffbased.common.worldview.DiffBasedWorldState; +import org.hyperledger.besu.evm.operation.BlockHashOperation; +import org.hyperledger.besu.evm.worldstate.WorldUpdater; +import org.hyperledger.besu.metrics.BesuMetricCategory; +import org.hyperledger.besu.plugin.services.MetricsSystem; +import org.hyperledger.besu.plugin.services.metrics.Counter; + +import java.util.List; +import java.util.Optional; + +public class MainnetParallelBlockProcessor extends MainnetBlockProcessor { + + private final Optional metricsSystem; + private final Optional confirmedParallelizedTransactionCounter; + private final Optional conflictingButCachedTransactionCounter; + + public MainnetParallelBlockProcessor( + final MainnetTransactionProcessor transactionProcessor, + final TransactionReceiptFactory transactionReceiptFactory, + final Wei blockReward, + final MiningBeneficiaryCalculator miningBeneficiaryCalculator, + final boolean skipZeroBlockRewards, + final ProtocolSchedule protocolSchedule, + final MetricsSystem metricsSystem) { + super( + transactionProcessor, + transactionReceiptFactory, + blockReward, + miningBeneficiaryCalculator, + skipZeroBlockRewards, + protocolSchedule); + this.metricsSystem = Optional.of(metricsSystem); + this.confirmedParallelizedTransactionCounter = + Optional.of( + this.metricsSystem + .get() + .createCounter( + BesuMetricCategory.BLOCK_PROCESSING, + "parallelized_transactions_counter", + "Counter for the number of parallelized transactions during block processing")); + + this.conflictingButCachedTransactionCounter = + Optional.of( + this.metricsSystem + .get() + .createCounter( + BesuMetricCategory.BLOCK_PROCESSING, + "conflicted_transactions_counter", + "Counter for the number of conflicted transactions during block processing")); + } + + @Override + protected Optional runBlockPreProcessing( + final MutableWorldState worldState, + final PrivateMetadataUpdater privateMetadataUpdater, + final BlockHeader blockHeader, + final List transactions, + final Address miningBeneficiary, + final BlockHashOperation.BlockHashLookup blockHashLookup, + final Wei blobGasPrice) { + if ((worldState instanceof DiffBasedWorldState)) { + ParallelizedConcurrentTransactionProcessor parallelizedConcurrentTransactionProcessor = + new ParallelizedConcurrentTransactionProcessor(transactionProcessor); + // runAsyncBlock, if activated, facilitates the non-blocking parallel execution of + // transactions in the background through an optimistic strategy. + parallelizedConcurrentTransactionProcessor.runAsyncBlock( + worldState, + blockHeader, + transactions, + miningBeneficiary, + blockHashLookup, + blobGasPrice, + privateMetadataUpdater); + return Optional.of( + new ParallelizedPreProcessingContext(parallelizedConcurrentTransactionProcessor)); + } + return Optional.empty(); + } + + @Override + protected TransactionProcessingResult getTransactionProcessingResult( + final Optional preProcessingContext, + final MutableWorldState worldState, + final WorldUpdater blockUpdater, + final PrivateMetadataUpdater privateMetadataUpdater, + final BlockHeader blockHeader, + final Wei blobGasPrice, + final Address miningBeneficiary, + final Transaction transaction, + final int location, + final BlockHashOperation.BlockHashLookup blockHashLookup) { + + TransactionProcessingResult transactionProcessingResult = null; + + if (preProcessingContext.isPresent()) { + final ParallelizedPreProcessingContext parallelizedPreProcessingContext = + (ParallelizedPreProcessingContext) preProcessingContext.get(); + transactionProcessingResult = + parallelizedPreProcessingContext + .getParallelizedConcurrentTransactionProcessor() + .applyParallelizedTransactionResult( + worldState, + miningBeneficiary, + transaction, + location, + confirmedParallelizedTransactionCounter, + conflictingButCachedTransactionCounter) + .orElse(null); + } + + if (transactionProcessingResult == null) { + return super.getTransactionProcessingResult( + preProcessingContext, + worldState, + blockUpdater, + privateMetadataUpdater, + blockHeader, + blobGasPrice, + miningBeneficiary, + transaction, + location, + blockHashLookup); + } else { + return transactionProcessingResult; + } + } + + static class ParallelizedPreProcessingContext implements PreprocessingContext { + final ParallelizedConcurrentTransactionProcessor parallelizedConcurrentTransactionProcessor; + + public ParallelizedPreProcessingContext( + final ParallelizedConcurrentTransactionProcessor + parallelizedConcurrentTransactionProcessor) { + this.parallelizedConcurrentTransactionProcessor = parallelizedConcurrentTransactionProcessor; + } + + public ParallelizedConcurrentTransactionProcessor + getParallelizedConcurrentTransactionProcessor() { + return parallelizedConcurrentTransactionProcessor; + } + } + + public static class ParallelBlockProcessorBuilder + implements ProtocolSpecBuilder.BlockProcessorBuilder { + + final MetricsSystem metricsSystem; + + public ParallelBlockProcessorBuilder(final MetricsSystem metricsSystem) { + this.metricsSystem = metricsSystem; + } + + @Override + public BlockProcessor apply( + final MainnetTransactionProcessor transactionProcessor, + final TransactionReceiptFactory transactionReceiptFactory, + final Wei blockReward, + final MiningBeneficiaryCalculator miningBeneficiaryCalculator, + final boolean skipZeroBlockRewards, + final ProtocolSchedule protocolSchedule) { + return new MainnetParallelBlockProcessor( + transactionProcessor, + transactionReceiptFactory, + blockReward, + miningBeneficiaryCalculator, + skipZeroBlockRewards, + protocolSchedule, + metricsSystem); + } + } +} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/parallelization/ParallelizedConcurrentTransactionProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/parallelization/ParallelizedConcurrentTransactionProcessor.java new file mode 100644 index 0000000000..c6beaa2f40 --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/parallelization/ParallelizedConcurrentTransactionProcessor.java @@ -0,0 +1,268 @@ +/* + * Copyright contributors to Hyperledger Besu. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.mainnet.parallelization; + +import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.datatypes.Wei; +import org.hyperledger.besu.ethereum.core.BlockHeader; +import org.hyperledger.besu.ethereum.core.MutableWorldState; +import org.hyperledger.besu.ethereum.core.Transaction; +import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor; +import org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams; +import org.hyperledger.besu.ethereum.privacy.storage.PrivateMetadataUpdater; +import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult; +import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.cache.NoopBonsaiCachedMerkleTrieLoader; +import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.worldview.BonsaiWorldState; +import org.hyperledger.besu.ethereum.trie.diffbased.common.worldview.DiffBasedWorldState; +import org.hyperledger.besu.ethereum.trie.diffbased.common.worldview.accumulator.DiffBasedWorldStateUpdateAccumulator; +import org.hyperledger.besu.evm.operation.BlockHashOperation; +import org.hyperledger.besu.evm.tracing.OperationTracer; +import org.hyperledger.besu.evm.worldstate.WorldView; +import org.hyperledger.besu.plugin.services.metrics.Counter; + +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; + +import com.google.common.annotations.VisibleForTesting; + +/** + * Optimizes transaction processing by executing transactions in parallel within a given block. + * Transactions are executed optimistically in a non-blocking manner. After execution, the class + * checks for potential conflicts among transactions to ensure data integrity before applying the + * results to the world state. + */ +@SuppressWarnings({"unchecked", "rawtypes"}) +public class ParallelizedConcurrentTransactionProcessor { + + private static final int NCPU = Runtime.getRuntime().availableProcessors(); + private static final Executor executor = Executors.newFixedThreadPool(NCPU); + + private final MainnetTransactionProcessor transactionProcessor; + + private final TransactionCollisionDetector transactionCollisionDetector; + + private final Map + parallelizedTransactionContextByLocation = new ConcurrentHashMap<>(); + + /** + * Constructs a PreloadConcurrentTransactionProcessor with a specified transaction processor. This + * processor is responsible for the individual processing of transactions. + * + * @param transactionProcessor The transaction processor for processing individual transactions. + */ + public ParallelizedConcurrentTransactionProcessor( + final MainnetTransactionProcessor transactionProcessor) { + this.transactionProcessor = transactionProcessor; + this.transactionCollisionDetector = new TransactionCollisionDetector(); + } + + @VisibleForTesting + public ParallelizedConcurrentTransactionProcessor( + final MainnetTransactionProcessor transactionProcessor, + final TransactionCollisionDetector transactionCollisionDetector) { + this.transactionProcessor = transactionProcessor; + this.transactionCollisionDetector = transactionCollisionDetector; + } + + /** + * Initiates the parallel and optimistic execution of transactions within a block by creating a + * copy of the world state for each transaction. This method processes transactions in a + * non-blocking manner. Transactions are executed against their respective copies of the world + * state, ensuring that the original world state passed as a parameter remains unmodified during + * this process. + * + * @param worldState Mutable world state intended for applying transaction results. This world + * state is not modified directly; instead, copies are made for transaction execution. + * @param blockHeader Header of the current block containing the transactions. + * @param transactions List of transactions to be processed. + * @param miningBeneficiary Address of the beneficiary to receive mining rewards. + * @param blockHashLookup Function for block hash lookup. + * @param blobGasPrice Gas price for blob transactions. + * @param privateMetadataUpdater Updater for private transaction metadata. + */ + public void runAsyncBlock( + final MutableWorldState worldState, + final BlockHeader blockHeader, + final List transactions, + final Address miningBeneficiary, + final BlockHashOperation.BlockHashLookup blockHashLookup, + final Wei blobGasPrice, + final PrivateMetadataUpdater privateMetadataUpdater) { + for (int i = 0; i < transactions.size(); i++) { + final Transaction transaction = transactions.get(i); + final int transactionLocation = i; + /* + * All transactions are executed in the background by copying the world state of the block on which the transactions need to be executed, ensuring that each one has its own accumulator. + */ + CompletableFuture.runAsync( + () -> + runTransaction( + worldState, + blockHeader, + transactionLocation, + transaction, + miningBeneficiary, + blockHashLookup, + blobGasPrice, + privateMetadataUpdater), + executor); + } + } + + @VisibleForTesting + public void runTransaction( + final MutableWorldState worldState, + final BlockHeader blockHeader, + final int transactionLocation, + final Transaction transaction, + final Address miningBeneficiary, + final BlockHashOperation.BlockHashLookup blockHashLookup, + final Wei blobGasPrice, + final PrivateMetadataUpdater privateMetadataUpdater) { + try (final DiffBasedWorldState roundWorldState = + new BonsaiWorldState( + (BonsaiWorldState) worldState, new NoopBonsaiCachedMerkleTrieLoader())) { + roundWorldState.freeze(); // make the clone frozen + final ParallelizedTransactionContext.Builder contextBuilder = + new ParallelizedTransactionContext.Builder(); + final DiffBasedWorldStateUpdateAccumulator roundWorldStateUpdater = + (DiffBasedWorldStateUpdateAccumulator) roundWorldState.updater(); + final TransactionProcessingResult result = + transactionProcessor.processTransaction( + roundWorldStateUpdater, + blockHeader, + transaction, + miningBeneficiary, + new OperationTracer() { + @Override + public void traceBeforeRewardTransaction( + final WorldView worldView, + final org.hyperledger.besu.datatypes.Transaction tx, + final Wei miningReward) { + /* + * This part checks if the mining beneficiary's account was accessed before increasing its balance for rewards. + * Indeed, if the transaction has interacted with the address to read or modify it, + * it means that the value is necessary for the proper execution of the transaction and will therefore be considered in collision detection. + * If this is not the case, we can ignore this address during conflict detection. + */ + if (transactionCollisionDetector + .getAddressesTouchedByTransaction( + transaction, Optional.of(roundWorldStateUpdater)) + .contains(miningBeneficiary)) { + contextBuilder.isMiningBeneficiaryTouchedPreRewardByTransaction(true); + } + contextBuilder.miningBeneficiaryReward(miningReward); + } + }, + blockHashLookup, + true, + TransactionValidationParams.processingBlock(), + privateMetadataUpdater, + blobGasPrice); + + // commit the accumulator in order to apply all the modifications + roundWorldState.getAccumulator().commit(); + + contextBuilder + .transactionAccumulator(roundWorldState.getAccumulator()) + .transactionProcessingResult(result); + + final ParallelizedTransactionContext parallelizedTransactionContext = contextBuilder.build(); + if (!parallelizedTransactionContext.isMiningBeneficiaryTouchedPreRewardByTransaction()) { + /* + * If the address of the mining beneficiary has been touched only for adding rewards, + * we remove it from the accumulator to avoid a false positive collision. + * The balance will be increased during the sequential processing. + */ + roundWorldStateUpdater.getAccountsToUpdate().remove(miningBeneficiary); + } + parallelizedTransactionContextByLocation.put( + transactionLocation, parallelizedTransactionContext); + } + } + + /** + * Applies the results of parallelized transactions to the world state after checking for + * conflicts. + * + *

If a transaction was executed optimistically without any detected conflicts, its result is + * directly applied to the world state. If there is a conflict, this method does not apply the + * transaction's modifications directly to the world state. Instead, it caches the data read from + * the database during the transaction's execution. This cached data is then used to optimize the + * replay of the transaction by reducing the need for additional reads from the disk, thereby + * making the replay process faster. This approach ensures that the integrity of the world state + * is maintained while optimizing the performance of transaction processing. + * + * @param worldState Mutable world state intended for applying transaction results. + * @param miningBeneficiary Address of the beneficiary for mining rewards. + * @param transaction Transaction for which the result is to be applied. + * @param transactionLocation Index of the transaction within the block. + * @param confirmedParallelizedTransactionCounter Metric counter for confirmed parallelized + * transactions + * @param conflictingButCachedTransactionCounter Metric counter for conflicting but cached + * transactions + * @return Optional containing the transaction processing result if applied, or empty if the + * transaction needs to be replayed due to a conflict. + */ + public Optional applyParallelizedTransactionResult( + final MutableWorldState worldState, + final Address miningBeneficiary, + final Transaction transaction, + final int transactionLocation, + final Optional confirmedParallelizedTransactionCounter, + final Optional conflictingButCachedTransactionCounter) { + final DiffBasedWorldState diffBasedWorldState = (DiffBasedWorldState) worldState; + final DiffBasedWorldStateUpdateAccumulator blockAccumulator = + (DiffBasedWorldStateUpdateAccumulator) diffBasedWorldState.updater(); + final ParallelizedTransactionContext parallelizedTransactionContext = + parallelizedTransactionContextByLocation.remove(transactionLocation); + /* + * If `parallelizedTransactionContext` is not null, it means that the transaction had time to complete in the background. + */ + if (parallelizedTransactionContext != null) { + final DiffBasedWorldStateUpdateAccumulator transactionAccumulator = + parallelizedTransactionContext.transactionAccumulator(); + final TransactionProcessingResult transactionProcessingResult = + parallelizedTransactionContext.transactionProcessingResult(); + final boolean hasCollision = + transactionCollisionDetector.hasCollision( + transaction, miningBeneficiary, parallelizedTransactionContext, blockAccumulator); + if (transactionProcessingResult.isSuccessful() && !hasCollision) { + blockAccumulator + .getOrCreate(miningBeneficiary) + .incrementBalance(parallelizedTransactionContext.miningBeneficiaryReward()); + + blockAccumulator.importStateChangesFromSource(transactionAccumulator); + + if (confirmedParallelizedTransactionCounter.isPresent()) + confirmedParallelizedTransactionCounter.get().inc(); + return Optional.of(transactionProcessingResult); + } else { + blockAccumulator.importPriorStateFromSource(transactionAccumulator); + if (conflictingButCachedTransactionCounter.isPresent()) + conflictingButCachedTransactionCounter.get().inc(); + // If there is a conflict, we return an empty result to signal the block processor to + // re-execute the transaction. + return Optional.empty(); + } + } + return Optional.empty(); + } +} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/parallelization/ParallelizedTransactionContext.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/parallelization/ParallelizedTransactionContext.java new file mode 100644 index 0000000000..30305ce00b --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/parallelization/ParallelizedTransactionContext.java @@ -0,0 +1,133 @@ +/* + * Copyright contributors to Hyperledger Besu. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.mainnet.parallelization; + +import org.hyperledger.besu.datatypes.Wei; +import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult; +import org.hyperledger.besu.ethereum.trie.diffbased.common.worldview.accumulator.DiffBasedWorldStateUpdateAccumulator; + +import java.util.Objects; + +public final class ParallelizedTransactionContext { + private final DiffBasedWorldStateUpdateAccumulator transactionAccumulator; + private final TransactionProcessingResult transactionProcessingResult; + private final boolean isMiningBeneficiaryTouchedPreRewardByTransaction; + private final Wei miningBeneficiaryReward; + + public ParallelizedTransactionContext( + final DiffBasedWorldStateUpdateAccumulator transactionAccumulator, + final TransactionProcessingResult transactionProcessingResult, + final boolean isMiningBeneficiaryTouchedPreRewardByTransaction, + final Wei miningBeneficiaryReward) { + this.transactionAccumulator = transactionAccumulator; + this.transactionProcessingResult = transactionProcessingResult; + this.isMiningBeneficiaryTouchedPreRewardByTransaction = + isMiningBeneficiaryTouchedPreRewardByTransaction; + this.miningBeneficiaryReward = miningBeneficiaryReward; + } + + public DiffBasedWorldStateUpdateAccumulator transactionAccumulator() { + return transactionAccumulator; + } + + public TransactionProcessingResult transactionProcessingResult() { + return transactionProcessingResult; + } + + public boolean isMiningBeneficiaryTouchedPreRewardByTransaction() { + return isMiningBeneficiaryTouchedPreRewardByTransaction; + } + + public Wei miningBeneficiaryReward() { + return miningBeneficiaryReward; + } + + @Override + public boolean equals(final Object obj) { + if (obj == this) return true; + if (obj == null || obj.getClass() != this.getClass()) return false; + var that = (ParallelizedTransactionContext) obj; + return Objects.equals(this.transactionAccumulator, that.transactionAccumulator) + && Objects.equals(this.transactionProcessingResult, that.transactionProcessingResult) + && this.isMiningBeneficiaryTouchedPreRewardByTransaction + == that.isMiningBeneficiaryTouchedPreRewardByTransaction + && Objects.equals(this.miningBeneficiaryReward, that.miningBeneficiaryReward); + } + + @Override + public int hashCode() { + return Objects.hash( + transactionAccumulator, + transactionProcessingResult, + isMiningBeneficiaryTouchedPreRewardByTransaction, + miningBeneficiaryReward); + } + + @Override + public String toString() { + return "ParallelizedTransactionContext[" + + "transactionAccumulator=" + + transactionAccumulator + + ", " + + "transactionProcessingResult=" + + transactionProcessingResult + + ", " + + "isMiningBeneficiaryTouchedPreRewardByTransaction=" + + isMiningBeneficiaryTouchedPreRewardByTransaction + + ", " + + "miningBeneficiaryReward=" + + miningBeneficiaryReward + + ']'; + } + + public static class Builder { + private DiffBasedWorldStateUpdateAccumulator transactionAccumulator; + private TransactionProcessingResult transactionProcessingResult; + private boolean isMiningBeneficiaryTouchedPreRewardByTransaction; + private Wei miningBeneficiaryReward = Wei.ZERO; + + public Builder transactionAccumulator( + final DiffBasedWorldStateUpdateAccumulator transactionAccumulator) { + this.transactionAccumulator = transactionAccumulator; + return this; + } + + public Builder transactionProcessingResult( + final TransactionProcessingResult transactionProcessingResult) { + this.transactionProcessingResult = transactionProcessingResult; + return this; + } + + public Builder isMiningBeneficiaryTouchedPreRewardByTransaction( + final boolean isMiningBeneficiaryTouchedPreRewardByTransaction) { + this.isMiningBeneficiaryTouchedPreRewardByTransaction = + isMiningBeneficiaryTouchedPreRewardByTransaction; + return this; + } + + public Builder miningBeneficiaryReward(final Wei miningBeneficiaryReward) { + this.miningBeneficiaryReward = miningBeneficiaryReward; + return this; + } + + public ParallelizedTransactionContext build() { + return new ParallelizedTransactionContext( + transactionAccumulator, + transactionProcessingResult, + isMiningBeneficiaryTouchedPreRewardByTransaction, + miningBeneficiaryReward); + } + } +} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/parallelization/TransactionCollisionDetector.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/parallelization/TransactionCollisionDetector.java new file mode 100644 index 0000000000..4120c0edb1 --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/parallelization/TransactionCollisionDetector.java @@ -0,0 +1,114 @@ +/* + * Copyright contributors to Hyperledger Besu. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.mainnet.parallelization; + +import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.ethereum.core.Transaction; +import org.hyperledger.besu.ethereum.trie.diffbased.common.worldview.accumulator.DiffBasedWorldStateUpdateAccumulator; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Optional; +import java.util.Set; + +public class TransactionCollisionDetector { + + /** + * Determines if a transaction has a collision based on the addresses it touches. A collision + * occurs if the transaction touches the mining beneficiary address or if there are common + * addresses touched by both the transaction and other transactions within the same block. + * + * @param transaction The transaction to check for collisions. + * @param miningBeneficiary The address of the mining beneficiary. + * @param parallelizedTransactionContext The context containing the accumulator for the + * transaction. + * @param blockAccumulator The accumulator for the block. + * @return true if there is a collision; false otherwise. + */ + public boolean hasCollision( + final Transaction transaction, + final Address miningBeneficiary, + final ParallelizedTransactionContext parallelizedTransactionContext, + final DiffBasedWorldStateUpdateAccumulator blockAccumulator) { + final Set

addressesTouchedByTransaction = + getAddressesTouchedByTransaction( + transaction, Optional.of(parallelizedTransactionContext.transactionAccumulator())); + if (addressesTouchedByTransaction.contains(miningBeneficiary)) { + return true; + } + final Set
addressesTouchedByBlock = + getAddressesTouchedByBlock(Optional.of(blockAccumulator)); + final Iterator
it = addressesTouchedByTransaction.iterator(); + boolean commonAddressFound = false; + while (it.hasNext() && !commonAddressFound) { + if (addressesTouchedByBlock.contains(it.next())) { + commonAddressFound = true; + } + } + return commonAddressFound; + } + + /** + * Retrieves the set of addresses that were touched by a transaction. This includes the sender and + * recipient of the transaction, as well as any addresses that were read from or written to by the + * transaction's execution. + * + * @param transaction The transaction to analyze. + * @param accumulator An optional accumulator containing state changes made by the transaction. + * @return A set of addresses touched by the transaction. + */ + public Set
getAddressesTouchedByTransaction( + final Transaction transaction, + final Optional> accumulator) { + HashSet
addresses = new HashSet<>(); + addresses.add(transaction.getSender()); + if (transaction.getTo().isPresent()) { + addresses.add(transaction.getTo().get()); + } + accumulator.ifPresent( + diffBasedWorldStateUpdateAccumulator -> { + diffBasedWorldStateUpdateAccumulator + .getAccountsToUpdate() + .forEach((address, diffBasedValue) -> addresses.add(address)); + addresses.addAll(diffBasedWorldStateUpdateAccumulator.getDeletedAccountAddresses()); + }); + return addresses; + } + + /** + * Retrieves the set of addresses that were touched by all transactions within a block. This + * method filters out addresses that were only read and not modified. + * + * @param accumulator An optional accumulator containing state changes made by the block. + * @return A set of addresses that were modified by the block's transactions. + */ + private Set
getAddressesTouchedByBlock( + final Optional> accumulator) { + HashSet
addresses = new HashSet<>(); + accumulator.ifPresent( + diffBasedWorldStateUpdateAccumulator -> { + diffBasedWorldStateUpdateAccumulator + .getAccountsToUpdate() + .forEach( + (address, diffBasedValue) -> { + if (!diffBasedValue.isUnchanged()) { + addresses.add(address); + } + }); + addresses.addAll(diffBasedWorldStateUpdateAccumulator.getDeletedAccountAddresses()); + }); + return addresses; + } +} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/cache/NoopBonsaiCachedMerkleTrieLoader.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/cache/NoopBonsaiCachedMerkleTrieLoader.java new file mode 100644 index 0000000000..8f58e697fe --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/cache/NoopBonsaiCachedMerkleTrieLoader.java @@ -0,0 +1,44 @@ +/* + * Copyright contributors to Hyperledger Besu. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.trie.diffbased.bonsai.cache; + +import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.datatypes.Hash; +import org.hyperledger.besu.datatypes.StorageSlotKey; +import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.BonsaiWorldStateKeyValueStorage; +import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; + +public class NoopBonsaiCachedMerkleTrieLoader extends BonsaiCachedMerkleTrieLoader { + + public NoopBonsaiCachedMerkleTrieLoader() { + super(new NoOpMetricsSystem()); + } + + @Override + public void preLoadAccount( + final BonsaiWorldStateKeyValueStorage worldStateKeyValueStorage, + final Hash worldStateRootHash, + final Address account) { + // noop + } + + @Override + public void preLoadStorageSlot( + final BonsaiWorldStateKeyValueStorage worldStateKeyValueStorage, + final Address account, + final StorageSlotKey slotKey) { + // noop + } +} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/worldview/BonsaiWorldState.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/worldview/BonsaiWorldState.java index ad838aa528..b62805c1fd 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/worldview/BonsaiWorldState.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/worldview/BonsaiWorldState.java @@ -76,6 +76,18 @@ public class BonsaiWorldState extends DiffBasedWorldState { diffBasedWorldStateConfig); } + public BonsaiWorldState( + final BonsaiWorldState worldState, + final BonsaiCachedMerkleTrieLoader cachedMerkleTrieLoader) { + this( + new BonsaiWorldStateLayerStorage(worldState.getWorldStateStorage()), + cachedMerkleTrieLoader, + worldState.cachedWorldStorageManager, + worldState.trieLogManager, + worldState.accumulator.getEvmConfiguration(), + new DiffBasedWorldStateConfig(worldState.worldStateConfig)); + } + public BonsaiWorldState( final BonsaiWorldStateKeyValueStorage worldStateKeyValueStorage, final BonsaiCachedMerkleTrieLoader bonsaiCachedMerkleTrieLoader, diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/worldview/accumulator/DiffBasedWorldStateUpdateAccumulator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/worldview/accumulator/DiffBasedWorldStateUpdateAccumulator.java index b5bae0aed9..0799ed3db2 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/worldview/accumulator/DiffBasedWorldStateUpdateAccumulator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/worldview/accumulator/DiffBasedWorldStateUpdateAccumulator.java @@ -90,7 +90,7 @@ public abstract class DiffBasedWorldStateUpdateAccumulator source) { + public void cloneFromUpdater(final DiffBasedWorldStateUpdateAccumulator source) { accountsToUpdate.putAll(source.getAccountsToUpdate()); codeToUpdate.putAll(source.codeToUpdate); storageToClear.addAll(source.storageToClear); @@ -100,6 +100,120 @@ public abstract class DiffBasedWorldStateUpdateAccumulator source) { + source + .getAccountsToUpdate() + .forEach( + (address, diffBasedValue) -> { + ACCOUNT copyPrior = + diffBasedValue.getPrior() != null + ? copyAccount(diffBasedValue.getPrior(), this, false) + : null; + ACCOUNT copyUpdated = + diffBasedValue.getUpdated() != null + ? copyAccount(diffBasedValue.getUpdated(), this, true) + : null; + accountsToUpdate.put(address, new DiffBasedValue<>(copyPrior, copyUpdated)); + }); + source + .getCodeToUpdate() + .forEach( + (address, diffBasedValue) -> { + codeToUpdate.put( + address, + new DiffBasedValue<>(diffBasedValue.getPrior(), diffBasedValue.getUpdated())); + }); + source + .getStorageToUpdate() + .forEach( + (address, slots) -> { + StorageConsumingMap> storageConsumingMap = + storageToUpdate.computeIfAbsent( + address, + k -> + new StorageConsumingMap<>( + address, new ConcurrentHashMap<>(), storagePreloader)); + slots.forEach( + (storageSlotKey, uInt256DiffBasedValue) -> { + storageConsumingMap.put( + storageSlotKey, + new DiffBasedValue<>( + uInt256DiffBasedValue.getPrior(), uInt256DiffBasedValue.getUpdated())); + }); + }); + storageToClear.addAll(source.storageToClear); + + this.isAccumulatorStateChanged = true; + } + + /** + * Imports unchanged state data from an external source into the current state. This method + * focuses on integrating state data from the specified source that has been read but not + * modified. + * + *

The method ensures that only new, unmodified data from the source is added to the current + * state. If a state data has already been read or modified in the current state, it will not be + * added again to avoid overwriting any existing modifications. + * + * @param source The source accumulator + */ + public void importPriorStateFromSource( + final DiffBasedWorldStateUpdateAccumulator source) { + + source + .getAccountsToUpdate() + .forEach( + (address, diffBasedValue) -> { + ACCOUNT copyPrior = + diffBasedValue.getPrior() != null + ? copyAccount(diffBasedValue.getPrior(), this, false) + : null; + ACCOUNT copyUpdated = + diffBasedValue.getPrior() != null + ? copyAccount(diffBasedValue.getPrior(), this, true) + : null; + accountsToUpdate.putIfAbsent(address, new DiffBasedValue<>(copyPrior, copyUpdated)); + }); + source + .getCodeToUpdate() + .forEach( + (address, diffBasedValue) -> { + codeToUpdate.putIfAbsent( + address, + new DiffBasedValue<>(diffBasedValue.getPrior(), diffBasedValue.getPrior())); + }); + source + .getStorageToUpdate() + .forEach( + (address, slots) -> { + StorageConsumingMap> storageConsumingMap = + storageToUpdate.computeIfAbsent( + address, + k -> + new StorageConsumingMap<>( + address, new ConcurrentHashMap<>(), storagePreloader)); + slots.forEach( + (storageSlotKey, uInt256DiffBasedValue) -> { + storageConsumingMap.putIfAbsent( + storageSlotKey, + new DiffBasedValue<>( + uInt256DiffBasedValue.getPrior(), uInt256DiffBasedValue.getPrior())); + }); + }); + this.isAccumulatorStateChanged = true; + } + protected Consumer> getAccountPreloader() { return accountPreloader; } @@ -108,7 +222,7 @@ public abstract class DiffBasedWorldStateUpdateAccumulator accountValue = accountsToUpdate.computeIfAbsent( @@ -305,7 +420,6 @@ public abstract class DiffBasedWorldStateUpdateAccumulator updatedAccountValue = accountsToUpdate.get(updatedAddress); - final Map> pendingStorageUpdates = storageToUpdate.computeIfAbsent( updatedAddress, @@ -359,12 +473,6 @@ public abstract class DiffBasedWorldStateUpdateAccumulator Hash.EMPTY, + blobGasPrice, + privateMetadataUpdater); + + verify(transactionProcessor, times(1)) + .processTransaction( + any(DiffBasedWorldStateUpdateAccumulator.class), + eq(blockHeader), + eq(transaction), + eq(miningBeneficiary), + any(OperationTracer.class), + any(BlockHashOperation.BlockHashLookup.class), + eq(true), + eq(TransactionValidationParams.processingBlock()), + eq(privateMetadataUpdater), + eq(blobGasPrice)); + + assertTrue( + processor + .applyParallelizedTransactionResult( + worldState, miningBeneficiary, transaction, 0, Optional.empty(), Optional.empty()) + .isPresent(), + "Expected the transaction context to be stored"); + } + + @Test + void testRunTransactionWithFailure() { + Address miningBeneficiary = Address.fromHexString("0x1"); + Wei blobGasPrice = Wei.ZERO; + + when(transactionProcessor.processTransaction( + any(), any(), any(), any(), any(), any(), anyBoolean(), any(), any(), any())) + .thenReturn( + TransactionProcessingResult.failed( + 0, + 0, + ValidationResult.invalid( + TransactionInvalidReason.BLOB_GAS_PRICE_BELOW_CURRENT_BLOB_BASE_FEE), + Optional.of(Bytes.EMPTY))); + + processor.runTransaction( + worldState, + blockHeader, + 0, + transaction, + miningBeneficiary, + (blockNumber) -> Hash.EMPTY, + blobGasPrice, + privateMetadataUpdater); + + Optional result = + processor.applyParallelizedTransactionResult( + worldState, miningBeneficiary, transaction, 0, Optional.empty(), Optional.empty()); + assertTrue(result.isEmpty(), "Expected the transaction result to indicate a failure"); + } + + @Test + void testRunTransactionWithConflict() { + + Address miningBeneficiary = Address.fromHexString("0x1"); + Wei blobGasPrice = Wei.ZERO; + + Mockito.when( + transactionProcessor.processTransaction( + any(), any(), any(), any(), any(), any(), anyBoolean(), any(), any(), any())) + .thenReturn( + TransactionProcessingResult.successful( + Collections.emptyList(), 0, 0, Bytes.EMPTY, ValidationResult.valid())); + + processor.runTransaction( + worldState, + blockHeader, + 0, + transaction, + miningBeneficiary, + (blockNumber) -> Hash.EMPTY, + blobGasPrice, + privateMetadataUpdater); + + verify(transactionProcessor, times(1)) + .processTransaction( + any(DiffBasedWorldStateUpdateAccumulator.class), + eq(blockHeader), + eq(transaction), + eq(miningBeneficiary), + any(OperationTracer.class), + any(BlockHashOperation.BlockHashLookup.class), + eq(true), + eq(TransactionValidationParams.processingBlock()), + eq(privateMetadataUpdater), + eq(blobGasPrice)); + + // simulate a conflict + when(transactionCollisionDetector.hasCollision(any(), any(), any(), any())).thenReturn(true); + + Optional result = + processor.applyParallelizedTransactionResult( + worldState, miningBeneficiary, transaction, 0, Optional.empty(), Optional.empty()); + assertTrue(result.isEmpty(), "Expected no transaction result to be applied due to conflict"); + } +} diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/parallelization/TransactionCollisionDetectorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/parallelization/TransactionCollisionDetectorTest.java new file mode 100644 index 0000000000..0cd1bad3c5 --- /dev/null +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/parallelization/TransactionCollisionDetectorTest.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.mainnet.parallelization; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.datatypes.Hash; +import org.hyperledger.besu.datatypes.Wei; +import org.hyperledger.besu.ethereum.core.Transaction; +import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.BonsaiAccount; +import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.worldview.BonsaiWorldState; +import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.worldview.BonsaiWorldStateUpdateAccumulator; +import org.hyperledger.besu.ethereum.trie.diffbased.common.DiffBasedValue; +import org.hyperledger.besu.evm.internal.EvmConfiguration; + +import java.math.BigInteger; + +import org.apache.tuweni.bytes.Bytes; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class TransactionCollisionDetectorTest { + + private TransactionCollisionDetector collisionDetector; + @Mock BonsaiWorldState worldState; + BonsaiWorldStateUpdateAccumulator bonsaiUpdater; + BonsaiWorldStateUpdateAccumulator trxUpdater; + + @BeforeEach + public void setUp() { + collisionDetector = new TransactionCollisionDetector(); + bonsaiUpdater = + new BonsaiWorldStateUpdateAccumulator( + worldState, (__, ___) -> {}, (__, ___) -> {}, EvmConfiguration.DEFAULT); + trxUpdater = + new BonsaiWorldStateUpdateAccumulator( + worldState, (__, ___) -> {}, (__, ___) -> {}, EvmConfiguration.DEFAULT); + } + + private Transaction createTransaction(final Address sender, final Address to) { + return new Transaction.Builder() + .nonce(1) + .gasPrice(Wei.of(1)) + .gasLimit(21000) + .to(to) + .value(Wei.ZERO) + .payload(Bytes.EMPTY) + .chainId(BigInteger.ONE) + .sender(sender) + .build(); + } + + private BonsaiAccount createAccount(final Address address) { + return new BonsaiAccount( + worldState, + address, + Hash.hash(Address.ZERO), + 0, + Wei.ONE, + Hash.EMPTY_TRIE_HASH, + Hash.EMPTY, + false); + } + + @Test + void testCollisionWithModifiedBalance() { + final Address address = Address.fromHexString("0x1"); + final BonsaiAccount priorAccountValue = createAccount(address); + final BonsaiAccount nextAccountValue = new BonsaiAccount(priorAccountValue, worldState, true); + nextAccountValue.setBalance(Wei.MAX_WEI); + + // Simulate that the address was already modified in the block + bonsaiUpdater + .getAccountsToUpdate() + .put(address, new DiffBasedValue<>(priorAccountValue, nextAccountValue)); + + final Transaction transaction = createTransaction(address, address); + + // Simulate that the address is read in the next transaction + trxUpdater + .getAccountsToUpdate() + .put(address, new DiffBasedValue<>(priorAccountValue, priorAccountValue)); + + boolean hasCollision = + collisionDetector.hasCollision( + transaction, + Address.ZERO, + new ParallelizedTransactionContext(trxUpdater, null, false, Wei.ZERO), + bonsaiUpdater); + + assertTrue(hasCollision, "Expected a collision with the modified address"); + } + + @Test + void testCollisionWithModifiedNonce() { + final Address address = Address.fromHexString("0x1"); + final BonsaiAccount priorAccountValue = createAccount(address); + final BonsaiAccount nextAccountValue = new BonsaiAccount(priorAccountValue, worldState, true); + nextAccountValue.setNonce(1); + + // Simulate that the address was already modified in the block + bonsaiUpdater + .getAccountsToUpdate() + .put(address, new DiffBasedValue<>(priorAccountValue, nextAccountValue)); + + final Transaction transaction = createTransaction(address, address); + + // Simulate that the address is read in the next transaction + trxUpdater + .getAccountsToUpdate() + .put(address, new DiffBasedValue<>(priorAccountValue, priorAccountValue)); + + boolean hasCollision = + collisionDetector.hasCollision( + transaction, + Address.ZERO, + new ParallelizedTransactionContext(trxUpdater, null, false, Wei.ZERO), + bonsaiUpdater); + + assertTrue(hasCollision, "Expected a collision with the modified address"); + } + + @Test + void testCollisionWithModifiedCode() { + final Address address = Address.fromHexString("0x1"); + final BonsaiAccount priorAccountValue = createAccount(address); + final BonsaiAccount nextAccountValue = new BonsaiAccount(priorAccountValue, worldState, true); + nextAccountValue.setCode(Bytes.repeat((byte) 0x01, 10)); + + // Simulate that the address was already modified in the block + bonsaiUpdater + .getAccountsToUpdate() + .put(address, new DiffBasedValue<>(priorAccountValue, nextAccountValue)); + + final Transaction transaction = createTransaction(address, address); + + // Simulate that the address is read in the next transaction + trxUpdater + .getAccountsToUpdate() + .put(address, new DiffBasedValue<>(priorAccountValue, priorAccountValue)); + + boolean hasCollision = + collisionDetector.hasCollision( + transaction, + Address.ZERO, + new ParallelizedTransactionContext(trxUpdater, null, false, Wei.ZERO), + bonsaiUpdater); + + assertTrue(hasCollision, "Expected a collision with the modified address"); + } + + @Test + void testCollisionWithModifiedStorageRoot() { + final Address address = Address.fromHexString("0x1"); + final BonsaiAccount priorAccountValue = createAccount(address); + final BonsaiAccount nextAccountValue = new BonsaiAccount(priorAccountValue, worldState, true); + nextAccountValue.setStorageRoot(Hash.EMPTY); + + // Simulate that the address was already modified in the block + bonsaiUpdater + .getAccountsToUpdate() + .put(address, new DiffBasedValue<>(priorAccountValue, nextAccountValue)); + + final Transaction transaction = createTransaction(address, address); + + // Simulate that the address is read in the next transaction + trxUpdater + .getAccountsToUpdate() + .put(address, new DiffBasedValue<>(priorAccountValue, priorAccountValue)); + + boolean hasCollision = + collisionDetector.hasCollision( + transaction, + Address.ZERO, + new ParallelizedTransactionContext(trxUpdater, null, false, Wei.ZERO), + bonsaiUpdater); + + assertTrue(hasCollision, "Expected a collision with the modified address"); + } + + @Test + void testCollisionWithMiningBeneficiaryAddress() { + final Address miningBeneficiary = Address.ZERO; + final Address address = Address.fromHexString("0x1"); + + final Transaction transaction = createTransaction(miningBeneficiary, address); + + boolean hasCollision = + collisionDetector.hasCollision( + transaction, + miningBeneficiary, + new ParallelizedTransactionContext(trxUpdater, null, false, Wei.ZERO), + bonsaiUpdater); + + assertTrue(hasCollision, "Expected collision with the mining beneficiary address as sender"); + } + + @Test + void testCollisionWithAnotherMiningBeneficiaryAddress() { + final Address miningBeneficiary = Address.ZERO; + final Address address = Address.fromHexString("0x1"); + final BonsaiAccount miningBeneficiaryValue = createAccount(address); + + final Transaction transaction = createTransaction(address, address); + + // Simulate that the mining beneficiary is read in the next transaction + trxUpdater + .getAccountsToUpdate() + .put( + miningBeneficiary, + new DiffBasedValue<>(miningBeneficiaryValue, miningBeneficiaryValue)); + + boolean hasCollision = + collisionDetector.hasCollision( + transaction, + miningBeneficiary, + new ParallelizedTransactionContext(trxUpdater, null, true, Wei.ZERO), + bonsaiUpdater); + + assertTrue(hasCollision, "Expected collision with the read mining beneficiary address"); + } + + @Test + void testCollisionWithDeletedAddress() { + final Address address = Address.fromHexString("0x1"); + final BonsaiAccount accountValue = createAccount(address); + + // Simulate that the address was deleted in the block + bonsaiUpdater.getDeletedAccountAddresses().add(address); + + final Transaction transaction = createTransaction(address, address); + + // Simulate that the deleted address is read in the next transaction + trxUpdater.getAccountsToUpdate().put(address, new DiffBasedValue<>(accountValue, accountValue)); + + boolean hasCollision = + collisionDetector.hasCollision( + transaction, + Address.ZERO, + new ParallelizedTransactionContext(trxUpdater, null, false, Wei.ZERO), + bonsaiUpdater); + + assertTrue(hasCollision, "Expected a collision with the deleted address"); + } + + @Test + void testCollisionWithNoModifiedAddress() { + final Address address = Address.fromHexString("0x1"); + final BonsaiAccount priorAccountValue = createAccount(address); + + // Simulate that the address was already read in the block + bonsaiUpdater + .getAccountsToUpdate() + .put(address, new DiffBasedValue<>(priorAccountValue, priorAccountValue)); + + final Transaction transaction = createTransaction(address, address); + + // Simulate that the address is read in the next transaction + trxUpdater + .getAccountsToUpdate() + .put(address, new DiffBasedValue<>(priorAccountValue, priorAccountValue)); + + boolean hasCollision = + collisionDetector.hasCollision( + transaction, + Address.ZERO, + new ParallelizedTransactionContext(trxUpdater, null, false, Wei.ZERO), + bonsaiUpdater); + + assertFalse(hasCollision, "Expected no collision with the read address"); + } +} diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/AbstractIsolationTests.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/AbstractIsolationTests.java index 845b859ef7..388a112699 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/AbstractIsolationTests.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/AbstractIsolationTests.java @@ -105,7 +105,9 @@ public abstract class AbstractIsolationTests { MainnetProtocolSchedule.fromConfig( GenesisConfigFile.fromResource("/dev.json").getConfigOptions(), MiningParameters.MINING_DISABLED, - new BadBlockManager()); + new BadBlockManager(), + false, + new NoOpMetricsSystem()); protected final GenesisState genesisState = GenesisState.fromConfig(GenesisConfigFile.fromResource("/dev.json"), protocolSchedule); protected final MutableBlockchain blockchain = createInMemoryBlockchain(genesisState.getBlock()); diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/messages/BlockBodiesMessageTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/messages/BlockBodiesMessageTest.java index ac3b8f2fc6..b11afeb4c5 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/messages/BlockBodiesMessageTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/messages/BlockBodiesMessageTest.java @@ -34,6 +34,7 @@ import org.hyperledger.besu.ethereum.rlp.RLP; import org.hyperledger.besu.ethereum.rlp.RLPException; import org.hyperledger.besu.ethereum.rlp.RLPInput; import org.hyperledger.besu.evm.internal.EvmConfiguration; +import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import java.io.IOException; import java.nio.ByteBuffer; @@ -60,7 +61,9 @@ public final class BlockBodiesMessageTest { false, EvmConfiguration.DEFAULT, MiningParameters.MINING_DISABLED, - new BadBlockManager()); + new BadBlockManager(), + false, + new NoOpMetricsSystem()); } @Test diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/messages/BlockHeadersMessageTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/messages/BlockHeadersMessageTest.java index 2b9105ed46..72f089a53e 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/messages/BlockHeadersMessageTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/messages/BlockHeadersMessageTest.java @@ -26,6 +26,7 @@ import org.hyperledger.besu.ethereum.rlp.BytesValueRLPInput; import org.hyperledger.besu.ethereum.rlp.RLP; import org.hyperledger.besu.ethereum.rlp.RLPInput; import org.hyperledger.besu.evm.internal.EvmConfiguration; +import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import java.io.IOException; import java.nio.ByteBuffer; @@ -67,7 +68,9 @@ public final class BlockHeadersMessageTest { false, EvmConfiguration.DEFAULT, MiningParameters.MINING_DISABLED, - new BadBlockManager())); + new BadBlockManager(), + false, + new NoOpMetricsSystem())); for (int i = 0; i < 50; ++i) { Assertions.assertThat(readHeaders.get(i)).isEqualTo(headers.get(i)); diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/ChainHeadTrackerTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/ChainHeadTrackerTest.java index 4bad73ebb6..5f7baaff41 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/ChainHeadTrackerTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/ChainHeadTrackerTest.java @@ -59,7 +59,9 @@ public class ChainHeadTrackerTest { false, EvmConfiguration.DEFAULT, MiningParameters.MINING_DISABLED, - new BadBlockManager()); + new BadBlockManager(), + false, + new NoOpMetricsSystem()); private final TrailingPeerLimiter trailingPeerLimiter = mock(TrailingPeerLimiter.class); diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/backwardsync/BackwardSyncContextTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/backwardsync/BackwardSyncContextTest.java index 9afba66ad3..cfc9f9dc12 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/backwardsync/BackwardSyncContextTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/backwardsync/BackwardSyncContextTest.java @@ -48,6 +48,7 @@ import org.hyperledger.besu.ethereum.mainnet.MainnetProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; import org.hyperledger.besu.ethereum.referencetests.ForestReferenceTestWorldState; +import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import org.hyperledger.besu.plugin.services.MetricsSystem; import org.hyperledger.besu.services.kvstore.InMemoryKeyValueStorage; @@ -93,7 +94,11 @@ public class BackwardSyncContextTest { @Spy private ProtocolSchedule protocolSchedule = MainnetProtocolSchedule.fromConfig( - new StubGenesisConfigOptions(), MiningParameters.MINING_DISABLED, new BadBlockManager()); + new StubGenesisConfigOptions(), + MiningParameters.MINING_DISABLED, + new BadBlockManager(), + false, + new NoOpMetricsSystem()); @Spy private ProtocolSpec protocolSpec = diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/backwardsync/BackwardSyncStepTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/backwardsync/BackwardSyncStepTest.java index ecb72881ed..6dc69ea274 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/backwardsync/BackwardSyncStepTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/backwardsync/BackwardSyncStepTest.java @@ -39,6 +39,7 @@ import org.hyperledger.besu.ethereum.eth.manager.exceptions.MaxRetriesReachedExc import org.hyperledger.besu.ethereum.mainnet.MainnetBlockHeaderFunctions; import org.hyperledger.besu.ethereum.mainnet.MainnetProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; +import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import org.hyperledger.besu.services.kvstore.InMemoryKeyValueStorage; import org.hyperledger.besu.testutil.DeterministicEthScheduler; @@ -70,7 +71,11 @@ public class BackwardSyncStepTest { private final ProtocolSchedule protocolSchedule = MainnetProtocolSchedule.fromConfig( - new StubGenesisConfigOptions(), MiningParameters.MINING_DISABLED, new BadBlockManager()); + new StubGenesisConfigOptions(), + MiningParameters.MINING_DISABLED, + new BadBlockManager(), + false, + new NoOpMetricsSystem()); private final DeterministicEthScheduler ethScheduler = new DeterministicEthScheduler(); diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/backwardsync/ForwardSyncStepTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/backwardsync/ForwardSyncStepTest.java index 5fb47a557a..a5d2cf6104 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/backwardsync/ForwardSyncStepTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/backwardsync/ForwardSyncStepTest.java @@ -38,6 +38,7 @@ import org.hyperledger.besu.ethereum.mainnet.MainnetBlockHeaderFunctions; import org.hyperledger.besu.ethereum.mainnet.MainnetProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.referencetests.ForestReferenceTestWorldState; +import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import org.hyperledger.besu.services.kvstore.InMemoryKeyValueStorage; import java.nio.charset.StandardCharsets; @@ -73,7 +74,11 @@ public class ForwardSyncStepTest { private final ProtocolSchedule protocolSchedule = MainnetProtocolSchedule.fromConfig( - new StubGenesisConfigOptions(), MiningParameters.MINING_DISABLED, new BadBlockManager()); + new StubGenesisConfigOptions(), + MiningParameters.MINING_DISABLED, + new BadBlockManager(), + false, + new NoOpMetricsSystem()); private MutableBlockchain localBlockchain; GenericKeyValueStorageFacade headersStorage; GenericKeyValueStorageFacade blocksStorage; 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 23eb9d02bf..cd780c2dc9 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 @@ -201,7 +201,9 @@ public abstract class AbstractTransactionPoolTest { false, EvmConfiguration.DEFAULT, MiningParameters.MINING_DISABLED, - new BadBlockManager()) + new BadBlockManager(), + false, + new NoOpMetricsSystem()) .createProtocolSchedule(); final ExecutionContextTestFixture executionContextTestFixture = ExecutionContextTestFixture.builder(genesisConfigFile) diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TestNode.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TestNode.java index 8e9bda89c0..c679183b0f 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TestNode.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TestNode.java @@ -123,7 +123,9 @@ public class TestNode implements Closeable { false, EvmConfiguration.DEFAULT, MiningParameters.MINING_DISABLED, - new BadBlockManager()); + new BadBlockManager(), + false, + new NoOpMetricsSystem()); final GenesisState genesisState = GenesisState.fromConfig(genesisConfigFile, protocolSchedule); final BlockHeaderFunctions blockHeaderFunctions = diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolFactoryTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolFactoryTest.java index ef8d070178..5742637c3e 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolFactoryTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolFactoryTest.java @@ -379,7 +379,9 @@ public class TransactionPoolFactoryTest { false, EvmConfiguration.DEFAULT, MiningParameters.MINING_DISABLED, - new BadBlockManager()) + new BadBlockManager(), + false, + new NoOpMetricsSystem()) .createProtocolSchedule(); protocolContext = mock(ProtocolContext.class); 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 db70ccf41f..4f10650273 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 @@ -29,6 +29,7 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolScheduleBuilder; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecAdapters; import org.hyperledger.besu.evm.EvmSpecVersion; import org.hyperledger.besu.evm.internal.EvmConfiguration; +import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import java.math.BigInteger; import java.util.Locale; @@ -80,7 +81,12 @@ class MainnetGenesisFileModule extends GenesisFileModule { } return MainnetProtocolSchedule.fromConfig( - configOptions, evmConfiguration, MiningParameters.newDefault(), new BadBlockManager()); + configOptions, + evmConfiguration, + MiningParameters.newDefault(), + new BadBlockManager(), + false, + new NoOpMetricsSystem()); } public static Map> createSchedules() { @@ -145,7 +151,9 @@ class MainnetGenesisFileModule extends GenesisFileModule { false, EvmConfiguration.DEFAULT, MiningParameters.MINING_DISABLED, - new BadBlockManager()) + new BadBlockManager(), + false, + new NoOpMetricsSystem()) .createProtocolSchedule(); } } diff --git a/ethereum/referencetests/build.gradle b/ethereum/referencetests/build.gradle index 11db6b8eee..3c073136ac 100644 --- a/ethereum/referencetests/build.gradle +++ b/ethereum/referencetests/build.gradle @@ -194,6 +194,7 @@ dependencies { referenceTestImplementation project(path: ':config') referenceTestImplementation project(path: ':datatypes') referenceTestImplementation project(path: ':ethereum:core') + referenceTestImplementation project(path: ':metrics:core') referenceTestImplementation project(path: ':ethereum:core', configuration: 'testSupportArtifacts') referenceTestImplementation project(path: ':ethereum:rlp') referenceTestImplementation project(path: ':ethereum:rlp', configuration: 'testSupportArtifacts') 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 8ac419f7a6..5dfb12f1d6 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 @@ -27,6 +27,7 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecAdapters; import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.evm.precompile.KZGPointEvalPrecompiledContract; +import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import java.math.BigInteger; import java.util.Arrays; @@ -130,7 +131,9 @@ public class ReferenceTestProtocolSchedules { false, EvmConfiguration.DEFAULT, MiningParameters.MINING_DISABLED, - new BadBlockManager()) + new BadBlockManager(), + false, + new NoOpMetricsSystem()) .createProtocolSchedule(); } diff --git a/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/mainnet/DifficultyCalculatorTests.java b/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/mainnet/DifficultyCalculatorTests.java index 6377b1ae3b..00733de1f8 100644 --- a/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/mainnet/DifficultyCalculatorTests.java +++ b/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/mainnet/DifficultyCalculatorTests.java @@ -18,6 +18,7 @@ package org.hyperledger.besu.ethereum.mainnet; import static org.assertj.core.api.Assertions.assertThat; +import org.checkerframework.checker.units.qual.N; import org.hyperledger.besu.config.GenesisConfigFile; import org.hyperledger.besu.config.JsonUtil; import org.hyperledger.besu.config.StubGenesisConfigOptions; @@ -43,6 +44,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.common.io.Resources; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.units.bigints.UInt256; +import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; @@ -59,64 +61,64 @@ public class DifficultyCalculatorTests { MainnetProtocolSchedule.fromConfig( GenesisConfigFile.mainnet() .getConfigOptions(postMergeOverrides), - EvmConfiguration.DEFAULT, MiningParameters.newDefault(), new BadBlockManager())), + EvmConfiguration.DEFAULT, MiningParameters.newDefault(), new BadBlockManager(), false, new NoOpMetricsSystem())), Arguments.of( "/DifficultyTests/dfGrayGlacier/difficultyGrayGlacierForkBlock.json", MainnetProtocolSchedule.fromConfig( - new StubGenesisConfigOptions().grayGlacierBlock(15050000), MiningParameters.newDefault(), new BadBlockManager()) + new StubGenesisConfigOptions().grayGlacierBlock(15050000), MiningParameters.newDefault(), new BadBlockManager(), false, new NoOpMetricsSystem()) ), Arguments.of( "/DifficultyTests/dfGrayGlacier/difficultyGrayGlacierTimeDiff1.json", MainnetProtocolSchedule.fromConfig( - new StubGenesisConfigOptions().grayGlacierBlock(15050000), MiningParameters.newDefault(), new BadBlockManager()) + new StubGenesisConfigOptions().grayGlacierBlock(15050000), MiningParameters.newDefault(), new BadBlockManager(), false, new NoOpMetricsSystem()) ), Arguments.of( "/DifficultyTests/dfGrayGlacier/difficultyGrayGlacierTimeDiff2.json", MainnetProtocolSchedule.fromConfig( - new StubGenesisConfigOptions().grayGlacierBlock(15050000), MiningParameters.newDefault(), new BadBlockManager()) + new StubGenesisConfigOptions().grayGlacierBlock(15050000), MiningParameters.newDefault(), new BadBlockManager(), false, new NoOpMetricsSystem()) ), Arguments.of( "/DifficultyTests/dfArrowGlacier/difficultyArrowGlacierForkBlock.json", MainnetProtocolSchedule.fromConfig( - new StubGenesisConfigOptions().arrowGlacierBlock(13773000), MiningParameters.newDefault(), new BadBlockManager()) + new StubGenesisConfigOptions().arrowGlacierBlock(13773000), MiningParameters.newDefault(), new BadBlockManager(), false, new NoOpMetricsSystem()) ), Arguments.of( "/DifficultyTests/dfArrowGlacier/difficultyArrowGlacierTimeDiff1.json", MainnetProtocolSchedule.fromConfig( - new StubGenesisConfigOptions().arrowGlacierBlock(13773000), MiningParameters.newDefault(), new BadBlockManager()) + new StubGenesisConfigOptions().arrowGlacierBlock(13773000), MiningParameters.newDefault(), new BadBlockManager(), false, new NoOpMetricsSystem()) ), Arguments.of( "/DifficultyTests/dfArrowGlacier/difficultyArrowGlacierTimeDiff2.json", MainnetProtocolSchedule.fromConfig( - new StubGenesisConfigOptions().arrowGlacierBlock(13773000), MiningParameters.newDefault(), new BadBlockManager()) + new StubGenesisConfigOptions().arrowGlacierBlock(13773000), MiningParameters.newDefault(), new BadBlockManager(), false, new NoOpMetricsSystem()) ), Arguments.of( "/DifficultyTests/dfByzantium/difficultyByzantium.json", - MainnetProtocolSchedule.fromConfig(new StubGenesisConfigOptions().byzantiumBlock(0), MiningParameters.newDefault(), new BadBlockManager()) + MainnetProtocolSchedule.fromConfig(new StubGenesisConfigOptions().byzantiumBlock(0), MiningParameters.newDefault(), new BadBlockManager(), false, new NoOpMetricsSystem()) ), Arguments.of( "/DifficultyTests/dfConstantinople/difficultyConstantinople.json", - MainnetProtocolSchedule.fromConfig(new StubGenesisConfigOptions().constantinopleBlock(0), MiningParameters.newDefault(), new BadBlockManager()) + MainnetProtocolSchedule.fromConfig(new StubGenesisConfigOptions().constantinopleBlock(0), MiningParameters.newDefault(), new BadBlockManager(), false, new NoOpMetricsSystem()) ), Arguments.of( "/DifficultyTests/dfEIP2384/difficultyEIP2384.json", - MainnetProtocolSchedule.fromConfig(new StubGenesisConfigOptions().muirGlacierBlock(0), MiningParameters.newDefault(), new BadBlockManager()) + MainnetProtocolSchedule.fromConfig(new StubGenesisConfigOptions().muirGlacierBlock(0), MiningParameters.newDefault(), new BadBlockManager(), false, new NoOpMetricsSystem()) ), Arguments.of( "/DifficultyTests/dfEIP2384/difficultyEIP2384_random.json", - MainnetProtocolSchedule.fromConfig(new StubGenesisConfigOptions().muirGlacierBlock(0), MiningParameters.newDefault(), new BadBlockManager()) + MainnetProtocolSchedule.fromConfig(new StubGenesisConfigOptions().muirGlacierBlock(0), MiningParameters.newDefault(), new BadBlockManager(), false, new NoOpMetricsSystem()) ), Arguments.of( "/DifficultyTests/dfEIP2384/difficultyEIP2384_random_to20M.json", - MainnetProtocolSchedule.fromConfig(new StubGenesisConfigOptions().muirGlacierBlock(0), MiningParameters.newDefault(), new BadBlockManager()) + MainnetProtocolSchedule.fromConfig(new StubGenesisConfigOptions().muirGlacierBlock(0), MiningParameters.newDefault(), new BadBlockManager(), false, new NoOpMetricsSystem()) ), Arguments.of( "/DifficultyTests/dfFrontier/difficultyFrontier.json", - MainnetProtocolSchedule.fromConfig(new StubGenesisConfigOptions(), MiningParameters.newDefault(), new BadBlockManager()) + MainnetProtocolSchedule.fromConfig(new StubGenesisConfigOptions(), MiningParameters.newDefault(), new BadBlockManager(), false, new NoOpMetricsSystem()) ), Arguments.of( "/DifficultyTests/dfHomestead/difficultyHomestead.json", - MainnetProtocolSchedule.fromConfig(new StubGenesisConfigOptions().homesteadBlock(0), MiningParameters.newDefault(), new BadBlockManager()) + MainnetProtocolSchedule.fromConfig(new StubGenesisConfigOptions().homesteadBlock(0), MiningParameters.newDefault(), new BadBlockManager(), false, new NoOpMetricsSystem()) )); } diff --git a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/RetestethContext.java b/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/RetestethContext.java index fd39ef7f44..32d4e0bab1 100644 --- a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/RetestethContext.java +++ b/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/RetestethContext.java @@ -161,7 +161,12 @@ public class RetestethContext { JsonUtil.getObjectNode(genesisConfig, "config").get()); protocolSchedule = MainnetProtocolSchedule.fromConfig( - jsonGenesisConfigOptions, EvmConfiguration.DEFAULT, miningParameters, badBlockManager); + jsonGenesisConfigOptions, + EvmConfiguration.DEFAULT, + miningParameters, + badBlockManager, + false, + new NoOpMetricsSystem()); if ("NoReward".equalsIgnoreCase(sealEngine)) { protocolSchedule = new NoRewardProtocolScheduleWrapper(protocolSchedule, badBlockManager); } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/tracing/OperationTracer.java b/evm/src/main/java/org/hyperledger/besu/evm/tracing/OperationTracer.java index 34e28bbb32..f139386118 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/tracing/OperationTracer.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/tracing/OperationTracer.java @@ -16,6 +16,7 @@ package org.hyperledger.besu.evm.tracing; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Transaction; +import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.log.Log; @@ -85,6 +86,17 @@ public interface OperationTracer { */ default void traceStartTransaction(final WorldView worldView, final Transaction transaction) {} + /** + * Trace the end of a transaction just before mining reward. + * + * @param worldView an immutable view of the execution context + * @param tx the transaction that just concluded + * @param miningReward the reward that the mining beneficiary will receive. + */ + default void traceBeforeRewardTransaction( + final WorldView worldView, final Transaction tx, final Wei miningReward) {} + ; + /** * Trace the end of a transaction. * diff --git a/metrics/core/src/main/java/org/hyperledger/besu/metrics/BesuMetricCategory.java b/metrics/core/src/main/java/org/hyperledger/besu/metrics/BesuMetricCategory.java index d419a6ac7c..4151320177 100644 --- a/metrics/core/src/main/java/org/hyperledger/besu/metrics/BesuMetricCategory.java +++ b/metrics/core/src/main/java/org/hyperledger/besu/metrics/BesuMetricCategory.java @@ -53,7 +53,9 @@ public enum BesuMetricCategory implements MetricCategory { /** Transaction pool besu metric category. */ TRANSACTION_POOL("transaction_pool"), /** Stratum besu metric category. */ - STRATUM("stratum"); + STRATUM("stratum"), + /** Block processing besu metric category. */ + BLOCK_PROCESSING("block_processing"); private static final Optional BESU_PREFIX = Optional.of("besu_"); From 0269d83f39f39d1022848c24ce8c126913c51f08 Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Mon, 22 Jul 2024 09:22:33 +1000 Subject: [PATCH 055/259] 7732: Remove datagas related stuff in favour of blobgas (#7353) * 7732: Remove datagas related stuff in favour of blobgas Signed-off-by: Matilda Clerke --------- Signed-off-by: Matilda Clerke --- .../selectors/BlobSizeTransactionSelector.java | 2 +- .../BlockchainReferenceTestCaseSpec.java | 12 ++---------- .../StateTestVersionedTransaction.java | 5 +---- 3 files changed, 4 insertions(+), 15 deletions(-) diff --git a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/BlobSizeTransactionSelector.java b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/BlobSizeTransactionSelector.java index 9df006722e..9a4c83e962 100644 --- a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/BlobSizeTransactionSelector.java +++ b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/BlobSizeTransactionSelector.java @@ -26,7 +26,7 @@ import org.slf4j.LoggerFactory; /** * This class extends AbstractTransactionSelector and provides a specific implementation for * evaluating transactions based on blobs size. It checks if a transaction supports blobs, and if - * so, checks that there is enough remaining data gas in the block to fit the blobs of the tx. + * so, checks that there is enough remaining blob gas in the block to fit the blobs of the tx. */ public class BlobSizeTransactionSelector extends AbstractTransactionSelector { private static final Logger LOG = LoggerFactory.getLogger(BlobSizeTransactionSelector.class); 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 1048f6238a..4645abdfcf 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 @@ -165,10 +165,6 @@ public class BlockchainReferenceTestCaseSpec { @JsonProperty("nonce") final String nonce, @JsonProperty("withdrawalsRoot") final String withdrawalsRoot, @JsonProperty("requestsRoot") final String requestsRoot, - @JsonProperty("dataGasUsed") - final String dataGasUsed, // TODO: remove once reference tests have been updated - @JsonProperty("excessDataGas") - final String excessDataGas, // TODO: remove once reference tests have been updated @JsonProperty("blobGasUsed") final String blobGasUsed, @JsonProperty("excessBlobGas") final String excessBlobGas, @JsonProperty("parentBeaconBlockRoot") final String parentBeaconBlockRoot, @@ -195,12 +191,8 @@ public class BlockchainReferenceTestCaseSpec { Hash.fromHexString(mixHash), // mixHash Bytes.fromHexStringLenient(nonce).toLong(), withdrawalsRoot != null ? Hash.fromHexString(withdrawalsRoot) : null, - dataGasUsed != null - ? Long.decode(dataGasUsed) - : blobGasUsed != null ? Long.decode(blobGasUsed) : 0, - excessDataGas != null - ? BlobGas.fromHexString(excessDataGas) - : excessBlobGas != null ? BlobGas.fromHexString(excessBlobGas) : null, + blobGasUsed != null ? Long.decode(blobGasUsed) : 0, + excessBlobGas != null ? BlobGas.fromHexString(excessBlobGas) : null, parentBeaconBlockRoot != null ? Bytes32.fromHexString(parentBeaconBlockRoot) : null, requestsRoot != null ? Hash.fromHexString(requestsRoot) : null, new BlockHeaderFunctions() { diff --git a/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/StateTestVersionedTransaction.java b/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/StateTestVersionedTransaction.java index 9748d2aa03..a36d380432 100644 --- a/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/StateTestVersionedTransaction.java +++ b/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/StateTestVersionedTransaction.java @@ -103,7 +103,6 @@ public class StateTestVersionedTransaction { @JsonDeserialize(using = StateTestAccessListDeserializer.class) @JsonProperty("accessLists") final List> maybeAccessLists, @JsonProperty("maxFeePerBlobGas") final String maxFeePerBlobGas, - @JsonProperty("maxFeePerDataGas") final String maxFeePerDataGas, @JsonProperty("blobVersionedHashes") final List blobVersionedHashes) { this.nonce = Bytes.fromHexStringLenient(nonce).toLong(); @@ -123,9 +122,7 @@ public class StateTestVersionedTransaction { this.payloads = parseArray(data, Bytes::fromHexString); this.maybeAccessLists = Optional.ofNullable(maybeAccessLists); this.maxFeePerBlobGas = - Optional.ofNullable(maxFeePerBlobGas == null ? maxFeePerDataGas : maxFeePerBlobGas) - .map(Wei::fromHexString) - .orElse(null); + Optional.ofNullable(maxFeePerBlobGas).map(Wei::fromHexString).orElse(null); this.blobVersionedHashes = blobVersionedHashes; } From bcbfec0c27eb2bca9b0f3f56b9cf6522e8673e16 Mon Sep 17 00:00:00 2001 From: Stefan Pingel <16143240+pinges@users.noreply.github.com> Date: Mon, 22 Jul 2024 12:43:06 +1000 Subject: [PATCH 056/259] Fix NPE for legacy ForkId with no forks (#7349) Fix NPE for legacy ForkId with no forks Signed-off-by: stefan.pingel@consensys.net --- .../besu/ethereum/forkid/ForkIdManager.java | 5 ++--- .../forkid/ForkIdBackwardCompatibilityTest.java | 17 ++++++++++++----- .../ethereum/forkid/LegacyForkIdManager.java | 15 ++++++++------- .../eth/manager/EthProtocolManagerTest.java | 12 ++++++++++-- 4 files changed, 32 insertions(+), 17 deletions(-) diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/forkid/ForkIdManager.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/forkid/ForkIdManager.java index 859fb918a4..407e5149d6 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/forkid/ForkIdManager.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/forkid/ForkIdManager.java @@ -79,8 +79,7 @@ public class ForkIdManager { .sorted() .collect(Collectors.toUnmodifiableList()); final List allForkNumbers = - Stream.concat(blockNumberForks.stream(), timestampForks.stream()) - .collect(Collectors.toList()); + Stream.concat(blockNumberForks.stream(), timestampForks.stream()).toList(); this.forkNext = createForkIds(); this.allForkIds = Stream.concat(blockNumbersForkIds.stream(), timestampsForkIds.stream()) @@ -93,7 +92,7 @@ public class ForkIdManager { public ForkId getForkIdForChainHead() { if (legacyEth64) { return blockNumbersForkIds.isEmpty() - ? null + ? new ForkId(genesisHashCrc, 0) : blockNumbersForkIds.get(blockNumbersForkIds.size() - 1); } final BlockHeader header = chainHeadSupplier.get(); diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/forkid/ForkIdBackwardCompatibilityTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/forkid/ForkIdBackwardCompatibilityTest.java index 84c24bc9a2..df97386e9f 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/forkid/ForkIdBackwardCompatibilityTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/forkid/ForkIdBackwardCompatibilityTest.java @@ -18,6 +18,8 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.hyperledger.besu.ethereum.forkid.ForkIdTestUtil.GenesisHash; import static org.hyperledger.besu.ethereum.forkid.ForkIdTestUtil.mockBlockchain; +import org.hyperledger.besu.ethereum.chain.Blockchain; + import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -77,6 +79,13 @@ public class ForkIdBackwardCompatibilityTest { 8L, Arrays.asList(0L, 0L, 4L, 5L, 6L), true, + null), + Arguments.of( + "no forks and legacyEth64=true", + GenesisHash.PRIVATE, + 8L, + Collections.emptyList(), + true, null)); } @@ -90,13 +99,11 @@ public class ForkIdBackwardCompatibilityTest { final boolean legacyEth64, final ForkId wantForkId) { LOG.info("Running test case {}", name); + final Blockchain blockchain = mockBlockchain(genesisHash, head, 0); final ForkIdManager forkIdManager = - new ForkIdManager( - mockBlockchain(genesisHash, head, 0), forks, Collections.emptyList(), legacyEth64); + new ForkIdManager(blockchain, forks, Collections.emptyList(), legacyEth64); final ForkId legacyForkId = - legacyEth64 - ? new LegacyForkIdManager(mockBlockchain(genesisHash, head, 0), forks).getLatestForkId() - : null; + legacyEth64 ? new LegacyForkIdManager(blockchain, forks).getLatestForkId() : null; assertThat(forkIdManager.getForkIdForChainHead()) .isEqualTo(legacyEth64 ? legacyForkId : wantForkId); } diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/forkid/LegacyForkIdManager.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/forkid/LegacyForkIdManager.java index 325fd41c81..bc9196e6d5 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/forkid/LegacyForkIdManager.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/forkid/LegacyForkIdManager.java @@ -20,7 +20,6 @@ import org.hyperledger.besu.ethereum.rlp.RLPInput; import java.util.ArrayList; import java.util.List; -import java.util.stream.Collectors; import java.util.zip.CRC32; import org.apache.tuweni.bytes.Bytes; @@ -30,12 +29,13 @@ public class LegacyForkIdManager { private final Hash genesisHash; private final List forks; private List forkAndHashList; + private CRC32 crc; + private Bytes genesisHashCrc; public LegacyForkIdManager(final Blockchain blockchain, final List forks) { this.genesisHash = blockchain.getGenesisBlock().getHash(); // de-dupe and sanitize forks - this.forks = - forks.stream().filter(fork -> fork > 0).distinct().collect(Collectors.toUnmodifiableList()); + this.forks = forks.stream().filter(fork -> fork > 0).distinct().toList(); createForkIds(); } @@ -44,10 +44,10 @@ public class LegacyForkIdManager { } public ForkId getLatestForkId() { - if (forkAndHashList.size() > 0) { - return forkAndHashList.get(forkAndHashList.size() - 1); + if (!forkAndHashList.isEmpty()) { + return forkAndHashList.getLast(); } - return null; + return new ForkId(genesisHashCrc, 0); } public static ForkId readFrom(final RLPInput in) { @@ -59,8 +59,9 @@ public class LegacyForkIdManager { } private void createForkIds() { - final CRC32 crc = new CRC32(); + crc = new CRC32(); crc.update(genesisHash.toArray()); + genesisHashCrc = getCurrentCrcHash(crc); final List forkHashes = new ArrayList<>(List.of(getCurrentCrcHash(crc))); for (final Long fork : forks) { updateCrc(crc, fork); diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/EthProtocolManagerTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/EthProtocolManagerTest.java index 93a80be2fd..3a3331b568 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/EthProtocolManagerTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/EthProtocolManagerTest.java @@ -64,6 +64,7 @@ import org.hyperledger.besu.ethereum.eth.transactions.BlobCache; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolFactory; +import org.hyperledger.besu.ethereum.forkid.ForkId; import org.hyperledger.besu.ethereum.forkid.ForkIdManager; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.p2p.rlpx.connections.PeerConnection; @@ -93,6 +94,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; +import java.util.zip.CRC32; import com.google.common.collect.Lists; import org.apache.tuweni.bytes.Bytes; @@ -1136,7 +1138,7 @@ public final class EthProtocolManagerTest { } @Test - public void forkIdForChainHeadMayBeNull() { + public void forkIdForChainHeadLegacyNoForksNotEmpty() { final EthScheduler ethScheduler = mock(EthScheduler.class); try (final EthProtocolManager ethManager = EthProtocolManagerTestUtil.create( @@ -1149,7 +1151,13 @@ public final class EthProtocolManagerTest { new ForkIdManager( blockchain, Collections.emptyList(), Collections.emptyList(), true))) { - assertThat(ethManager.getForkIdAsBytesList()).isEmpty(); + assertThat(ethManager.getForkIdAsBytesList()).isNotEmpty(); + final CRC32 genesisHashCRC = new CRC32(); + genesisHashCRC.update(blockchain.getGenesisBlock().getHash().toArray()); + assertThat(ethManager.getForkIdAsBytesList()) + .isEqualTo( + new ForkId(Bytes.ofUnsignedInt(genesisHashCRC.getValue()), 0L) + .getForkIdAsBytesList()); } } From 7e4a25a9ba980f142d47d7efec859ff0e90c1394 Mon Sep 17 00:00:00 2001 From: Matt Whitehead Date: Tue, 23 Jul 2024 10:25:07 +0100 Subject: [PATCH 057/259] Add new PoA network option to use bootnodes during any peer table refresh, not just the first one (#7314) * Add new config option to use bootnodes during any peer table refresh, not just the first one Signed-off-by: Matthew Whitehead * Update everything-config list Signed-off-by: Matthew Whitehead * Revert debug setting Signed-off-by: Matthew Whitehead * Update ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/internal/PeerDiscoveryController.java Co-authored-by: Stefan Pingel <16143240+pinges@users.noreply.github.com> Signed-off-by: Matt Whitehead --------- Signed-off-by: Matthew Whitehead Signed-off-by: Matt Whitehead Co-authored-by: Stefan Pingel <16143240+pinges@users.noreply.github.com> --- CHANGELOG.md | 2 ++ .../org/hyperledger/besu/RunnerBuilder.java | 15 ++++++++++++ .../org/hyperledger/besu/cli/BesuCommand.java | 14 +++++++++++ .../hyperledger/besu/cli/BesuCommandTest.java | 22 +++++++++++++++++ .../besu/cli/CommandTestAbstract.java | 1 + besu/src/test/resources/complete_config.toml | 1 + .../src/test/resources/everything_config.toml | 1 + .../p2p/config/DiscoveryConfiguration.java | 11 +++++++++ .../p2p/discovery/PeerDiscoveryAgent.java | 1 + .../internal/PeerDiscoveryController.java | 24 +++++++++++++++++-- 10 files changed, 90 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c6cb373ba..d0e62bc5ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,8 @@ - Add trie log pruner metrics [#7352](https://github.com/hyperledger/besu/pull/7352) - `--Xbonsai-parallel-tx-processing-enabled` option enables executing transactions in parallel during block processing for Bonsai nodes +- Add option `--poa-discovery-retry-bootnodes` for PoA networks to always use bootnodes during peer refresh, not just on first start [#7314](https://github.com/hyperledger/besu/pull/7314) + ### Bug fixes - Fix `eth_call` deserialization to correctly ignore unknown fields in the transaction object. [#7323](https://github.com/hyperledger/besu/pull/7323) diff --git a/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java b/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java index 7ed627cfc1..dfd09165b7 100644 --- a/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java @@ -195,6 +195,7 @@ public class RunnerBuilder { private boolean legacyForkIdEnabled; private Optional enodeDnsConfiguration; private List allowedSubnets = new ArrayList<>(); + private boolean poaDiscoveryRetryBootnodes = true; /** Instantiates a new Runner builder. */ public RunnerBuilder() {} @@ -603,6 +604,17 @@ public class RunnerBuilder { return this; } + /** + * Flag to indicate if peer table refreshes should always query bootnodes + * + * @param poaDiscoveryRetryBootnodes whether to always query bootnodes + * @return the runner builder + */ + public RunnerBuilder poaDiscoveryRetryBootnodes(final boolean poaDiscoveryRetryBootnodes) { + this.poaDiscoveryRetryBootnodes = poaDiscoveryRetryBootnodes; + return this; + } + /** * Build Runner instance. * @@ -625,6 +637,8 @@ public class RunnerBuilder { bootstrap = ethNetworkConfig.bootNodes(); } discoveryConfiguration.setBootnodes(bootstrap); + discoveryConfiguration.setIncludeBootnodesOnPeerRefresh( + besuController.getGenesisConfigOptions().isPoa() && poaDiscoveryRetryBootnodes); LOG.info("Resolved {} bootnodes.", bootstrap.size()); LOG.debug("Bootnodes = {}", bootstrap); discoveryConfiguration.setDnsDiscoveryURL(ethNetworkConfig.dnsDiscoveryUrl()); @@ -694,6 +708,7 @@ public class RunnerBuilder { final boolean fallbackEnabled = natMethod == NatMethod.AUTO || natMethodFallbackEnabled; final NatService natService = new NatService(buildNatManager(natMethod), fallbackEnabled); final NetworkBuilder inactiveNetwork = caps -> new NoopP2PNetwork(); + final NetworkBuilder activeNetwork = caps -> { return DefaultP2PNetwork.builder() 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 198c26fe2a..2607f6e595 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java @@ -513,6 +513,19 @@ public class BesuCommand implements DefaultCommandValues, Runnable { } } + // 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. @@ -2324,6 +2337,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { .rpcEndpointService(rpcEndpointServiceImpl) .enodeDnsConfiguration(getEnodeDnsConfiguration()) .allowedSubnets(p2PDiscoveryOptionGroup.allowedSubnets) + .poaDiscoveryRetryBootnodes(p2PDiscoveryOptionGroup.poaDiscoveryRetryBootnodes) .build(); addShutdownHook(runner); 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 efeff412d6..c892ffe7fe 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java @@ -804,6 +804,28 @@ public class BesuCommandTest extends CommandTestAbstract { assertThat(commandErrorOutput.toString(UTF_8)).isEmpty(); } + @Test + public void poaDiscoveryRetryBootnodesValueTrueMustBeUsed() { + parseCommand("--poa-discovery-retry-bootnodes", "true"); + + verify(mockRunnerBuilder).poaDiscoveryRetryBootnodes(eq(true)); + verify(mockRunnerBuilder).build(); + + assertThat(commandOutput.toString(UTF_8)).isEmpty(); + assertThat(commandErrorOutput.toString(UTF_8)).isEmpty(); + } + + @Test + public void poaDiscoveryRetryBootnodesValueFalseMustBeUsed() { + parseCommand("--poa-discovery-retry-bootnodes", "false"); + + verify(mockRunnerBuilder).poaDiscoveryRetryBootnodes(eq(false)); + verify(mockRunnerBuilder).build(); + + assertThat(commandOutput.toString(UTF_8)).isEmpty(); + assertThat(commandErrorOutput.toString(UTF_8)).isEmpty(); + } + @Test public void callingWithBootnodesOptionButNoValueMustPassEmptyBootnodeList() { parseCommand("--bootnodes"); 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 8a6a578119..c77ced5c6f 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/CommandTestAbstract.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/CommandTestAbstract.java @@ -350,6 +350,7 @@ public abstract class CommandTestAbstract { when(mockRunnerBuilder.apiConfiguration(any())).thenReturn(mockRunnerBuilder); when(mockRunnerBuilder.enodeDnsConfiguration(any())).thenReturn(mockRunnerBuilder); when(mockRunnerBuilder.allowedSubnets(any())).thenReturn(mockRunnerBuilder); + when(mockRunnerBuilder.poaDiscoveryRetryBootnodes(anyBoolean())).thenReturn(mockRunnerBuilder); when(mockRunnerBuilder.build()).thenReturn(mockRunner); final SignatureAlgorithm signatureAlgorithm = SignatureAlgorithmFactory.getInstance(); diff --git a/besu/src/test/resources/complete_config.toml b/besu/src/test/resources/complete_config.toml index 3243b05613..8ae2105efd 100644 --- a/besu/src/test/resources/complete_config.toml +++ b/besu/src/test/resources/complete_config.toml @@ -6,6 +6,7 @@ data-path="/opt/besu" # Path # network discovery-enabled=false +poa-discovery-retry-bootnodes=true bootnodes=[ "enode://6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@192.168.0.1:4567", "enode://6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@192.168.0.1:4567", diff --git a/besu/src/test/resources/everything_config.toml b/besu/src/test/resources/everything_config.toml index a5e03bd599..27ea5c1645 100644 --- a/besu/src/test/resources/everything_config.toml +++ b/besu/src/test/resources/everything_config.toml @@ -29,6 +29,7 @@ nat-method="NONE" Xnat-kube-service-name="besu" Xnat-method-fallback-enabled=true discovery-enabled=false +poa-discovery-retry-bootnodes=true bootnodes=[ "enode://6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@192.168.0.1:4567", "enode://6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@192.168.0.1:4567", diff --git a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/config/DiscoveryConfiguration.java b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/config/DiscoveryConfiguration.java index 86bb079a29..3f59abf2fd 100644 --- a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/config/DiscoveryConfiguration.java +++ b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/config/DiscoveryConfiguration.java @@ -33,6 +33,7 @@ public class DiscoveryConfiguration { private String dnsDiscoveryURL; private boolean discoveryV5Enabled = false; private boolean filterOnEnrForkId = NetworkingConfiguration.DEFAULT_FILTER_ON_ENR_FORK_ID; + private boolean includeBootnodesOnPeerRefresh = true; public static DiscoveryConfiguration create() { return new DiscoveryConfiguration(); @@ -88,6 +89,16 @@ public class DiscoveryConfiguration { return this; } + public boolean getIncludeBootnodesOnPeerRefresh() { + return includeBootnodesOnPeerRefresh; + } + + public DiscoveryConfiguration setIncludeBootnodesOnPeerRefresh( + final boolean includeBootnodesOnPeerRefresh) { + this.includeBootnodesOnPeerRefresh = includeBootnodesOnPeerRefresh; + return this; + } + public String getAdvertisedHost() { return advertisedHost; } diff --git a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/PeerDiscoveryAgent.java b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/PeerDiscoveryAgent.java index d1f17b5304..7efc50750f 100644 --- a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/PeerDiscoveryAgent.java +++ b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/PeerDiscoveryAgent.java @@ -274,6 +274,7 @@ public abstract class PeerDiscoveryAgent { .filterOnEnrForkId((config.isFilterOnEnrForkIdEnabled())) .rlpxAgent(rlpxAgent) .peerTable(peerTable) + .includeBootnodesOnPeerRefresh(config.getIncludeBootnodesOnPeerRefresh()) .build(); } diff --git a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/internal/PeerDiscoveryController.java b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/internal/PeerDiscoveryController.java index 5d0fee1845..11b5216a82 100644 --- a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/internal/PeerDiscoveryController.java +++ b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/internal/PeerDiscoveryController.java @@ -143,6 +143,7 @@ public class PeerDiscoveryController { private final AtomicBoolean peerTableIsDirty = new AtomicBoolean(false); private OptionalLong cleanTableTimerId = OptionalLong.empty(); private RecursivePeerRefreshState recursivePeerRefreshState; + private final boolean includeBootnodesOnPeerRefresh; private PeerDiscoveryController( final NodeKey nodeKey, @@ -159,7 +160,8 @@ public class PeerDiscoveryController { final MetricsSystem metricsSystem, final Optional> maybeCacheForEnrRequests, final boolean filterOnEnrForkId, - final RlpxAgent rlpxAgent) { + final RlpxAgent rlpxAgent, + final boolean includeBootnodesOnPeerRefresh) { this.timerUtil = timerUtil; this.nodeKey = nodeKey; this.localPeer = localPeer; @@ -173,6 +175,7 @@ public class PeerDiscoveryController { this.discoveryProtocolLogger = new DiscoveryProtocolLogger(metricsSystem); this.peerPermissions = new PeerDiscoveryPermissions(localPeer, peerPermissions); this.rlpxAgent = rlpxAgent; + this.includeBootnodesOnPeerRefresh = includeBootnodesOnPeerRefresh; metricsSystem.createIntegerGauge( BesuMetricCategory.NETWORK, @@ -483,7 +486,17 @@ public class PeerDiscoveryController { */ private void refreshTable() { final Bytes target = Peer.randomId(); + final List initialPeers = peerTable.nearestBondedPeers(Peer.randomId(), 16); + if (includeBootnodesOnPeerRefresh) { + bootstrapNodes.stream() + .filter(p -> p.getStatus() != PeerDiscoveryStatus.BONDED) + .forEach(p -> p.setStatus(PeerDiscoveryStatus.KNOWN)); + + // If configured to retry bootnodes during peer table refresh, include them + // in the initial peers list. + initialPeers.addAll(bootstrapNodes); + } recursivePeerRefreshState.start(initialPeers, target); lastRefreshTime = System.currentTimeMillis(); } @@ -816,6 +829,7 @@ public class PeerDiscoveryController { private long cleanPeerTableIntervalMs = MILLISECONDS.convert(1, TimeUnit.MINUTES); private final List bootstrapNodes = new ArrayList<>(); private PeerTable peerTable; + private boolean includeBootnodesOnPeerRefresh = true; // Required dependencies private NodeKey nodeKey; @@ -849,7 +863,8 @@ public class PeerDiscoveryController { metricsSystem, Optional.of(cachedEnrRequests), filterOnEnrForkId, - rlpxAgent); + rlpxAgent, + includeBootnodesOnPeerRefresh); } private void validate() { @@ -953,5 +968,10 @@ public class PeerDiscoveryController { this.rlpxAgent = rlpxAgent; return this; } + + public Builder includeBootnodesOnPeerRefresh(final boolean includeBootnodesOnPeerRefresh) { + this.includeBootnodesOnPeerRefresh = includeBootnodesOnPeerRefresh; + return this; + } } } From e68a6c6a52ffee016f9cdfe7c03bef30e8118e91 Mon Sep 17 00:00:00 2001 From: Simon Dudley Date: Wed, 24 Jul 2024 14:51:25 +1000 Subject: [PATCH 058/259] Disable limit trie logs for trie log subcommand (#7366) This avoids executing TrieLogPruner.preload Signed-off-by: Simon Dudley --- CHANGELOG.md | 1 + .../org/hyperledger/besu/cli/BesuCommand.java | 7 +- .../storage/TrieLogSubCommand.java | 10 ++- .../storage/TrieLogSubCommandTest.java | 74 +++++++++++++++++++ 4 files changed, 90 insertions(+), 2 deletions(-) create mode 100644 besu/src/test/java/org/hyperledger/besu/cli/subcommands/storage/TrieLogSubCommandTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index d0e62bc5ef..8b999bca71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ ### Bug fixes - Fix `eth_call` deserialization to correctly ignore unknown fields in the transaction object. [#7323](https://github.com/hyperledger/besu/pull/7323) +- Avoid executing pruner preload during trie log subcommands [#7366](https://github.com/hyperledger/besu/pull/7366) ## 24.7.0 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 2607f6e595..1eaab20bd2 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java @@ -2246,7 +2246,12 @@ public class BesuCommand implements DefaultCommandValues, Runnable { return miningParameters; } - private DataStorageConfiguration getDataStorageConfiguration() { + /** + * Get the data storage configuration + * + * @return the data storage configuration + */ + public DataStorageConfiguration getDataStorageConfiguration() { if (dataStorageConfiguration == null) { dataStorageConfiguration = dataStorageOptions.toDomainObject(); } 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 de42616822..e054bfb615 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 @@ -28,6 +28,7 @@ import org.hyperledger.besu.ethereum.storage.StorageProvider; import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.BonsaiWorldStateKeyValueStorage; 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.plugin.services.storage.DataStorageFormat; import java.io.IOException; @@ -82,7 +83,14 @@ public class TrieLogSubCommand implements Runnable { } private static BesuController createBesuController() { - return parentCommand.besuCommand.buildController(); + final DataStorageConfiguration config = parentCommand.besuCommand.getDataStorageConfiguration(); + // disable limit trie logs to avoid preloading during subcommand execution + return parentCommand + .besuCommand + .getControllerBuilder() + .dataStorageConfiguration( + ImmutableDataStorageConfiguration.copyOf(config).withBonsaiLimitTrieLogsEnabled(false)) + .build(); } @Command( 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 new file mode 100644 index 0000000000..66536070a7 --- /dev/null +++ b/besu/src/test/java/org/hyperledger/besu/cli/subcommands/storage/TrieLogSubCommandTest.java @@ -0,0 +1,74 @@ +/* + * 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.subcommands.storage; + +import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; +import static org.mockito.Mockito.atLeastOnce; +import static org.mockito.Mockito.verify; + +import org.hyperledger.besu.cli.CommandTestAbstract; +import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; + +import java.util.List; + +import org.junit.jupiter.api.Test; + +class TrieLogSubCommandTest extends CommandTestAbstract { + + @Test + void limitTrieLogsDefaultDisabledForAllSubcommands() { + assertTrieLogSubcommand("prune"); + assertTrieLogSubcommand("count"); + assertTrieLogSubcommand("import"); + assertTrieLogSubcommand("export"); + } + + @Test + void limitTrieLogsDisabledForAllSubcommands() { + assertTrieLogSubcommandWithExplicitLimitEnabled("prune"); + assertTrieLogSubcommandWithExplicitLimitEnabled("count"); + assertTrieLogSubcommandWithExplicitLimitEnabled("import"); + assertTrieLogSubcommandWithExplicitLimitEnabled("export"); + } + + private void assertTrieLogSubcommand(final String trieLogSubcommand) { + parseCommand("storage", "trie-log", trieLogSubcommand); + assertConfigurationIsDisabledBySubcommand(); + } + + private void assertTrieLogSubcommandWithExplicitLimitEnabled(final String trieLogSubcommand) { + parseCommand("--bonsai-limit-trie-logs-enabled=true", "storage", "trie-log", trieLogSubcommand); + assertConfigurationIsDisabledBySubcommand(); + } + + private void assertConfigurationIsDisabledBySubcommand() { + verify(mockControllerBuilder, atLeastOnce()) + .dataStorageConfiguration(dataStorageConfigurationArgumentCaptor.capture()); + final List configs = + dataStorageConfigurationArgumentCaptor.getAllValues(); + assertThat(configs.get(0).getBonsaiLimitTrieLogsEnabled()).isTrue(); + assertThat(configs.get(1).getBonsaiLimitTrieLogsEnabled()).isFalse(); + } + + @Test + void limitTrieLogsDefaultEnabledForBesuMainCommand() { + parseCommand(); + verify(mockControllerBuilder, atLeastOnce()) + .dataStorageConfiguration(dataStorageConfigurationArgumentCaptor.capture()); + final List configs = + dataStorageConfigurationArgumentCaptor.getAllValues(); + assertThat(configs).allMatch(DataStorageConfiguration::getBonsaiLimitTrieLogsEnabled); + } +} From e57c811e472b7f9fc4d229ac5c9fd30983c9de52 Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Wed, 24 Jul 2024 08:36:38 -0600 Subject: [PATCH 059/259] Add EXTCODE* unit Tests (#7374) Add unit tests to the EXTCODE* series operations. Also, put all EVM operations tests in the proper package. Signed-off-by: Danno Ferrin --- .../org/hyperledger/besu/evm/MainnetEVMs.java | 11 +- .../evm/operation/ExtCodeCopyOperation.java | 18 +- .../evm/operation/ExtCodeHashOperation.java | 18 +- .../evm/operation/ExtCodeSizeOperation.java | 18 +- .../BaseFeeOperationTest.java | 4 +- .../BlobHashOperationTest.java | 4 +- .../BlockHashOperationTest.java | 3 +- .../CallFOperationTest.java | 4 +- .../ChainIdOperationTest.java | 3 +- ...stantinopleSStoreOperationGasCostTest.java | 2 +- .../Create2OperationTest.java | 3 +- .../CreateOperationTest.java | 3 +- .../DataCopyOperationTest.java | 4 +- .../EofCreateOperationTest.java | 2 +- .../ExtCallOperationTest.java | 4 +- .../operation/ExtCodeCopyOperationTest.java | 245 ++++++++++++++++++ .../ExtCodeHashOperationTest.java | 54 +++- .../operation/ExtCodeSizeOperationTest.java | 183 +++++++++++++ .../ExtDelegateCallOperationTest.java | 4 +- .../ExtStaticCallOperationTest.java | 4 +- .../JumpFOperationTest.java | 4 +- .../JumpOperationTest.java | 3 +- .../LondonSStoreOperationGasCostTest.java | 2 +- .../MCopyOperationTest.java | 4 +- .../PrevRanDaoOperationTest.java | 4 +- .../Push0OperationTest.java | 4 +- .../RelativeJumpOperationTest.java | 6 +- .../RetFOperationTest.java | 4 +- .../RevertOperationTest.java | 3 +- .../SStoreOperationTest.java | 3 +- .../SarOperationTest.java | 3 +- .../SelfDestructOperationTest.java | 4 +- .../ShlOperationTest.java | 3 +- .../ShrOperationTest.java | 3 +- .../TStoreOperationTest.java | 4 +- 35 files changed, 565 insertions(+), 80 deletions(-) rename evm/src/test/java/org/hyperledger/besu/evm/{operations => operation}/BaseFeeOperationTest.java (95%) rename evm/src/test/java/org/hyperledger/besu/evm/{operations => operation}/BlobHashOperationTest.java (96%) rename evm/src/test/java/org/hyperledger/besu/evm/{operations => operation}/BlockHashOperationTest.java (97%) rename evm/src/test/java/org/hyperledger/besu/evm/{operations => operation}/CallFOperationTest.java (93%) rename evm/src/test/java/org/hyperledger/besu/evm/{operations => operation}/ChainIdOperationTest.java (96%) rename evm/src/test/java/org/hyperledger/besu/evm/{operations => operation}/ConstantinopleSStoreOperationGasCostTest.java (98%) rename evm/src/test/java/org/hyperledger/besu/evm/{operations => operation}/Create2OperationTest.java (99%) rename evm/src/test/java/org/hyperledger/besu/evm/{operations => operation}/CreateOperationTest.java (99%) rename evm/src/test/java/org/hyperledger/besu/evm/{operations => operation}/DataCopyOperationTest.java (97%) rename evm/src/test/java/org/hyperledger/besu/evm/{operations => operation}/EofCreateOperationTest.java (99%) rename evm/src/test/java/org/hyperledger/besu/evm/{operations => operation}/ExtCallOperationTest.java (98%) create mode 100644 evm/src/test/java/org/hyperledger/besu/evm/operation/ExtCodeCopyOperationTest.java rename evm/src/test/java/org/hyperledger/besu/evm/{operations => operation}/ExtCodeHashOperationTest.java (70%) create mode 100644 evm/src/test/java/org/hyperledger/besu/evm/operation/ExtCodeSizeOperationTest.java rename evm/src/test/java/org/hyperledger/besu/evm/{operations => operation}/ExtDelegateCallOperationTest.java (98%) rename evm/src/test/java/org/hyperledger/besu/evm/{operations => operation}/ExtStaticCallOperationTest.java (97%) rename evm/src/test/java/org/hyperledger/besu/evm/{operations => operation}/JumpFOperationTest.java (93%) rename evm/src/test/java/org/hyperledger/besu/evm/{operations => operation}/JumpOperationTest.java (98%) rename evm/src/test/java/org/hyperledger/besu/evm/{operations => operation}/LondonSStoreOperationGasCostTest.java (98%) rename evm/src/test/java/org/hyperledger/besu/evm/{operations => operation}/MCopyOperationTest.java (96%) rename evm/src/test/java/org/hyperledger/besu/evm/{operations => operation}/PrevRanDaoOperationTest.java (94%) rename evm/src/test/java/org/hyperledger/besu/evm/{operations => operation}/Push0OperationTest.java (94%) rename evm/src/test/java/org/hyperledger/besu/evm/{operations => operation}/RelativeJumpOperationTest.java (96%) rename evm/src/test/java/org/hyperledger/besu/evm/{operations => operation}/RetFOperationTest.java (93%) rename evm/src/test/java/org/hyperledger/besu/evm/{operations => operation}/RevertOperationTest.java (95%) rename evm/src/test/java/org/hyperledger/besu/evm/{operations => operation}/SStoreOperationTest.java (97%) rename evm/src/test/java/org/hyperledger/besu/evm/{operations => operation}/SarOperationTest.java (98%) rename evm/src/test/java/org/hyperledger/besu/evm/{operations => operation}/SelfDestructOperationTest.java (97%) rename evm/src/test/java/org/hyperledger/besu/evm/{operations => operation}/ShlOperationTest.java (98%) rename evm/src/test/java/org/hyperledger/besu/evm/{operations => operation}/ShrOperationTest.java (98%) rename evm/src/test/java/org/hyperledger/besu/evm/{operations => operation}/TStoreOperationTest.java (99%) 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 2d9be8d312..06ef2da253 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/MainnetEVMs.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/MainnetEVMs.java @@ -240,8 +240,8 @@ public class MainnetEVMs { registry.put(new CodeSizeOperation(gasCalculator)); registry.put(new CodeCopyOperation(gasCalculator)); registry.put(new GasPriceOperation(gasCalculator)); - registry.put(new ExtCodeCopyOperation(gasCalculator)); - registry.put(new ExtCodeSizeOperation(gasCalculator)); + registry.put(new ExtCodeCopyOperation(gasCalculator, false)); + registry.put(new ExtCodeSizeOperation(gasCalculator, false)); registry.put(new BlockHashOperation(gasCalculator)); registry.put(new CoinbaseOperation(gasCalculator)); registry.put(new TimestampOperation(gasCalculator)); @@ -478,7 +478,7 @@ public class MainnetEVMs { registry.put(new SarOperation(gasCalculator)); registry.put(new ShlOperation(gasCalculator)); registry.put(new ShrOperation(gasCalculator)); - registry.put(new ExtCodeHashOperation(gasCalculator)); + registry.put(new ExtCodeHashOperation(gasCalculator, false)); } /** @@ -1114,6 +1114,11 @@ public class MainnetEVMs { registry.put(new SwapNOperation(gasCalculator)); registry.put(new ExchangeOperation(gasCalculator)); + // EIP-3540 EOF Aware EXTCODE* operations + registry.put(new ExtCodeCopyOperation(gasCalculator, true)); + registry.put(new ExtCodeHashOperation(gasCalculator, true)); + registry.put(new ExtCodeSizeOperation(gasCalculator, true)); + // EIP-4200 relative jump registry.put(new RelativeJumpOperation(gasCalculator)); registry.put(new RelativeJumpIfOperation(gasCalculator)); diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtCodeCopyOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtCodeCopyOperation.java index 37a92ffc6e..2f1c139182 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtCodeCopyOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtCodeCopyOperation.java @@ -34,13 +34,26 @@ public class ExtCodeCopyOperation extends AbstractOperation { /** This is the "code" legacy contracts see when copying code from an EOF contract. */ public static final Bytes EOF_REPLACEMENT_CODE = Bytes.fromHexString("0xef00"); + private final boolean enableEIP3540; + /** * Instantiates a new Ext code copy operation. * * @param gasCalculator the gas calculator */ public ExtCodeCopyOperation(final GasCalculator gasCalculator) { + this(gasCalculator, false); + } + + /** + * Instantiates a new Ext code copy operation. + * + * @param gasCalculator the gas calculator + * @param enableEIP3540 enable EIP-3540 semantics (don't copy EOF) + */ + public ExtCodeCopyOperation(final GasCalculator gasCalculator, final boolean enableEIP3540) { super(0x3C, "EXTCODECOPY", 4, 0, gasCalculator); + this.enableEIP3540 = enableEIP3540; } /** @@ -82,7 +95,10 @@ public class ExtCodeCopyOperation extends AbstractOperation { final Account account = frame.getWorldUpdater().get(address); final Bytes code = account != null ? account.getCode() : Bytes.EMPTY; - if (code.size() >= 2 && code.get(0) == EOFLayout.EOF_PREFIX_BYTE && code.get(1) == 0) { + if (enableEIP3540 + && code.size() >= 2 + && code.get(0) == EOFLayout.EOF_PREFIX_BYTE + && code.get(1) == 0) { frame.writeMemory(memOffset, sourceOffset, numBytes, EOF_REPLACEMENT_CODE); } else { frame.writeMemory(memOffset, sourceOffset, numBytes, code); diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtCodeHashOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtCodeHashOperation.java index 953ddfb04d..c08331b006 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtCodeHashOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtCodeHashOperation.java @@ -34,13 +34,26 @@ public class ExtCodeHashOperation extends AbstractOperation { // // 0x9dbf3648db8210552e9c4f75c6a1c3057c0ca432043bd648be15fe7be05646f5 static final Hash EOF_REPLACEMENT_HASH = Hash.hash(ExtCodeCopyOperation.EOF_REPLACEMENT_CODE); + private final boolean enableEIP3540; + /** * Instantiates a new Ext code hash operation. * * @param gasCalculator the gas calculator */ public ExtCodeHashOperation(final GasCalculator gasCalculator) { + this(gasCalculator, false); + } + + /** + * Instantiates a new Ext code copy operation. + * + * @param gasCalculator the gas calculator + * @param enableEIP3540 enable EIP-3540 semantics (don't copy EOF) + */ + public ExtCodeHashOperation(final GasCalculator gasCalculator, final boolean enableEIP3540) { super(0x3F, "EXTCODEHASH", 1, 1, gasCalculator); + this.enableEIP3540 = enableEIP3540; } /** @@ -71,7 +84,10 @@ public class ExtCodeHashOperation extends AbstractOperation { frame.pushStackItem(Bytes.EMPTY); } else { final Bytes code = account.getCode(); - if (code.size() >= 2 && code.get(0) == EOFLayout.EOF_PREFIX_BYTE && code.get(1) == 0) { + if (enableEIP3540 + && code.size() >= 2 + && code.get(0) == EOFLayout.EOF_PREFIX_BYTE + && code.get(1) == 0) { frame.pushStackItem(EOF_REPLACEMENT_HASH); } else { frame.pushStackItem(account.getCodeHash()); diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtCodeSizeOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtCodeSizeOperation.java index 95e5acc6ff..1779175f15 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtCodeSizeOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtCodeSizeOperation.java @@ -32,13 +32,26 @@ public class ExtCodeSizeOperation extends AbstractOperation { static final Bytes EOF_SIZE = Bytes.of(2); + private final boolean enableEIP3540; + /** * Instantiates a new Ext code size operation. * * @param gasCalculator the gas calculator */ public ExtCodeSizeOperation(final GasCalculator gasCalculator) { + this(gasCalculator, false); + } + + /** + * Instantiates a new Ext code size operation. + * + * @param gasCalculator the gas calculator + * @param enableEIP3540 enable EIP-3540 semantics (EOF is size 2) + */ + public ExtCodeSizeOperation(final GasCalculator gasCalculator, final boolean enableEIP3540) { super(0x3B, "EXTCODESIZE", 1, 1, gasCalculator); + this.enableEIP3540 = enableEIP3540; } /** @@ -70,7 +83,10 @@ public class ExtCodeSizeOperation extends AbstractOperation { codeSize = Bytes.EMPTY; } else { final Bytes code = account.getCode(); - if (code.size() >= 2 && code.get(0) == EOFLayout.EOF_PREFIX_BYTE && code.get(1) == 0) { + if (enableEIP3540 + && code.size() >= 2 + && code.get(0) == EOFLayout.EOF_PREFIX_BYTE + && code.get(1) == 0) { codeSize = EOF_SIZE; } else { codeSize = Words.intBytes(code.size()); diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operations/BaseFeeOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operation/BaseFeeOperationTest.java similarity index 95% rename from evm/src/test/java/org/hyperledger/besu/evm/operations/BaseFeeOperationTest.java rename to evm/src/test/java/org/hyperledger/besu/evm/operation/BaseFeeOperationTest.java index ac816137af..13f0484988 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operations/BaseFeeOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operation/BaseFeeOperationTest.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.evm.operations; +package org.hyperledger.besu.evm.operation; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; @@ -26,8 +26,6 @@ import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.gascalculator.BerlinGasCalculator; import org.hyperledger.besu.evm.gascalculator.GasCalculator; import org.hyperledger.besu.evm.internal.Words; -import org.hyperledger.besu.evm.operation.BaseFeeOperation; -import org.hyperledger.besu.evm.operation.Operation; import org.hyperledger.besu.evm.operation.Operation.OperationResult; import java.util.Optional; diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operations/BlobHashOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operation/BlobHashOperationTest.java similarity index 96% rename from evm/src/test/java/org/hyperledger/besu/evm/operations/BlobHashOperationTest.java rename to evm/src/test/java/org/hyperledger/besu/evm/operation/BlobHashOperationTest.java index cebffeb910..9692c27625 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operations/BlobHashOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operation/BlobHashOperationTest.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.evm.operations; +package org.hyperledger.besu.evm.operation; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; @@ -25,8 +25,6 @@ import org.hyperledger.besu.evm.EVM; import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.gascalculator.CancunGasCalculator; import org.hyperledger.besu.evm.gascalculator.LondonGasCalculator; -import org.hyperledger.besu.evm.operation.BlobHashOperation; -import org.hyperledger.besu.evm.operation.Operation; import java.util.ArrayList; import java.util.Arrays; diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operations/BlockHashOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operation/BlockHashOperationTest.java similarity index 97% rename from evm/src/test/java/org/hyperledger/besu/evm/operations/BlockHashOperationTest.java rename to evm/src/test/java/org/hyperledger/besu/evm/operation/BlockHashOperationTest.java index d19e94e0a6..3ce7e3c207 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operations/BlockHashOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operation/BlockHashOperationTest.java @@ -12,14 +12,13 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.evm.operations; +package org.hyperledger.besu.evm.operation; import static org.assertj.core.api.Assertions.assertThat; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.gascalculator.FrontierGasCalculator; -import org.hyperledger.besu.evm.operation.BlockHashOperation; import org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup; import org.hyperledger.besu.evm.testutils.FakeBlockValues; import org.hyperledger.besu.evm.testutils.TestMessageFrameBuilder; diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operations/CallFOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operation/CallFOperationTest.java similarity index 93% rename from evm/src/test/java/org/hyperledger/besu/evm/operations/CallFOperationTest.java rename to evm/src/test/java/org/hyperledger/besu/evm/operation/CallFOperationTest.java index fe662893e1..9d7fa85d41 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operations/CallFOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operation/CallFOperationTest.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.evm.operations; +package org.hyperledger.besu.evm.operation; import static org.assertj.core.api.Assertions.assertThat; import static org.hyperledger.besu.evm.testutils.OperationsTestUtils.mockCode; @@ -24,8 +24,6 @@ import org.hyperledger.besu.evm.code.CodeSection; import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.gascalculator.GasCalculator; import org.hyperledger.besu.evm.internal.ReturnStack; -import org.hyperledger.besu.evm.operation.CallFOperation; -import org.hyperledger.besu.evm.operation.Operation; import org.hyperledger.besu.evm.testutils.TestMessageFrameBuilder; import org.apache.tuweni.bytes.Bytes; diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operations/ChainIdOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operation/ChainIdOperationTest.java similarity index 96% rename from evm/src/test/java/org/hyperledger/besu/evm/operations/ChainIdOperationTest.java rename to evm/src/test/java/org/hyperledger/besu/evm/operation/ChainIdOperationTest.java index 969039266d..acae6249c4 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operations/ChainIdOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operation/ChainIdOperationTest.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.evm.operations; +package org.hyperledger.besu.evm.operation; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; @@ -20,7 +20,6 @@ import static org.mockito.Mockito.when; import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.gascalculator.ConstantinopleGasCalculator; -import org.hyperledger.besu.evm.operation.ChainIdOperation; import org.hyperledger.besu.evm.operation.Operation.OperationResult; import java.util.List; diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operations/ConstantinopleSStoreOperationGasCostTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operation/ConstantinopleSStoreOperationGasCostTest.java similarity index 98% rename from evm/src/test/java/org/hyperledger/besu/evm/operations/ConstantinopleSStoreOperationGasCostTest.java rename to evm/src/test/java/org/hyperledger/besu/evm/operation/ConstantinopleSStoreOperationGasCostTest.java index 3cea9300e1..b8a254bbe4 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operations/ConstantinopleSStoreOperationGasCostTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operation/ConstantinopleSStoreOperationGasCostTest.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.evm.operations; +package org.hyperledger.besu.evm.operation; import static org.assertj.core.api.Assertions.assertThat; diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operations/Create2OperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operation/Create2OperationTest.java similarity index 99% rename from evm/src/test/java/org/hyperledger/besu/evm/operations/Create2OperationTest.java rename to evm/src/test/java/org/hyperledger/besu/evm/operation/Create2OperationTest.java index 73a4abd34a..51e2863a69 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operations/Create2OperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operation/Create2OperationTest.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.evm.operations; +package org.hyperledger.besu.evm.operation; import static org.assertj.core.api.Assertions.assertThat; import static org.hyperledger.besu.evm.MainnetEVMs.DEV_NET_CHAIN_ID; @@ -35,7 +35,6 @@ import org.hyperledger.besu.evm.gascalculator.ConstantinopleGasCalculator; import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.evm.internal.Words; import org.hyperledger.besu.evm.log.Log; -import org.hyperledger.besu.evm.operation.Create2Operation; import org.hyperledger.besu.evm.operation.Operation.OperationResult; import org.hyperledger.besu.evm.processor.ContractCreationProcessor; import org.hyperledger.besu.evm.testutils.TestMessageFrameBuilder; diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operations/CreateOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operation/CreateOperationTest.java similarity index 99% rename from evm/src/test/java/org/hyperledger/besu/evm/operations/CreateOperationTest.java rename to evm/src/test/java/org/hyperledger/besu/evm/operation/CreateOperationTest.java index 4fa5a0fdd7..c10d8f3d6c 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operations/CreateOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operation/CreateOperationTest.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.evm.operations; +package org.hyperledger.besu.evm.operation; import static org.assertj.core.api.Assertions.assertThat; import static org.hyperledger.besu.evm.MainnetEVMs.DEV_NET_CHAIN_ID; @@ -34,7 +34,6 @@ import org.hyperledger.besu.evm.gascalculator.ConstantinopleGasCalculator; import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.evm.internal.Words; import org.hyperledger.besu.evm.log.Log; -import org.hyperledger.besu.evm.operation.CreateOperation; import org.hyperledger.besu.evm.processor.ContractCreationProcessor; import org.hyperledger.besu.evm.testutils.TestMessageFrameBuilder; import org.hyperledger.besu.evm.tracing.OperationTracer; diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operations/DataCopyOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operation/DataCopyOperationTest.java similarity index 97% rename from evm/src/test/java/org/hyperledger/besu/evm/operations/DataCopyOperationTest.java rename to evm/src/test/java/org/hyperledger/besu/evm/operation/DataCopyOperationTest.java index 83d7f09e5a..af5922aa07 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operations/DataCopyOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operation/DataCopyOperationTest.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.evm.operations; +package org.hyperledger.besu.evm.operation; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assumptions.assumeThat; @@ -24,8 +24,6 @@ import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.gascalculator.PragueGasCalculator; import org.hyperledger.besu.evm.internal.EvmConfiguration; -import org.hyperledger.besu.evm.operation.DataCopyOperation; -import org.hyperledger.besu.evm.operation.Operation; import org.hyperledger.besu.evm.testutils.TestMessageFrameBuilder; import java.util.Arrays; diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operations/EofCreateOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operation/EofCreateOperationTest.java similarity index 99% rename from evm/src/test/java/org/hyperledger/besu/evm/operations/EofCreateOperationTest.java rename to evm/src/test/java/org/hyperledger/besu/evm/operation/EofCreateOperationTest.java index 86a0f8cce1..d5d1212dfb 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operations/EofCreateOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operation/EofCreateOperationTest.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.evm.operations; +package org.hyperledger.besu.evm.operation; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.fail; diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operations/ExtCallOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operation/ExtCallOperationTest.java similarity index 98% rename from evm/src/test/java/org/hyperledger/besu/evm/operations/ExtCallOperationTest.java rename to evm/src/test/java/org/hyperledger/besu/evm/operation/ExtCallOperationTest.java index 946dd0b52e..c43893a543 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operations/ExtCallOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operation/ExtCallOperationTest.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.evm.operations; +package org.hyperledger.besu.evm.operation; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; @@ -29,8 +29,6 @@ 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.internal.EvmConfiguration; -import org.hyperledger.besu.evm.operation.AbstractExtCallOperation; -import org.hyperledger.besu.evm.operation.ExtCallOperation; import org.hyperledger.besu.evm.testutils.TestMessageFrameBuilder; import org.hyperledger.besu.evm.worldstate.WorldUpdater; diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operation/ExtCodeCopyOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operation/ExtCodeCopyOperationTest.java new file mode 100644 index 0000000000..b45824a92b --- /dev/null +++ b/evm/src/test/java/org/hyperledger/besu/evm/operation/ExtCodeCopyOperationTest.java @@ -0,0 +1,245 @@ +/* + * Copyright contributors to Hyperledger Besu. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.evm.operation; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.evm.EVM; +import org.hyperledger.besu.evm.account.MutableAccount; +import org.hyperledger.besu.evm.frame.MessageFrame; +import org.hyperledger.besu.evm.gascalculator.PragueGasCalculator; +import org.hyperledger.besu.evm.testutils.TestMessageFrameBuilder; +import org.hyperledger.besu.evm.toy.ToyWorld; +import org.hyperledger.besu.evm.worldstate.WorldUpdater; + +import java.util.Arrays; +import java.util.Collection; + +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.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class ExtCodeCopyOperationTest { + + private static final Address REQUESTED_ADDRESS = Address.fromHexString("0x22222222"); + + private final ToyWorld toyWorld = new ToyWorld(); + private final WorldUpdater worldStateUpdater = toyWorld.updater(); + + @Mock EVM evm; + + static Collection extCodeCopyTestVector() { + return Arrays.asList( + new Object[][] { + { + "Copy after, no overlap", + Bytes.fromHexString("0123456789abcdef000000000000000000000000000000000000000000000000"), + 32, + 0, + 8, + Bytes.fromHexString( + "00000000000000000000000000000000000000000000000000000000000000000123456789abcdef"), + false, + 2609L + }, + { + "copy from uninitialized memory", + Bytes.EMPTY, + 0, + 24, + 16, + Bytes.fromHexString( + "0x000000000000000000000000000000000000000000000000000000000000000000"), + false, + 2606L + }, + { + "copy from initialized + uninitialized memory", + Bytes.fromHexString( + "0x0000000000000000000000000000000000000000000000000123456789abcdef"), + 64, + 24, + 16, + Bytes.fromHexString( + "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000123456789abcdef000000000000000000000000000000000000000000000000"), + false, + 2612L + }, + { + "overlapping src < dst", + Bytes.fromHexString( + "0x0123456789abcdef000000000000000000000000000000000000000000000000"), + 4, + 0, + 8, + Bytes.fromHexString( + "0x000000000123456789abcdef0000000000000000000000000000000000000000"), + false, + 2606L + }, + { + "overlapping src > dst", + Bytes.fromHexString( + "0x00112233445566778899aabbccddeeff00000000000000000000000000000000"), + 0, + 4, + 8, + Bytes.fromHexString( + "0x445566778899aabb000000000000000000000000000000000000000000000000"), + false, + 2606L + }, + { + "overlapping src == dst", + Bytes.fromHexString( + "0x00112233445566778899aabbccddeeff00000000000000000000000000000000"), + 4, + 4, + 8, + Bytes.fromHexString( + "0x00000000445566778899aabb0000000000000000000000000000000000000000"), + false, + 2606L + }, + { + "EOF-reserved pre-eof", + Bytes.fromHexString("0xEF009f918bf09f9fa9"), + 0, + 0, + 9, + Bytes.fromHexString("0xEF009f918bf09f9fa9"), + false, + 2606L + }, + { + "EOF-reserved post-epf", + Bytes.fromHexString("0xEF009f918bf09f9fa9"), + 0, + 0, + 9, + Bytes.fromHexString("0xEF000000000000000000"), + true, + 2606L + }, + { + "EF-reserved pre-epf", + Bytes.fromHexString("0xEFF09f918bf09f9fa9"), + 0, + 0, + 9, + Bytes.fromHexString("0xEFF09f918bf09f9fa9"), + false, + 2606L + }, + { + "EOF-reserved post-eof", + Bytes.fromHexString("0xEFF09f918bf09f9fa9"), + 0, + 0, + 9, + Bytes.fromHexString("0xEFF09f918bf09f9fa9"), + true, + 2606L + } + }); + } + + @SuppressWarnings("unused") + @ParameterizedTest(name = "{0}") + @MethodSource("extCodeCopyTestVector") + void testExtCodeCopy( + final String name, + final Bytes code, + final long dst, + final long src, + final long len, + final Bytes expected, + final boolean eof, + final long gasCost) { + final MutableAccount account = worldStateUpdater.getOrCreate(REQUESTED_ADDRESS); + account.setCode(code); + + ExtCodeCopyOperation subject = new ExtCodeCopyOperation(new PragueGasCalculator(), eof); + MessageFrame frame = + new TestMessageFrameBuilder() + .worldUpdater(worldStateUpdater) + .pushStackItem(Bytes.ofUnsignedLong(len)) + .pushStackItem(Bytes.ofUnsignedLong(src)) + .pushStackItem(Bytes.ofUnsignedLong(dst)) + .pushStackItem(REQUESTED_ADDRESS) + .build(); + + Operation.OperationResult result = subject.execute(frame, evm); + + assertThat(frame.readMemory(0, expected.size())).isEqualTo(expected); + assertThat(frame.memoryWordSize()).isEqualTo((expected.size() + 31) / 32); + assertThat(result.getGasCost()).isEqualTo(gasCost); + } + + @Test + void testExtCodeCopyCold() { + final MutableAccount account = worldStateUpdater.getOrCreate(REQUESTED_ADDRESS); + Bytes code = Bytes.fromHexString("0xEFF09f918bf09f9fa9"); + account.setCode(code); + + ExtCodeCopyOperation subject = new ExtCodeCopyOperation(new PragueGasCalculator(), false); + MessageFrame frame = + new TestMessageFrameBuilder() + .worldUpdater(worldStateUpdater) + .pushStackItem(Bytes.ofUnsignedLong(9)) + .pushStackItem(Bytes.ofUnsignedLong(0)) + .pushStackItem(Bytes.ofUnsignedLong(0)) + .pushStackItem(REQUESTED_ADDRESS) + .build(); + frame.warmUpAddress(REQUESTED_ADDRESS); + + Operation.OperationResult result = subject.execute(frame, evm); + + assertThat(frame.readMemory(0, 9)).isEqualTo(code); + assertThat(frame.memoryWordSize()).isEqualTo(1); + assertThat(result.getGasCost()).isEqualTo(106); + } + + @Test + void testExtCodeEOFDirtyMemory() { + final MutableAccount account = worldStateUpdater.getOrCreate(REQUESTED_ADDRESS); + Bytes code = Bytes.fromHexString("0xEF009f918bf09f9fa9"); + account.setCode(code); + + ExtCodeCopyOperation subject = new ExtCodeCopyOperation(new PragueGasCalculator(), true); + MessageFrame frame = + new TestMessageFrameBuilder() + .worldUpdater(worldStateUpdater) + .pushStackItem(Bytes.ofUnsignedLong(9)) + .pushStackItem(Bytes.ofUnsignedLong(0)) + .pushStackItem(Bytes.ofUnsignedLong(0)) + .pushStackItem(REQUESTED_ADDRESS) + .build(); + frame.writeMemory(0, 15, Bytes.fromHexString("0x112233445566778899aabbccddeeff")); + + Operation.OperationResult result = subject.execute(frame, evm); + + assertThat(frame.readMemory(0, 16)) + .isEqualTo(Bytes.fromHexString("0xEF0000000000000000aabbccddeeff00")); + assertThat(frame.memoryWordSize()).isEqualTo(1); + assertThat(result.getGasCost()).isEqualTo(2603); + } +} diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operations/ExtCodeHashOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operation/ExtCodeHashOperationTest.java similarity index 70% rename from evm/src/test/java/org/hyperledger/besu/evm/operations/ExtCodeHashOperationTest.java rename to evm/src/test/java/org/hyperledger/besu/evm/operation/ExtCodeHashOperationTest.java index a7ca5eefe6..97461cdbcd 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operations/ExtCodeHashOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operation/ExtCodeHashOperationTest.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.evm.operations; +package org.hyperledger.besu.evm.operation; import static org.assertj.core.api.Assertions.assertThat; @@ -24,8 +24,8 @@ import org.hyperledger.besu.evm.frame.BlockValues; import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.gascalculator.ConstantinopleGasCalculator; import org.hyperledger.besu.evm.gascalculator.IstanbulGasCalculator; +import org.hyperledger.besu.evm.gascalculator.PragueGasCalculator; import org.hyperledger.besu.evm.internal.Words; -import org.hyperledger.besu.evm.operation.ExtCodeHashOperation; import org.hyperledger.besu.evm.operation.Operation.OperationResult; import org.hyperledger.besu.evm.testutils.FakeBlockValues; import org.hyperledger.besu.evm.testutils.TestMessageFrameBuilder; @@ -44,9 +44,11 @@ class ExtCodeHashOperationTest { private final WorldUpdater worldStateUpdater = toyWorld.updater(); private final ExtCodeHashOperation operation = - new ExtCodeHashOperation(new ConstantinopleGasCalculator()); + new ExtCodeHashOperation(new ConstantinopleGasCalculator(), false); private final ExtCodeHashOperation operationIstanbul = - new ExtCodeHashOperation(new IstanbulGasCalculator()); + new ExtCodeHashOperation(new IstanbulGasCalculator(), false); + private final ExtCodeHashOperation operationEOF = + new ExtCodeHashOperation(new PragueGasCalculator(), true); @Test void shouldCharge400Gas() { @@ -113,6 +115,50 @@ class ExtCodeHashOperationTest { assertThat(frame.getStackItem(0)).isEqualTo(Hash.hash(code)); } + @Test + void shouldGetNonEOFHash() { + final Bytes code = Bytes.fromHexString("0xEFF09f918bf09f9fa9"); + final MutableAccount account = worldStateUpdater.getOrCreate(REQUESTED_ADDRESS); + account.setCode(code); + final UInt256 value = + UInt256.fromBytes(Words.fromAddress(REQUESTED_ADDRESS)) + .add(UInt256.valueOf(2).pow(UInt256.valueOf(160))); + + final MessageFrame frame = createMessageFrame(value); + operation.execute(frame, null); + assertThat(frame.getStackItem(0)).isEqualTo(Hash.hash(code)); + + final MessageFrame frameIstanbul = createMessageFrame(value); + operationIstanbul.execute(frameIstanbul, null); + assertThat(frameIstanbul.getStackItem(0)).isEqualTo(Hash.hash(code)); + + final MessageFrame frameEOF = createMessageFrame(value); + operationEOF.execute(frameEOF, null); + assertThat(frameEOF.getStackItem(0)).isEqualTo(Hash.hash(code)); + } + + @Test + void shouldGetEOFHash() { + final Bytes code = Bytes.fromHexString("0xEF009f918bf09f9fa9"); + final MutableAccount account = worldStateUpdater.getOrCreate(REQUESTED_ADDRESS); + account.setCode(code); + final UInt256 value = + UInt256.fromBytes(Words.fromAddress(REQUESTED_ADDRESS)) + .add(UInt256.valueOf(2).pow(UInt256.valueOf(160))); + + final MessageFrame frame = createMessageFrame(value); + operation.execute(frame, null); + assertThat(frame.getStackItem(0)).isEqualTo(Hash.hash(code)); + + final MessageFrame frameIstanbul = createMessageFrame(value); + operationIstanbul.execute(frameIstanbul, null); + assertThat(frameIstanbul.getStackItem(0)).isEqualTo(Hash.hash(code)); + + final MessageFrame frameEOF = createMessageFrame(value); + operationEOF.execute(frameEOF, null); + assertThat(frameEOF.getStackItem(0)).isEqualTo(Hash.hash(Bytes.fromHexString("0xef00"))); + } + private Bytes executeOperation(final Address requestedAddress) { final MessageFrame frame = createMessageFrame(requestedAddress); operation.execute(frame, null); diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operation/ExtCodeSizeOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operation/ExtCodeSizeOperationTest.java new file mode 100644 index 0000000000..8c32469223 --- /dev/null +++ b/evm/src/test/java/org/hyperledger/besu/evm/operation/ExtCodeSizeOperationTest.java @@ -0,0 +1,183 @@ +/* + * 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.evm.operation; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.datatypes.Wei; +import org.hyperledger.besu.evm.account.MutableAccount; +import org.hyperledger.besu.evm.frame.BlockValues; +import org.hyperledger.besu.evm.frame.MessageFrame; +import org.hyperledger.besu.evm.gascalculator.ConstantinopleGasCalculator; +import org.hyperledger.besu.evm.gascalculator.IstanbulGasCalculator; +import org.hyperledger.besu.evm.gascalculator.PragueGasCalculator; +import org.hyperledger.besu.evm.internal.Words; +import org.hyperledger.besu.evm.operation.Operation.OperationResult; +import org.hyperledger.besu.evm.testutils.FakeBlockValues; +import org.hyperledger.besu.evm.testutils.TestMessageFrameBuilder; +import org.hyperledger.besu.evm.toy.ToyWorld; +import org.hyperledger.besu.evm.worldstate.WorldUpdater; + +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.units.bigints.UInt256; +import org.junit.jupiter.api.Test; + +class ExtCodeSizeOperationTest { + + private static final Address REQUESTED_ADDRESS = Address.fromHexString("0x22222222"); + + private final ToyWorld toyWorld = new ToyWorld(); + private final WorldUpdater worldStateUpdater = toyWorld.updater(); + + private final ExtCodeSizeOperation operation = + new ExtCodeSizeOperation(new ConstantinopleGasCalculator(), false); + private final ExtCodeSizeOperation operationIstanbul = + new ExtCodeSizeOperation(new IstanbulGasCalculator(), false); + private final ExtCodeSizeOperation operationEOF = + new ExtCodeSizeOperation(new PragueGasCalculator(), true); + + @Test + void shouldCharge700Gas() { + final OperationResult result = operation.execute(createMessageFrame(REQUESTED_ADDRESS), null); + assertThat(result.getGasCost()).isEqualTo(700L); + } + + @Test + void istanbulShouldCharge700Gas() { + final OperationResult result = + operationIstanbul.execute(createMessageFrame(REQUESTED_ADDRESS), null); + assertThat(result.getGasCost()).isEqualTo(700L); + } + + @Test + void shouldReturnZeroWhenAccountDoesNotExist() { + final Bytes result = executeOperation(REQUESTED_ADDRESS); + assertThat(result.trimLeadingZeros()).isEqualTo(Bytes.EMPTY); + } + + @Test + void shouldReturnSizeOfEmptyDataWhenAccountExistsButDoesNotHaveCode() { + worldStateUpdater.getOrCreate(REQUESTED_ADDRESS).setBalance(Wei.of(1)); + assertThat(executeOperation(REQUESTED_ADDRESS).toInt()).isZero(); + } + + @Test + void shouldReturnZeroWhenAccountExistsButIsEmpty() { + worldStateUpdater.getOrCreate(REQUESTED_ADDRESS); + assertThat(executeOperation(REQUESTED_ADDRESS).trimLeadingZeros()).isEqualTo(Bytes.EMPTY); + } + + @Test + void shouldReturnZeroWhenPrecompiledContractHasNoBalance() { + assertThat(executeOperation(Address.ECREC).trimLeadingZeros()).isEqualTo(Bytes.EMPTY); + } + + @Test + void shouldReturnEmptyCodeSizeWhenPrecompileHasBalance() { + // Sending money to a precompile causes it to exist in the world state archive. + worldStateUpdater.getOrCreate(Address.ECREC).setBalance(Wei.of(10)); + assertThat(executeOperation(Address.ECREC).toInt()).isZero(); + } + + @Test + void shouldGetSizeOfAccountCodeWhenCodeIsPresent() { + final Bytes code = Bytes.fromHexString("0xabcdef"); + final MutableAccount account = worldStateUpdater.getOrCreate(REQUESTED_ADDRESS); + account.setCode(code); + assertThat(executeOperation(REQUESTED_ADDRESS).toInt()).isEqualTo(3); + } + + @Test + void shouldZeroOutLeftMostBitsToGetAddress() { + // If EXTCODESIZE of A is X, then EXTCODESIZE of A + 2**160 is X. + final Bytes code = Bytes.fromHexString("0xabcdef"); + final MutableAccount account = worldStateUpdater.getOrCreate(REQUESTED_ADDRESS); + account.setCode(code); + final UInt256 value = + UInt256.fromBytes(Words.fromAddress(REQUESTED_ADDRESS)) + .add(UInt256.valueOf(2).pow(UInt256.valueOf(160))); + final MessageFrame frame = createMessageFrame(value); + operation.execute(frame, null); + assertThat(frame.getStackItem(0).toInt()).isEqualTo(3); + } + + @Test + void shouldGetNonEOFSize() { + final Bytes code = Bytes.fromHexString("0xEFF09f918bf09f9fa9"); + final MutableAccount account = worldStateUpdater.getOrCreate(REQUESTED_ADDRESS); + account.setCode(code); + final UInt256 value = + UInt256.fromBytes(Words.fromAddress(REQUESTED_ADDRESS)) + .add(UInt256.valueOf(2).pow(UInt256.valueOf(160))); + + final MessageFrame frame = createMessageFrame(value); + operation.execute(frame, null); + assertThat(frame.getStackItem(0).toInt()).isEqualTo(9); + + final MessageFrame frameIstanbul = createMessageFrame(value); + operationIstanbul.execute(frameIstanbul, null); + assertThat(frame.getStackItem(0).toInt()).isEqualTo(9); + + final MessageFrame frameEOF = createMessageFrame(value); + operationEOF.execute(frameEOF, null); + assertThat(frame.getStackItem(0).toInt()).isEqualTo(9); + } + + @Test + void shouldGetEOFSize() { + final Bytes code = Bytes.fromHexString("0xEF009f918bf09f9fa9"); + final MutableAccount account = worldStateUpdater.getOrCreate(REQUESTED_ADDRESS); + account.setCode(code); + final UInt256 value = + UInt256.fromBytes(Words.fromAddress(REQUESTED_ADDRESS)) + .add(UInt256.valueOf(2).pow(UInt256.valueOf(160))); + + final MessageFrame frame = createMessageFrame(value); + operation.execute(frame, null); + assertThat(frame.getStackItem(0).toInt()).isEqualTo(9); + + final MessageFrame frameIstanbul = createMessageFrame(value); + operationIstanbul.execute(frameIstanbul, null); + + assertThat(frameIstanbul.getStackItem(0).toInt()).isEqualTo(9); + final MessageFrame frameEOF = createMessageFrame(value); + operationEOF.execute(frameEOF, null); + assertThat(frameEOF.getStackItem(0).toInt()).isEqualTo(2); + } + + private Bytes executeOperation(final Address requestedAddress) { + final MessageFrame frame = createMessageFrame(requestedAddress); + operation.execute(frame, null); + return frame.getStackItem(0); + } + + private MessageFrame createMessageFrame(final Address requestedAddress) { + final UInt256 stackItem = Words.fromAddress(requestedAddress); + return createMessageFrame(stackItem); + } + + private MessageFrame createMessageFrame(final UInt256 stackItem) { + final BlockValues blockValues = new FakeBlockValues(1337); + final MessageFrame frame = + new TestMessageFrameBuilder() + .worldUpdater(worldStateUpdater) + .blockValues(blockValues) + .build(); + + frame.pushStackItem(stackItem); + return frame; + } +} diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operations/ExtDelegateCallOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operation/ExtDelegateCallOperationTest.java similarity index 98% rename from evm/src/test/java/org/hyperledger/besu/evm/operations/ExtDelegateCallOperationTest.java rename to evm/src/test/java/org/hyperledger/besu/evm/operation/ExtDelegateCallOperationTest.java index d83e9f3ddc..e1881892d5 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operations/ExtDelegateCallOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operation/ExtDelegateCallOperationTest.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.evm.operations; +package org.hyperledger.besu.evm.operation; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; @@ -29,8 +29,6 @@ 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.internal.EvmConfiguration; -import org.hyperledger.besu.evm.operation.AbstractExtCallOperation; -import org.hyperledger.besu.evm.operation.ExtDelegateCallOperation; import org.hyperledger.besu.evm.testutils.TestMessageFrameBuilder; import org.hyperledger.besu.evm.worldstate.WorldUpdater; diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operations/ExtStaticCallOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operation/ExtStaticCallOperationTest.java similarity index 97% rename from evm/src/test/java/org/hyperledger/besu/evm/operations/ExtStaticCallOperationTest.java rename to evm/src/test/java/org/hyperledger/besu/evm/operation/ExtStaticCallOperationTest.java index 76f267ec53..90f2d30088 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operations/ExtStaticCallOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operation/ExtStaticCallOperationTest.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.evm.operations; +package org.hyperledger.besu.evm.operation; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; @@ -29,8 +29,6 @@ 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.internal.EvmConfiguration; -import org.hyperledger.besu.evm.operation.AbstractExtCallOperation; -import org.hyperledger.besu.evm.operation.ExtStaticCallOperation; import org.hyperledger.besu.evm.testutils.TestMessageFrameBuilder; import org.hyperledger.besu.evm.worldstate.WorldUpdater; diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operations/JumpFOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operation/JumpFOperationTest.java similarity index 93% rename from evm/src/test/java/org/hyperledger/besu/evm/operations/JumpFOperationTest.java rename to evm/src/test/java/org/hyperledger/besu/evm/operation/JumpFOperationTest.java index 52a7211050..4611faa0f8 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operations/JumpFOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operation/JumpFOperationTest.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.evm.operations; +package org.hyperledger.besu.evm.operation; import static org.assertj.core.api.Assertions.assertThat; import static org.hyperledger.besu.evm.testutils.OperationsTestUtils.mockCode; @@ -23,8 +23,6 @@ import org.hyperledger.besu.evm.Code; import org.hyperledger.besu.evm.code.CodeSection; import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.gascalculator.GasCalculator; -import org.hyperledger.besu.evm.operation.JumpFOperation; -import org.hyperledger.besu.evm.operation.Operation; import org.hyperledger.besu.evm.testutils.TestMessageFrameBuilder; import org.apache.tuweni.bytes.Bytes; diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operations/JumpOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operation/JumpOperationTest.java similarity index 98% rename from evm/src/test/java/org/hyperledger/besu/evm/operations/JumpOperationTest.java rename to evm/src/test/java/org/hyperledger/besu/evm/operation/JumpOperationTest.java index 3c466422ed..7b9fab338e 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operations/JumpOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operation/JumpOperationTest.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.evm.operations; +package org.hyperledger.besu.evm.operation; import static org.assertj.core.api.Assertions.assertThat; @@ -24,7 +24,6 @@ import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.gascalculator.IstanbulGasCalculator; import org.hyperledger.besu.evm.internal.EvmConfiguration; -import org.hyperledger.besu.evm.operation.JumpOperation; import org.hyperledger.besu.evm.operation.Operation.OperationResult; import org.hyperledger.besu.evm.testutils.FakeBlockValues; import org.hyperledger.besu.evm.testutils.TestMessageFrameBuilder; diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operations/LondonSStoreOperationGasCostTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operation/LondonSStoreOperationGasCostTest.java similarity index 98% rename from evm/src/test/java/org/hyperledger/besu/evm/operations/LondonSStoreOperationGasCostTest.java rename to evm/src/test/java/org/hyperledger/besu/evm/operation/LondonSStoreOperationGasCostTest.java index f2cf950683..b4865df5d2 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operations/LondonSStoreOperationGasCostTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operation/LondonSStoreOperationGasCostTest.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.evm.operations; +package org.hyperledger.besu.evm.operation; import static org.assertj.core.api.Assertions.assertThat; diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operations/MCopyOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operation/MCopyOperationTest.java similarity index 96% rename from evm/src/test/java/org/hyperledger/besu/evm/operations/MCopyOperationTest.java rename to evm/src/test/java/org/hyperledger/besu/evm/operation/MCopyOperationTest.java index 2975312920..6bf5a8afd2 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operations/MCopyOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operation/MCopyOperationTest.java @@ -12,15 +12,13 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.evm.operations; +package org.hyperledger.besu.evm.operation; import static org.assertj.core.api.Assertions.assertThat; import org.hyperledger.besu.evm.EVM; import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.gascalculator.CancunGasCalculator; -import org.hyperledger.besu.evm.operation.MCopyOperation; -import org.hyperledger.besu.evm.operation.Operation; import org.hyperledger.besu.evm.testutils.TestMessageFrameBuilder; import java.util.Arrays; diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operations/PrevRanDaoOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operation/PrevRanDaoOperationTest.java similarity index 94% rename from evm/src/test/java/org/hyperledger/besu/evm/operations/PrevRanDaoOperationTest.java rename to evm/src/test/java/org/hyperledger/besu/evm/operation/PrevRanDaoOperationTest.java index 25a2682e87..28340920a0 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operations/PrevRanDaoOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operation/PrevRanDaoOperationTest.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.evm.operations; +package org.hyperledger.besu.evm.operation; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; @@ -23,8 +23,6 @@ import org.hyperledger.besu.evm.EVM; import org.hyperledger.besu.evm.frame.BlockValues; import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.gascalculator.LondonGasCalculator; -import org.hyperledger.besu.evm.operation.Operation; -import org.hyperledger.besu.evm.operation.PrevRanDaoOperation; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operations/Push0OperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operation/Push0OperationTest.java similarity index 94% rename from evm/src/test/java/org/hyperledger/besu/evm/operations/Push0OperationTest.java rename to evm/src/test/java/org/hyperledger/besu/evm/operation/Push0OperationTest.java index 3309fccce8..d7440b0796 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operations/Push0OperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operation/Push0OperationTest.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.evm.operations; +package org.hyperledger.besu.evm.operation; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; @@ -24,9 +24,7 @@ import org.hyperledger.besu.evm.frame.BlockValues; import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.gascalculator.BerlinGasCalculator; import org.hyperledger.besu.evm.gascalculator.GasCalculator; -import org.hyperledger.besu.evm.operation.Operation; import org.hyperledger.besu.evm.operation.Operation.OperationResult; -import org.hyperledger.besu.evm.operation.Push0Operation; import org.hyperledger.besu.evm.testutils.FakeBlockValues; import java.util.Optional; diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operations/RelativeJumpOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operation/RelativeJumpOperationTest.java similarity index 96% rename from evm/src/test/java/org/hyperledger/besu/evm/operations/RelativeJumpOperationTest.java rename to evm/src/test/java/org/hyperledger/besu/evm/operation/RelativeJumpOperationTest.java index 3104225775..7ca5eb04ca 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operations/RelativeJumpOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operation/RelativeJumpOperationTest.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.evm.operations; +package org.hyperledger.besu.evm.operation; import static org.assertj.core.api.Assertions.assertThat; import static org.hyperledger.besu.evm.testutils.OperationsTestUtils.mockCode; @@ -23,10 +23,6 @@ import org.hyperledger.besu.evm.Code; import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.gascalculator.GasCalculator; import org.hyperledger.besu.evm.internal.Words; -import org.hyperledger.besu.evm.operation.Operation; -import org.hyperledger.besu.evm.operation.RelativeJumpIfOperation; -import org.hyperledger.besu.evm.operation.RelativeJumpOperation; -import org.hyperledger.besu.evm.operation.RelativeJumpVectorOperation; import org.hyperledger.besu.evm.testutils.TestMessageFrameBuilder; import org.apache.tuweni.bytes.Bytes; diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operations/RetFOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operation/RetFOperationTest.java similarity index 93% rename from evm/src/test/java/org/hyperledger/besu/evm/operations/RetFOperationTest.java rename to evm/src/test/java/org/hyperledger/besu/evm/operation/RetFOperationTest.java index 672628140c..f2a0947086 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operations/RetFOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operation/RetFOperationTest.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.evm.operations; +package org.hyperledger.besu.evm.operation; import static org.assertj.core.api.Assertions.assertThat; import static org.hyperledger.besu.evm.testutils.OperationsTestUtils.mockCode; @@ -24,8 +24,6 @@ import org.hyperledger.besu.evm.code.CodeSection; import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.gascalculator.GasCalculator; import org.hyperledger.besu.evm.internal.ReturnStack; -import org.hyperledger.besu.evm.operation.Operation; -import org.hyperledger.besu.evm.operation.RetFOperation; import org.hyperledger.besu.evm.testutils.TestMessageFrameBuilder; import org.apache.tuweni.bytes.Bytes; diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operations/RevertOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operation/RevertOperationTest.java similarity index 95% rename from evm/src/test/java/org/hyperledger/besu/evm/operations/RevertOperationTest.java rename to evm/src/test/java/org/hyperledger/besu/evm/operation/RevertOperationTest.java index 9ffc422d60..d5094494a3 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operations/RevertOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operation/RevertOperationTest.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.evm.operations; +package org.hyperledger.besu.evm.operation; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.anyLong; @@ -20,7 +20,6 @@ import static org.mockito.Mockito.when; import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.gascalculator.ConstantinopleGasCalculator; -import org.hyperledger.besu.evm.operation.RevertOperation; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.units.bigints.UInt256; diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operations/SStoreOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operation/SStoreOperationTest.java similarity index 97% rename from evm/src/test/java/org/hyperledger/besu/evm/operations/SStoreOperationTest.java rename to evm/src/test/java/org/hyperledger/besu/evm/operation/SStoreOperationTest.java index 3993d9f81e..6f3c7fd21f 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operations/SStoreOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operation/SStoreOperationTest.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.evm.operations; +package org.hyperledger.besu.evm.operation; import static org.assertj.core.api.Assertions.assertThat; import static org.hyperledger.besu.evm.frame.ExceptionalHaltReason.INSUFFICIENT_GAS; @@ -25,7 +25,6 @@ import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.gascalculator.ConstantinopleGasCalculator; import org.hyperledger.besu.evm.gascalculator.GasCalculator; import org.hyperledger.besu.evm.operation.Operation.OperationResult; -import org.hyperledger.besu.evm.operation.SStoreOperation; import org.hyperledger.besu.evm.testutils.FakeBlockValues; import org.hyperledger.besu.evm.testutils.TestMessageFrameBuilder; import org.hyperledger.besu.evm.toy.ToyWorld; diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operations/SarOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operation/SarOperationTest.java similarity index 98% rename from evm/src/test/java/org/hyperledger/besu/evm/operations/SarOperationTest.java rename to evm/src/test/java/org/hyperledger/besu/evm/operation/SarOperationTest.java index 86182e47e3..c7d7cad00d 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operations/SarOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operation/SarOperationTest.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.evm.operations; +package org.hyperledger.besu.evm.operation; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; @@ -22,7 +22,6 @@ import static org.mockito.Mockito.when; import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.gascalculator.GasCalculator; import org.hyperledger.besu.evm.gascalculator.SpuriousDragonGasCalculator; -import org.hyperledger.besu.evm.operation.SarOperation; import java.util.List; diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operations/SelfDestructOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operation/SelfDestructOperationTest.java similarity index 97% rename from evm/src/test/java/org/hyperledger/besu/evm/operations/SelfDestructOperationTest.java rename to evm/src/test/java/org/hyperledger/besu/evm/operation/SelfDestructOperationTest.java index 7842174e90..d3a3db754b 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operations/SelfDestructOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operation/SelfDestructOperationTest.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.evm.operations; +package org.hyperledger.besu.evm.operation; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.atLeast; @@ -31,8 +31,6 @@ import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.gascalculator.ConstantinopleGasCalculator; import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.evm.internal.Words; -import org.hyperledger.besu.evm.operation.Operation; -import org.hyperledger.besu.evm.operation.SelfDestructOperation; import org.hyperledger.besu.evm.worldstate.WorldUpdater; import org.apache.tuweni.bytes.Bytes; diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operations/ShlOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operation/ShlOperationTest.java similarity index 98% rename from evm/src/test/java/org/hyperledger/besu/evm/operations/ShlOperationTest.java rename to evm/src/test/java/org/hyperledger/besu/evm/operation/ShlOperationTest.java index b567cb6302..a4d0b8f310 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operations/ShlOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operation/ShlOperationTest.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.evm.operations; +package org.hyperledger.besu.evm.operation; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; @@ -22,7 +22,6 @@ import static org.mockito.Mockito.when; import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.gascalculator.GasCalculator; import org.hyperledger.besu.evm.gascalculator.SpuriousDragonGasCalculator; -import org.hyperledger.besu.evm.operation.ShlOperation; import java.util.Arrays; diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operations/ShrOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operation/ShrOperationTest.java similarity index 98% rename from evm/src/test/java/org/hyperledger/besu/evm/operations/ShrOperationTest.java rename to evm/src/test/java/org/hyperledger/besu/evm/operation/ShrOperationTest.java index 659c50d35c..5acc7466a2 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operations/ShrOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operation/ShrOperationTest.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.evm.operations; +package org.hyperledger.besu.evm.operation; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; @@ -22,7 +22,6 @@ import static org.mockito.Mockito.when; import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.gascalculator.GasCalculator; import org.hyperledger.besu.evm.gascalculator.SpuriousDragonGasCalculator; -import org.hyperledger.besu.evm.operation.ShrOperation; import java.util.Arrays; diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operations/TStoreOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operation/TStoreOperationTest.java similarity index 99% rename from evm/src/test/java/org/hyperledger/besu/evm/operations/TStoreOperationTest.java rename to evm/src/test/java/org/hyperledger/besu/evm/operation/TStoreOperationTest.java index c73a4544f9..c7c3470825 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operations/TStoreOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operation/TStoreOperationTest.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.evm.operations; +package org.hyperledger.besu.evm.operation; import static org.assertj.core.api.Assertions.assertThat; import static org.hyperledger.besu.evm.frame.ExceptionalHaltReason.INSUFFICIENT_GAS; @@ -26,8 +26,6 @@ import org.hyperledger.besu.evm.gascalculator.CancunGasCalculator; import org.hyperledger.besu.evm.gascalculator.GasCalculator; import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.evm.operation.Operation.OperationResult; -import org.hyperledger.besu.evm.operation.TLoadOperation; -import org.hyperledger.besu.evm.operation.TStoreOperation; import org.hyperledger.besu.evm.testutils.ByteCodeBuilder; import org.hyperledger.besu.evm.testutils.FakeBlockValues; import org.hyperledger.besu.evm.testutils.TestCodeExecutor; From 30dfa66c1ebd01c53966f4274af626b2168e1ee2 Mon Sep 17 00:00:00 2001 From: Fabio Di Fabio Date: Thu, 25 Jul 2024 23:53:53 +0200 Subject: [PATCH 060/259] Penalize invalid transient pending transactions in the layered transaction pool (#7359) * Introduce score for pending transactions Signed-off-by: Fabio Di Fabio * Introduce score for pending transactions Signed-off-by: Fabio Di Fabio * Update package javadoc Signed-off-by: Fabio Di Fabio --------- Signed-off-by: Fabio Di Fabio --- .../txselection/BlockTransactionSelector.java | 21 +++- .../ProcessingResultTransactionSelector.java | 3 +- .../AbstractBlockTransactionSelectorTest.java | 37 +++--- .../eth/transactions/PendingTransaction.java | 48 +++++--- .../transactions/TransactionPoolMetrics.java | 20 ++++ .../AbstractPrioritizedTransactions.java | 65 +++++++++++ .../layered/AbstractTransactionsLayer.java | 12 ++ .../BaseFeePrioritizedTransactions.java | 30 +++-- .../eth/transactions/layered/EndLayer.java | 3 + .../GasPricePrioritizedTransactions.java | 29 +++-- .../layered/LayeredPendingTransactions.java | 99 ++++++++++------ .../layered/ReadyTransactions.java | 34 ++++-- .../layered/SparseTransactions.java | 5 + .../layered/TransactionsLayer.java | 13 +++ .../transactions/layered/package-info.java | 27 +++-- .../eth/transactions/layered/LayersTest.java | 106 +++++++++++++++++- plugin-api/build.gradle | 2 +- .../data/TransactionSelectionResult.java | 49 ++++++-- 18 files changed, 480 insertions(+), 123 deletions(-) diff --git a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/BlockTransactionSelector.java b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/BlockTransactionSelector.java index c106b7aff1..ed028767d6 100644 --- a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/BlockTransactionSelector.java +++ b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/BlockTransactionSelector.java @@ -15,6 +15,7 @@ package org.hyperledger.besu.ethereum.blockcreation.txselection; import static org.hyperledger.besu.plugin.data.TransactionSelectionResult.BLOCK_SELECTION_TIMEOUT; +import static org.hyperledger.besu.plugin.data.TransactionSelectionResult.INVALID_TX_EVALUATION_TOO_LONG; import static org.hyperledger.besu.plugin.data.TransactionSelectionResult.SELECTED; import static org.hyperledger.besu.plugin.data.TransactionSelectionResult.TX_EVALUATION_TOO_LONG; @@ -419,11 +420,14 @@ public class BlockTransactionSelector { final var pendingTransaction = evaluationContext.getPendingTransaction(); - // check if this tx took too much to evaluate, and in case remove it from the pool + // check if this tx took too much to evaluate, and in case it was invalid remove it from the + // pool, otherwise penalize it. final TransactionSelectionResult actualResult = isTimeout.get() - ? transactionTookTooLong(evaluationContext) - ? TX_EVALUATION_TOO_LONG + ? transactionTookTooLong(evaluationContext, selectionResult) + ? selectionResult.discard() + ? INVALID_TX_EVALUATION_TOO_LONG + : TX_EVALUATION_TOO_LONG : BLOCK_SELECTION_TIMEOUT : selectionResult; @@ -441,16 +445,21 @@ public class BlockTransactionSelector { return actualResult; } - private boolean transactionTookTooLong(final TransactionEvaluationContext evaluationContext) { + private boolean transactionTookTooLong( + final TransactionEvaluationContext evaluationContext, + final TransactionSelectionResult selectionResult) { final var evaluationTimer = evaluationContext.getEvaluationTimer(); if (evaluationTimer.elapsed(TimeUnit.MILLISECONDS) > blockTxsSelectionMaxTime) { LOG.atWarn() .setMessage( - "Transaction {} is too late for inclusion, evaluated in {} that is over the max limit of {}ms" - + ", removing it from the pool") + "Transaction {} is too late for inclusion, with result {}, evaluated in {} that is over the max limit of {}ms" + + ", {}") .addArgument(evaluationContext.getPendingTransaction()::getHash) + .addArgument(selectionResult) .addArgument(evaluationTimer) .addArgument(blockTxsSelectionMaxTime) + .addArgument( + selectionResult.discard() ? "removing it from the pool" : "penalizing it in the pool") .log(); return true; } diff --git a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/ProcessingResultTransactionSelector.java b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/ProcessingResultTransactionSelector.java index 85d97bdf46..9eed2bff09 100644 --- a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/ProcessingResultTransactionSelector.java +++ b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/ProcessingResultTransactionSelector.java @@ -110,7 +110,8 @@ public class ProcessingResultTransactionSelector extends AbstractTransactionSele * @return True if the invalid reason is transient, false otherwise. */ private boolean isTransientValidationError(final TransactionInvalidReason invalidReason) { - return invalidReason.equals(TransactionInvalidReason.GAS_PRICE_BELOW_CURRENT_BASE_FEE) + return invalidReason.equals(TransactionInvalidReason.UPFRONT_COST_EXCEEDS_BALANCE) + || invalidReason.equals(TransactionInvalidReason.GAS_PRICE_BELOW_CURRENT_BASE_FEE) || invalidReason.equals(TransactionInvalidReason.NONCE_TOO_HIGH); } } diff --git a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockTransactionSelectorTest.java b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockTransactionSelectorTest.java index c6ee454241..adcc3ee1e2 100644 --- a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockTransactionSelectorTest.java +++ b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockTransactionSelectorTest.java @@ -18,8 +18,9 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.entry; import static org.awaitility.Awaitility.await; import static org.hyperledger.besu.ethereum.core.MiningParameters.DEFAULT_NON_POA_BLOCK_TXS_SELECTION_MAX_TIME; -import static org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason.UPFRONT_COST_EXCEEDS_BALANCE; +import static org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason.NONCE_TOO_LOW; import static org.hyperledger.besu.plugin.data.TransactionSelectionResult.BLOCK_SELECTION_TIMEOUT; +import static org.hyperledger.besu.plugin.data.TransactionSelectionResult.INVALID_TX_EVALUATION_TOO_LONG; import static org.hyperledger.besu.plugin.data.TransactionSelectionResult.PRIORITY_FEE_PER_GAS_BELOW_CURRENT_MIN; import static org.hyperledger.besu.plugin.data.TransactionSelectionResult.SELECTED; import static org.hyperledger.besu.plugin.data.TransactionSelectionResult.TX_EVALUATION_TOO_LONG; @@ -296,7 +297,7 @@ public abstract class AbstractBlockTransactionSelectorTest { final Transaction tx = createTransaction(i, Wei.of(7), 100_000); transactionsToInject.add(tx); if (i == 1) { - ensureTransactionIsInvalid(tx, TransactionInvalidReason.UPFRONT_COST_EXCEEDS_BALANCE); + ensureTransactionIsInvalid(tx, TransactionInvalidReason.NONCE_TOO_LOW); } else { ensureTransactionIsValid(tx); } @@ -311,8 +312,7 @@ public abstract class AbstractBlockTransactionSelectorTest { .containsOnly( entry( invalidTx, - TransactionSelectionResult.invalid( - TransactionInvalidReason.UPFRONT_COST_EXCEEDS_BALANCE.name()))); + TransactionSelectionResult.invalid(TransactionInvalidReason.NONCE_TOO_LOW.name()))); assertThat(results.getSelectedTransactions().size()).isEqualTo(4); assertThat(results.getSelectedTransactions().contains(invalidTx)).isFalse(); assertThat(results.getReceipts().size()).isEqualTo(4); @@ -568,8 +568,7 @@ public abstract class AbstractBlockTransactionSelectorTest { ensureTransactionIsValid(validTransaction, 21_000, 0); final Transaction invalidTransaction = createTransaction(3, Wei.of(10), 21_000); - ensureTransactionIsInvalid( - invalidTransaction, TransactionInvalidReason.UPFRONT_COST_EXCEEDS_BALANCE); + ensureTransactionIsInvalid(invalidTransaction, TransactionInvalidReason.NONCE_TOO_LOW); transactionPool.addRemoteTransactions(List.of(validTransaction, invalidTransaction)); @@ -582,8 +581,7 @@ public abstract class AbstractBlockTransactionSelectorTest { .containsOnly( entry( invalidTransaction, - TransactionSelectionResult.invalid( - TransactionInvalidReason.UPFRONT_COST_EXCEEDS_BALANCE.name()))); + TransactionSelectionResult.invalid(TransactionInvalidReason.NONCE_TOO_LOW.name()))); } @Test @@ -948,7 +946,7 @@ public abstract class AbstractBlockTransactionSelectorTest { @ParameterizedTest @MethodSource("subsetOfPendingTransactionsIncludedWhenTxSelectionMaxTimeIsOver") - public void pendingTransactionsThatTakesTooLongToEvaluateIsDroppedFromThePool( + public void pendingTransactionsThatTakesTooLongToEvaluateIsPenalized( final boolean isPoa, final boolean preProcessingTooLate, final boolean processingTooLate, @@ -961,7 +959,7 @@ public abstract class AbstractBlockTransactionSelectorTest { postProcessingTooLate, 900, TX_EVALUATION_TOO_LONG, - true); + false); } private void internalBlockSelectionTimeoutSimulation( @@ -1085,7 +1083,7 @@ public abstract class AbstractBlockTransactionSelectorTest { 500, BLOCK_SELECTION_TIMEOUT, false, - UPFRONT_COST_EXCEEDS_BALANCE); + NONCE_TOO_LOW); } @ParameterizedTest @@ -1102,9 +1100,9 @@ public abstract class AbstractBlockTransactionSelectorTest { processingTooLate, postProcessingTooLate, 900, - TX_EVALUATION_TOO_LONG, + INVALID_TX_EVALUATION_TOO_LONG, true, - UPFRONT_COST_EXCEEDS_BALANCE); + NONCE_TOO_LOW); } private void internalBlockSelectionTimeoutSimulationInvalidTxs( @@ -1423,15 +1421,17 @@ public abstract class AbstractBlockTransactionSelectorTest { private static class PluginTransactionSelectionResult extends TransactionSelectionResult { private enum PluginStatus implements Status { - PLUGIN_INVALID(false, true), - PLUGIN_INVALID_TRANSIENT(false, false); + PLUGIN_INVALID(false, true, false), + PLUGIN_INVALID_TRANSIENT(false, false, true); private final boolean stop; private final boolean discard; + private final boolean penalize; - PluginStatus(final boolean stop, final boolean discard) { + PluginStatus(final boolean stop, final boolean discard, final boolean penalize) { this.stop = stop; this.discard = discard; + this.penalize = penalize; } @Override @@ -1443,6 +1443,11 @@ public abstract class AbstractBlockTransactionSelectorTest { public boolean discard() { return discard; } + + @Override + public boolean penalize() { + return penalize; + } } public static final TransactionSelectionResult GENERIC_PLUGIN_INVALID_TRANSIENT = diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/PendingTransaction.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/PendingTransaction.java index 6ce8f47a7a..bd98bee5ad 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/PendingTransaction.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/PendingTransaction.java @@ -50,18 +50,20 @@ public abstract class PendingTransaction private final Transaction transaction; private final long addedAt; private final long sequence; // Allows prioritization based on order transactions are added + private volatile byte score; private int memorySize = NOT_INITIALIZED; private PendingTransaction( - final Transaction transaction, final long addedAt, final long sequence) { + final Transaction transaction, final long addedAt, final long sequence, final byte score) { this.transaction = transaction; this.addedAt = addedAt; this.sequence = sequence; + this.score = score; } private PendingTransaction(final Transaction transaction, final long addedAt) { - this(transaction, addedAt, TRANSACTIONS_ADDED.getAndIncrement()); + this(transaction, addedAt, TRANSACTIONS_ADDED.getAndIncrement(), Byte.MAX_VALUE); } public static PendingTransaction newPendingTransaction( @@ -123,6 +125,20 @@ public abstract class PendingTransaction return memorySize; } + public byte getScore() { + return score; + } + + public void decrementScore() { + // use temp var to avoid non-atomic update of volatile var + final byte newScore = (byte) (score - 1); + + // check to avoid underflow + if (newScore < score) { + score = newScore; + } + } + public abstract PendingTransaction detachedCopy(); private int computeMemorySize() { @@ -255,6 +271,8 @@ public abstract class PendingTransaction + isReceivedFromLocalSource() + ", hasPriority=" + hasPriority() + + ", score=" + + score + '}'; } @@ -267,6 +285,8 @@ public abstract class PendingTransaction + isReceivedFromLocalSource() + ", hasPriority=" + hasPriority() + + ", score=" + + score + ", " + transaction.toTraceLog() + "}"; @@ -282,13 +302,13 @@ public abstract class PendingTransaction this(transaction, System.currentTimeMillis()); } - private Local(final long sequence, final Transaction transaction) { - super(transaction, System.currentTimeMillis(), sequence); + private Local(final long sequence, final byte score, final Transaction transaction) { + super(transaction, System.currentTimeMillis(), sequence, score); } @Override public PendingTransaction detachedCopy() { - return new Local(getSequence(), getTransaction().detachedCopy()); + return new Local(getSequence(), getScore(), getTransaction().detachedCopy()); } @Override @@ -310,13 +330,13 @@ public abstract class PendingTransaction super(transaction, addedAt); } - public Priority(final long sequence, final Transaction transaction) { - super(sequence, transaction); + public Priority(final long sequence, final byte score, final Transaction transaction) { + super(sequence, score, transaction); } @Override public PendingTransaction detachedCopy() { - return new Priority(getSequence(), getTransaction().detachedCopy()); + return new Priority(getSequence(), getScore(), getTransaction().detachedCopy()); } @Override @@ -336,13 +356,13 @@ public abstract class PendingTransaction this(transaction, System.currentTimeMillis()); } - private Remote(final long sequence, final Transaction transaction) { - super(transaction, System.currentTimeMillis(), sequence); + private Remote(final long sequence, final byte score, final Transaction transaction) { + super(transaction, System.currentTimeMillis(), sequence, score); } @Override public PendingTransaction detachedCopy() { - return new Remote(getSequence(), getTransaction().detachedCopy()); + return new Remote(getSequence(), getScore(), getTransaction().detachedCopy()); } @Override @@ -364,13 +384,13 @@ public abstract class PendingTransaction super(transaction, addedAt); } - public Priority(final long sequence, final Transaction transaction) { - super(sequence, transaction); + public Priority(final long sequence, final byte score, final Transaction transaction) { + super(sequence, score, transaction); } @Override public PendingTransaction detachedCopy() { - return new Priority(getSequence(), getTransaction().detachedCopy()); + return new Priority(getSequence(), getScore(), getTransaction().detachedCopy()); } @Override diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolMetrics.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolMetrics.java index 812e7de9f4..90e9628e5c 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolMetrics.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolMetrics.java @@ -37,12 +37,14 @@ public class TransactionPoolMetrics { public static final String ADDED_COUNTER_NAME = "added_total"; public static final String REMOVED_COUNTER_NAME = "removed_total"; public static final String REJECTED_COUNTER_NAME = "rejected_total"; + public static final String PENALIZED_COUNTER_NAME = "penalized_total"; public static final String EXPIRED_MESSAGES_COUNTER_NAME = "messages_expired_total"; private static final int SKIPPED_MESSAGES_LOGGING_THRESHOLD = 1000; private final MetricsSystem metricsSystem; private final LabelledMetric addedCounter; private final LabelledMetric removedCounter; private final LabelledMetric rejectedCounter; + private final LabelledMetric penalizedCounter; private final LabelledGauge spaceUsed; private final LabelledGauge transactionCount; private final LabelledGauge transactionCountByType; @@ -88,6 +90,15 @@ public class TransactionPoolMetrics { "reason", "layer"); + penalizedCounter = + metricsSystem.createLabelledCounter( + BesuMetricCategory.TRANSACTION_POOL, + PENALIZED_COUNTER_NAME, + "Count of penalized transactions in the transaction pool", + "source", + "priority", + "layer"); + spaceUsed = metricsSystem.createLabelledGauge( BesuMetricCategory.TRANSACTION_POOL, @@ -246,6 +257,15 @@ public class TransactionPoolMetrics { .inc(); } + public void incrementPenalized(final PendingTransaction pendingTransaction, final String layer) { + penalizedCounter + .labels( + location(pendingTransaction.isReceivedFromLocalSource()), + priority(pendingTransaction.hasPriority()), + layer) + .inc(); + } + public void incrementExpiredMessages(final String message) { expiredMessagesCounter.labels(message).inc(); } 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 7a65b3febc..470e7f5b7b 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 @@ -24,13 +24,17 @@ 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 java.util.ArrayList; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.NavigableMap; +import java.util.TreeMap; import java.util.TreeSet; import java.util.function.BiFunction; import java.util.function.Predicate; +import java.util.stream.Collectors; /** * Holds the current set of executable pending transactions, that are candidate for inclusion on @@ -137,6 +141,13 @@ public abstract class AbstractPrioritizedTransactions extends AbstractSequential orderByFee.remove(removedTx); } + @Override + protected void internalPenalize(final PendingTransaction penalizedTx) { + orderByFee.remove(penalizedTx); + penalizedTx.decrementScore(); + orderByFee.add(penalizedTx); + } + @Override public List promote( final Predicate promotionFilter, @@ -188,6 +199,60 @@ public abstract class AbstractPrioritizedTransactions extends AbstractSequential .toList(); } + /** + * Returns pending txs by sender and ordered by score desc. In case a sender has pending txs with + * different scores, then in nonce sequence, every time there is a score decrease, his pending txs + * will be put in a new entry with that score. For example if a sender has 3 pending txs (where + * the first number is the nonce and the score is between parenthesis): 0(127), 1(126), 2(127), + * then for he there will be 2 entries: + * + *

    + *
  • 0(127) + *
  • 1(126), 2(127) + *
+ * + * @return pending txs by sender and ordered by score desc + */ + public NavigableMap> getByScore() { + final var sendersToAdd = new HashSet<>(txsBySender.keySet()); + return orderByFee.descendingSet().stream() + .map(PendingTransaction::getSender) + .filter(sendersToAdd::remove) + .flatMap(sender -> splitByScore(sender, txsBySender.get(sender)).entrySet().stream()) + .collect( + Collectors.toMap( + Map.Entry::getKey, + Map.Entry::getValue, + (a, b) -> { + a.addAll(b); + return a; + }, + TreeMap::new)) + .descendingMap(); + } + + private Map> splitByScore( + final Address sender, final NavigableMap txsBySender) { + final var splitByScore = new HashMap>(); + byte currScore = txsBySender.firstEntry().getValue().getScore(); + var currSplit = new ArrayList(); + for (final var entry : txsBySender.entrySet()) { + if (entry.getValue().getScore() < currScore) { + // score decreased, we need to save current split and start a new one + splitByScore + .computeIfAbsent(currScore, k -> new ArrayList<>()) + .add(new SenderPendingTransactions(sender, currSplit)); + currSplit = new ArrayList<>(); + currScore = entry.getValue().getScore(); + } + currSplit.add(entry.getValue()); + } + splitByScore + .computeIfAbsent(currScore, k -> new ArrayList<>()) + .add(new SenderPendingTransactions(sender, currSplit)); + return splitByScore; + } + @Override protected long cacheFreeSpace() { return Integer.MAX_VALUE; 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 5997fe6c18..b4f6e927c0 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 @@ -463,6 +463,18 @@ public abstract class AbstractTransactionsLayer implements TransactionsLayer { } } + @Override + public void penalize(final PendingTransaction penalizedTransaction) { + if (pendingTransactions.containsKey(penalizedTransaction.getHash())) { + internalPenalize(penalizedTransaction); + metrics.incrementPenalized(penalizedTransaction, name()); + } else { + nextLayer.penalize(penalizedTransaction); + } + } + + protected abstract void internalPenalize(final PendingTransaction pendingTransaction); + /** * How many txs of a specified type can be promoted? This make sense when a max number of txs of a * type can be included in a single block (ex. blob txs), to avoid filling the layer with more txs 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 8140cd5d7a..b3dec34b77 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 @@ -19,7 +19,6 @@ import static org.hyperledger.besu.ethereum.eth.transactions.layered.Transaction import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.MiningParameters; -import org.hyperledger.besu.ethereum.core.Transaction; import org.hyperledger.besu.ethereum.eth.manager.EthScheduler; import org.hyperledger.besu.ethereum.eth.transactions.BlobCache; import org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction; @@ -66,7 +65,8 @@ public class BaseFeePrioritizedTransactions extends AbstractPrioritizedTransacti @Override protected int compareByFee(final PendingTransaction pt1, final PendingTransaction pt2) { - return Comparator.comparing(PendingTransaction::hasPriority) + return Comparator.comparing(PendingTransaction::getScore) + .thenComparing(PendingTransaction::hasPriority) .thenComparing( (PendingTransaction pendingTransaction) -> pendingTransaction.getTransaction().getEffectivePriorityFeePerGas(nextBlockBaseFee)) @@ -195,8 +195,8 @@ public class BaseFeePrioritizedTransactions extends AbstractPrioritizedTransacti return "Basefee Prioritized: Empty"; } - final Transaction highest = orderByFee.last().getTransaction(); - final Transaction lowest = orderByFee.first().getTransaction(); + final PendingTransaction highest = orderByFee.last(); + final PendingTransaction lowest = orderByFee.first(); return "Basefee Prioritized: " + "count: " @@ -205,16 +205,26 @@ public class BaseFeePrioritizedTransactions extends AbstractPrioritizedTransacti + spaceUsed + ", unique senders: " + txsBySender.size() - + ", highest priority tx: [max fee: " - + highest.getMaxGasPrice().toHumanReadableString() + + ", highest priority tx: [score: " + + highest.getScore() + + ", max fee: " + + highest.getTransaction().getMaxGasPrice().toHumanReadableString() + ", curr prio fee: " - + highest.getEffectivePriorityFeePerGas(nextBlockBaseFee).toHumanReadableString() + + highest + .getTransaction() + .getEffectivePriorityFeePerGas(nextBlockBaseFee) + .toHumanReadableString() + ", hash: " + highest.getHash() - + "], lowest priority tx: [max fee: " - + lowest.getMaxGasPrice().toHumanReadableString() + + "], lowest priority tx: [score: " + + lowest.getScore() + + ", max fee: " + + lowest.getTransaction().getMaxGasPrice().toHumanReadableString() + ", curr prio fee: " - + lowest.getEffectivePriorityFeePerGas(nextBlockBaseFee).toHumanReadableString() + + lowest + .getTransaction() + .getEffectivePriorityFeePerGas(nextBlockBaseFee) + .toHumanReadableString() + ", hash: " + lowest.getHash() + "], next block base fee: " 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 0f5d9a6d15..f383f178c2 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 @@ -85,6 +85,9 @@ public class EndLayer implements TransactionsLayer { @Override public void remove(final PendingTransaction pendingTransaction, final RemovalReason reason) {} + @Override + public void penalize(final PendingTransaction penalizedTx) {} + @Override public void blockAdded( final FeeMarket feeMarket, diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/GasPricePrioritizedTransactions.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/GasPricePrioritizedTransactions.java index 97bd3a88ee..504a453fa8 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/GasPricePrioritizedTransactions.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/GasPricePrioritizedTransactions.java @@ -56,7 +56,8 @@ public class GasPricePrioritizedTransactions extends AbstractPrioritizedTransact @Override protected int compareByFee(final PendingTransaction pt1, final PendingTransaction pt2) { - return comparing(PendingTransaction::hasPriority) + return comparing(PendingTransaction::getScore) + .thenComparing(PendingTransaction::hasPriority) .thenComparing(PendingTransaction::getGasPrice) .thenComparing(PendingTransaction::getSequence) .compare(pt1, pt2); @@ -78,21 +79,33 @@ public class GasPricePrioritizedTransactions extends AbstractPrioritizedTransact } @Override - public String internalLogStats() { + protected String internalLogStats() { if (orderByFee.isEmpty()) { return "GasPrice Prioritized: Empty"; } + final PendingTransaction highest = orderByFee.last(); + final PendingTransaction lowest = orderByFee.first(); + return "GasPrice Prioritized: " + "count: " + pendingTransactions.size() - + " space used: " + + ", space used: " + spaceUsed - + " unique senders: " + + ", unique senders: " + txsBySender.size() - + ", highest fee tx: " - + orderByFee.last().getTransaction().getGasPrice().get().toHumanReadableString() - + ", lowest fee tx: " - + orderByFee.first().getTransaction().getGasPrice().get().toHumanReadableString(); + + ", highest priority tx: [score: " + + highest.getScore() + + ", gas price: " + + highest.getTransaction().getGasPrice().get().toHumanReadableString() + + ", hash: " + + highest.getHash() + + "], lowest priority tx: [score: " + + lowest.getScore() + + ", gas price: " + + lowest.getTransaction().getGasPrice().get().toHumanReadableString() + + ", hash: " + + lowest.getHash() + + "]"; } } 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 9444885ebe..5297f08021 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 @@ -42,10 +42,12 @@ import org.hyperledger.besu.plugin.data.TransactionSelectionResult; import java.util.ArrayDeque; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.OptionalLong; +import java.util.Set; import java.util.stream.Collector; import java.util.stream.Collectors; @@ -314,55 +316,80 @@ public class LayeredPendingTransactions implements PendingTransactions { @Override public void selectTransactions(final PendingTransactions.TransactionSelector selector) { final List invalidTransactions = new ArrayList<>(); + final List penalizedTransactions = new ArrayList<>(); + final Set
skipSenders = new HashSet<>(); - final List candidateTxsBySender; + final Map> candidateTxsByScore; synchronized (this) { // since selecting transactions for block creation is a potential long operation // we want to avoid to keep the lock for all the process, but we just lock to get // the candidate transactions - candidateTxsBySender = prioritizedTransactions.getBySender(); + candidateTxsByScore = prioritizedTransactions.getByScore(); } selection: - for (final var senderTxs : candidateTxsBySender) { - LOG.trace("highPrioSenderTxs {}", senderTxs); - - for (final var candidatePendingTx : senderTxs.pendingTransactions()) { - final var selectionResult = selector.evaluateTransaction(candidatePendingTx); - - LOG.atTrace() - .setMessage("Selection result {} for transaction {}") - .addArgument(selectionResult) - .addArgument(candidatePendingTx::toTraceLog) - .log(); - - if (selectionResult.discard()) { - invalidTransactions.add(candidatePendingTx); - logDiscardedTransaction(candidatePendingTx, selectionResult); - } - - if (selectionResult.stop()) { - LOG.trace("Stopping selection"); - break selection; - } - - if (!selectionResult.selected()) { - // avoid processing other txs from this sender if this one is skipped - // since the following will not be selected due to the nonce gap - LOG.trace("Skipping remaining txs for sender {}", candidatePendingTx.getSender()); - break; + for (final var entry : candidateTxsByScore.entrySet()) { + LOG.trace("Evaluating txs with score {}", entry.getKey()); + + for (final var senderTxs : entry.getValue()) { + LOG.trace("Evaluating sender txs {}", senderTxs); + + if (!skipSenders.contains(senderTxs.sender())) { + + for (final var candidatePendingTx : senderTxs.pendingTransactions()) { + final var selectionResult = selector.evaluateTransaction(candidatePendingTx); + + LOG.atTrace() + .setMessage("Selection result {} for transaction {}") + .addArgument(selectionResult) + .addArgument(candidatePendingTx::toTraceLog) + .log(); + + if (selectionResult.discard()) { + invalidTransactions.add(candidatePendingTx); + logDiscardedTransaction(candidatePendingTx, selectionResult); + } + + if (selectionResult.penalize()) { + penalizedTransactions.add(candidatePendingTx); + LOG.atTrace() + .setMessage("Transaction {} penalized") + .addArgument(candidatePendingTx::toTraceLog) + .log(); + } + + if (selectionResult.stop()) { + LOG.trace("Stopping selection"); + break selection; + } + + if (!selectionResult.selected()) { + // avoid processing other txs from this sender if this one is skipped + // since the following will not be selected due to the nonce gap + LOG.trace("Skipping remaining txs for sender {}", candidatePendingTx.getSender()); + skipSenders.add(candidatePendingTx.getSender()); + break; + } + } } } } ethScheduler.scheduleTxWorkerTask( - () -> - invalidTransactions.forEach( - invalidTx -> { - synchronized (this) { - prioritizedTransactions.remove(invalidTx, INVALIDATED); - } - })); + () -> { + invalidTransactions.forEach( + invalidTx -> { + synchronized (this) { + prioritizedTransactions.remove(invalidTx, INVALIDATED); + } + }); + penalizedTransactions.forEach( + penalizedTx -> { + synchronized (this) { + prioritizedTransactions.internalPenalize(penalizedTx); + } + }); + }); } @Override 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 1f9fc0ab8d..0f52e1c5c3 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 @@ -18,7 +18,6 @@ import static org.hyperledger.besu.ethereum.eth.transactions.layered.Transaction import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.ethereum.core.BlockHeader; -import org.hyperledger.besu.ethereum.core.Transaction; import org.hyperledger.besu.ethereum.eth.manager.EthScheduler; import org.hyperledger.besu.ethereum.eth.transactions.BlobCache; import org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction; @@ -43,7 +42,8 @@ public class ReadyTransactions extends AbstractSequentialTransactionsLayer { private final NavigableSet orderByMaxFee = new TreeSet<>( - Comparator.comparing(PendingTransaction::hasPriority) + Comparator.comparing(PendingTransaction::getScore) + .thenComparing(PendingTransaction::hasPriority) .thenComparing((PendingTransaction pt) -> pt.getTransaction().getMaxGasPrice()) .thenComparing(PendingTransaction::getSequence)); @@ -116,6 +116,20 @@ public class ReadyTransactions extends AbstractSequentialTransactionsLayer { } } + @Override + protected void internalPenalize(final PendingTransaction penalizedTx) { + final var senderTxs = txsBySender.get(penalizedTx.getSender()); + if (senderTxs.firstKey() == penalizedTx.getNonce()) { + // since we only sort the first tx of sender, we only need to re-sort in this case + orderByMaxFee.remove(penalizedTx); + penalizedTx.decrementScore(); + orderByMaxFee.add(penalizedTx); + } else { + // otherwise we just decrement the score + penalizedTx.decrementScore(); + } + } + @Override protected void internalReplaced(final PendingTransaction replacedTx) { orderByMaxFee.remove(replacedTx); @@ -213,8 +227,8 @@ public class ReadyTransactions extends AbstractSequentialTransactionsLayer { return "Ready: Empty"; } - final Transaction top = orderByMaxFee.last().getTransaction(); - final Transaction last = orderByMaxFee.first().getTransaction(); + final PendingTransaction top = orderByMaxFee.last(); + final PendingTransaction last = orderByMaxFee.first(); return "Ready: " + "count=" @@ -223,12 +237,16 @@ public class ReadyTransactions extends AbstractSequentialTransactionsLayer { + spaceUsed + ", unique senders: " + txsBySender.size() - + ", top by max fee[max fee:" - + top.getMaxGasPrice().toHumanReadableString() + + ", top by score and max gas price[score: " + + top.getScore() + + ", max gas price:" + + top.getTransaction().getMaxGasPrice().toHumanReadableString() + ", hash: " + top.getHash() - + "], last by max fee [max fee: " - + last.getMaxGasPrice().toHumanReadableString() + + "], last by score and max gas price [score: " + + last.getScore() + + ", max fee: " + + last.getTransaction().getMaxGasPrice().toHumanReadableString() + ", hash: " + last.getHash() + "]"; 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 52f598ba71..aef318e6df 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 @@ -303,6 +303,11 @@ public class SparseTransactions extends AbstractTransactionsLayer { } } + @Override + protected void internalPenalize(final PendingTransaction penalizedTx) { + // intentionally no-op + } + private void deleteGap(final Address sender) { orderByGap.get(gapBySender.remove(sender)).remove(sender); } 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 d3c22aeef1..531add0af7 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 @@ -45,6 +45,19 @@ public interface TransactionsLayer { void remove(PendingTransaction pendingTransaction, RemovalReason reason); + /** + * Penalize a pending transaction. Penalization could be applied to notify the txpool that this + * pending tx has some temporary issues that prevent it from being included in a block, and so it + * should be de-prioritized in some ways, so it will be re-evaluated only after non penalized + * pending txs. For example: if during the evaluation for block inclusion, the pending tx is + * excluded because the sender has not enough balance to send it, this could be a transient issue + * since later the sender could receive some funds, but in any case we penalize the pending tx, so + * it is pushed down in the order of prioritized pending txs. + * + * @param penalizedTransaction the tx to penalize + */ + void penalize(PendingTransaction penalizedTransaction); + void blockAdded( FeeMarket feeMarket, BlockHeader blockHeader, diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/package-info.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/package-info.java index fbc9da9fe5..ff274ce4ea 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/package-info.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/package-info.java @@ -22,7 +22,8 @@ * transactions that could be selected for a future block proposal, and at the same time, without * penalizing legitimate unordered transactions, that are only temporary non-executable. * - *

It is disabled by default, to enable use the option {@code Xlayered-tx-pool=true} + *

It is enabled by default on public networks, to switch to another implementation use the + * option {@code tx-pool} * *

The main idea is to organize the txpool in an arbitrary number of layers, where each layer has * specific rules and constraints that determine if a transaction belong or not to that layer and @@ -38,6 +39,14 @@ * transactions are removed since confirmed in a block, transactions from the next layer are * promoted until there is space. * + *

Some layers could make use of the score of a pending transactions, to push back in the rank + * those pending transactions that have been penalized. + * + *

Layers are not thread safe, since they are not meant to be accessed directly, and all the + * synchronization is managed at the level of {@link + * org.hyperledger.besu.ethereum.eth.transactions.layered.LayeredPendingTransactions + * LayeredPendingTransactions} class. + * *

The current implementation is based on 3 layers, plus the last one that just drop every * transaction when the previous layers are full. The 3 layers are, in order: * @@ -48,20 +57,20 @@ * * *

Prioritized: This is where candidate transactions are selected for creating a new block. - * Transactions ordered by the effective priority fee, and it is limited by size, 2000 by default, - * to reduce the overhead of the sorting and because that number is enough to fill any block, at the - * current gas limit. Does not allow nonce gaps, and the first transaction for each sender must be - * the next one for that sender. Eviction is done removing the transaction with the higher nonce for - * the sender of the less valuable transaction, to avoid creating nonce gaps, evicted transactions - * go into the next layer Ready. + * Transactions ordered by score and then effective priority fee, and it is limited by size, 2000 by + * default, to reduce the overhead of the sorting and because that number is enough to fill any + * block, at the current gas limit. Does not allow nonce gaps, and the first transaction for each + * sender must be the next one for that sender. Eviction is done removing the transaction with the + * higher nonce for the sender of the less score and less effective priority fee transaction, to + * avoid creating nonce gaps, evicted transactions go into the next layer Ready. * *

Ready: Similar to the Prioritized, it does not allow nonce gaps, and the first transaction for * each sender must be the next one for that sender, but it is limited by space instead of count, * thus allowing many more transactions, think about this layer like a buffer for the Prioritized. * Since it is meant to keep ten to hundreds of thousand of transactions, it does not have a full * ordering, like the previous, but only the first transaction for each sender is ordered using a - * stable value that is the max fee per gas. Eviction is the same as the Prioritized, and evicted - * transaction go into the next layer Sparse. + * stable value that is score and then max fee per gas. Eviction is the same as the Prioritized, and + * evicted transaction go into the next layer Sparse. * *

Sparse: This is the first layer where nonce gaps are allowed and where the first transaction * for a sender could not be the next expected one for that sender. The main purpose of this layer 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 c5c2bdcf97..84ac759a79 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 @@ -159,6 +159,12 @@ public class LayersTest extends BaseTransactionPoolTest { assertScenario(scenario, BLOB_TX_POOL_CONFIG); } + @ParameterizedTest + @MethodSource("providerPenalized") + void penalized(final Scenario scenario) { + assertScenario(scenario); + } + private void assertScenario(final Scenario scenario) { assertScenario(scenario, DEFAULT_TX_POOL_CONFIG); } @@ -1256,6 +1262,79 @@ public class LayersTest extends BaseTransactionPoolTest { .expectedSparseForSenders())); } + static Stream providerPenalized() { + return Stream.of( + Arguments.of( + new Scenario("single sender, single tx") + .addForSender(S1, 0) + .expectedPrioritizedForSender(S1, 0) + .penalizeForSender(S1, 0) + .expectedPrioritizedForSender(S1, 0)), + Arguments.of( + new Scenario("single sender penalize last") + .addForSender(S1, 0, 1) + .expectedPrioritizedForSender(S1, 0, 1) + .penalizeForSender(S1, 1) + .expectedPrioritizedForSender(S1, 0, 1)), + Arguments.of( + new Scenario("single sender penalize first") + .addForSender(S1, 0, 1) + .expectedPrioritizedForSender(S1, 0, 1) + .penalizeForSender(S1, 0, 1) + // even if 0 has less score it is always the first for the sender + // since otherwise there is a nonce gap + .expectedPrioritizedForSender(S1, 0, 1)), + Arguments.of( + new Scenario("multiple senders, penalize top") + .addForSenders(S1, 0, S2, 0) + // remember S2 pays more fees + .expectedPrioritizedForSenders(S2, 0, S1, 0) + .penalizeForSender(S2, 0) + .expectedPrioritizedForSenders(S1, 0, S2, 0)), + Arguments.of( + new Scenario("multiple senders, penalize bottom") + .addForSenders(S1, 0, S2, 0) + .expectedPrioritizedForSenders(S2, 0, S1, 0) + .penalizeForSender(S1, 0) + .expectedPrioritizedForSenders(S2, 0, S1, 0)), + Arguments.of( + new Scenario("multiple senders, penalize middle") + .addForSenders(S1, 0, S2, 0, S3, 0) + .expectedPrioritizedForSenders(S3, 0, S2, 0, S1, 0) + .penalizeForSender(S2, 0) + .expectedPrioritizedForSenders(S3, 0, S1, 0, S2, 0)), + Arguments.of( + new Scenario("single sender, promote from ready") + .addForSender(S1, 0, 1, 2, 3, 4, 5) + .expectedPrioritizedForSender(S1, 0, 1, 2) + .expectedReadyForSender(S1, 3, 4, 5) + .penalizeForSender(S1, 3) + .confirmedForSenders(S1, 0) + // even if penalized 3 is promoted to avoid nonce gap + .expectedPrioritizedForSender(S1, 1, 2, 3) + .expectedReadyForSender(S1, 4, 5)), + Arguments.of( + new Scenario("multiple senders, overflow to ready") + .addForSenders(S1, 0, S2, 0, S3, 0) + .expectedPrioritizedForSenders(S3, 0, S2, 0, S1, 0) + .expectedReadyForSenders() + .penalizeForSender(S3, 0) + .addForSender(S1, 1) + .expectedPrioritizedForSenders(S2, 0, S1, 0, S1, 1) + // S3(0) is demoted to ready even if it is paying more fees, + // since has a lower score + .expectedReadyForSender(S3, 0)), + Arguments.of( + new Scenario("multiple senders, overflow to sparse") + .addForSenders(S1, 0, S2, 0, S3, 0, S1, 1, S2, 1, S3, 1) + .expectedPrioritizedForSenders(S3, 0, S3, 1, S2, 0) + .expectedReadyForSenders(S2, 1, S1, 0, S1, 1) + .penalizeForSender(S2, 1) + .addForSender(S2, 2) + .expectedReadyForSenders(S1, 0, S1, 1, S2, 1) + .expectedSparseForSender(S2, 2))); + } + private static BlockHeader mockBlockHeader() { final BlockHeader blockHeader = mock(BlockHeader.class); when(blockHeader.getBaseFee()).thenReturn(Optional.of(BASE_FEE)); @@ -1511,10 +1590,12 @@ public class LayersTest extends BaseTransactionPoolTest { private void assertExpectedPrioritized( final AbstractPrioritizedTransactions prioLayer, final List expected) { - assertThat(prioLayer.getBySender()) - .describedAs("Prioritized") - .flatExtracting(SenderPendingTransactions::pendingTransactions) - .containsExactlyElementsOf(expected); + final var flatOrder = + prioLayer.getByScore().values().stream() + .flatMap(List::stream) + .flatMap(spt -> spt.pendingTransactions().stream()) + .toList(); + assertThat(flatOrder).describedAs("Prioritized").containsExactlyElementsOf(expected); } private void assertExpectedReady( @@ -1582,6 +1663,23 @@ public class LayersTest extends BaseTransactionPoolTest { return this; } + public Scenario penalizeForSender(final Sender sender, final long... nonce) { + Arrays.stream(nonce) + .forEach( + n -> { + actions.add( + (pending, prio, ready, sparse, dropped) -> { + final var senderTxs = prio.getAllFor(sender.address); + Arrays.stream(nonce) + .mapToObj( + n2 -> senderTxs.stream().filter(pt -> pt.getNonce() == n2).findAny()) + .map(Optional::get) + .forEach(prio::penalize); + }); + }); + return this; + } + public Scenario expectedSelectedTransactions(final Object... args) { List expectedSelected = new ArrayList<>(); for (int i = 0; i < args.length; i = i + 2) { diff --git a/plugin-api/build.gradle b/plugin-api/build.gradle index 58c241509e..81e66a06a0 100644 --- a/plugin-api/build.gradle +++ b/plugin-api/build.gradle @@ -70,7 +70,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 = 'F07ix5Mkvycb2W2luprKmcMyrWcSLB4Xtou5Id10DW0=' + knownHash = '6L5dNJ975Ka/X7g4lTdpkBvPQrJgJu+vAf/m1dFCneU=' } check.dependsOn('checkAPIChanges') diff --git a/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/TransactionSelectionResult.java b/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/TransactionSelectionResult.java index b59fb26967..66b1c1f2d6 100644 --- a/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/TransactionSelectionResult.java +++ b/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/TransactionSelectionResult.java @@ -42,6 +42,13 @@ public class TransactionSelectionResult { */ boolean discard(); + /** + * Should the score of this transaction be decremented? + * + * @return yes if the score of this transaction needs to be decremented + */ + boolean penalize(); + /** * Name of this status * @@ -52,30 +59,34 @@ public class TransactionSelectionResult { private enum BaseStatus implements Status { SELECTED, - BLOCK_FULL(true, false), - BLOBS_FULL(false, false), - BLOCK_OCCUPANCY_ABOVE_THRESHOLD(true, false), - BLOCK_SELECTION_TIMEOUT(true, false), - TX_EVALUATION_TOO_LONG(true, true), - INVALID_TRANSIENT(false, false), - INVALID(false, true); + BLOCK_FULL(true, false, false), + BLOBS_FULL(false, false, false), + BLOCK_OCCUPANCY_ABOVE_THRESHOLD(true, false, false), + BLOCK_SELECTION_TIMEOUT(true, false, false), + TX_EVALUATION_TOO_LONG(true, false, true), + INVALID_TX_EVALUATION_TOO_LONG(true, true, true), + INVALID_TRANSIENT(false, false, true), + INVALID(false, true, false); private final boolean stop; private final boolean discard; + private final boolean penalize; BaseStatus() { this.stop = false; this.discard = false; + this.penalize = false; } - BaseStatus(final boolean stop, final boolean discard) { + BaseStatus(final boolean stop, final boolean discard, final boolean penalize) { this.stop = stop; this.discard = discard; + this.penalize = penalize; } @Override public String toString() { - return name() + " (stop=" + stop + ", discard=" + discard + ")"; + return name() + " (stop=" + stop + ", discard=" + discard + ", penalize=" + penalize + ")"; } @Override @@ -87,6 +98,11 @@ public class TransactionSelectionResult { public boolean discard() { return discard; } + + @Override + public boolean penalize() { + return penalize; + } } /** The transaction has been selected to be included in the new block */ @@ -105,10 +121,14 @@ public class TransactionSelectionResult { public static final TransactionSelectionResult BLOCK_SELECTION_TIMEOUT = new TransactionSelectionResult(BaseStatus.BLOCK_SELECTION_TIMEOUT); - /** Transaction took too much to evaluate */ + /** Transaction took too much to evaluate, but it was not invalid */ public static final TransactionSelectionResult TX_EVALUATION_TOO_LONG = new TransactionSelectionResult(BaseStatus.TX_EVALUATION_TOO_LONG); + /** Transaction took too much to evaluate, and it was invalid */ + public static final TransactionSelectionResult INVALID_TX_EVALUATION_TOO_LONG = + new TransactionSelectionResult(BaseStatus.INVALID_TX_EVALUATION_TOO_LONG); + /** * The transaction has not been selected since too large and the occupancy of the block is enough * to stop the selection. @@ -215,6 +235,15 @@ public class TransactionSelectionResult { return status.discard(); } + /** + * Should the score of this transaction be decremented? + * + * @return yes if the score of this transaction needs to be decremented + */ + public boolean penalize() { + return status.penalize(); + } + /** * Is the candidate transaction selected for block inclusion? * From cf358c0e7ae222428029f6ae93c09a56c1529d5f Mon Sep 17 00:00:00 2001 From: Gaurav Ahuja Date: Fri, 26 Jul 2024 03:50:05 +0530 Subject: [PATCH 061/259] Update GeneralStateTestCaseEipSpec for use in linea-arithmetization (#7377) * Update GeneralStateTestCaseEipSpec for use in linea-arithmetization Signed-off-by: Gaurav Ahuja * formatting Signed-off-by: Sally MacFarlane --------- Signed-off-by: Gaurav Ahuja Signed-off-by: Sally MacFarlane Co-authored-by: Sally MacFarlane --- .../besu/evmtool/StateTestSubCommand.java | 2 +- .../GeneralStateTestCaseEipSpec.java | 15 ++++++++++----- .../referencetests/GeneralStateTestCaseSpec.java | 5 +++-- .../vm/GeneralStateReferenceTestTools.java | 2 +- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/StateTestSubCommand.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/StateTestSubCommand.java index 064a093e84..40f36f18f1 100644 --- a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/StateTestSubCommand.java +++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/StateTestSubCommand.java @@ -232,7 +232,7 @@ public class StateTestSubCommand implements Runnable { } final BlockHeader blockHeader = spec.getBlockHeader(); - final Transaction transaction = spec.getTransaction(); + final Transaction transaction = spec.getTransaction(0); final ObjectNode summaryLine = objectMapper.createObjectNode(); if (transaction == null) { if (parentCommand.showJsonAlloc || parentCommand.showJsonResults) { diff --git a/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/GeneralStateTestCaseEipSpec.java b/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/GeneralStateTestCaseEipSpec.java index d9ed46c336..ddf6ac2eb1 100644 --- a/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/GeneralStateTestCaseEipSpec.java +++ b/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/GeneralStateTestCaseEipSpec.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.Transaction; +import java.util.List; import java.util.function.Supplier; public class GeneralStateTestCaseEipSpec { @@ -33,7 +34,7 @@ public class GeneralStateTestCaseEipSpec { // anything // is run, which isn't friendly and 2) this makes it harder to parallelize this step. Anyway, this // is why this is a supplier: calling get() actually does the signing. - private final Supplier transactionSupplier; + private final List> transactionSuppliers; private final ReferenceTestWorldState initialWorldState; @@ -51,7 +52,7 @@ public class GeneralStateTestCaseEipSpec { GeneralStateTestCaseEipSpec( final String fork, - final Supplier transactionSupplier, + final List> transactionSuppliers, final ReferenceTestWorldState initialWorldState, final Hash expectedRootHash, final Hash expectedLogsHash, @@ -61,7 +62,7 @@ public class GeneralStateTestCaseEipSpec { final int valueIndex, final String expectException) { this.fork = fork; - this.transactionSupplier = transactionSupplier; + this.transactionSuppliers = transactionSuppliers; this.initialWorldState = initialWorldState; this.expectedRootHash = expectedRootHash; this.expectedLogsHash = expectedLogsHash; @@ -88,9 +89,13 @@ public class GeneralStateTestCaseEipSpec { return expectedLogsHash; } - public Transaction getTransaction() { + public int getTransactionsCount() { + return transactionSuppliers.size(); + } + + public Transaction getTransaction(final int txIndex) { try { - return transactionSupplier.get(); + return transactionSuppliers.get(txIndex).get(); } catch (RuntimeException re) { // some tests specify invalid transactions. We throw exceptions in // GeneralStateTests but they are encoded in BlockchainTests, so we diff --git a/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/GeneralStateTestCaseSpec.java b/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/GeneralStateTestCaseSpec.java index affc6e4601..394cb9a269 100644 --- a/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/GeneralStateTestCaseSpec.java +++ b/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/GeneralStateTestCaseSpec.java @@ -72,11 +72,12 @@ public class GeneralStateTestCaseSpec { .stateRoot(p.rootHash) .blockHeaderFunctions(MAINNET_FUNCTIONS) .buildBlockHeader(); - final Supplier txSupplier = () -> versionedTransaction.get(p.indexes); + final List> txSupplierList = + List.of(() -> versionedTransaction.get(p.indexes)); specs.add( new GeneralStateTestCaseEipSpec( eip, - txSupplier, + txSupplierList, initialWorldState, p.rootHash, p.logsHash, diff --git a/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/vm/GeneralStateReferenceTestTools.java b/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/vm/GeneralStateReferenceTestTools.java index f948a5b24e..18d574adc1 100644 --- a/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/vm/GeneralStateReferenceTestTools.java +++ b/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/vm/GeneralStateReferenceTestTools.java @@ -120,7 +120,7 @@ public class GeneralStateReferenceTestTools { public static void executeTest(final GeneralStateTestCaseEipSpec spec) { final BlockHeader blockHeader = spec.getBlockHeader(); final ReferenceTestWorldState initialWorldState = spec.getInitialWorldState(); - final Transaction transaction = spec.getTransaction(); + final Transaction transaction = spec.getTransaction(0); ProtocolSpec protocolSpec = protocolSpec(spec.getFork()); BlockchainReferenceTestTools.verifyJournaledEVMAccountCompatability(initialWorldState, protocolSpec); From c182ba113ac35632ac0983c79c6a1ba011fb231e Mon Sep 17 00:00:00 2001 From: garyschulte Date: Thu, 25 Jul 2024 15:41:45 -0700 Subject: [PATCH 062/259] bump execution-spec-tests, account for new name for main stable artifact (#7380) Signed-off-by: garyschulte --- ethereum/referencetests/build.gradle | 2 +- gradle/verification-metadata.xml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ethereum/referencetests/build.gradle b/ethereum/referencetests/build.gradle index 3c073136ac..426c1084db 100644 --- a/ethereum/referencetests/build.gradle +++ b/ethereum/referencetests/build.gradle @@ -204,7 +204,7 @@ dependencies { referenceTestImplementation project(path: ':testutil') referenceTestImplementation project(path: ':util') // the following will be resolved via custom ivy repository declared in root build.gradle - referenceTestImplementation 'ethereum:execution-spec-tests:2.1.1:fixtures@tar.gz' + referenceTestImplementation 'ethereum:execution-spec-tests:3.0.0:fixtures_stable@tar.gz' referenceTestImplementation 'com.fasterxml.jackson.core:jackson-databind' referenceTestImplementation 'com.google.guava:guava' referenceTestImplementation 'io.tmio:tuweni-bytes' diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index 7cdf7ce080..950e0ee866 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -1385,9 +1385,9 @@ - - - + + + From 4a670a1dbe1da35f31fce75d1e760f195a5b1059 Mon Sep 17 00:00:00 2001 From: Simon Dudley Date: Fri, 26 Jul 2024 09:16:49 +1000 Subject: [PATCH 063/259] Disable bonsai-limit-trie-logs-enabled if sync-mode=FULL (#7357) There is still a startup error when bonsai-limit-trie-logs-enabled is explicitly set to true --------- Signed-off-by: Simon Dudley --- CHANGELOG.md | 3 +- .../org/hyperledger/besu/cli/BesuCommand.java | 29 ++++++++++++++++++- .../options/stable/DataStorageOptions.java | 16 ++-------- .../hyperledger/besu/cli/BesuCommandTest.java | 26 +++++++++++++++-- .../stable/DataStorageOptionsTest.java | 8 ----- 5 files changed, 57 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b999bca71..c5754da1c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,12 +23,13 @@ - Added EIP-7702 [#7237](https://github.com/hyperledger/besu/pull/7237) - Implement gnark-crypto for eip-196 [#7262](https://github.com/hyperledger/besu/pull/7262) - Add trie log pruner metrics [#7352](https://github.com/hyperledger/besu/pull/7352) +- Force bonsai-limit-trie-logs-enabled=false when sync-mode=FULL instead of startup error [#7357](https://github.com/hyperledger/besu/pull/7357) - `--Xbonsai-parallel-tx-processing-enabled` option enables executing transactions in parallel during block processing for Bonsai nodes - - Add option `--poa-discovery-retry-bootnodes` for PoA networks to always use bootnodes during peer refresh, not just on first start [#7314](https://github.com/hyperledger/besu/pull/7314) ### Bug fixes - Fix `eth_call` deserialization to correctly ignore unknown fields in the transaction object. [#7323](https://github.com/hyperledger/besu/pull/7323) +- Prevent Besu from starting up with sync-mode=FULL and bonsai-limit-trie-logs-enabled=true for private networks [#7357](https://github.com/hyperledger/besu/pull/7357) - Avoid executing pruner preload during trie log subcommands [#7366](https://github.com/hyperledger/besu/pull/7366) ## 24.7.0 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 1eaab20bd2..d300fbea45 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java @@ -139,6 +139,7 @@ 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.ImmutableDataStorageConfiguration; import org.hyperledger.besu.evm.precompile.AbstractAltBnPrecompiledContract; import org.hyperledger.besu.evm.precompile.BigIntegerModularExponentiationPrecompiledContract; import org.hyperledger.besu.evm.precompile.KZGPointEvalPrecompiledContract; @@ -1587,7 +1588,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { } private void validateDataStorageOptions() { - dataStorageOptions.validate(commandLine, syncMode); + dataStorageOptions.validate(commandLine); } private void validateRequiredOptions() { @@ -2255,6 +2256,32 @@ public class BesuCommand implements DefaultCommandValues, Runnable { if (dataStorageConfiguration == null) { dataStorageConfiguration = dataStorageOptions.toDomainObject(); } + + if (SyncMode.FULL.equals(getDefaultSyncModeIfNotSet()) + && DataStorageFormat.BONSAI.equals(dataStorageConfiguration.getDataStorageFormat()) + && dataStorageConfiguration.getBonsaiLimitTrieLogsEnabled()) { + + 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) + .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; } 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 index fc92a7e5dd..a0403c3942 100644 --- 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 @@ -24,7 +24,6 @@ import static org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration. import org.hyperledger.besu.cli.options.CLIOptions; import org.hyperledger.besu.cli.util.CommandLineUtils; -import org.hyperledger.besu.ethereum.eth.sync.SyncMode; import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; import org.hyperledger.besu.ethereum.worldstate.ImmutableDataStorageConfiguration; import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; @@ -63,7 +62,8 @@ public class DataStorageOptions implements CLIOptions arity = "1") private Long bonsaiMaxLayersToLoad = DEFAULT_BONSAI_MAX_LAYERS_TO_LOAD; - private static final String BONSAI_LIMIT_TRIE_LOGS_ENABLED = "--bonsai-limit-trie-logs-enabled"; + /** 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 = @@ -147,20 +147,10 @@ public class DataStorageOptions implements CLIOptions * Validates the data storage options * * @param commandLine the full commandLine to check all the options specified by the user - * @param syncMode the sync mode */ - public void validate(final CommandLine commandLine, final SyncMode syncMode) { + public void validate(final CommandLine commandLine) { if (DataStorageFormat.BONSAI == dataStorageFormat) { if (bonsaiLimitTrieLogsEnabled) { - if (SyncMode.FULL == syncMode) { - throw new CommandLine.ParameterException( - commandLine, - String.format( - "Cannot enable %s with sync-mode %s. You must set %s or use a different sync-mode", - BONSAI_LIMIT_TRIE_LOGS_ENABLED, - SyncMode.FULL, - BONSAI_LIMIT_TRIE_LOGS_ENABLED + "=false")); - } if (bonsaiMaxLayersToLoad < MINIMUM_BONSAI_TRIE_LOG_RETENTION_LIMIT) { throw new CommandLine.ParameterException( commandLine, 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 c892ffe7fe..d0c42f6718 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java @@ -65,6 +65,7 @@ import org.hyperledger.besu.evm.precompile.KZGPointEvalPrecompiledContract; import org.hyperledger.besu.metrics.StandardMetricCategory; import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration; import org.hyperledger.besu.plugin.data.EnodeURL; +import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; import org.hyperledger.besu.util.number.Fraction; import org.hyperledger.besu.util.number.Percentage; import org.hyperledger.besu.util.number.PositiveNumber; @@ -1303,13 +1304,34 @@ public class BesuCommandTest extends CommandTestAbstract { } @Test - public void parsesInvalidDefaultBonsaiLimitTrieLogsWhenFullSyncEnabled() { + public void bonsaiLimitTrieLogsDisabledWhenFullSyncEnabled() { parseCommand("--sync-mode=FULL"); + verify(mockControllerBuilder) + .dataStorageConfiguration(dataStorageConfigurationArgumentCaptor.capture()); + + final DataStorageConfiguration dataStorageConfiguration = + dataStorageConfigurationArgumentCaptor.getValue(); + assertThat(dataStorageConfiguration.getDataStorageFormat()).isEqualTo(BONSAI); + assertThat(dataStorageConfiguration.getBonsaiLimitTrieLogsEnabled()).isFalse(); + verify(mockLogger) + .warn( + "Forcing {}, since it cannot be enabled with --sync-mode={} and --data-storage-format={}.", + "--bonsai-limit-trie-logs-enabled=false", + SyncMode.FULL, + DataStorageFormat.BONSAI); + assertThat(commandErrorOutput.toString(UTF_8)).isEmpty(); + } + + @Test + public void parsesInvalidWhenFullSyncAndBonsaiLimitTrieLogsExplicitlyTrue() { + parseCommand("--sync-mode=FULL", "--bonsai-limit-trie-logs-enabled=true"); + Mockito.verifyNoInteractions(mockRunnerBuilder); assertThat(commandOutput.toString(UTF_8)).isEmpty(); assertThat(commandErrorOutput.toString(UTF_8)) - .contains("Cannot enable --bonsai-limit-trie-logs-enabled with sync-mode FULL"); + .contains( + "Cannot enable --bonsai-limit-trie-logs-enabled with --sync-mode=FULL and --data-storage-format=BONSAI. You must set --bonsai-limit-trie-logs-enabled=false or use a different sync-mode"); } @Test 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 5ab2757f88..2086381825 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 @@ -55,14 +55,6 @@ public class DataStorageOptionsTest "--bonsai-limit-trie-logs-enabled=false"); } - @Test - public void bonsaiTrieLogPruningWindowSizeShouldBePositive2() { - internalTestFailure( - "Cannot enable --bonsai-limit-trie-logs-enabled with sync-mode FULL. You must set --bonsai-limit-trie-logs-enabled=false or use a different sync-mode", - "--sync-mode", - "FULL"); - } - @Test public void bonsaiTrieLogPruningWindowSizeShouldBePositive() { internalTestFailure( From a1efd211572b36f345eea985390a0a888d20806e Mon Sep 17 00:00:00 2001 From: Matt Whitehead Date: Fri, 26 Jul 2024 01:10:23 +0100 Subject: [PATCH 064/259] Do not maintain connections to bootnodes (#7358) * Do not maintain connections to bootnodes Signed-off-by: Matthew Whitehead * Update changelog entry Signed-off-by: Matthew Whitehead --------- Signed-off-by: Matthew Whitehead Co-authored-by: Stefan Pingel <16143240+pinges@users.noreply.github.com> --- CHANGELOG.md | 1 + .../java/org/hyperledger/besu/RunnerBuilder.java | 15 +-------------- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c5754da1c9..813cf6804b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ ### Breaking Changes - Remove deprecated sync modes (X_SNAP and X_CHECKPOINT). Use SNAP and CHECKPOINT instead [#7309](https://github.com/hyperledger/besu/pull/7309) - Remove PKI-backed QBFT (deprecated in 24.5.1) Other forms of QBFT remain unchanged. [#7293](https://github.com/hyperledger/besu/pull/7293) +- Do not maintain connections to PoA bootnodes [#7358](https://github.com/hyperledger/besu/pull/7358). See [#7314](https://github.com/hyperledger/besu/pull/7314) for recommended alternative behaviour. ### Additions and Improvements - `--Xsnapsync-bft-enabled` option enables experimental support for snap sync with IBFT/QBFT permissioned Bonsai-DB chains [#7140](https://github.com/hyperledger/besu/pull/7140) diff --git a/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java b/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java index dfd09165b7..d0c434fc81 100644 --- a/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java @@ -807,20 +807,7 @@ public class RunnerBuilder { LOG.debug("added ethash observer: {}", stratumServer.get()); } - final Stream maintainedPeers; - if (besuController.getGenesisConfigOptions().isPoa()) { - // In a permissioned chain Besu should maintain connections to both static nodes and - // bootnodes, which includes retries periodically - maintainedPeers = - sanitizePeers( - network, - Stream.concat(staticNodes.stream(), bootnodes.stream()).collect(Collectors.toList())); - LOG.debug("Added bootnodes to the maintained peer list"); - } else { - // In a public chain only maintain connections to static nodes - maintainedPeers = sanitizePeers(network, staticNodes); - } - maintainedPeers + sanitizePeers(network, staticNodes) .map(DefaultPeer::fromEnodeURL) .forEach(peerNetwork::addMaintainedConnectionPeer); From 51bb6c786e293b046a8372d9d311e0ba00e72bca Mon Sep 17 00:00:00 2001 From: Simon Dudley Date: Fri, 26 Jul 2024 12:17:08 +1000 Subject: [PATCH 065/259] TrieLogPruner preload with 30 second timeout (#7365) Also reduce pruning window from 30_000 to 5_000 --------- Signed-off-by: Simon Dudley Co-authored-by: Sally MacFarlane --- CHANGELOG.md | 2 + .../common/trielog/TrieLogPruner.java | 71 ++++++++++++++++--- .../worldstate/DataStorageConfiguration.java | 2 +- 3 files changed, 64 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 813cf6804b..4d3f9eb401 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,11 +26,13 @@ - Add trie log pruner metrics [#7352](https://github.com/hyperledger/besu/pull/7352) - Force bonsai-limit-trie-logs-enabled=false when sync-mode=FULL instead of startup error [#7357](https://github.com/hyperledger/besu/pull/7357) - `--Xbonsai-parallel-tx-processing-enabled` option enables executing transactions in parallel during block processing for Bonsai nodes +- Reduce default trie log pruning window size from 30,000 to 5,000 [#7365](https://github.com/hyperledger/besu/pull/7365) - Add option `--poa-discovery-retry-bootnodes` for PoA networks to always use bootnodes during peer refresh, not just on first start [#7314](https://github.com/hyperledger/besu/pull/7314) ### Bug fixes - Fix `eth_call` deserialization to correctly ignore unknown fields in the transaction object. [#7323](https://github.com/hyperledger/besu/pull/7323) - Prevent Besu from starting up with sync-mode=FULL and bonsai-limit-trie-logs-enabled=true for private networks [#7357](https://github.com/hyperledger/besu/pull/7357) +- Add 30 second timeout to trie log pruner preload [#7365](https://github.com/hyperledger/besu/pull/7365) - Avoid executing pruner preload during trie log subcommands [#7366](https://github.com/hyperledger/besu/pull/7366) ## 24.7.0 diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/trielog/TrieLogPruner.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/trielog/TrieLogPruner.java index cea5c1a327..98bc4246eb 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/trielog/TrieLogPruner.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/trielog/TrieLogPruner.java @@ -26,6 +26,12 @@ import org.hyperledger.besu.plugin.services.trielogs.TrieLogEvent; import java.util.Comparator; import java.util.Optional; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; import java.util.function.Consumer; import java.util.stream.Stream; @@ -40,6 +46,7 @@ import org.slf4j.LoggerFactory; public class TrieLogPruner implements TrieLogEvent.TrieLogObserver { private static final Logger LOG = LoggerFactory.getLogger(TrieLogPruner.class); + private static final int PRELOAD_TIMEOUT_IN_SECONDS = 30; private final int pruningLimit; private final int loadingLimit; @@ -83,25 +90,60 @@ public class TrieLogPruner implements TrieLogEvent.TrieLogObserver { BesuMetricCategory.PRUNER, "trie_log_pruned_orphan", "trie log pruned orphan"); } - public int initialize() { - return preloadQueue(); + public void initialize() { + preloadQueueWithTimeout(); } - private int preloadQueue() { + private void preloadQueueWithTimeout() { + LOG.atInfo() - .setMessage("Loading first {} trie logs from database...") + .setMessage("Attempting to load first {} trie logs from database...") .addArgument(loadingLimit) .log(); + + try (final ScheduledExecutorService preloadExecutor = Executors.newScheduledThreadPool(1)) { + + final AtomicBoolean timeoutOccurred = new AtomicBoolean(false); + final Runnable timeoutTask = + () -> { + timeoutOccurred.set(true); + LOG.atWarn() + .setMessage( + "Timeout occurred while loading and processing {} trie logs from database") + .addArgument(loadingLimit) + .log(); + }; + + final ScheduledFuture timeoutFuture = + preloadExecutor.schedule(timeoutTask, PRELOAD_TIMEOUT_IN_SECONDS, TimeUnit.SECONDS); + LOG.atInfo() + .setMessage( + "Trie log pruning will timeout after {} seconds. If this is timing out, consider using `besu storage trie-log prune` subcommand, see https://besu.hyperledger.org/public-networks/how-to/bonsai-limit-trie-logs") + .addArgument(PRELOAD_TIMEOUT_IN_SECONDS) + .log(); + + preloadQueue(timeoutOccurred, timeoutFuture); + } + } + + private void preloadQueue( + final AtomicBoolean timeoutOccurred, final ScheduledFuture timeoutFuture) { + try (final Stream trieLogKeys = rootWorldStateStorage.streamTrieLogKeys(loadingLimit)) { - final AtomicLong count = new AtomicLong(); + + final AtomicLong addToPruneQueueCount = new AtomicLong(); final AtomicLong orphansPruned = new AtomicLong(); trieLogKeys.forEach( blockHashAsBytes -> { + if (timeoutOccurred.get()) { + throw new RuntimeException( + new TimeoutException("Timeout occurred while preloading trie log prune queue")); + } final Hash blockHash = Hash.wrap(Bytes32.wrap(blockHashAsBytes)); final Optional header = blockchain.getBlockHeader(blockHash); if (header.isPresent()) { addToPruneQueue(header.get().getNumber(), blockHash); - count.getAndIncrement(); + addToPruneQueueCount.getAndIncrement(); } else { // prune orphaned blocks (sometimes created during block production) rootWorldStateStorage.pruneTrieLog(blockHash); @@ -109,12 +151,21 @@ public class TrieLogPruner implements TrieLogEvent.TrieLogObserver { prunedOrphanCounter.inc(); } }); + + timeoutFuture.cancel(true); LOG.atDebug().log("Pruned {} orphaned trie logs from database...", orphansPruned.intValue()); - LOG.atInfo().log("Loaded {} trie logs from database", count); - return pruneFromQueue() + orphansPruned.intValue(); + LOG.atInfo().log( + "Added {} trie logs to prune queue. Commencing pruning of eligible trie logs...", + addToPruneQueueCount.intValue()); + int prunedCount = pruneFromQueue(); + LOG.atInfo().log("Pruned {} trie logs.", prunedCount); } catch (Exception e) { - LOG.error("Error loading trie logs from database, nothing pruned", e); - return 0; + if (e.getCause() != null && e.getCause() instanceof TimeoutException) { + int prunedCount = pruneFromQueue(); + LOG.atInfo().log("Operation timed out, but still pruned {} trie logs.", prunedCount); + } else { + LOG.error("Error loading trie logs from database, nothing pruned", e); + } } } 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 615b5bad6e..8d767f442a 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 @@ -25,7 +25,7 @@ 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 = 30_000; + int DEFAULT_BONSAI_TRIE_LOG_PRUNING_WINDOW_SIZE = 5_000; boolean DEFAULT_RECEIPT_COMPACTION_ENABLED = false; DataStorageConfiguration DEFAULT_CONFIG = From d6f8645ae521a85f22f964f1a8bbe861717fe68a Mon Sep 17 00:00:00 2001 From: Jason Frame Date: Mon, 29 Jul 2024 08:58:03 +1000 Subject: [PATCH 066/259] Snap server GetTrieNodes to return empty bytes when trienode doesn't exist (#7305) Signed-off-by: Jason Frame --- .../ethereum/eth/manager/snap/SnapServer.java | 32 +++++++++---------- .../eth/manager/snap/SnapServerTest.java | 23 +++++++++++-- 2 files changed, 36 insertions(+), 19 deletions(-) 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 d6bfe900d9..cb92941e5b 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 @@ -518,15 +518,13 @@ class SnapServer implements BesuEvents.InitialSyncCompletionListener { if (optStorage.isEmpty() && location.isEmpty()) { optStorage = Optional.of(MerkleTrie.EMPTY_TRIE_NODE); } - if (optStorage.isPresent()) { - if (!trieNodes.isEmpty() - && (sumListBytes(trieNodes) + optStorage.get().size() > maxResponseBytes - || stopWatch.getTime() > StatefulPredicate.MAX_MILLIS_PER_REQUEST)) { - break; - } - trieNodes.add(optStorage.get()); + var trieNode = optStorage.orElse(Bytes.EMPTY); + if (!trieNodes.isEmpty() + && (sumListBytes(trieNodes) + trieNode.size() > maxResponseBytes + || stopWatch.getTime() > StatefulPredicate.MAX_MILLIS_PER_REQUEST)) { + break; } - + trieNodes.add(trieNode); } else { // There must be at least one element in the path otherwise it is invalid if (triePath.isEmpty()) { @@ -537,7 +535,11 @@ class SnapServer implements BesuEvents.InitialSyncCompletionListener { // otherwise the first element should be account hash, and subsequent paths // are compact encoded account storage paths - final Bytes accountPrefix = Bytes32.leftPad(triePath.getFirst()); + final Bytes32 accountPrefix = Bytes32.leftPad(triePath.getFirst()); + var optAccount = storage.getAccount(Hash.wrap(accountPrefix)); + if (optAccount.isEmpty()) { + continue; + } List storagePaths = triePath.subList(1, triePath.size()); for (var path : storagePaths) { @@ -547,14 +549,12 @@ class SnapServer implements BesuEvents.InitialSyncCompletionListener { if (optStorage.isEmpty() && location.isEmpty()) { optStorage = Optional.of(MerkleTrie.EMPTY_TRIE_NODE); } - if (optStorage.isPresent()) { - if (!trieNodes.isEmpty() - && sumListBytes(trieNodes) + optStorage.get().size() - > maxResponseBytes) { - break; - } - trieNodes.add(optStorage.get()); + var trieNode = optStorage.orElse(Bytes.EMPTY); + if (!trieNodes.isEmpty() + && sumListBytes(trieNodes) + trieNode.size() > maxResponseBytes) { + break; } + trieNodes.add(trieNode); } } } 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 2103af4124..e252fe0335 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 @@ -531,7 +531,25 @@ public class SnapServerTest { assertThat(trieNodeRequest).isNotNull(); List trieNodes = trieNodeRequest.nodes(false); assertThat(trieNodes).isNotNull(); - assertThat(trieNodes.size()).isEqualTo(4); + assertThat(trieNodes.size()).isEqualTo(6); + assertThat(trieNodes.get(2)).isEqualTo(Bytes.EMPTY); + assertThat(trieNodes.get(5)).isEqualTo(Bytes.EMPTY); + } + + @Test + public void assertStorageTriePathRequest_accountNotPresent() { + insertTestAccounts(acct4); + var pathToSlot11 = CompactEncoding.encode(Bytes.fromHexStringLenient("0x0101")); + var trieNodeRequest = + requestTrieNodes( + storageTrie.getRootHash(), + List.of( + List.of(acct3.addressHash, pathToSlot11) // account not present + )); + assertThat(trieNodeRequest).isNotNull(); + List trieNodes = trieNodeRequest.nodes(false); + assertThat(trieNodes).isNotNull(); + assertThat(trieNodes.size()).isEqualTo(0); } @Test @@ -582,8 +600,7 @@ public class SnapServerTest { assertThat(trieNodeRequest).isNotNull(); List trieNodes = trieNodeRequest.nodes(false); assertThat(trieNodes).isNotNull(); - // TODO: adjust this assertion after sorting out the request fudge factor - assertThat(trieNodes.size()).isEqualTo(trieNodeLimit * 90 / 100); + assertThat(trieNodes.size()).isEqualTo(3); } @Test From f8edb7332cb6881735867534064fb50349dc7588 Mon Sep 17 00:00:00 2001 From: Simon Dudley Date: Mon, 29 Jul 2024 09:36:17 +1000 Subject: [PATCH 067/259] Rotate changelog for 24.7.1 (#7385) Signed-off-by: Simon Dudley --- CHANGELOG.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d3f9eb401..04e0f76e4a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,11 +8,25 @@ - --Xbonsai-trie-logs-pruning-window-size is deprecated, use --bonsai-trie-logs-pruning-window-size instead - `besu storage x-trie-log` subcommand is deprecated, use `besu storage trie-log` instead +### Breaking Changes + +### Additions and Improvements + +### Bug fixes + +## 24.7.1 + ### Breaking Changes - Remove deprecated sync modes (X_SNAP and X_CHECKPOINT). Use SNAP and CHECKPOINT instead [#7309](https://github.com/hyperledger/besu/pull/7309) - Remove PKI-backed QBFT (deprecated in 24.5.1) Other forms of QBFT remain unchanged. [#7293](https://github.com/hyperledger/besu/pull/7293) - Do not maintain connections to PoA bootnodes [#7358](https://github.com/hyperledger/besu/pull/7358). See [#7314](https://github.com/hyperledger/besu/pull/7314) for recommended alternative behaviour. +### Upcoming Breaking Changes +- Receipt compaction will be enabled by default in a future version of Besu. After this change it will not be possible to downgrade to the previous Besu version. +- --Xbonsai-limit-trie-logs-enabled is deprecated, use --bonsai-limit-trie-logs-enabled instead +- --Xbonsai-trie-logs-pruning-window-size is deprecated, use --bonsai-trie-logs-pruning-window-size instead +- `besu storage x-trie-log` subcommand is deprecated, use `besu storage trie-log` instead + ### Additions and Improvements - `--Xsnapsync-bft-enabled` option enables experimental support for snap sync with IBFT/QBFT permissioned Bonsai-DB chains [#7140](https://github.com/hyperledger/besu/pull/7140) - Add support to load external profiles using `--profile` [#7265](https://github.com/hyperledger/besu/issues/7265) From 94b497e261ca87c1811bf4d9f13bf81bdb1787f3 Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Mon, 29 Jul 2024 16:19:11 +1000 Subject: [PATCH 068/259] 7288: include WithdrawalRequestPredeployAddress in genesis configuration (#7356) * 7288: include WithdrawalRequestPredeployAddress in genesis configuration Signed-off-by: Matilda Clerke * 7288: Update changelog Signed-off-by: Matilda Clerke * 7288: Fix typo in new variable Signed-off-by: Matilda Clerke * 7288: Rename withdrawalRequestPredeployAddress to withdrawalRequestContractAddress Signed-off-by: Matilda Clerke * 7288: Update changelog to match recent changes Signed-off-by: Matilda Clerke * 5098: Move changelog item to next release Signed-off-by: Matilda Clerke --------- Signed-off-by: Matilda Clerke Signed-off-by: Matilda-Clerke --- CHANGELOG.md | 1 + .../besu/config/GenesisConfigOptions.java | 7 +++++ .../besu/config/JsonGenesisConfigOptions.java | 11 ++++++++ .../besu/config/StubGenesisConfigOptions.java | 5 ++++ .../besu/config/GenesisConfigOptionsTest.java | 26 +++++++++++++++++++ .../mainnet/MainnetProtocolSpecs.java | 8 +++++- .../requests/MainnetRequestsValidator.java | 6 +++-- .../requests/WithdrawalRequestProcessor.java | 10 +++++-- 8 files changed, 69 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 04e0f76e4a..072a84c2ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ - --Xbonsai-limit-trie-logs-enabled is deprecated, use --bonsai-limit-trie-logs-enabled instead - --Xbonsai-trie-logs-pruning-window-size is deprecated, use --bonsai-trie-logs-pruning-window-size instead - `besu storage x-trie-log` subcommand is deprecated, use `besu storage trie-log` instead +- Allow configuration of Withdrawal Request Contract Address via genesis configuration [#7356](https://github.com/hyperledger/besu/pull/7356) ### Breaking Changes 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 849b121186..d6323ee9bf 100644 --- a/config/src/main/java/org/hyperledger/besu/config/GenesisConfigOptions.java +++ b/config/src/main/java/org/hyperledger/besu/config/GenesisConfigOptions.java @@ -525,6 +525,13 @@ public interface GenesisConfigOptions { */ boolean isFixedBaseFee(); + /** + * The withdrawal request predeploy address + * + * @return the withdrawal request predeploy address + */ + Optional

getWithdrawalRequestContractAddress(); + /** * The deposit contract address that should be in the logger field in Receipt of Deposit * transaction 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 b418a67851..67114b29bf 100644 --- a/config/src/main/java/org/hyperledger/besu/config/JsonGenesisConfigOptions.java +++ b/config/src/main/java/org/hyperledger/besu/config/JsonGenesisConfigOptions.java @@ -49,6 +49,8 @@ public class JsonGenesisConfigOptions implements GenesisConfigOptions { private static final String CHECKPOINT_CONFIG_KEY = "checkpoint"; private static final String ZERO_BASE_FEE_KEY = "zerobasefee"; private static final String FIXED_BASE_FEE_KEY = "fixedbasefee"; + private static final String WITHDRAWAL_REQUEST_CONTRACT_ADDRESS_KEY = + "withdrawalrequestcontractaddress"; private static final String DEPOSIT_CONTRACT_ADDRESS_KEY = "depositcontractaddress"; private final ObjectNode configRoot; @@ -438,6 +440,13 @@ public class JsonGenesisConfigOptions implements GenesisConfigOptions { return getOptionalBoolean(FIXED_BASE_FEE_KEY).orElse(false); } + @Override + public Optional
getWithdrawalRequestContractAddress() { + Optional inputAddress = + JsonUtil.getString(configRoot, WITHDRAWAL_REQUEST_CONTRACT_ADDRESS_KEY); + return inputAddress.map(Address::fromHexString); + } + @Override public Optional
getDepositContractAddress() { Optional inputAddress = JsonUtil.getString(configRoot, DEPOSIT_CONTRACT_ADDRESS_KEY); @@ -492,6 +501,8 @@ public class JsonGenesisConfigOptions implements GenesisConfigOptions { getEvmStackSize().ifPresent(l -> builder.put("evmstacksize", l)); getEcip1017EraRounds().ifPresent(l -> builder.put("ecip1017EraRounds", l)); + getWithdrawalRequestContractAddress() + .ifPresent(l -> builder.put("withdrawalRequestContractAddress", l)); getDepositContractAddress().ifPresent(l -> builder.put("depositContractAddress", l)); if (isClique()) { 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 24f3331029..efe56a086d 100644 --- a/config/src/main/java/org/hyperledger/besu/config/StubGenesisConfigOptions.java +++ b/config/src/main/java/org/hyperledger/besu/config/StubGenesisConfigOptions.java @@ -457,6 +457,11 @@ public class StubGenesisConfigOptions implements GenesisConfigOptions, Cloneable return Collections.emptyList(); } + @Override + public Optional
getWithdrawalRequestContractAddress() { + return Optional.empty(); + } + @Override public Optional
getDepositContractAddress() { return Optional.empty(); 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 ed313ad6cf..219ea4fcf8 100644 --- a/config/src/test/java/org/hyperledger/besu/config/GenesisConfigOptionsTest.java +++ b/config/src/test/java/org/hyperledger/besu/config/GenesisConfigOptionsTest.java @@ -332,6 +332,32 @@ class GenesisConfigOptionsTest { assertThat(config.asMap()).containsOnlyKeys("fixedBaseFee").containsValue(true); } + @Test + void shouldGetWithdrawalRequestContractAddress() { + final GenesisConfigOptions config = + fromConfigOptions( + singletonMap( + "withdrawalRequestContractAddress", "0x00000000219ab540356cbb839cbe05303d7705fa")); + assertThat(config.getWithdrawalRequestContractAddress()) + .hasValue(Address.fromHexString("0x00000000219ab540356cbb839cbe05303d7705fa")); + } + + @Test + void shouldNotHaveWithdrawalRequestContractAddressWhenEmpty() { + final GenesisConfigOptions config = fromConfigOptions(emptyMap()); + assertThat(config.getWithdrawalRequestContractAddress()).isEmpty(); + } + + @Test + void asMapIncludesWithdrawalRequestContractAddress() { + final GenesisConfigOptions config = + fromConfigOptions(Map.of("withdrawalRequestContractAddress", "0x0")); + + assertThat(config.asMap()) + .containsOnlyKeys("withdrawalRequestContractAddress") + .containsValue(Address.ZERO); + } + @Test void shouldGetDepositContractAddress() { final GenesisConfigOptions config = 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 36d8257ffb..a96ca58fdd 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 @@ -17,6 +17,7 @@ package org.hyperledger.besu.ethereum.mainnet; import static org.hyperledger.besu.ethereum.mainnet.requests.DepositRequestProcessor.DEFAULT_DEPOSIT_CONTRACT_ADDRESS; 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.WithdrawalRequestProcessor.DEFAULT_WITHDRAWAL_REQUEST_CONTRACT_ADDRESS; import org.hyperledger.besu.config.GenesisConfigOptions; import org.hyperledger.besu.config.PowAlgorithm; @@ -766,6 +767,10 @@ public abstract class MainnetProtocolSpecs { final boolean isParallelTxProcessingEnabled, final MetricsSystem metricsSystem) { + final Address withdrawalRequestContractAddress = + genesisConfigOptions + .getWithdrawalRequestContractAddress() + .orElse(DEFAULT_WITHDRAWAL_REQUEST_CONTRACT_ADDRESS); final Address depositContractAddress = genesisConfigOptions.getDepositContractAddress().orElse(DEFAULT_DEPOSIT_CONTRACT_ADDRESS); @@ -791,7 +796,8 @@ public abstract class MainnetProtocolSpecs { // EIP-7002 Withdrawals / EIP-6610 Deposits / EIP-7685 Requests .requestsValidator(pragueRequestsValidator(depositContractAddress)) // EIP-7002 Withdrawals / EIP-6610 Deposits / EIP-7685 Requests - .requestProcessorCoordinator(pragueRequestsProcessors(depositContractAddress)) + .requestProcessorCoordinator( + pragueRequestsProcessors(withdrawalRequestContractAddress, depositContractAddress)) // change to accept EIP-7702 transactions .transactionValidatorFactoryBuilder( 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 d855544ede..6e61a0343c 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 @@ -28,9 +28,11 @@ public class MainnetRequestsValidator { } public static RequestProcessorCoordinator pragueRequestsProcessors( - final Address depositContractAddress) { + final Address withdrawalRequestContractAddress, final Address depositContractAddress) { return new RequestProcessorCoordinator.Builder() - .addProcessor(RequestType.WITHDRAWAL, new WithdrawalRequestProcessor()) + .addProcessor( + RequestType.WITHDRAWAL, + new WithdrawalRequestProcessor(withdrawalRequestContractAddress)) .addProcessor(RequestType.CONSOLIDATION, new ConsolidationRequestProcessor()) .addProcessor(RequestType.DEPOSIT, new DepositRequestProcessor(depositContractAddress)) .build(); 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 index b230a6d610..d4021c9a10 100644 --- 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 @@ -26,7 +26,7 @@ import org.apache.tuweni.units.bigints.UInt64; public class WithdrawalRequestProcessor extends AbstractSystemCallRequestProcessor { - public static final Address WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS = + public static final Address DEFAULT_WITHDRAWAL_REQUEST_CONTRACT_ADDRESS = Address.fromHexString("0x00A3ca265EBcb825B45F985A16CEFB49958cE017"); private static final int ADDRESS_BYTES = 20; @@ -35,6 +35,12 @@ public class WithdrawalRequestProcessor 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. * @@ -42,7 +48,7 @@ public class WithdrawalRequestProcessor */ @Override protected Address getCallAddress() { - return WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS; + return withdrawalRequestContractAddress; } /** From ab77523814cbd0527ba41140da6aafe62f35ca90 Mon Sep 17 00:00:00 2001 From: Fabio Di Fabio Date: Mon, 29 Jul 2024 13:42:05 +0200 Subject: [PATCH 069/259] Move `JsonRpcResponseType` to `RpcResponseType` in the plugin API module (#7392) Signed-off-by: Fabio Di Fabio --- .../clique/jsonrpc/methods/DiscardTest.java | 10 +++++----- .../clique/jsonrpc/methods/ProposeTest.java | 18 +++++++++--------- .../DebugTraceTransactionIntegrationTest.java | 4 ++-- .../api/handlers/JsonRpcArrayExecutor.java | 4 ++-- .../api/handlers/JsonRpcObjectExecutor.java | 4 ++-- .../execution/TracedJsonRpcProcessor.java | 4 ++-- .../response/JsonRpcErrorResponse.java | 5 +++-- .../internal/response/JsonRpcNoResponse.java | 6 ++++-- .../internal/response/JsonRpcResponse.java | 4 +++- .../response/JsonRpcSuccessResponse.java | 6 ++++-- .../response/JsonRpcUnauthorizedResponse.java | 6 ++++-- .../api/jsonrpc/ipc/JsonRpcIpcService.java | 4 ++-- .../websocket/WebSocketMessageHandler.java | 4 ++-- .../methods/EthGetBlockByNumberTest.java | 8 ++++---- .../AbstractEngineForkchoiceUpdatedTest.java | 6 +++--- .../engine/AbstractEngineNewPayloadTest.java | 6 +++--- .../engine/EngineExchangeCapabilitiesTest.java | 4 ++-- ...ineExchangeTransitionConfigurationTest.java | 4 ++-- .../EngineGetPayloadBodiesByHashV1Test.java | 6 +++--- .../EngineGetPayloadBodiesByRangeV1Test.java | 6 +++--- .../MultiTenancyRpcMethodDecoratorTest.java | 8 ++++---- .../priv/PrivDebugGetStateRootTest.java | 6 +++--- .../MutableJsonRpcSuccessResponse.java | 6 ++++-- .../PrivacyApiGroupJsonRpcMethodsTest.java | 4 ++-- .../methods/TestImportRawBlockTest.java | 14 +++++++------- plugin-api/build.gradle | 2 +- .../plugin/services/rpc/RpcResponseType.java | 12 ++++++++---- 27 files changed, 93 insertions(+), 78 deletions(-) rename ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/response/JsonRpcResponseType.java => plugin-api/src/main/java/org/hyperledger/besu/plugin/services/rpc/RpcResponseType.java (67%) diff --git a/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/DiscardTest.java b/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/DiscardTest.java index f5810520fc..038f97e1e7 100644 --- a/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/DiscardTest.java +++ b/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/DiscardTest.java @@ -28,9 +28,9 @@ 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.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponseType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; import org.hyperledger.besu.ethereum.chain.Blockchain; +import org.hyperledger.besu.plugin.services.rpc.RpcResponseType; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -61,7 +61,7 @@ public class DiscardTest { final JsonRpcResponse response = discard.response(requestWithParams(a0)); - assertThat(response.getType()).isEqualTo(JsonRpcResponseType.SUCCESS); + assertThat(response.getType()).isEqualTo(RpcResponseType.SUCCESS); final JsonRpcSuccessResponse successResponse = (JsonRpcSuccessResponse) response; assertThat(successResponse.getResult()).isEqualTo(true); assertThat(validatorProvider.getVoteProviderAtHead().get().getProposals().get(a0)).isNull(); @@ -77,7 +77,7 @@ public class DiscardTest { final JsonRpcResponse response = discard.response(requestWithParams(a0)); assertThat(validatorProvider.getVoteProviderAtHead().get().getProposals().get(a0)).isNull(); - assertThat(response.getType()).isEqualTo(JsonRpcResponseType.SUCCESS); + assertThat(response.getType()).isEqualTo(RpcResponseType.SUCCESS); final JsonRpcSuccessResponse successResponse = (JsonRpcSuccessResponse) response; assertThat(successResponse.getResult()).isEqualTo(true); } @@ -92,7 +92,7 @@ public class DiscardTest { final JsonRpcResponse response = discard.response(requestWithParams(a0)); assertThat(validatorProvider.getVoteProviderAtHead().get().getProposals().get(a0)).isNull(); - assertThat(response.getType()).isEqualTo(JsonRpcResponseType.SUCCESS); + assertThat(response.getType()).isEqualTo(RpcResponseType.SUCCESS); final JsonRpcSuccessResponse successResponse = (JsonRpcSuccessResponse) response; assertThat(successResponse.getResult()).isEqualTo(true); } @@ -111,7 +111,7 @@ public class DiscardTest { assertThat(validatorProvider.getVoteProviderAtHead().get().getProposals().get(a0)).isNull(); assertThat(validatorProvider.getVoteProviderAtHead().get().getProposals().get(a1)) .isEqualTo(VoteType.ADD); - assertThat(response.getType()).isEqualTo(JsonRpcResponseType.SUCCESS); + assertThat(response.getType()).isEqualTo(RpcResponseType.SUCCESS); final JsonRpcSuccessResponse successResponse = (JsonRpcSuccessResponse) response; assertThat(successResponse.getResult()).isEqualTo(true); } diff --git a/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/ProposeTest.java b/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/ProposeTest.java index efbc78542c..7e7d7bf770 100644 --- a/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/ProposeTest.java +++ b/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/ProposeTest.java @@ -27,10 +27,10 @@ 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.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponseType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.chain.Blockchain; +import org.hyperledger.besu.plugin.services.rpc.RpcResponseType; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -59,7 +59,7 @@ public class ProposeTest { assertThat(validatorProvider.getVoteProviderAtHead().get().getProposals().get(a1)) .isEqualTo(VoteType.ADD); - assertThat(response.getType()).isEqualTo(JsonRpcResponseType.SUCCESS); + assertThat(response.getType()).isEqualTo(RpcResponseType.SUCCESS); final JsonRpcSuccessResponse successResponse = (JsonRpcSuccessResponse) response; assertThat(successResponse.getResult()).isEqualTo(true); } @@ -72,7 +72,7 @@ public class ProposeTest { final JsonRpcResponse response = propose.response(requestWithParams(a0, true)); assertThat(validatorProvider.getVoteProviderAtHead().get().getProposals().get(a0)).isNull(); - assertThat(response.getType()).isEqualTo(JsonRpcResponseType.ERROR); + assertThat(response.getType()).isEqualTo(RpcResponseType.ERROR); final JsonRpcErrorResponse errorResponse = (JsonRpcErrorResponse) response; assertThat(errorResponse.getErrorType()).isEqualTo(RpcErrorType.INVALID_REQUEST); } @@ -86,7 +86,7 @@ public class ProposeTest { assertThat(validatorProvider.getVoteProviderAtHead().get().getProposals().get(a1)) .isEqualTo(VoteType.DROP); - assertThat(response.getType()).isEqualTo(JsonRpcResponseType.SUCCESS); + assertThat(response.getType()).isEqualTo(RpcResponseType.SUCCESS); final JsonRpcSuccessResponse successResponse = (JsonRpcSuccessResponse) response; assertThat(successResponse.getResult()).isEqualTo(true); } @@ -99,7 +99,7 @@ public class ProposeTest { final JsonRpcResponse response = propose.response(requestWithParams(a0, false)); assertThat(validatorProvider.getVoteProviderAtHead().get().getProposals().get(a0)).isNull(); - assertThat(response.getType()).isEqualTo(JsonRpcResponseType.ERROR); + assertThat(response.getType()).isEqualTo(RpcResponseType.ERROR); final JsonRpcErrorResponse errorResponse = (JsonRpcErrorResponse) response; assertThat(errorResponse.getErrorType()).isEqualTo(RpcErrorType.INVALID_REQUEST); } @@ -114,7 +114,7 @@ public class ProposeTest { assertThat(validatorProvider.getVoteProviderAtHead().get().getProposals().get(a1)) .isEqualTo(VoteType.ADD); - assertThat(response.getType()).isEqualTo(JsonRpcResponseType.SUCCESS); + assertThat(response.getType()).isEqualTo(RpcResponseType.SUCCESS); final JsonRpcSuccessResponse successResponse = (JsonRpcSuccessResponse) response; assertThat(successResponse.getResult()).isEqualTo(true); } @@ -129,7 +129,7 @@ public class ProposeTest { assertThat(validatorProvider.getVoteProviderAtHead().get().getProposals().get(a1)) .isEqualTo(VoteType.DROP); - assertThat(response.getType()).isEqualTo(JsonRpcResponseType.SUCCESS); + assertThat(response.getType()).isEqualTo(RpcResponseType.SUCCESS); final JsonRpcSuccessResponse successResponse = (JsonRpcSuccessResponse) response; assertThat(successResponse.getResult()).isEqualTo(true); } @@ -144,7 +144,7 @@ public class ProposeTest { assertThat(validatorProvider.getVoteProviderAtHead().get().getProposals().get(a1)) .isEqualTo(VoteType.ADD); - assertThat(response.getType()).isEqualTo(JsonRpcResponseType.SUCCESS); + assertThat(response.getType()).isEqualTo(RpcResponseType.SUCCESS); final JsonRpcSuccessResponse successResponse = (JsonRpcSuccessResponse) response; assertThat(successResponse.getResult()).isEqualTo(true); } @@ -159,7 +159,7 @@ public class ProposeTest { assertThat(validatorProvider.getVoteProviderAtHead().get().getProposals().get(a0)) .isEqualTo(VoteType.DROP); - assertThat(response.getType()).isEqualTo(JsonRpcResponseType.SUCCESS); + assertThat(response.getType()).isEqualTo(RpcResponseType.SUCCESS); final JsonRpcSuccessResponse successResponse = (JsonRpcSuccessResponse) response; assertThat(successResponse.getResult()).isEqualTo(true); } diff --git a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/DebugTraceTransactionIntegrationTest.java b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/DebugTraceTransactionIntegrationTest.java index d285ef3816..5b48898716 100644 --- a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/DebugTraceTransactionIntegrationTest.java +++ b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/DebugTraceTransactionIntegrationTest.java @@ -23,9 +23,9 @@ 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.response.JsonRpcResponse; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponseType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.DebugTraceTransactionResult; +import org.hyperledger.besu.plugin.services.rpc.RpcResponseType; import org.hyperledger.besu.testutil.BlockTestUtil; import java.util.Map; @@ -69,7 +69,7 @@ public class DebugTraceTransactionIntegrationTest { new JsonRpcRequestContext(new JsonRpcRequest("2.0", DEBUG_TRACE_TRANSACTION, params)); final JsonRpcResponse response = method.response(request); - assertThat(response.getType()).isEqualTo(JsonRpcResponseType.SUCCESS); + assertThat(response.getType()).isEqualTo(RpcResponseType.SUCCESS); DebugTraceTransactionResult debugTraceTransactionResult = (DebugTraceTransactionResult) ((JsonRpcSuccessResponse) response).getResult(); assertThat(debugTraceTransactionResult.getGas()).isEqualTo(23705L); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/handlers/JsonRpcArrayExecutor.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/handlers/JsonRpcArrayExecutor.java index 5a839d8ad0..72d6c5b615 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/handlers/JsonRpcArrayExecutor.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/handlers/JsonRpcArrayExecutor.java @@ -22,8 +22,8 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.context.ContextKey; import org.hyperledger.besu.ethereum.api.jsonrpc.execution.JsonRpcExecutor; 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.JsonRpcResponseType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; +import org.hyperledger.besu.plugin.services.rpc.RpcResponseType; import java.io.IOException; @@ -74,7 +74,7 @@ public class JsonRpcArrayExecutor extends AbstractJsonRpcExecutor { generator.writeStartArray(); for (int i = 0; i < rpcRequestBatch.size(); i++) { JsonRpcResponse response = processMaybeRequest(rpcRequestBatch.getValue(i)); - if (response.getType() != JsonRpcResponseType.NONE) { + if (response.getType() != RpcResponseType.NONE) { generator.writeObject(response); } } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/handlers/JsonRpcObjectExecutor.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/handlers/JsonRpcObjectExecutor.java index d2a2cb3742..70c78e9ab3 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/handlers/JsonRpcObjectExecutor.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/handlers/JsonRpcObjectExecutor.java @@ -22,8 +22,8 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.context.ContextKey; import org.hyperledger.besu.ethereum.api.jsonrpc.execution.JsonRpcExecutor; 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.JsonRpcResponseType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; +import org.hyperledger.besu.plugin.services.rpc.RpcResponseType; import java.io.IOException; @@ -70,7 +70,7 @@ public class JsonRpcObjectExecutor extends AbstractJsonRpcExecutor { final RoutingContext ctx) throws IOException { response.setStatusCode(status(jsonRpcResponse).code()); - if (jsonRpcResponse.getType() == JsonRpcResponseType.NONE) { + if (jsonRpcResponse.getType() == RpcResponseType.NONE) { response.end(); } else { try (final JsonResponseStreamer streamer = 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 c40c8f8c1f..369e425b6f 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 @@ -19,11 +19,11 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestId; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; 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.JsonRpcResponseType; 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.LabelledMetric; +import org.hyperledger.besu.plugin.services.rpc.RpcResponseType; import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.StatusCode; @@ -52,7 +52,7 @@ public class TracedJsonRpcProcessor implements JsonRpcProcessor { final Span metricSpan, final JsonRpcRequestContext request) { JsonRpcResponse jsonRpcResponse = rpcProcessor.process(id, method, metricSpan, request); - if (JsonRpcResponseType.ERROR == jsonRpcResponse.getType()) { + if (RpcResponseType.ERROR == jsonRpcResponse.getType()) { JsonRpcErrorResponse errorResponse = (JsonRpcErrorResponse) jsonRpcResponse; this.rpcErrorsCounter.labels(method.getName(), errorResponse.getErrorType().name()).inc(); switch (errorResponse.getErrorType()) { diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/response/JsonRpcErrorResponse.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/response/JsonRpcErrorResponse.java index 3dffff4956..4cfd7a1df3 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/response/JsonRpcErrorResponse.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/response/JsonRpcErrorResponse.java @@ -15,6 +15,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.response; import org.hyperledger.besu.ethereum.mainnet.ValidationResult; +import org.hyperledger.besu.plugin.services.rpc.RpcResponseType; import java.util.Arrays; import java.util.Collections; @@ -72,8 +73,8 @@ public class JsonRpcErrorResponse implements JsonRpcResponse { @Override @JsonIgnore - public JsonRpcResponseType getType() { - return JsonRpcResponseType.ERROR; + public RpcResponseType getType() { + return RpcResponseType.ERROR; } @Override diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/response/JsonRpcNoResponse.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/response/JsonRpcNoResponse.java index b7391a867b..92a63174ac 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/response/JsonRpcNoResponse.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/response/JsonRpcNoResponse.java @@ -14,10 +14,12 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.response; +import org.hyperledger.besu.plugin.services.rpc.RpcResponseType; + public class JsonRpcNoResponse implements JsonRpcResponse { @Override - public JsonRpcResponseType getType() { - return JsonRpcResponseType.NONE; + public RpcResponseType getType() { + return RpcResponseType.NONE; } } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/response/JsonRpcResponse.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/response/JsonRpcResponse.java index 3b308ff9d7..6817d2cfbb 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/response/JsonRpcResponse.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/response/JsonRpcResponse.java @@ -14,6 +14,8 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.response; +import org.hyperledger.besu.plugin.services.rpc.RpcResponseType; + import com.fasterxml.jackson.annotation.JsonGetter; public interface JsonRpcResponse { @@ -23,5 +25,5 @@ public interface JsonRpcResponse { return "2.0"; } - JsonRpcResponseType getType(); + RpcResponseType getType(); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/response/JsonRpcSuccessResponse.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/response/JsonRpcSuccessResponse.java index 82b1b8835b..e26e2cf972 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/response/JsonRpcSuccessResponse.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/response/JsonRpcSuccessResponse.java @@ -14,6 +14,8 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.response; +import org.hyperledger.besu.plugin.services.rpc.RpcResponseType; + import java.util.Objects; import com.fasterxml.jackson.annotation.JsonGetter; @@ -50,8 +52,8 @@ public class JsonRpcSuccessResponse implements JsonRpcResponse { @Override @JsonIgnore - public JsonRpcResponseType getType() { - return JsonRpcResponseType.SUCCESS; + public RpcResponseType getType() { + return RpcResponseType.SUCCESS; } @Override diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/response/JsonRpcUnauthorizedResponse.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/response/JsonRpcUnauthorizedResponse.java index f59b49a30b..cdf7661678 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/response/JsonRpcUnauthorizedResponse.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/response/JsonRpcUnauthorizedResponse.java @@ -14,6 +14,8 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.response; +import org.hyperledger.besu.plugin.services.rpc.RpcResponseType; + import java.util.Arrays; import java.util.Objects; @@ -50,8 +52,8 @@ public class JsonRpcUnauthorizedResponse implements JsonRpcResponse { @Override @JsonIgnore - public JsonRpcResponseType getType() { - return JsonRpcResponseType.UNAUTHORIZED; + public RpcResponseType getType() { + return RpcResponseType.UNAUTHORIZED; } @Override diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/ipc/JsonRpcIpcService.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/ipc/JsonRpcIpcService.java index 41214d9021..b980c750d5 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/ipc/JsonRpcIpcService.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/ipc/JsonRpcIpcService.java @@ -20,8 +20,8 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.execution.JsonRpcExecutor; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest; 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.JsonRpcResponseType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; +import org.hyperledger.besu.plugin.services.rpc.RpcResponseType; import java.io.IOException; import java.nio.file.Files; @@ -155,7 +155,7 @@ public class JsonRpcIpcService { .filter( jsonRpcResponse -> jsonRpcResponse.getType() - != JsonRpcResponseType.NONE) + != RpcResponseType.NONE) .toArray(JsonRpcResponse[]::new); socket.write( diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/WebSocketMessageHandler.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/WebSocketMessageHandler.java index d88f6cba8e..da7baa5084 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/WebSocketMessageHandler.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/WebSocketMessageHandler.java @@ -20,10 +20,10 @@ import org.hyperledger.besu.ethereum.api.handlers.IsAliveHandler; import org.hyperledger.besu.ethereum.api.jsonrpc.execution.JsonRpcExecutor; 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.JsonRpcResponseType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.websocket.methods.WebSocketRpcRequest; import org.hyperledger.besu.ethereum.eth.manager.EthScheduler; +import org.hyperledger.besu.plugin.services.rpc.RpcResponseType; import java.io.IOException; import java.util.ArrayList; @@ -151,7 +151,7 @@ public class WebSocketMessageHandler { jsonRpcBatchResponse.stream() .filter( jsonRpcResponse -> - jsonRpcResponse.getType() != JsonRpcResponseType.NONE) + jsonRpcResponse.getType() != RpcResponseType.NONE) .toArray(JsonRpcResponse[]::new); replyToClient(websocket, completed); }) diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByNumberTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByNumberTest.java index 1c1cbaf6f7..b12cdbe22f 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByNumberTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByNumberTest.java @@ -26,7 +26,6 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; 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.JsonRpcResponseType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.BlockResult; @@ -41,6 +40,7 @@ import org.hyperledger.besu.ethereum.core.Synchronizer; import org.hyperledger.besu.ethereum.core.TransactionReceipt; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; +import org.hyperledger.besu.plugin.services.rpc.RpcResponseType; import java.util.List; @@ -146,7 +146,7 @@ public class EthGetBlockByNumberTest { @Test public void errorWhenAskingFinalizedButFinalizedIsNotPresent() { JsonRpcResponse resp = method.response(requestWithParams("finalized", "false")); - assertThat(resp.getType()).isEqualTo(JsonRpcResponseType.ERROR); + assertThat(resp.getType()).isEqualTo(RpcResponseType.ERROR); JsonRpcErrorResponse errorResp = (JsonRpcErrorResponse) resp; assertThat(errorResp.getErrorType()).isEqualTo(RpcErrorType.UNKNOWN_BLOCK); } @@ -154,7 +154,7 @@ public class EthGetBlockByNumberTest { @Test public void errorWhenAskingSafeButSafeIsNotPresent() { JsonRpcResponse resp = method.response(requestWithParams("safe", "false")); - assertThat(resp.getType()).isEqualTo(JsonRpcResponseType.ERROR); + assertThat(resp.getType()).isEqualTo(RpcResponseType.ERROR); JsonRpcErrorResponse errorResp = (JsonRpcErrorResponse) resp; assertThat(errorResp.getErrorType()).isEqualTo(RpcErrorType.UNKNOWN_BLOCK); } @@ -181,7 +181,7 @@ public class EthGetBlockByNumberTest { private void assertSuccess(final String tag, final long height) { JsonRpcResponse resp = method.response(requestWithParams(tag, "false")); - assertThat(resp.getType()).isEqualTo(JsonRpcResponseType.SUCCESS); + assertThat(resp.getType()).isEqualTo(RpcResponseType.SUCCESS); JsonRpcSuccessResponse successResp = (JsonRpcSuccessResponse) resp; BlockResult blockResult = (BlockResult) successResp.getResult(); assertThat(blockResult.getHash()) diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineForkchoiceUpdatedTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineForkchoiceUpdatedTest.java index 4cb4c81cc9..6936f2833d 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineForkchoiceUpdatedTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineForkchoiceUpdatedTest.java @@ -44,7 +44,6 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.EnginePaylo import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.WithdrawalParameter; 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.JsonRpcResponseType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.EngineUpdateForkchoiceResult; @@ -55,6 +54,7 @@ import org.hyperledger.besu.ethereum.core.Withdrawal; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; import org.hyperledger.besu.ethereum.mainnet.WithdrawalsValidator; +import org.hyperledger.besu.plugin.services.rpc.RpcResponseType; import java.util.List; import java.util.Optional; @@ -752,7 +752,7 @@ public abstract class AbstractEngineForkchoiceUpdatedTest { abstract String getMethodName(); private EngineUpdateForkchoiceResult fromSuccessResp(final JsonRpcResponse resp) { - assertThat(resp.getType()).isEqualTo(JsonRpcResponseType.SUCCESS); + assertThat(resp.getType()).isEqualTo(RpcResponseType.SUCCESS); return Optional.of(resp) .map(JsonRpcSuccessResponse.class::cast) .map(JsonRpcSuccessResponse::getResult) @@ -766,7 +766,7 @@ public abstract class AbstractEngineForkchoiceUpdatedTest { private void assertInvalidForkchoiceState( final JsonRpcResponse resp, final RpcErrorType jsonRpcError) { - assertThat(resp.getType()).isEqualTo(JsonRpcResponseType.ERROR); + assertThat(resp.getType()).isEqualTo(RpcResponseType.ERROR); var errorResp = (JsonRpcErrorResponse) resp; assertThat(errorResp.getErrorType()).isEqualTo(jsonRpcError); 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 10da8a4486..9b3e94330e 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 @@ -47,7 +47,6 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.WithdrawalR 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.JsonRpcResponseType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.EnginePayloadStatusResult; import org.hyperledger.besu.ethereum.chain.MutableBlockchain; @@ -66,6 +65,7 @@ import org.hyperledger.besu.ethereum.mainnet.WithdrawalsValidator; import org.hyperledger.besu.ethereum.mainnet.requests.RequestsValidatorCoordinator; 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; @@ -459,7 +459,7 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT } protected EnginePayloadStatusResult fromSuccessResp(final JsonRpcResponse resp) { - assertThat(resp.getType()).isEqualTo(JsonRpcResponseType.SUCCESS); + assertThat(resp.getType()).isEqualTo(RpcResponseType.SUCCESS); return Optional.of(resp) .map(JsonRpcSuccessResponse.class::cast) .map(JsonRpcSuccessResponse::getResult) @@ -468,7 +468,7 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT } protected JsonRpcError fromErrorResp(final JsonRpcResponse resp) { - assertThat(resp.getType()).isEqualTo(JsonRpcResponseType.ERROR); + assertThat(resp.getType()).isEqualTo(RpcResponseType.ERROR); return Optional.of(resp) .map(JsonRpcErrorResponse.class::cast) .map(JsonRpcErrorResponse::getError) diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineExchangeCapabilitiesTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineExchangeCapabilitiesTest.java index e3a3268aa6..4ccd9318a2 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineExchangeCapabilitiesTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineExchangeCapabilitiesTest.java @@ -23,8 +23,8 @@ 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.response.JsonRpcResponse; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponseType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; +import org.hyperledger.besu.plugin.services.rpc.RpcResponseType; import java.util.Collections; import java.util.List; @@ -85,7 +85,7 @@ public class EngineExchangeCapabilitiesTest { @SuppressWarnings("unchecked") private List fromSuccessResp(final JsonRpcResponse resp) { - assertThat(resp.getType()).isEqualTo(JsonRpcResponseType.SUCCESS); + assertThat(resp.getType()).isEqualTo(RpcResponseType.SUCCESS); return Optional.of(resp) .map(JsonRpcSuccessResponse.class::cast) .map(JsonRpcSuccessResponse::getResult) diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineExchangeTransitionConfigurationTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineExchangeTransitionConfigurationTest.java index d3104670de..f1575f81ab 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineExchangeTransitionConfigurationTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineExchangeTransitionConfigurationTest.java @@ -30,7 +30,6 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.EngineExchangeTransitionConfigurationParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.UnsignedLongParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponseType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.EngineExchangeTransitionConfigurationResult; import org.hyperledger.besu.ethereum.core.BlockHeader; @@ -39,6 +38,7 @@ import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture; import org.hyperledger.besu.ethereum.core.Difficulty; import org.hyperledger.besu.ethereum.core.ParsedExtraData; import org.hyperledger.besu.evm.log.LogsBloomFilter; +import org.hyperledger.besu.plugin.services.rpc.RpcResponseType; import java.math.BigInteger; import java.util.Map; @@ -223,7 +223,7 @@ public class EngineExchangeTransitionConfigurationTest { } private EngineExchangeTransitionConfigurationResult fromSuccessResp(final JsonRpcResponse resp) { - assertThat(resp.getType()).isEqualTo(JsonRpcResponseType.SUCCESS); + assertThat(resp.getType()).isEqualTo(RpcResponseType.SUCCESS); return Optional.of(resp) .map(JsonRpcSuccessResponse.class::cast) .map(JsonRpcSuccessResponse::getResult) 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 42f2a5df0b..8a99fa9439 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 @@ -31,7 +31,6 @@ 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.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponseType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.BlockResultFactory; @@ -40,6 +39,7 @@ import org.hyperledger.besu.ethereum.chain.MutableBlockchain; import org.hyperledger.besu.ethereum.core.BlockBody; import org.hyperledger.besu.ethereum.core.TransactionTestFixture; import org.hyperledger.besu.ethereum.core.Withdrawal; +import org.hyperledger.besu.plugin.services.rpc.RpcResponseType; import java.util.Collections; import java.util.List; @@ -255,7 +255,7 @@ public class EngineGetPayloadBodiesByHashV1Test { } private EngineGetPayloadBodiesResultV1 fromSuccessResp(final JsonRpcResponse resp) { - assertThat(resp.getType()).isEqualTo(JsonRpcResponseType.SUCCESS); + assertThat(resp.getType()).isEqualTo(RpcResponseType.SUCCESS); return Optional.of(resp) .map(JsonRpcSuccessResponse.class::cast) .map(JsonRpcSuccessResponse::getResult) @@ -264,7 +264,7 @@ public class EngineGetPayloadBodiesByHashV1Test { } private RpcErrorType fromErrorResp(final JsonRpcResponse resp) { - assertThat(resp.getType()).isEqualTo(JsonRpcResponseType.ERROR); + assertThat(resp.getType()).isEqualTo(RpcResponseType.ERROR); return Optional.of(resp) .map(JsonRpcErrorResponse.class::cast) .map(JsonRpcErrorResponse::getErrorType) 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 60fb2ed1f8..6bc89ba679 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 @@ -33,7 +33,6 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; 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.JsonRpcResponseType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.BlockResultFactory; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.EngineGetPayloadBodiesResultV1; @@ -41,6 +40,7 @@ import org.hyperledger.besu.ethereum.chain.MutableBlockchain; import org.hyperledger.besu.ethereum.core.BlockBody; import org.hyperledger.besu.ethereum.core.TransactionTestFixture; import org.hyperledger.besu.ethereum.core.Withdrawal; +import org.hyperledger.besu.plugin.services.rpc.RpcResponseType; import java.util.Collections; import java.util.List; @@ -344,7 +344,7 @@ public class EngineGetPayloadBodiesByRangeV1Test { } private EngineGetPayloadBodiesResultV1 fromSuccessResp(final JsonRpcResponse resp) { - assertThat(resp.getType()).isEqualTo(JsonRpcResponseType.SUCCESS); + assertThat(resp.getType()).isEqualTo(RpcResponseType.SUCCESS); return Optional.of(resp) .map(JsonRpcSuccessResponse.class::cast) .map(JsonRpcSuccessResponse::getResult) @@ -353,7 +353,7 @@ public class EngineGetPayloadBodiesByRangeV1Test { } private JsonRpcError fromErrorResp(final JsonRpcResponse resp) { - assertThat(resp.getType()).isEqualTo(JsonRpcResponseType.ERROR); + assertThat(resp.getType()).isEqualTo(RpcResponseType.ERROR); return Optional.of(resp) .map(JsonRpcErrorResponse.class::cast) .map(JsonRpcErrorResponse::getError) diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/MultiTenancyRpcMethodDecoratorTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/MultiTenancyRpcMethodDecoratorTest.java index 8803540392..d7979dccc8 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/MultiTenancyRpcMethodDecoratorTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/MultiTenancyRpcMethodDecoratorTest.java @@ -22,10 +22,10 @@ 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.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponseType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcUnauthorizedResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; +import org.hyperledger.besu.plugin.services.rpc.RpcResponseType; import io.vertx.core.json.JsonObject; import io.vertx.ext.auth.User; @@ -58,7 +58,7 @@ public class MultiTenancyRpcMethodDecoratorTest { assertThat(tokenRpcDecorator.getName()).isEqualTo("delegate"); final JsonRpcResponse response = tokenRpcDecorator.response(rpcRequestContext); - assertThat(response.getType()).isEqualTo(JsonRpcResponseType.SUCCESS); + assertThat(response.getType()).isEqualTo(RpcResponseType.SUCCESS); final JsonRpcSuccessResponse successResponse = (JsonRpcSuccessResponse) response; assertThat(successResponse.getResult()).isEqualTo("b"); } @@ -73,7 +73,7 @@ public class MultiTenancyRpcMethodDecoratorTest { assertThat(tokenRpcDecorator.getName()).isEqualTo("delegate"); final JsonRpcResponse response = tokenRpcDecorator.response(rpcRequestContext); - assertThat(response.getType()).isEqualTo(JsonRpcResponseType.UNAUTHORIZED); + assertThat(response.getType()).isEqualTo(RpcResponseType.UNAUTHORIZED); final JsonRpcUnauthorizedResponse errorResponse = (JsonRpcUnauthorizedResponse) response; assertThat(errorResponse.getErrorType()).isEqualTo(RpcErrorType.UNAUTHORIZED); } @@ -89,7 +89,7 @@ public class MultiTenancyRpcMethodDecoratorTest { assertThat(tokenRpcDecorator.getName()).isEqualTo("delegate"); final JsonRpcResponse response = tokenRpcDecorator.response(rpcRequestContext); - assertThat(response.getType()).isEqualTo(JsonRpcResponseType.ERROR); + assertThat(response.getType()).isEqualTo(RpcResponseType.ERROR); final JsonRpcErrorResponse errorResponse = (JsonRpcErrorResponse) response; assertThat(errorResponse.getErrorType()).isEqualTo(RpcErrorType.INVALID_REQUEST); } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDebugGetStateRootTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDebugGetStateRootTest.java index 7c2b616266..a7a4f6f590 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDebugGetStateRootTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDebugGetStateRootTest.java @@ -33,11 +33,11 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParame import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.PrivacyIdProvider; 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.JsonRpcResponseType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; import org.hyperledger.besu.ethereum.privacy.PrivacyController; import org.hyperledger.besu.ethereum.privacy.RestrictedDefaultPrivacyController; +import org.hyperledger.besu.plugin.services.rpc.RpcResponseType; import java.util.Collections; import java.util.Optional; @@ -91,7 +91,7 @@ public class PrivDebugGetStateRootTest { when(privacyController.findPrivacyGroupByGroupId(anyString(), anyString())) .thenReturn(Optional.empty()); final JsonRpcResponse response = method.response(request("not_base64", "latest")); - assertThat(response.getType()).isEqualByComparingTo(JsonRpcResponseType.ERROR); + assertThat(response.getType()).isEqualByComparingTo(RpcResponseType.ERROR); assertThat(((JsonRpcErrorResponse) response).getError().getMessage()) .contains(FIND_PRIVACY_GROUP_ERROR.getMessage()); } @@ -102,7 +102,7 @@ public class PrivDebugGetStateRootTest { .thenReturn(Optional.empty()); final String invalidGroupId = Base64.toBase64String("invalid_group_id".getBytes(UTF_8)); final JsonRpcResponse response = method.response(request(invalidGroupId, "latest")); - assertThat(response.getType()).isEqualByComparingTo(JsonRpcResponseType.ERROR); + assertThat(response.getType()).isEqualByComparingTo(RpcResponseType.ERROR); assertThat(((JsonRpcErrorResponse) response).getError().getMessage()) .contains(FIND_PRIVACY_GROUP_ERROR.getMessage()); } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/response/MutableJsonRpcSuccessResponse.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/response/MutableJsonRpcSuccessResponse.java index 7e61830ce6..a9b9376dc3 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/response/MutableJsonRpcSuccessResponse.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/response/MutableJsonRpcSuccessResponse.java @@ -14,6 +14,8 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.response; +import org.hyperledger.besu.plugin.services.rpc.RpcResponseType; + import java.util.Objects; import com.fasterxml.jackson.annotation.JsonGetter; @@ -74,8 +76,8 @@ public class MutableJsonRpcSuccessResponse { } @JsonIgnore - public JsonRpcResponseType getType() { - return JsonRpcResponseType.SUCCESS; + public RpcResponseType getType() { + return RpcResponseType.SUCCESS; } @Override diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/PrivacyApiGroupJsonRpcMethodsTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/PrivacyApiGroupJsonRpcMethodsTest.java index ab7b90735b..52a875a4cb 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/PrivacyApiGroupJsonRpcMethodsTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/PrivacyApiGroupJsonRpcMethodsTest.java @@ -27,7 +27,6 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.MultiT import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.PrivacyIdProvider; 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.JsonRpcResponseType; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; import org.hyperledger.besu.ethereum.core.PrivacyParameters; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool; @@ -35,6 +34,7 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.privacy.MultiTenancyPrivacyController; import org.hyperledger.besu.ethereum.privacy.PrivacyController; import org.hyperledger.besu.plugin.services.privacy.PrivateMarkerTransactionFactory; +import org.hyperledger.besu.plugin.services.rpc.RpcResponseType; import java.util.Map; import java.util.Optional; @@ -140,7 +140,7 @@ public class PrivacyApiGroupJsonRpcMethodsTest { final JsonRpcRequestContext request = new JsonRpcRequestContext(new JsonRpcRequest("2.0", "priv_method", null)); final JsonRpcResponse response = privMethod.response(request); - assertThat(response.getType()).isEqualTo(JsonRpcResponseType.ERROR); + assertThat(response.getType()).isEqualTo(RpcResponseType.ERROR); JsonRpcErrorResponse errorResponse = (JsonRpcErrorResponse) response; assertThat(errorResponse.getErrorType()).isEqualTo(PRIVACY_NOT_ENABLED); diff --git a/ethereum/retesteth/src/test/java/org/hyperledger/besu/ethereum/retesteth/methods/TestImportRawBlockTest.java b/ethereum/retesteth/src/test/java/org/hyperledger/besu/ethereum/retesteth/methods/TestImportRawBlockTest.java index 7649623538..b156f2294d 100644 --- a/ethereum/retesteth/src/test/java/org/hyperledger/besu/ethereum/retesteth/methods/TestImportRawBlockTest.java +++ b/ethereum/retesteth/src/test/java/org/hyperledger/besu/ethereum/retesteth/methods/TestImportRawBlockTest.java @@ -19,10 +19,10 @@ import static org.assertj.core.api.Assertions.assertThat; 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.response.JsonRpcErrorResponse; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponseType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.retesteth.RetestethContext; +import org.hyperledger.besu.plugin.services.rpc.RpcResponseType; import java.io.IOException; @@ -69,7 +69,7 @@ public class TestImportRawBlockTest { "2.0", TestImportRawBlock.METHOD_NAME, new Object[] {rawBlockRLPString})); final var response = test_importRawBlock.response(request); - assertThat(response.getType()).isEqualTo(JsonRpcResponseType.ERROR); + assertThat(response.getType()).isEqualTo(RpcResponseType.ERROR); assertThat(((JsonRpcErrorResponse) response).getErrorType()) .isEqualTo(RpcErrorType.BLOCK_IMPORT_ERROR); } @@ -84,7 +84,7 @@ public class TestImportRawBlockTest { "2.0", TestImportRawBlock.METHOD_NAME, new Object[] {rawBlockRLPString})); final var response = test_importRawBlock.response(request); - assertThat(response.getType()).isEqualTo(JsonRpcResponseType.ERROR); + assertThat(response.getType()).isEqualTo(RpcResponseType.ERROR); assertThat(((JsonRpcErrorResponse) response).getErrorType()) .isEqualTo(RpcErrorType.BLOCK_RLP_IMPORT_ERROR); } @@ -100,7 +100,7 @@ public class TestImportRawBlockTest { "2.0", TestImportRawBlock.METHOD_NAME, new Object[] {rawBlockRLPString})); final var response = test_importRawBlock.response(request); - assertThat(response.getType()).isEqualTo(JsonRpcResponseType.SUCCESS); + assertThat(response.getType()).isEqualTo(RpcResponseType.SUCCESS); } @Test @@ -118,11 +118,11 @@ public class TestImportRawBlockTest { new JsonRpcRequest("2.0", TestRewindToBlock.METHOD_NAME, new Object[] {0L})); final var response = test_importRawBlock.response(request); - assertThat(response.getType()).isEqualTo(JsonRpcResponseType.SUCCESS); + assertThat(response.getType()).isEqualTo(RpcResponseType.SUCCESS); final var rewindResponse = test_rewindToBlock.response(requestRewind); - assertThat(rewindResponse.getType()).isEqualTo(JsonRpcResponseType.SUCCESS); + assertThat(rewindResponse.getType()).isEqualTo(RpcResponseType.SUCCESS); final var reimportResponse = test_importRawBlock.response(request); - assertThat(reimportResponse.getType()).isEqualTo(JsonRpcResponseType.SUCCESS); + assertThat(reimportResponse.getType()).isEqualTo(RpcResponseType.SUCCESS); assertThat(context.getBlockchain().getChainHead().getHeight()).isEqualTo(1L); } diff --git a/plugin-api/build.gradle b/plugin-api/build.gradle index 81e66a06a0..0d593b1105 100644 --- a/plugin-api/build.gradle +++ b/plugin-api/build.gradle @@ -70,7 +70,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 = '6L5dNJ975Ka/X7g4lTdpkBvPQrJgJu+vAf/m1dFCneU=' + knownHash = 'oPsVhFhdIkzHqD+jjwRX7dbgeNeKbpCmPjiBWDdMV7o=' } check.dependsOn('checkAPIChanges') diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/response/JsonRpcResponseType.java b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/rpc/RpcResponseType.java similarity index 67% rename from ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/response/JsonRpcResponseType.java rename to plugin-api/src/main/java/org/hyperledger/besu/plugin/services/rpc/RpcResponseType.java index 9d5be9c430..b02b45c857 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/response/JsonRpcResponseType.java +++ b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/rpc/RpcResponseType.java @@ -1,5 +1,5 @@ /* - * Copyright ConsenSys AG. + * 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 @@ -12,12 +12,16 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.ethereum.api.jsonrpc.internal.response; +package org.hyperledger.besu.plugin.services.rpc; -/** Various types of responses that the JSON-RPC component may produce. */ -public enum JsonRpcResponseType { +/** Various types of responses that the RPC component may produce. */ +public enum RpcResponseType { + /** No response */ NONE, + /** Successful response */ SUCCESS, + /** Error response */ ERROR, + /** Not authorized response */ UNAUTHORIZED } From 4ace9e42c0e87425612005d00cf4b5d574cd432b Mon Sep 17 00:00:00 2001 From: daniellehrner Date: Mon, 29 Jul 2024 17:45:15 +0200 Subject: [PATCH 070/259] 7702 bugfixes for devnet-1 (#7394) * process the authority list before increasing the sender nonce, make sure that the updated balance of the sender is calculated correctly if they sign an authorization as well Signed-off-by: Daniel Lehrner --- .../SetCodeTransactionAcceptanceTest.java | 72 ++++++++++++++++++- .../ethereum/mainnet/AuthorityProcessor.java | 6 +- .../mainnet/MainnetTransactionProcessor.java | 24 ++++--- 3 files changed, 86 insertions(+), 16 deletions(-) diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/ethereum/SetCodeTransactionAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/ethereum/SetCodeTransactionAcceptanceTest.java index f1b2558a97..b134b1f5c0 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/ethereum/SetCodeTransactionAcceptanceTest.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/ethereum/SetCodeTransactionAcceptanceTest.java @@ -34,6 +34,7 @@ import java.util.Optional; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.web3j.protocol.core.methods.response.TransactionReceipt; @@ -57,6 +58,8 @@ public class SetCodeTransactionAcceptanceTest extends AcceptanceTestBase { public static final Bytes TRANSACTION_SPONSOR_PRIVATE_KEY = Bytes.fromHexString("3a4ff6d22d7502ef2452368165422861c01a0f72f851793b372b87888dc3c453"); + private final Account otherAccount = accounts.createAccount("otherAccount"); + private BesuNode besuNode; private PragueAcceptanceTestHelper testHelper; @@ -68,11 +71,17 @@ public class SetCodeTransactionAcceptanceTest extends AcceptanceTestBase { testHelper = new PragueAcceptanceTestHelper(besuNode, ethTransactions); } + @AfterEach + void tearDown() { + besuNode.close(); + cluster.close(); + } + /** * At the beginning of the test both the authorizer and the transaction sponsor have a balance of * 90000 ETH. The authorizer creates an authorization for a contract that send all its ETH to any - * given address. The transaction sponsor created a 7702 transaction with it and sends all the ETH - * from the authorizer to itself. The authorizer balance should be 0 and the transaction sponsor + * given address. The transaction sponsor sponsors the 7702 transaction and sends all the ETH from + * the authorizer to itself. The authorizer balance should be 0 and the transaction sponsor's * balance should be 180000 ETH minus the transaction costs. */ @Test @@ -122,4 +131,63 @@ public class SetCodeTransactionAcceptanceTest extends AcceptanceTestBase { BigInteger expectedSponsorBalance = new BigInteger("180000000000000000000000").subtract(txCost); cluster.verify(transactionSponsor.balanceEquals(Amount.wei(expectedSponsorBalance))); } + + /** + * The authorizer creates an authorization for a contract that sends all its ETH to any given + * address. But the nonce is 1 and the authorization list is processed before the nonce increase + * of the sender. Therefore, the authorization should be invalid and will be ignored. No balance + * change, except for a decrease for paying the transaction cost should occur. + */ + @Test + public void shouldCheckNonceBeforeNonceIncreaseOfSender() throws IOException { + + cluster.verify(authorizer.balanceEquals(Amount.ether(90000))); + + final org.hyperledger.besu.datatypes.SetCodeAuthorization authorization = + SetCodeAuthorization.builder() + .chainId(BigInteger.valueOf(20211)) + .nonces( + Optional.of( + 1L)) // nonce is 1, but because it is validated before the nonce increase, it + // should be 0 + .address(SEND_ALL_ETH_CONTRACT_ADDRESS) + .signAndBuild( + secp256k1.createKeyPair( + secp256k1.createPrivateKey(AUTHORIZER_PRIVATE_KEY.toUnsignedBigInteger()))); + + final Transaction tx = + Transaction.builder() + .type(TransactionType.SET_CODE) + .chainId(BigInteger.valueOf(20211)) + .nonce(0) + .maxPriorityFeePerGas(Wei.of(1000000000)) + .maxFeePerGas(Wei.fromHexString("0x02540BE400")) + .gasLimit(1000000) + .to(Address.fromHexStringStrict(authorizer.getAddress())) + .value(Wei.ZERO) + .payload(Bytes32.leftPad(Bytes.fromHexString(otherAccount.getAddress()))) + .accessList(List.of()) + .setCodeTransactionPayloads(List.of(authorization)) + .signAndBuild( + secp256k1.createKeyPair( + secp256k1.createPrivateKey(AUTHORIZER_PRIVATE_KEY.toUnsignedBigInteger()))); + + final String txHash = + besuNode.execute(ethTransactions.sendRawTransaction(tx.encoded().toHexString())); + testHelper.buildNewBlock(); + + Optional maybeTransactionReceipt = + besuNode.execute(ethTransactions.getTransactionReceipt(txHash)); + assertThat(maybeTransactionReceipt).isPresent(); + + // verify that the balance of the other account has not changed + cluster.verify(otherAccount.balanceEquals(0)); + + final String gasPriceWithout0x = + maybeTransactionReceipt.get().getEffectiveGasPrice().substring(2); + final BigInteger txCost = + maybeTransactionReceipt.get().getGasUsed().multiply(new BigInteger(gasPriceWithout0x, 16)); + BigInteger expectedSenderBalance = new BigInteger("90000000000000000000000").subtract(txCost); + cluster.verify(authorizer.balanceEquals(Amount.wei(expectedSenderBalance))); + } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/AuthorityProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/AuthorityProcessor.java index f79e2c98e3..c40eca0f74 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/AuthorityProcessor.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/AuthorityProcessor.java @@ -38,7 +38,7 @@ public class AuthorityProcessor { } public void addContractToAuthority( - final WorldUpdater worldUpdater, + final WorldUpdater worldState, final AuthorizedCodeService authorizedCodeService, final Transaction transaction) { @@ -60,7 +60,7 @@ public class AuthorityProcessor { } final Optional maybeAccount = - Optional.ofNullable(worldUpdater.getAccount(authorityAddress)); + Optional.ofNullable(worldState.getAccount(authorityAddress)); final long accountNonce = maybeAccount.map(AccountState::getNonce).orElse(0L); @@ -74,7 +74,7 @@ public class AuthorityProcessor { } Optional codeAccount = - Optional.ofNullable(worldUpdater.get(payload.address())); + Optional.ofNullable(worldState.get(payload.address())); final Bytes code; if (codeAccount.isPresent()) { code = codeAccount.get().getCode(); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java index 5fa2b119f1..cb9cd24e23 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java @@ -306,7 +306,6 @@ public class MainnetTransactionProcessor { } final Address senderAddress = transaction.getSender(); - final MutableAccount sender = worldState.getOrCreateSenderAccount(senderAddress); validationResult = @@ -318,6 +317,19 @@ public class MainnetTransactionProcessor { operationTracer.tracePrepareTransaction(worldState, transaction); + final Set
addressList = new BytesTrieSet<>(Address.SIZE); + + if (transaction.getAuthorizationList().isPresent()) { + if (maybeAuthorityProcessor.isEmpty()) { + throw new RuntimeException("Authority processor is required for 7702 transactions"); + } + + maybeAuthorityProcessor + .get() + .addContractToAuthority(worldState, authorizedCodeService, transaction); + addressList.addAll(authorizedCodeService.getAuthorities()); + } + final long previousNonce = sender.incrementNonce(); LOG.trace( "Incremented sender {} nonce ({} -> {})", @@ -343,7 +355,6 @@ public class MainnetTransactionProcessor { final List accessListEntries = transaction.getAccessList().orElse(List.of()); // we need to keep a separate hash set of addresses in case they specify no storage. // No-storage is a common pattern, especially for Externally Owned Accounts - final Set
addressList = new BytesTrieSet<>(Address.SIZE); final Multimap storageList = HashMultimap.create(); int accessListStorageCount = 0; for (final var entry : accessListEntries) { @@ -408,15 +419,6 @@ public class MainnetTransactionProcessor { if (transaction.getVersionedHashes().isPresent()) { commonMessageFrameBuilder.versionedHashes( Optional.of(transaction.getVersionedHashes().get().stream().toList())); - } else if (transaction.getAuthorizationList().isPresent()) { - if (maybeAuthorityProcessor.isEmpty()) { - throw new RuntimeException("Authority processor is required for 7702 transactions"); - } - - maybeAuthorityProcessor - .get() - .addContractToAuthority(worldUpdater, authorizedCodeService, transaction); - addressList.addAll(authorizedCodeService.getAuthorities()); } else { commonMessageFrameBuilder.versionedHashes(Optional.empty()); } From ec8429f800845f2af0728161119f77762f97f219 Mon Sep 17 00:00:00 2001 From: Simon Dudley Date: Tue, 30 Jul 2024 16:51:06 +1000 Subject: [PATCH 071/259] Refactor TrieLogPruner preload timeout to be more testable (#7393) Also update logging Signed-off-by: Simon Dudley --- .../common/trielog/TrieLogPruner.java | 62 ++++++++++--------- .../trielog/TrieLogPrunerTest.java | 53 ++++++++++++++-- 2 files changed, 82 insertions(+), 33 deletions(-) rename ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/{bonsai => common}/trielog/TrieLogPrunerTest.java (87%) diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/trielog/TrieLogPruner.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/trielog/TrieLogPruner.java index 98bc4246eb..02ff553fe1 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/trielog/TrieLogPruner.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/trielog/TrieLogPruner.java @@ -26,16 +26,17 @@ import org.hyperledger.besu.plugin.services.trielogs.TrieLogEvent; import java.util.Comparator; import java.util.Optional; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; import java.util.function.Consumer; import java.util.stream.Stream; +import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Multimap; import com.google.common.collect.TreeMultimap; @@ -91,43 +92,44 @@ public class TrieLogPruner implements TrieLogEvent.TrieLogObserver { } public void initialize() { - preloadQueueWithTimeout(); + preloadQueueWithTimeout(PRELOAD_TIMEOUT_IN_SECONDS); } - private void preloadQueueWithTimeout() { + @VisibleForTesting + void preloadQueueWithTimeout(final int timeoutInSeconds) { + LOG.info("Trie log pruner queue preload starting..."); LOG.atInfo() .setMessage("Attempting to load first {} trie logs from database...") .addArgument(loadingLimit) .log(); - try (final ScheduledExecutorService preloadExecutor = Executors.newScheduledThreadPool(1)) { + try (final ExecutorService preloadExecutor = Executors.newSingleThreadExecutor()) { + final Future future = preloadExecutor.submit(this::preloadQueue); - final AtomicBoolean timeoutOccurred = new AtomicBoolean(false); - final Runnable timeoutTask = - () -> { - timeoutOccurred.set(true); - LOG.atWarn() - .setMessage( - "Timeout occurred while loading and processing {} trie logs from database") - .addArgument(loadingLimit) - .log(); - }; - - final ScheduledFuture timeoutFuture = - preloadExecutor.schedule(timeoutTask, PRELOAD_TIMEOUT_IN_SECONDS, TimeUnit.SECONDS); LOG.atInfo() .setMessage( "Trie log pruning will timeout after {} seconds. If this is timing out, consider using `besu storage trie-log prune` subcommand, see https://besu.hyperledger.org/public-networks/how-to/bonsai-limit-trie-logs") - .addArgument(PRELOAD_TIMEOUT_IN_SECONDS) + .addArgument(timeoutInSeconds) .log(); - preloadQueue(timeoutOccurred, timeoutFuture); + try { + future.get(timeoutInSeconds, TimeUnit.SECONDS); + } catch (InterruptedException | ExecutionException e) { + LOG.error("Error loading trie logs from database", e); + future.cancel(true); + } catch (TimeoutException e) { + future.cancel(true); + LOG.atWarn() + .setMessage("Timeout occurred while loading and processing {} trie logs from database") + .addArgument(loadingLimit) + .log(); + } } + LOG.info("Trie log pruner queue preload complete."); } - private void preloadQueue( - final AtomicBoolean timeoutOccurred, final ScheduledFuture timeoutFuture) { + private void preloadQueue() { try (final Stream trieLogKeys = rootWorldStateStorage.streamTrieLogKeys(loadingLimit)) { @@ -135,9 +137,9 @@ public class TrieLogPruner implements TrieLogEvent.TrieLogObserver { final AtomicLong orphansPruned = new AtomicLong(); trieLogKeys.forEach( blockHashAsBytes -> { - if (timeoutOccurred.get()) { + if (Thread.currentThread().isInterrupted()) { throw new RuntimeException( - new TimeoutException("Timeout occurred while preloading trie log prune queue")); + new InterruptedException("Thread interrupted during trie log processing.")); } final Hash blockHash = Hash.wrap(Bytes32.wrap(blockHashAsBytes)); final Optional header = blockchain.getBlockHeader(blockHash); @@ -152,17 +154,19 @@ public class TrieLogPruner implements TrieLogEvent.TrieLogObserver { } }); - timeoutFuture.cancel(true); LOG.atDebug().log("Pruned {} orphaned trie logs from database...", orphansPruned.intValue()); LOG.atInfo().log( "Added {} trie logs to prune queue. Commencing pruning of eligible trie logs...", addToPruneQueueCount.intValue()); int prunedCount = pruneFromQueue(); - LOG.atInfo().log("Pruned {} trie logs.", prunedCount); + LOG.atInfo().log("Pruned {} trie logs", prunedCount); } catch (Exception e) { - if (e.getCause() != null && e.getCause() instanceof TimeoutException) { + if (e instanceof InterruptedException + || (e.getCause() != null && e.getCause() instanceof InterruptedException)) { + LOG.info("Operation interrupted, but will attempt to prune what's in the queue so far..."); int prunedCount = pruneFromQueue(); - LOG.atInfo().log("Operation timed out, but still pruned {} trie logs.", prunedCount); + LOG.atInfo().log("...pruned {} trie logs", prunedCount); + Thread.currentThread().interrupt(); // Preserve interrupt status } else { LOG.error("Error loading trie logs from database, nothing pruned", e); } diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/trielog/TrieLogPrunerTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/common/trielog/TrieLogPrunerTest.java similarity index 87% rename from ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/trielog/TrieLogPrunerTest.java rename to ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/common/trielog/TrieLogPrunerTest.java index 621e73711a..5f985b1f89 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/trielog/TrieLogPrunerTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/common/trielog/TrieLogPrunerTest.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.ethereum.trie.diffbased.bonsai.trielog; +package org.hyperledger.besu.ethereum.trie.diffbased.common.trielog; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; @@ -26,9 +26,6 @@ import org.hyperledger.besu.ethereum.chain.Blockchain; import org.hyperledger.besu.ethereum.core.BlockDataGenerator; import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.BonsaiWorldStateKeyValueStorage; -import org.hyperledger.besu.ethereum.trie.diffbased.common.trielog.TrieLogAddedEvent; -import org.hyperledger.besu.ethereum.trie.diffbased.common.trielog.TrieLogLayer; -import org.hyperledger.besu.ethereum.trie.diffbased.common.trielog.TrieLogPruner; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import java.util.Optional; @@ -43,6 +40,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.InOrder; import org.mockito.Mockito; +import org.mockito.internal.stubbing.answers.AnswersWithDelay; public class TrieLogPrunerTest { @@ -82,6 +80,53 @@ public class TrieLogPrunerTest { verify(worldState, times(1)).pruneTrieLog(header2.getBlockHash()); } + @Test + public void preloadQueueWithTimeout_handles_timeout_during_streamTrieLogKeys() { + // Given + final int timeoutInSeconds = 1; + final long timeoutInMillis = timeoutInSeconds * 1000; + final int loadingLimit = 2; + TrieLogPruner trieLogPruner = + new TrieLogPruner( + worldState, blockchain, executeAsync, 3, loadingLimit, false, new NoOpMetricsSystem()); + + // Simulate a long-running operation + when(worldState.streamTrieLogKeys(loadingLimit)) + .thenAnswer(new AnswersWithDelay(timeoutInMillis * 2, invocation -> Stream.empty())); + + // When + long startTime = System.currentTimeMillis(); + trieLogPruner.preloadQueueWithTimeout(timeoutInSeconds); + long elapsedTime = System.currentTimeMillis() - startTime; + + // Then + assertThat(elapsedTime).isLessThan(timeoutInMillis * 2); + } + + @Test + public void preloadQueueWithTimeout_handles_timeout_during_getBlockHeader() { + // Given + final int timeoutInSeconds = 1; + final long timeoutInMillis = timeoutInSeconds * 1000; + TrieLogPruner trieLogPruner = setupPrunerAndFinalizedBlock(3, 1); + + // Simulate a long-running operation + when(blockchain.getBlockHeader(any(Hash.class))) + // delay on first invocation, then return empty + .thenAnswer(new AnswersWithDelay(timeoutInMillis * 2, invocation -> Optional.empty())) + .thenReturn(Optional.empty()); + + // When + long startTime = System.currentTimeMillis(); + trieLogPruner.preloadQueueWithTimeout(timeoutInSeconds); + long elapsedTime = System.currentTimeMillis() - startTime; + + // Then + assertThat(elapsedTime).isLessThan(timeoutInMillis * 2); + verify(worldState, times(1)).pruneTrieLog(key(1)); + verify(worldState, times(1)).pruneTrieLog(key(2)); + } + @Test public void trieLogs_pruned_in_reverse_order_within_pruning_window() { // Given From 6b1ae691e6b6d7bb13491afafeea8a3c2bcc7a63 Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Tue, 30 Jul 2024 08:51:47 -0600 Subject: [PATCH 072/259] Change EOF Parsing to be non-recursive (#7396) EOF subcontainer parsing was recursive, potentially opening up stack attacks. Replace subcontainer parsing with a flat iterative solution. Signed-off-by: Danno Ferrin --- .../hyperledger/besu/evm/code/EOFLayout.java | 164 ++++++++++++------ 1 file changed, 111 insertions(+), 53 deletions(-) diff --git a/evm/src/main/java/org/hyperledger/besu/evm/code/EOFLayout.java b/evm/src/main/java/org/hyperledger/besu/evm/code/EOFLayout.java index 401308715a..1249e475b4 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/code/EOFLayout.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/code/EOFLayout.java @@ -27,8 +27,10 @@ import java.io.DataOutputStream; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; +import java.util.ArrayDeque; import java.util.Arrays; import java.util.Objects; +import java.util.Queue; import java.util.concurrent.atomic.AtomicReference; import javax.annotation.Nullable; @@ -111,7 +113,14 @@ public record EOFLayout( private EOFLayout(final Bytes container, final int version, final String invalidReason) { this( - container, version, null, null, 0, Bytes.EMPTY, invalidReason, new AtomicReference<>(null)); + container, + version, + new CodeSection[0], + new EOFLayout[0], + 0, + Bytes.EMPTY, + invalidReason, + new AtomicReference<>(null)); } private static EOFLayout invalidLayout( @@ -147,6 +156,33 @@ public record EOFLayout( return parseEOF(container, true); } + private record EOFParseStep( + Bytes container, + boolean strictSize, + int index, + EOFParseStep parent, + EOFLayout[] parentSubcontainers) { + String subcontainerIndex() { + if (index < 0) { + return ""; + } + StringBuilder version = new StringBuilder(); + EOFParseStep current = this; + while (current != null) { + var prev = current.parent; + if (prev == null) { + version.insert(0, index); + break; + } else { + version.insert(0, '.'); + version.insert(1, current.index); + } + current = prev; + } + return version.toString(); + } + } + /** * Parse EOF. * @@ -156,43 +192,78 @@ public record EOFLayout( * @return the eof layout */ public static EOFLayout parseEOF(final Bytes container, final boolean strictSize) { - final ByteArrayInputStream inputStream = new ByteArrayInputStream(container.toArrayUnsafe()); + Queue parseQueue = new ArrayDeque<>(); + parseQueue.add(new EOFParseStep(container, strictSize, -1, null, null)); + EOFLayout result = null; + while (true) { + EOFParseStep step = parseQueue.remove(); + var parsedContainer = parseEOF(step, parseQueue); + if (result == null) { + result = parsedContainer; + } + + if (!parsedContainer.isValid()) { + return invalidLayout( + container, + result.version, + step.index == -1 + ? parsedContainer.invalidReason + : "Invalid subcontainer " + + step.subcontainerIndex() + + " - " + + parsedContainer.invalidReason); + } + if (step.container.size() < parsedContainer.container.size()) { + return invalidLayout(container, parsedContainer.version, "excess data in subcontainer"); + } + if (step.index >= 0) { + step.parentSubcontainers[step.index] = parsedContainer; + } + if (parseQueue.isEmpty()) { + return result; + } + } + } + + private static EOFLayout parseEOF(final EOFParseStep step, final Queue queue) { + final ByteArrayInputStream inputStream = + new ByteArrayInputStream(step.container.toArrayUnsafe()); if (inputStream.available() < 3) { - return invalidLayout(container, -1, "EOF Container too small"); + return invalidLayout(step.container, -1, "EOF Container too small"); } if (inputStream.read() != 0xEF) { - return invalidLayout(container, -1, "EOF header byte 0 incorrect"); + return invalidLayout(step.container, -1, "EOF header byte 0 incorrect"); } if (inputStream.read() != 0x0) { - return invalidLayout(container, -1, "EOF header byte 1 incorrect"); + return invalidLayout(step.container, -1, "EOF header byte 1 incorrect"); } final int version = inputStream.read(); if (version > MAX_SUPPORTED_VERSION || version < 1) { - return invalidLayout(container, version, "Unsupported EOF Version " + version); + return invalidLayout(step.container, version, "Unsupported EOF Version " + version); } String error = readKind(inputStream, SECTION_TYPES); if (error != null) { - return invalidLayout(container, version, error); + return invalidLayout(step.container, version, error); } int typesLength = readUnsignedShort(inputStream); if (typesLength <= 0 || typesLength % 4 != 0) { - return invalidLayout(container, version, "Invalid Types section size"); + return invalidLayout(step.container, version, "Invalid Types section size"); } error = readKind(inputStream, SECTION_CODE); if (error != null) { - return invalidLayout(container, version, error); + return invalidLayout(step.container, version, error); } int codeSectionCount = readUnsignedShort(inputStream); if (codeSectionCount <= 0) { - return invalidLayout(container, version, "Invalid Code section count"); + return invalidLayout(step.container, version, "Invalid Code section count"); } if (codeSectionCount * 4 != typesLength) { return invalidLayout( - container, + step.container, version, "Type section length incompatible with code section count - 0x" + Integer.toHexString(codeSectionCount) @@ -201,7 +272,7 @@ public record EOFLayout( } if (codeSectionCount > 1024) { return invalidLayout( - container, + step.container, version, "Too many code sections - 0x" + Integer.toHexString(codeSectionCount)); } @@ -209,7 +280,7 @@ public record EOFLayout( for (int i = 0; i < codeSectionCount; i++) { int size = readUnsignedShort(inputStream); if (size <= 0) { - return invalidLayout(container, version, "Invalid Code section size for section " + i); + return invalidLayout(step.container, version, "Invalid Code section size for section " + i); } codeSectionSizes[i] = size; } @@ -219,15 +290,15 @@ public record EOFLayout( if (peekKind(inputStream) == SECTION_CONTAINER) { error = readKind(inputStream, SECTION_CONTAINER); if (error != null) { - return invalidLayout(container, version, error); + return invalidLayout(step.container, version, error); } containerSectionCount = readUnsignedShort(inputStream); if (containerSectionCount <= 0) { - return invalidLayout(container, version, "Invalid container section count"); + return invalidLayout(step.container, version, "Invalid container section count"); } if (containerSectionCount > 256) { return invalidLayout( - container, + step.container, version, "Too many container sections - 0x" + Integer.toHexString(containerSectionCount)); } @@ -236,7 +307,7 @@ public record EOFLayout( int size = readUnsignedShort(inputStream); if (size <= 0) { return invalidLayout( - container, version, "Invalid container section size for section " + i); + step.container, version, "Invalid container section size for section " + i); } containerSectionSizes[i] = size; } @@ -247,16 +318,16 @@ public record EOFLayout( error = readKind(inputStream, SECTION_DATA); if (error != null) { - return invalidLayout(container, version, error); + return invalidLayout(step.container, version, error); } int dataSize = readUnsignedShort(inputStream); if (dataSize < 0) { - return invalidLayout(container, version, "Invalid Data section size"); + return invalidLayout(step.container, version, "Invalid Data section size"); } error = readKind(inputStream, SECTION_TERMINATOR); if (error != null) { - return invalidLayout(container, version, error); + return invalidLayout(step.container, version, error); } int[][] typeData = new int[codeSectionCount][3]; for (int i = 0; i < codeSectionCount; i++) { @@ -266,11 +337,11 @@ public record EOFLayout( typeData[i][2] = readUnsignedShort(inputStream); } if (typeData[codeSectionCount - 1][2] == -1) { - return invalidLayout(container, version, "Incomplete type section"); + return invalidLayout(step.container, version, "Incomplete type section"); } if (typeData[0][0] != 0 || (typeData[0][1] & 0x7f) != 0) { return invalidLayout( - container, version, "Code section does not have zero inputs and outputs"); + step.container, version, "Code section does not have zero inputs and outputs"); } CodeSection[] codeSections = new CodeSection[codeSectionCount]; int pos = // calculate pos in stream... @@ -290,23 +361,23 @@ public record EOFLayout( for (int i = 0; i < codeSectionCount; i++) { int codeSectionSize = codeSectionSizes[i]; if (inputStream.skip(codeSectionSize) != codeSectionSize) { - return invalidLayout(container, version, "Incomplete code section " + i); + return invalidLayout(step.container, version, "Incomplete code section " + i); } if (typeData[i][0] > 0x7f) { return invalidLayout( - container, + step.container, version, "Type data input stack too large - 0x" + Integer.toHexString(typeData[i][0])); } if (typeData[i][1] > 0x80) { return invalidLayout( - container, + step.container, version, "Type data output stack too large - 0x" + Integer.toHexString(typeData[i][1])); } if (typeData[i][2] > 0x3ff) { return invalidLayout( - container, + step.container, version, "Type data max stack too large - 0x" + Integer.toHexString(typeData[i][2])); } @@ -314,7 +385,7 @@ public record EOFLayout( new CodeSection(codeSectionSize, typeData[i][0], typeData[i][1], typeData[i][2], pos); if (i == 0 && typeData[0][1] != 0x80) { return invalidLayout( - container, + step.container, version, "Code section at zero expected non-returning flag, but had return stack of " + typeData[0][1]); @@ -324,44 +395,31 @@ public record EOFLayout( EOFLayout[] subContainers = new EOFLayout[containerSectionCount]; for (int i = 0; i < containerSectionCount; i++) { - int subcontianerSize = containerSectionSizes[i]; - if (subcontianerSize != inputStream.skip(subcontianerSize)) { - return invalidLayout(container, version, "incomplete subcontainer"); - } - Bytes subcontainer = container.slice(pos, subcontianerSize); - pos += subcontianerSize; - EOFLayout subLayout = EOFLayout.parseEOF(subcontainer, false); - if (subLayout.container.size() < subcontainer.size()) { - return invalidLayout(container, version, "excess data in subcontainer"); - } - if (!subLayout.isValid()) { - String invalidSubReason = subLayout.invalidReason; - return invalidLayout( - container, - version, - invalidSubReason.contains("invalid subcontainer") - ? invalidSubReason - : "invalid subcontainer - " + invalidSubReason); + int subcontainerSize = containerSectionSizes[i]; + if (subcontainerSize != inputStream.skip(subcontainerSize)) { + return invalidLayout(step.container, version, "incomplete subcontainer"); } - subContainers[i] = subLayout; + Bytes subcontainer = step.container.slice(pos, subcontainerSize); + pos += subcontainerSize; + queue.add(new EOFParseStep(subcontainer, false, i, step, subContainers)); } long loadedDataCount = inputStream.skip(dataSize); - Bytes data = container.slice(pos, (int) loadedDataCount); + Bytes data = step.container.slice(pos, (int) loadedDataCount); Bytes completeContainer; if (inputStream.read() != -1) { - if (strictSize) { - return invalidLayout(container, version, "Dangling data after end of all sections"); + if (step.strictSize) { + return invalidLayout(step.container, version, "Dangling data after end of all sections"); } else { - completeContainer = container.slice(0, pos + dataSize); + completeContainer = step.container.slice(0, pos + dataSize); } } else { - completeContainer = container; + completeContainer = step.container; } - if (strictSize && dataSize != data.size()) { + if (step.strictSize && dataSize != data.size()) { return invalidLayout( - container, version, "Truncated data section when a complete section was required"); + step.container, version, "Truncated data section when a complete section was required"); } return new EOFLayout(completeContainer, version, codeSections, subContainers, dataSize, data); From 9592b64310cd7e45d4d2f8bbad489af72ddad68d Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Tue, 30 Jul 2024 09:40:13 -0600 Subject: [PATCH 073/259] Lock evmtool code-validate into runtime mode (#7397) To conform to fuzzing practices, `code-validate` expects all code to be runtime code. Signed-off-by: Danno Ferrin --- .../hyperledger/besu/evmtool/CodeValidateSubCommand.java | 7 ++++++- .../org/hyperledger/besu/evmtool/EvmToolSpecTests.java | 5 +++++ .../hyperledger/besu/evmtool/code-validate/initcode.json | 7 +++++++ .../hyperledger/besu/evmtool/code-validate/runtime.json | 7 +++++++ 4 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/code-validate/initcode.json create mode 100644 ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/code-validate/runtime.json 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 e16d4014f0..3bc2d41d02 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 @@ -23,7 +23,9 @@ import org.hyperledger.besu.evm.Code; import org.hyperledger.besu.evm.EVM; import org.hyperledger.besu.evm.EvmSpecVersion; 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.evm.code.EOFLayout.EOFContainerMode; import org.hyperledger.besu.util.LogConfigurator; import java.io.BufferedReader; @@ -45,7 +47,7 @@ import picocli.CommandLine.ParentCommand; * fuzzing. It implements the Runnable interface and is annotated with the {@code * CommandLine.Command} annotation. */ -@SuppressWarnings({"ConstantValue", "DataFlowIssue"}) +@SuppressWarnings({"ConstantValue"}) @CommandLine.Command( name = COMMAND_NAME, description = "Validates EVM code for fuzzing", @@ -154,6 +156,9 @@ public class CodeValidateSubCommand implements Runnable { Code code = evm.getCodeUncached(codeBytes); if (code instanceof CodeInvalid codeInvalid) { return "err: " + codeInvalid.getInvalidReason(); + } else if (EOFContainerMode.INITCODE.equals( + ((CodeV1) code).getEofLayout().containerMode().get())) { + return "err: code is valid initcode. Runtime code expected"; } else { return "OK " + IntStream.range(0, code.getCodeSectionCount()) diff --git a/ethereum/evmtool/src/test/java/org/hyperledger/besu/evmtool/EvmToolSpecTests.java b/ethereum/evmtool/src/test/java/org/hyperledger/besu/evmtool/EvmToolSpecTests.java index 24cd858ba7..9ec5e431da 100644 --- a/ethereum/evmtool/src/test/java/org/hyperledger/besu/evmtool/EvmToolSpecTests.java +++ b/ethereum/evmtool/src/test/java/org/hyperledger/besu/evmtool/EvmToolSpecTests.java @@ -62,6 +62,10 @@ public class EvmToolSpecTests { return findSpecFiles(new String[] {"b11r"}); } + public static Object[][] codeValidateTests() { + return findSpecFiles(new String[] {"code-validate"}); + } + public static Object[][] prettyPrintTests() { return findSpecFiles(new String[] {"pretty-print"}); } @@ -122,6 +126,7 @@ public class EvmToolSpecTests { @MethodSource({ "blocktestTests", "b11rTests", + "codeValidateTests", "prettyPrintTests", "stateTestTests", "t8nTests", diff --git a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/code-validate/initcode.json b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/code-validate/initcode.json new file mode 100644 index 0000000000..c119235cdc --- /dev/null +++ b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/code-validate/initcode.json @@ -0,0 +1,7 @@ +{ + "cli": [ + "code-validate" + ], + "stdin": "ef000101000402000100060300010014040000000080000260006000ee00ef00010100040200010001040000000080000000", + "stdout": "err: code is valid initcode. Runtime code expected" +} diff --git a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/code-validate/runtime.json b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/code-validate/runtime.json new file mode 100644 index 0000000000..7965815559 --- /dev/null +++ b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/code-validate/runtime.json @@ -0,0 +1,7 @@ +{ + "cli": [ + "code-validate" + ], + "stdin": "ef00010100040200010001040000000080000000", + "stdout": "OK 00\n" +} From 9fe374a62b45a2687b8ba04556ea91cdb5cf86df Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Wed, 31 Jul 2024 09:27:37 +1000 Subject: [PATCH 074/259] 5098 Branch 1: Groundwork for coming changes (#7398) * 5098: Add RpcErrorTypes Signed-off-by: Matilda Clerke * 5098: Modify InvalidJsonRpcParameters and InvalidJsonRpcRequestException, apply spotless Signed-off-by: Matilda Clerke * 5098: Modify InvalidJsonRpcParameters and InvalidJsonRpcRequestException, apply spotless Signed-off-by: Matilda Clerke * 5098: Add JsonRpcParameterException for later use Signed-off-by: Matilda Clerke * 5098: Address review comments, apply spotless Signed-off-by: Matilda Clerke * 5098: Update plugin-api gradle hash Signed-off-by: Matilda Clerke * 5098: Add comment on INVALID_PARAMS_ERROR_CODE Signed-off-by: Matilda Clerke * 5098: Apply spotless on latest changes Signed-off-by: Matilda Clerke --------- Signed-off-by: Matilda Clerke --- .../execution/TracedJsonRpcProcessor.java | 66 ++++++++++++++ .../exception/InvalidJsonRpcParameters.java | 11 +++ .../InvalidJsonRpcRequestException.java | 22 +++++ .../internal/parameters/JsonRpcParameter.java | 16 ++++ .../internal/response/RpcErrorType.java | 87 ++++++++++++++++++- plugin-api/build.gradle | 2 +- .../plugin/services/rpc/RpcMethodError.java | 3 + 7 files changed, 204 insertions(+), 3 deletions(-) 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 369e425b6f..eba3827bfa 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 @@ -57,6 +57,72 @@ public class TracedJsonRpcProcessor implements JsonRpcProcessor { this.rpcErrorsCounter.labels(method.getName(), errorResponse.getErrorType().name()).inc(); switch (errorResponse.getErrorType()) { case INVALID_PARAMS: + case INVALID_ACCOUNT_PARAMS: + case INVALID_ADDRESS_HASH_PARAMS: + case INVALID_ADDRESS_PARAMS: + case INVALID_AUTH_PARAMS: + case INVALID_BLOB_COUNT: + case INVALID_BLOB_GAS_USED_PARAMS: + case INVALID_BLOCK_PARAMS: + case INVALID_BLOCK_COUNT_PARAMS: + case INVALID_BLOCK_HASH_PARAMS: + case INVALID_BLOCK_INDEX_PARAMS: + case INVALID_BLOCK_NUMBER_PARAMS: + case INVALID_CALL_PARAMS: + case INVALID_CONSOLIDATION_REQUEST_PARAMS: + case INVALID_CREATE_PRIVACY_GROUP_PARAMS: + case INVALID_DATA_PARAMS: + case INVALID_DEPOSIT_REQUEST_PARAMS: + case INVALID_ENGINE_EXCHANGE_TRANSITION_CONFIGURATION_PARAMS: + case INVALID_ENGINE_FORKCHOICE_UPDATED_PARAMS: + case INVALID_ENGINE_PAYLOAD_ATTRIBUTES_PARAMS: + case INVALID_ENGINE_PAYLOAD_PARAMS: + case INVALID_ENGINE_PREPARE_PAYLOAD_PARAMS: + case INVALID_ENODE_PARAMS: + case INVALID_EXCESS_BLOB_GAS_PARAMS: + case INVALID_EXTRA_DATA_PARAMS: + case INVALID_FILTER_PARAMS: + case INVALID_GAS_PRICE_PARAMS: + case INVALID_HASH_RATE_PARAMS: + case INVALID_ID_PARAMS: + case INVALID_IS_TRANSACTION_COMPLETE_PARAMS: + case INVALID_LOG_FILTER_PARAMS: + case INVALID_LOG_LEVEL_PARAMS: + case INVALID_MAX_RESULTS_PARAMS: + case INVALID_METHOD_PARAMS: + case INVALID_MIN_GAS_PRICE_PARAMS: + case INVALID_MIN_PRIORITY_FEE_PARAMS: + case INVALID_MIX_HASH_PARAMS: + case INVALID_NONCE_PARAMS: + case INVALID_PARENT_BEACON_BLOCK_ROOT_PARAMS: + case INVALID_PARAM_COUNT: + case INVALID_PAYLOAD_ID_PARAMS: + case INVALID_PENDING_TRANSACTIONS_PARAMS: + case INVAlID_PLUGIN_NAME_PARAMS: + case INVALID_POSITION_PARAMS: + case INVALID_POW_HASH_PARAMS: + case INVALID_PRIVACY_GROUP_PARAMS: + case INVALID_PRIVATE_FROM_PARAMS: + case INVALID_PRIVATE_FOR_PARAMS: + case INVALID_REMOTE_CAPABILITIES_PARAMS: + case INVALID_REWARD_PERCENTILES_PARAMS: + case INVALID_SEALER_ID_PARAMS: + case INVALID_STORAGE_KEYS_PARAMS: + case INVALID_SUBSCRIPTION_PARAMS: + case INVALID_TARGET_GAS_LIMIT_PARAMS: + case INVALID_TIMESTAMP_PARAMS: + case INVALID_TRACE_CALL_MANY_PARAMS: + case INVALID_TRACE_NUMBERS_PARAMS: + case INVALID_TRACE_TYPE_PARAMS: + case INVALID_TRANSACTION_PARAMS: + case INVALID_TRANSACTION_HASH_PARAMS: + case INVALID_TRANSACTION_ID_PARAMS: + case INVALID_TRANSACTION_INDEX_PARAMS: + case INVALID_TRANSACTION_LIMIT_PARAMS: + case INVALID_TRANSACTION_TRACE_PARAMS: + case INVALID_VERSIONED_HASH_PARAMS: + case INVALID_VOTE_TYPE_PARAMS: + case INVALID_WITHDRAWALS_PARAMS: metricSpan.setStatus(StatusCode.ERROR, "Invalid Params"); break; case UNAUTHORIZED: diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/exception/InvalidJsonRpcParameters.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/exception/InvalidJsonRpcParameters.java index 65fe455bd5..ea28ca7c4a 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/exception/InvalidJsonRpcParameters.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/exception/InvalidJsonRpcParameters.java @@ -14,13 +14,24 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; + public class InvalidJsonRpcParameters extends InvalidJsonRpcRequestException { public InvalidJsonRpcParameters(final String s) { super(s); } + public InvalidJsonRpcParameters(final String message, final RpcErrorType rpcErrorType) { + super(message, rpcErrorType); + } + public InvalidJsonRpcParameters(final String message, final Throwable cause) { super(message, cause); } + + public InvalidJsonRpcParameters( + final String message, final RpcErrorType rpcErrorType, final Throwable cause) { + super(message, rpcErrorType, cause); + } } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/exception/InvalidJsonRpcRequestException.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/exception/InvalidJsonRpcRequestException.java index 5353439e0b..7dcda5939c 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/exception/InvalidJsonRpcRequestException.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/exception/InvalidJsonRpcRequestException.java @@ -14,12 +14,34 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; + public class InvalidJsonRpcRequestException extends IllegalArgumentException { + + private final RpcErrorType rpcErrorType; + public InvalidJsonRpcRequestException(final String message) { super(message); + rpcErrorType = RpcErrorType.INVALID_PARAMS; + } + + public InvalidJsonRpcRequestException(final String message, final RpcErrorType rpcErrorType) { + super(message); + this.rpcErrorType = rpcErrorType; } public InvalidJsonRpcRequestException(final String message, final Throwable cause) { super(message, cause); + rpcErrorType = RpcErrorType.INVALID_PARAMS; + } + + public InvalidJsonRpcRequestException( + final String message, final RpcErrorType rpcErrorType, final Throwable cause) { + super(message, cause); + this.rpcErrorType = rpcErrorType; + } + + public RpcErrorType getRpcErrorType() { + return rpcErrorType; } } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/JsonRpcParameter.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/JsonRpcParameter.java index 6e10b7a231..a8b5fb7dc8 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/JsonRpcParameter.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/JsonRpcParameter.java @@ -40,6 +40,8 @@ public class JsonRpcParameter { * @param The type of parameter. * @return Returns the parameter cast as T if available, otherwise throws exception. */ + // TODO: update to throw JsonRpcParameterException as a checked exception, forcing callers to + // handle it to supply appropriate context public T required(final Object[] params, final int index, final Class paramClass) { return optional(params, index, paramClass) .orElseThrow( @@ -58,6 +60,8 @@ public class JsonRpcParameter { * @param The type of parameter. * @return Returns the parameter cast as T if available. */ + // TODO: update to throw JsonRpcParameterException as a checked exception, forcing callers to + // handle it to supply appropriate context @SuppressWarnings("unchecked") public Optional optional( final Object[] params, final int index, final Class paramClass) { @@ -87,6 +91,8 @@ public class JsonRpcParameter { return Optional.of(param); } + // TODO: update to throw JsonRpcParameterException as a checked exception, forcing callers to + // handle it to supply appropriate context public Optional> optionalList( final Object[] params, final int index, final Class listClass) { if (params == null || params.length <= index || params[index] == null) { @@ -108,4 +114,14 @@ public class JsonRpcParameter { } return Optional.empty(); } + + public static class JsonRpcParameterException extends Exception { + public JsonRpcParameterException(final String message) { + super(message); + } + + public JsonRpcParameterException(final String message, final Throwable cause) { + super(message, cause); + } + } } 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 1b1ee48c0a..309fe49862 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 @@ -26,7 +26,91 @@ public enum RpcErrorType implements RpcMethodError { PARSE_ERROR(-32700, "Parse error"), INVALID_REQUEST(-32600, "Invalid Request"), METHOD_NOT_FOUND(-32601, "Method not found"), - INVALID_PARAMS(-32602, "Invalid params"), + + INVALID_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid params"), + INVALID_ACCOUNT_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid account params"), + INVALID_ADDRESS_HASH_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid address hash params"), + INVALID_ADDRESS_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid address params"), + INVALID_AUTH_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid auth params"), + INVALID_BLOB_COUNT( + INVALID_PARAMS_ERROR_CODE, + "Invalid blob count (blob transactions must have at least one blob)"), + INVALID_BLOB_GAS_USED_PARAMS( + INVALID_PARAMS_ERROR_CODE, "Invalid blob gas used param (missing or invalid)"), + INVALID_BLOCK_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid block, unable to parse RLP"), + INVALID_BLOCK_COUNT_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid block count params"), + INVALID_BLOCK_HASH_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid block hash params"), + INVALID_BLOCK_INDEX_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid block index params"), + INVALID_BLOCK_NUMBER_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid block number params"), + INVALID_CALL_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid call params"), + INVALID_CONSOLIDATION_REQUEST_PARAMS( + INVALID_PARAMS_ERROR_CODE, "Invalid consolidation request params"), + INVALID_CREATE_PRIVACY_GROUP_PARAMS( + INVALID_PARAMS_ERROR_CODE, "Invalid create privacy group params"), + INVALID_DATA_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid data params"), + INVALID_DEPOSIT_REQUEST_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid deposit request"), + INVALID_ENGINE_EXCHANGE_TRANSITION_CONFIGURATION_PARAMS( + INVALID_PARAMS_ERROR_CODE, "Invalid engine exchange transition configuration params"), + INVALID_ENGINE_FORKCHOICE_UPDATED_PARAMS( + INVALID_PARAMS_ERROR_CODE, "Invalid engine forkchoice updated params"), + INVALID_ENGINE_PAYLOAD_ATTRIBUTES_PARAMS( + INVALID_PARAMS_ERROR_CODE, "Invalid engine payload attributes parameter"), + INVALID_ENGINE_PAYLOAD_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid engine payload parameter"), + INVALID_ENGINE_PREPARE_PAYLOAD_PARAMS( + INVALID_PARAMS_ERROR_CODE, "Invalid engine prepare payload parameter"), + 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_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"), + INVALID_HASH_RATE_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid hash rate params"), + INVALID_ID_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid ID params"), + INVALID_IS_TRANSACTION_COMPLETE_PARAMS( + INVALID_PARAMS_ERROR_CODE, "Invalid is transaction complete params"), + INVALID_LOG_FILTER_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid log filter params"), + INVALID_LOG_LEVEL_PARAMS( + INVALID_PARAMS_ERROR_CODE, "Invalid log level params (missing or incorrect)"), + INVALID_MAX_RESULTS_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid max results params"), + INVALID_METHOD_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid method params"), + INVALID_MIN_GAS_PRICE_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid min gas price params"), + INVALID_MIN_PRIORITY_FEE_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid min priority fee params"), + INVALID_MIX_HASH_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid mix hash params"), + INVALID_NONCE_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid nonce params"), + INVALID_PARENT_BEACON_BLOCK_ROOT_PARAMS( + INVALID_PARAMS_ERROR_CODE, "Invalid parent beacon block root (missing or incorrect)"), + INVALID_PARAM_COUNT(INVALID_PARAMS_ERROR_CODE, "Invalid number of params"), + INVALID_PAYLOAD_ID_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid payload id params"), + INVALID_PENDING_TRANSACTIONS_PARAMS( + INVALID_PARAMS_ERROR_CODE, "Invalid pending transactions params"), + INVAlID_PLUGIN_NAME_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid plug in name params"), + INVALID_POSITION_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid position params"), + INVALID_POW_HASH_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid pow hash params"), + INVALID_PRIVACY_GROUP_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid privacy group params"), + INVALID_PRIVATE_FROM_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid private from params"), + INVALID_PRIVATE_FOR_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid private for params"), + INVALID_REMOTE_CAPABILITIES_PARAMS( + INVALID_PARAMS_ERROR_CODE, "Invalid remote capabilities params"), + INVALID_REWARD_PERCENTILES_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid reward percentiles params"), + INVALID_SEALER_ID_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid sealer ID params"), + INVALID_STORAGE_KEYS_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid storage keys params"), + INVALID_SUBSCRIPTION_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid subscription params"), + INVALID_TARGET_GAS_LIMIT_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid target gas limit params"), + INVALID_TIMESTAMP_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid timestamp parameter"), + INVALID_TRACE_CALL_MANY_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid trace call many params"), + INVALID_TRACE_NUMBERS_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid trace numbers params"), + INVALID_TRACE_TYPE_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid trace type params"), + INVALID_TRANSACTION_PARAMS( + INVALID_PARAMS_ERROR_CODE, "Invalid transaction params (missing or incorrect)"), + INVALID_TRANSACTION_HASH_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid transaction hash params"), + INVALID_TRANSACTION_ID_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid transaction id params"), + INVALID_TRANSACTION_INDEX_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid transaction index params"), + INVALID_TRANSACTION_LIMIT_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid transaction limit params"), + INVALID_TRANSACTION_TRACE_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid transaction trace params"), + INVALID_VERSIONED_HASH_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid versioned hash params"), + INVALID_VOTE_TYPE_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid vote type params"), + INVALID_WITHDRAWALS_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid withdrawals"), + INTERNAL_ERROR(-32603, "Internal error"), TIMEOUT_ERROR(-32603, "Timeout expired"), @@ -231,7 +315,6 @@ public enum RpcErrorType implements RpcMethodError { UNKNOWN(-32603, "Unknown internal error"), INVALID_BLOBS(-32603, "blobs failed kzg validation"); - private final int code; private final String message; private final Function> dataDecoder; diff --git a/plugin-api/build.gradle b/plugin-api/build.gradle index 0d593b1105..c7203e2f88 100644 --- a/plugin-api/build.gradle +++ b/plugin-api/build.gradle @@ -70,7 +70,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 = 'oPsVhFhdIkzHqD+jjwRX7dbgeNeKbpCmPjiBWDdMV7o=' + knownHash = 'o0IuPVpCvE3YUzuZgVf4NP74q1ECpkbAkeC6u/Nr8yU=' } check.dependsOn('checkAPIChanges') diff --git a/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/rpc/RpcMethodError.java b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/rpc/RpcMethodError.java index b8d6791ece..efba770701 100644 --- a/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/rpc/RpcMethodError.java +++ b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/rpc/RpcMethodError.java @@ -23,6 +23,9 @@ import java.util.Optional; */ public interface RpcMethodError { + /** The error code for all invalid params */ + static final int INVALID_PARAMS_ERROR_CODE = -32602; + /** * Retrieves the error code associated with the RPC error. * From de957aaa1fa3dd46d992841f7121b8c7aa2791b4 Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Wed, 31 Jul 2024 16:03:01 +1000 Subject: [PATCH 075/259] 5098 branch 2 update invalid accounts params (#7402) * 5098: Add RpcErrorTypes Signed-off-by: Matilda Clerke * 5098: Modify InvalidJsonRpcParameters and InvalidJsonRpcRequestException, apply spotless Signed-off-by: Matilda Clerke * 5098: Modify InvalidJsonRpcParameters and InvalidJsonRpcRequestException, apply spotless Signed-off-by: Matilda Clerke * 5098: Add JsonRpcParameterException for later use Signed-off-by: Matilda Clerke * 5098: Update locations for RpcErrorType.INVALID_ACCOUNTS_PARAMS Signed-off-by: Matilda Clerke * 5098: Address review comments, apply spotless Signed-off-by: Matilda Clerke * 5098: Update with changes from branch 1 Signed-off-by: Matilda Clerke * 5098: apply spotless Signed-off-by: Matilda Clerke * 5098: Update plugin-api gradle hash Signed-off-by: Matilda Clerke * 5098: Add comment on INVALID_PARAMS_ERROR_CODE Signed-off-by: Matilda Clerke * 5098: Apply spotless on latest changes Signed-off-by: Matilda Clerke * 5098: Fix broken unit test Signed-off-by: Matilda Clerke * 5098: Fix broken unit test Signed-off-by: Matilda Clerke --------- Signed-off-by: Matilda Clerke --- .../permissioning/PermAddAccountsToAllowlist.java | 9 ++++++++- .../permissioning/PermRemoveAccountsFromAllowlist.java | 10 +++++++++- .../permissioning/PermAddAccountsToAllowlistTest.java | 3 +-- .../permissioning/PermAddAccountsToWhitelistTest.java | 3 +-- .../PermRemoveAccountsFromAllowlistTest.java | 3 +-- .../PermRemoveAccountsFromWhitelistTest.java | 3 +-- 6 files changed, 21 insertions(+), 10 deletions(-) diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermAddAccountsToAllowlist.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermAddAccountsToAllowlist.java index 21898c79ed..407edcd8fe 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermAddAccountsToAllowlist.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermAddAccountsToAllowlist.java @@ -16,6 +16,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.permissioning import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; @@ -44,7 +45,13 @@ public class PermAddAccountsToAllowlist implements JsonRpcMethod { @Override @SuppressWarnings("unchecked") public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { - final List accountsList = requestContext.getRequiredParameter(0, List.class); + final List accountsList; + try { + accountsList = requestContext.getRequiredParameter(0, List.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid accounts list parameter", RpcErrorType.INVALID_ACCOUNT_PARAMS, e); + } if (allowlistController.isPresent()) { final AllowlistOperationResult addResult = diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermRemoveAccountsFromAllowlist.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermRemoveAccountsFromAllowlist.java index aefd69141d..bd0176dbd3 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermRemoveAccountsFromAllowlist.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermRemoveAccountsFromAllowlist.java @@ -16,6 +16,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.permissioning import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; @@ -44,7 +45,14 @@ public class PermRemoveAccountsFromAllowlist implements JsonRpcMethod { @Override @SuppressWarnings("unchecked") public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { - final List accountsList = requestContext.getRequiredParameter(0, List.class); + final List accountsList; + try { + accountsList = requestContext.getRequiredParameter(0, List.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid accounts list parameter", RpcErrorType.INVALID_ACCOUNT_PARAMS, e); + } + if (allowlistController.isPresent()) { final AllowlistOperationResult removeResult = allowlistController.get().removeAccounts(accountsList); diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermAddAccountsToAllowlistTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermAddAccountsToAllowlistTest.java index 0892cc5c64..a37db420a1 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermAddAccountsToAllowlistTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermAddAccountsToAllowlistTest.java @@ -124,9 +124,8 @@ public class PermAddAccountsToAllowlistTest { final Throwable thrown = catchThrowable(() -> method.response(request)); assertThat(thrown) - .hasNoCause() .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage("Missing required json rpc parameter at index 0"); + .hasMessage("Invalid accounts list parameter"); } private JsonRpcRequestContext request(final List accounts) { diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermAddAccountsToWhitelistTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermAddAccountsToWhitelistTest.java index 0dd4fb73d4..d07beb934f 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermAddAccountsToWhitelistTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermAddAccountsToWhitelistTest.java @@ -125,9 +125,8 @@ public class PermAddAccountsToWhitelistTest { final Throwable thrown = catchThrowable(() -> method.response(request)); assertThat(thrown) - .hasNoCause() .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage("Missing required json rpc parameter at index 0"); + .hasMessage("Invalid accounts list parameter"); } private JsonRpcRequestContext request(final List accounts) { diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermRemoveAccountsFromAllowlistTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermRemoveAccountsFromAllowlistTest.java index a70ac9e4b3..2e8218752e 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermRemoveAccountsFromAllowlistTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermRemoveAccountsFromAllowlistTest.java @@ -125,9 +125,8 @@ public class PermRemoveAccountsFromAllowlistTest { final Throwable thrown = catchThrowable(() -> method.response(request)); assertThat(thrown) - .hasNoCause() .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage("Missing required json rpc parameter at index 0"); + .hasMessage("Invalid accounts list parameter"); } private JsonRpcRequestContext request(final List accounts) { diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermRemoveAccountsFromWhitelistTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermRemoveAccountsFromWhitelistTest.java index 934329052d..582ef1d32a 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermRemoveAccountsFromWhitelistTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermRemoveAccountsFromWhitelistTest.java @@ -126,9 +126,8 @@ public class PermRemoveAccountsFromWhitelistTest { final Throwable thrown = catchThrowable(() -> method.response(request)); assertThat(thrown) - .hasNoCause() .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage("Missing required json rpc parameter at index 0"); + .hasMessage("Invalid accounts list parameter"); } private JsonRpcRequestContext request(final List accounts) { From 4e79c810a6c9e94db6168a46e769d82e747da226 Mon Sep 17 00:00:00 2001 From: Sally MacFarlane Date: Wed, 31 Jul 2024 16:28:57 +1000 Subject: [PATCH 076/259] removed permissioning methods referencing whitelist (#7401) * removed whitelist permissioning methods * removed actual RPC methods Signed-off-by: Sally MacFarlane --------- Signed-off-by: Sally MacFarlane --- CHANGELOG.md | 1 + .../PermAddAccountsToWhitelist.java | 34 --- .../PermAddNodesToWhitelist.java | 34 --- .../PermGetAccountsWhitelist.java | 34 --- .../permissioning/PermGetNodesWhitelist.java | 34 --- .../PermRemoveAccountsFromWhitelist.java | 34 --- .../PermRemoveNodesFromWhitelist.java | 34 --- .../jsonrpc/methods/PermJsonRpcMethods.java | 12 -- .../PermAddAccountsToAllowlistTest.java | 16 +- .../PermAddAccountsToWhitelistTest.java | 136 ------------ .../PermAddNodesToWhitelistTest.java | 203 ------------------ .../PermGetAccountsWhitelistTest.java | 77 ------- .../PermGetNodesWhitelistTest.java | 124 ----------- .../PermRemoveAccountsFromWhitelistTest.java | 137 ------------ .../PermRemoveNodesFromWhitelistTest.java | 200 ----------------- .../methods/PermJsonRpcMethodsTest.java | 34 --- 16 files changed, 9 insertions(+), 1135 deletions(-) delete mode 100644 ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermAddAccountsToWhitelist.java delete mode 100644 ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermAddNodesToWhitelist.java delete mode 100644 ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermGetAccountsWhitelist.java delete mode 100644 ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermGetNodesWhitelist.java delete mode 100644 ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermRemoveAccountsFromWhitelist.java delete mode 100644 ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermRemoveNodesFromWhitelist.java delete mode 100644 ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermAddAccountsToWhitelistTest.java delete mode 100644 ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermAddNodesToWhitelistTest.java delete mode 100644 ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermGetAccountsWhitelistTest.java delete mode 100644 ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermGetNodesWhitelistTest.java delete mode 100644 ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermRemoveAccountsFromWhitelistTest.java delete mode 100644 ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermRemoveNodesFromWhitelistTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 072a84c2ba..498b3c1edd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ - Allow configuration of Withdrawal Request Contract Address via genesis configuration [#7356](https://github.com/hyperledger/besu/pull/7356) ### Breaking Changes +- Remove long-deprecated `perm*whitelist*` methods [#7401](https://github.com/hyperledger/besu/pull/7401) ### Additions and Improvements diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermAddAccountsToWhitelist.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermAddAccountsToWhitelist.java deleted file mode 100644 index 37d530634a..0000000000 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermAddAccountsToWhitelist.java +++ /dev/null @@ -1,34 +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.ethereum.api.jsonrpc.internal.methods.permissioning; - -import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; -import org.hyperledger.besu.ethereum.permissioning.AccountLocalConfigPermissioningController; - -import java.util.Optional; - -@Deprecated -public class PermAddAccountsToWhitelist extends PermAddAccountsToAllowlist { - - public PermAddAccountsToWhitelist( - final Optional allowlistController) { - super(allowlistController); - } - - @Override - public String getName() { - return RpcMethod.PERM_ADD_ACCOUNTS_TO_WHITELIST.getMethodName(); - } -} diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermAddNodesToWhitelist.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermAddNodesToWhitelist.java deleted file mode 100644 index c75a86e28c..0000000000 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermAddNodesToWhitelist.java +++ /dev/null @@ -1,34 +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.ethereum.api.jsonrpc.internal.methods.permissioning; - -import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; -import org.hyperledger.besu.ethereum.permissioning.NodeLocalConfigPermissioningController; - -import java.util.Optional; - -@Deprecated -public class PermAddNodesToWhitelist extends PermAddNodesToAllowlist { - - public PermAddNodesToWhitelist( - final Optional nodeAllowlistPermissioningController) { - super(nodeAllowlistPermissioningController); - } - - @Override - public String getName() { - return RpcMethod.PERM_ADD_NODES_TO_WHITELIST.getMethodName(); - } -} diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermGetAccountsWhitelist.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermGetAccountsWhitelist.java deleted file mode 100644 index 97281ae707..0000000000 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermGetAccountsWhitelist.java +++ /dev/null @@ -1,34 +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.ethereum.api.jsonrpc.internal.methods.permissioning; - -import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; -import org.hyperledger.besu.ethereum.permissioning.AccountLocalConfigPermissioningController; - -import java.util.Optional; - -@Deprecated -public class PermGetAccountsWhitelist extends PermGetAccountsAllowlist { - - public PermGetAccountsWhitelist( - final Optional allowlistController) { - super(allowlistController); - } - - @Override - public String getName() { - return RpcMethod.PERM_GET_ACCOUNTS_WHITELIST.getMethodName(); - } -} diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermGetNodesWhitelist.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermGetNodesWhitelist.java deleted file mode 100644 index 850872d3fd..0000000000 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermGetNodesWhitelist.java +++ /dev/null @@ -1,34 +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.ethereum.api.jsonrpc.internal.methods.permissioning; - -import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; -import org.hyperledger.besu.ethereum.permissioning.NodeLocalConfigPermissioningController; - -import java.util.Optional; - -@Deprecated -public class PermGetNodesWhitelist extends PermGetNodesAllowlist { - - public PermGetNodesWhitelist( - final Optional nodeAllowlistPermissioningController) { - super(nodeAllowlistPermissioningController); - } - - @Override - public String getName() { - return RpcMethod.PERM_GET_NODES_WHITELIST.getMethodName(); - } -} diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermRemoveAccountsFromWhitelist.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermRemoveAccountsFromWhitelist.java deleted file mode 100644 index f72984f03b..0000000000 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermRemoveAccountsFromWhitelist.java +++ /dev/null @@ -1,34 +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.ethereum.api.jsonrpc.internal.methods.permissioning; - -import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; -import org.hyperledger.besu.ethereum.permissioning.AccountLocalConfigPermissioningController; - -import java.util.Optional; - -@Deprecated -public class PermRemoveAccountsFromWhitelist extends PermRemoveAccountsFromAllowlist { - - public PermRemoveAccountsFromWhitelist( - final Optional allowlistController) { - super(allowlistController); - } - - @Override - public String getName() { - return RpcMethod.PERM_REMOVE_ACCOUNTS_FROM_WHITELIST.getMethodName(); - } -} diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermRemoveNodesFromWhitelist.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermRemoveNodesFromWhitelist.java deleted file mode 100644 index a0b4de534c..0000000000 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermRemoveNodesFromWhitelist.java +++ /dev/null @@ -1,34 +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.ethereum.api.jsonrpc.internal.methods.permissioning; - -import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; -import org.hyperledger.besu.ethereum.permissioning.NodeLocalConfigPermissioningController; - -import java.util.Optional; - -@Deprecated -public class PermRemoveNodesFromWhitelist extends PermRemoveNodesFromAllowlist { - - public PermRemoveNodesFromWhitelist( - final Optional nodeAllowlistPermissioningController) { - super(nodeAllowlistPermissioningController); - } - - @Override - public String getName() { - return RpcMethod.PERM_REMOVE_NODES_FROM_WHITELIST.getMethodName(); - } -} diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/PermJsonRpcMethods.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/PermJsonRpcMethods.java index 3a3b6cfb00..96fce83eab 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/PermJsonRpcMethods.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/PermJsonRpcMethods.java @@ -17,18 +17,12 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.methods; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.permissioning.PermAddAccountsToAllowlist; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.permissioning.PermAddAccountsToWhitelist; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.permissioning.PermAddNodesToAllowlist; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.permissioning.PermAddNodesToWhitelist; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.permissioning.PermGetAccountsAllowlist; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.permissioning.PermGetAccountsWhitelist; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.permissioning.PermGetNodesAllowlist; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.permissioning.PermGetNodesWhitelist; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.permissioning.PermReloadPermissionsFromFile; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.permissioning.PermRemoveAccountsFromAllowlist; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.permissioning.PermRemoveAccountsFromWhitelist; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.permissioning.PermRemoveNodesFromAllowlist; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.permissioning.PermRemoveNodesFromWhitelist; import org.hyperledger.besu.ethereum.permissioning.AccountLocalConfigPermissioningController; import org.hyperledger.besu.ethereum.permissioning.NodeLocalConfigPermissioningController; @@ -55,17 +49,11 @@ public class PermJsonRpcMethods extends ApiGroupJsonRpcMethods { @Override protected Map create() { return mapOf( - new PermAddNodesToWhitelist(nodeAllowlistController), new PermAddNodesToAllowlist(nodeAllowlistController), - new PermRemoveNodesFromWhitelist(nodeAllowlistController), new PermRemoveNodesFromAllowlist(nodeAllowlistController), - new PermGetNodesWhitelist(nodeAllowlistController), new PermGetNodesAllowlist(nodeAllowlistController), - new PermGetAccountsWhitelist(accountsAllowlistController), new PermGetAccountsAllowlist(accountsAllowlistController), - new PermAddAccountsToWhitelist(accountsAllowlistController), new PermAddAccountsToAllowlist(accountsAllowlistController), - new PermRemoveAccountsFromWhitelist(accountsAllowlistController), new PermRemoveAccountsFromAllowlist(accountsAllowlistController), new PermReloadPermissionsFromFile(accountsAllowlistController, nodeAllowlistController)); } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermAddAccountsToAllowlistTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermAddAccountsToAllowlistTest.java index a37db420a1..4a3300d16c 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermAddAccountsToAllowlistTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermAddAccountsToAllowlistTest.java @@ -43,12 +43,12 @@ import org.mockito.junit.jupiter.MockitoExtension; @ExtendWith(MockitoExtension.class) public class PermAddAccountsToAllowlistTest { - @Mock private AccountLocalConfigPermissioningController accountWhitelist; + @Mock private AccountLocalConfigPermissioningController accountAllowlist; private PermAddAccountsToAllowlist method; @BeforeEach public void before() { - method = new PermAddAccountsToAllowlist(java.util.Optional.of(accountWhitelist)); + method = new PermAddAccountsToAllowlist(java.util.Optional.of(accountAllowlist)); } @Test @@ -57,10 +57,10 @@ public class PermAddAccountsToAllowlistTest { } @Test - public void whenAccountsAreAddedToWhitelistShouldReturnSuccess() { + public void whenAccountsAreAddedToAllowlistShouldReturnSuccess() { List accounts = Arrays.asList("0x0", "0x1"); JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse(null); - when(accountWhitelist.addAccounts(eq(accounts))).thenReturn(AllowlistOperationResult.SUCCESS); + when(accountAllowlist.addAccounts(eq(accounts))).thenReturn(AllowlistOperationResult.SUCCESS); JsonRpcResponse actualResponse = method.response(request(accounts)); @@ -71,7 +71,7 @@ public class PermAddAccountsToAllowlistTest { public void whenAccountIsInvalidShouldReturnInvalidAccountErrorResponse() { JsonRpcResponse expectedResponse = new JsonRpcErrorResponse(null, RpcErrorType.ACCOUNT_ALLOWLIST_INVALID_ENTRY); - when(accountWhitelist.addAccounts(any())) + when(accountAllowlist.addAccounts(any())) .thenReturn(AllowlistOperationResult.ERROR_INVALID_ENTRY); JsonRpcResponse actualResponse = method.response(request(new ArrayList<>())); @@ -83,7 +83,7 @@ public class PermAddAccountsToAllowlistTest { public void whenAccountExistsShouldReturnExistingEntryErrorResponse() { JsonRpcResponse expectedResponse = new JsonRpcErrorResponse(null, RpcErrorType.ACCOUNT_ALLOWLIST_EXISTING_ENTRY); - when(accountWhitelist.addAccounts(any())) + when(accountAllowlist.addAccounts(any())) .thenReturn(AllowlistOperationResult.ERROR_EXISTING_ENTRY); JsonRpcResponse actualResponse = method.response(request(new ArrayList<>())); @@ -95,7 +95,7 @@ public class PermAddAccountsToAllowlistTest { public void whenInputHasDuplicatedAccountsShouldReturnDuplicatedEntryErrorResponse() { JsonRpcResponse expectedResponse = new JsonRpcErrorResponse(null, RpcErrorType.ACCOUNT_ALLOWLIST_DUPLICATED_ENTRY); - when(accountWhitelist.addAccounts(any())) + when(accountAllowlist.addAccounts(any())) .thenReturn(AllowlistOperationResult.ERROR_DUPLICATED_ENTRY); JsonRpcResponse actualResponse = method.response(request(new ArrayList<>())); @@ -108,7 +108,7 @@ public class PermAddAccountsToAllowlistTest { JsonRpcResponse expectedResponse = new JsonRpcErrorResponse(null, RpcErrorType.ACCOUNT_ALLOWLIST_EMPTY_ENTRY); - when(accountWhitelist.addAccounts(eq(new ArrayList<>()))) + when(accountAllowlist.addAccounts(eq(new ArrayList<>()))) .thenReturn(AllowlistOperationResult.ERROR_EMPTY_ENTRY); JsonRpcResponse actualResponse = method.response(request(new ArrayList<>())); diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermAddAccountsToWhitelistTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermAddAccountsToWhitelistTest.java deleted file mode 100644 index d07beb934f..0000000000 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermAddAccountsToWhitelistTest.java +++ /dev/null @@ -1,136 +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.ethereum.api.jsonrpc.internal.methods.permissioning; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.catchThrowable; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.when; - -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.exception.InvalidJsonRpcParameters; -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.api.jsonrpc.internal.response.RpcErrorType; -import org.hyperledger.besu.ethereum.permissioning.AccountLocalConfigPermissioningController; -import org.hyperledger.besu.ethereum.permissioning.AllowlistOperationResult; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -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; - -@Deprecated -@ExtendWith(MockitoExtension.class) -public class PermAddAccountsToWhitelistTest { - - @Mock private AccountLocalConfigPermissioningController accountWhitelist; - private PermAddAccountsToWhitelist method; - - @BeforeEach - public void before() { - method = new PermAddAccountsToWhitelist(java.util.Optional.of(accountWhitelist)); - } - - @Test - public void getNameShouldReturnExpectedName() { - assertThat(method.getName()).isEqualTo("perm_addAccountsToWhitelist"); - } - - @Test - public void whenAccountsAreAddedToWhitelistShouldReturnSuccess() { - List accounts = Arrays.asList("0x0", "0x1"); - JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse(null); - when(accountWhitelist.addAccounts(eq(accounts))).thenReturn(AllowlistOperationResult.SUCCESS); - - JsonRpcResponse actualResponse = method.response(request(accounts)); - - assertThat(actualResponse).usingRecursiveComparison().isEqualTo(expectedResponse); - } - - @Test - public void whenAccountIsInvalidShouldReturnInvalidAccountErrorResponse() { - JsonRpcResponse expectedResponse = - new JsonRpcErrorResponse(null, RpcErrorType.ACCOUNT_ALLOWLIST_INVALID_ENTRY); - when(accountWhitelist.addAccounts(any())) - .thenReturn(AllowlistOperationResult.ERROR_INVALID_ENTRY); - - JsonRpcResponse actualResponse = method.response(request(new ArrayList<>())); - - assertThat(actualResponse).usingRecursiveComparison().isEqualTo(expectedResponse); - } - - @Test - public void whenAccountExistsShouldReturnExistingEntryErrorResponse() { - JsonRpcResponse expectedResponse = - new JsonRpcErrorResponse(null, RpcErrorType.ACCOUNT_ALLOWLIST_EXISTING_ENTRY); - when(accountWhitelist.addAccounts(any())) - .thenReturn(AllowlistOperationResult.ERROR_EXISTING_ENTRY); - - JsonRpcResponse actualResponse = method.response(request(new ArrayList<>())); - - assertThat(actualResponse).usingRecursiveComparison().isEqualTo(expectedResponse); - } - - @Test - public void whenInputHasDuplicatedAccountsShouldReturnDuplicatedEntryErrorResponse() { - JsonRpcResponse expectedResponse = - new JsonRpcErrorResponse(null, RpcErrorType.ACCOUNT_ALLOWLIST_DUPLICATED_ENTRY); - when(accountWhitelist.addAccounts(any())) - .thenReturn(AllowlistOperationResult.ERROR_DUPLICATED_ENTRY); - - JsonRpcResponse actualResponse = method.response(request(new ArrayList<>())); - - assertThat(actualResponse).usingRecursiveComparison().isEqualTo(expectedResponse); - } - - @Test - public void whenEmptyListOnRequestShouldReturnEmptyEntryErrorResponse() { - JsonRpcResponse expectedResponse = - new JsonRpcErrorResponse(null, RpcErrorType.ACCOUNT_ALLOWLIST_EMPTY_ENTRY); - - when(accountWhitelist.addAccounts(eq(new ArrayList<>()))) - .thenReturn(AllowlistOperationResult.ERROR_EMPTY_ENTRY); - - JsonRpcResponse actualResponse = method.response(request(new ArrayList<>())); - - assertThat(actualResponse).usingRecursiveComparison().isEqualTo(expectedResponse); - } - - @Test - public void whenEmptyParamOnRequestShouldThrowInvalidJsonRpcException() { - JsonRpcRequestContext request = - new JsonRpcRequestContext( - new JsonRpcRequest("2.0", "perm_addAccountsToWhitelist", new Object[] {})); - - final Throwable thrown = catchThrowable(() -> method.response(request)); - assertThat(thrown) - .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage("Invalid accounts list parameter"); - } - - private JsonRpcRequestContext request(final List accounts) { - return new JsonRpcRequestContext( - new JsonRpcRequest("2.0", "perm_addAccountsToWhitelist", new Object[] {accounts})); - } -} diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermAddNodesToWhitelistTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermAddNodesToWhitelistTest.java deleted file mode 100644 index 237094b90c..0000000000 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermAddNodesToWhitelistTest.java +++ /dev/null @@ -1,203 +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.ethereum.api.jsonrpc.internal.methods.permissioning; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.hyperledger.besu.ethereum.permissioning.NodeLocalConfigPermissioningController.NodesAllowlistResult; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -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.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.api.jsonrpc.internal.response.RpcErrorType; -import org.hyperledger.besu.ethereum.permissioning.AllowlistOperationResult; -import org.hyperledger.besu.ethereum.permissioning.NodeLocalConfigPermissioningController; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Optional; - -import org.assertj.core.api.Assertions; -import org.assertj.core.util.Lists; -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; - -@Deprecated -@ExtendWith(MockitoExtension.class) -public class PermAddNodesToWhitelistTest { - - private PermAddNodesToWhitelist method; - private static final String METHOD_NAME = "perm_addNodesToWhitelist"; - - private final String enode1 = - "enode://6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@192.168.0.10:4567"; - private final String enode2 = - "enode://6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@192.168.0.10:4567"; - private final String enode3 = - "enode://6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@192.168.0.10:4567"; - private final String badEnode = "enod://dog@cat:fish"; - - @Mock private NodeLocalConfigPermissioningController nodeLocalConfigPermissioningController; - - @BeforeEach - public void setUp() { - method = new PermAddNodesToWhitelist(Optional.of(nodeLocalConfigPermissioningController)); - } - - @Test - public void shouldReturnCorrectMethodName() { - assertThat(method.getName()).isEqualTo(METHOD_NAME); - } - - @Test - public void shouldThrowInvalidJsonRpcParametersExceptionWhenOnlyBadEnode() { - final ArrayList enodeList = Lists.newArrayList(badEnode); - final JsonRpcRequestContext request = buildRequest(enodeList); - final JsonRpcResponse expected = - new JsonRpcErrorResponse( - request.getRequest().getId(), RpcErrorType.NODE_ALLOWLIST_INVALID_ENTRY); - - when(nodeLocalConfigPermissioningController.addNodes(eq(enodeList))) - .thenThrow(IllegalArgumentException.class); - - final JsonRpcResponse actual = method.response(request); - - assertThat(actual).usingRecursiveComparison().isEqualTo(expected); - } - - @Test - public void shouldThrowInvalidJsonRpcParametersExceptionWhenBadEnodeInList() { - final ArrayList enodeList = Lists.newArrayList(enode2, badEnode, enode1); - final JsonRpcRequestContext request = buildRequest(enodeList); - final JsonRpcResponse expected = - new JsonRpcErrorResponse( - request.getRequest().getId(), RpcErrorType.NODE_ALLOWLIST_INVALID_ENTRY); - - when(nodeLocalConfigPermissioningController.addNodes(eq(enodeList))) - .thenThrow(IllegalArgumentException.class); - - final JsonRpcResponse actual = method.response(request); - - assertThat(actual).usingRecursiveComparison().isEqualTo(expected); - } - - @Test - public void shouldThrowInvalidJsonRpcParametersExceptionWhenEmptyEnode() { - final JsonRpcRequestContext request = buildRequest(Collections.emptyList()); - final JsonRpcResponse expected = - new JsonRpcErrorResponse( - request.getRequest().getId(), RpcErrorType.NODE_ALLOWLIST_EMPTY_ENTRY); - - when(nodeLocalConfigPermissioningController.addNodes(Collections.emptyList())) - .thenReturn(new NodesAllowlistResult(AllowlistOperationResult.ERROR_EMPTY_ENTRY)); - - final JsonRpcResponse actual = method.response(request); - - assertThat(actual).usingRecursiveComparison().isEqualTo(expected); - } - - @Test - public void whenRequestContainsDuplicatedNodesShouldReturnDuplicatedEntryError() { - final JsonRpcRequestContext request = buildRequest(Lists.newArrayList(enode1, enode1)); - final JsonRpcResponse expected = - new JsonRpcErrorResponse( - request.getRequest().getId(), RpcErrorType.NODE_ALLOWLIST_DUPLICATED_ENTRY); - - when(nodeLocalConfigPermissioningController.addNodes(any())) - .thenReturn(new NodesAllowlistResult(AllowlistOperationResult.ERROR_DUPLICATED_ENTRY)); - - final JsonRpcResponse actual = method.response(request); - - assertThat(actual).usingRecursiveComparison().isEqualTo(expected); - } - - @Test - public void whenRequestContainsEmptyListOfNodesShouldReturnEmptyEntryError() { - final JsonRpcRequestContext request = buildRequest(new ArrayList<>()); - final JsonRpcResponse expected = - new JsonRpcErrorResponse( - request.getRequest().getId(), RpcErrorType.NODE_ALLOWLIST_EMPTY_ENTRY); - - when(nodeLocalConfigPermissioningController.addNodes(eq(new ArrayList<>()))) - .thenReturn(new NodesAllowlistResult(AllowlistOperationResult.ERROR_EMPTY_ENTRY)); - - final JsonRpcResponse actual = method.response(request); - - assertThat(actual).usingRecursiveComparison().isEqualTo(expected); - } - - @Test - public void shouldAddSingleValidNode() { - final JsonRpcRequestContext request = buildRequest(Lists.newArrayList(enode1)); - final JsonRpcResponse expected = new JsonRpcSuccessResponse(request.getRequest().getId()); - - when(nodeLocalConfigPermissioningController.addNodes(any())) - .thenReturn(new NodesAllowlistResult(AllowlistOperationResult.SUCCESS)); - - final JsonRpcResponse actual = method.response(request); - - assertThat(actual).usingRecursiveComparison().isEqualTo(expected); - - verify(nodeLocalConfigPermissioningController, times(1)).addNodes(any()); - verifyNoMoreInteractions(nodeLocalConfigPermissioningController); - } - - @Test - public void shouldAddMultipleValidNodes() { - final JsonRpcRequestContext request = buildRequest(Lists.newArrayList(enode1, enode2, enode3)); - final JsonRpcResponse expected = new JsonRpcSuccessResponse(request.getRequest().getId()); - - when(nodeLocalConfigPermissioningController.addNodes(any())) - .thenReturn(new NodesAllowlistResult(AllowlistOperationResult.SUCCESS)); - - final JsonRpcResponse actual = method.response(request); - - assertThat(actual).usingRecursiveComparison().isEqualTo(expected); - - verify(nodeLocalConfigPermissioningController, times(1)).addNodes(any()); - verifyNoMoreInteractions(nodeLocalConfigPermissioningController); - } - - @Test - public void shouldFailWhenP2pDisabled() { - method = new PermAddNodesToWhitelist(Optional.empty()); - - final JsonRpcRequestContext request = buildRequest(Lists.newArrayList(enode1, enode2, enode3)); - ; - final JsonRpcResponse expectedResponse = - new JsonRpcErrorResponse( - request.getRequest().getId(), RpcErrorType.NODE_ALLOWLIST_NOT_ENABLED); - - Assertions.assertThat(method.response(request)) - .usingRecursiveComparison() - .isEqualTo(expectedResponse); - } - - private JsonRpcRequestContext buildRequest(final List enodeList) { - return new JsonRpcRequestContext( - new JsonRpcRequest("2.0", METHOD_NAME, new Object[] {enodeList})); - } -} diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermGetAccountsWhitelistTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermGetAccountsWhitelistTest.java deleted file mode 100644 index 024349d8b2..0000000000 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermGetAccountsWhitelistTest.java +++ /dev/null @@ -1,77 +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.ethereum.api.jsonrpc.internal.methods.permissioning; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.when; - -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.response.JsonRpcResponse; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; -import org.hyperledger.besu.ethereum.permissioning.AccountLocalConfigPermissioningController; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -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; - -@Deprecated -@ExtendWith(MockitoExtension.class) -public class PermGetAccountsWhitelistTest { - - private static final JsonRpcRequestContext request = - new JsonRpcRequestContext(new JsonRpcRequest("2.0", "perm_getAccountsWhitelist", null)); - - @Mock private AccountLocalConfigPermissioningController accountWhitelist; - private PermGetAccountsWhitelist method; - - @BeforeEach - public void before() { - method = new PermGetAccountsWhitelist(java.util.Optional.of(accountWhitelist)); - } - - @Test - public void getNameShouldReturnExpectedName() { - assertThat(method.getName()).isEqualTo("perm_getAccountsWhitelist"); - } - - @Test - public void shouldReturnExpectedListOfAccountsWhenWhitelistHasBeenSet() { - List accountsList = Arrays.asList("0x0", "0x1"); - when(accountWhitelist.getAccountAllowlist()).thenReturn(accountsList); - JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse(null, accountsList); - - JsonRpcResponse actualResponse = method.response(request); - - assertThat(actualResponse).usingRecursiveComparison().isEqualTo(expectedResponse); - } - - @Test - public void shouldReturnEmptyListOfAccountsWhenWhitelistHasBeenSetAndIsEmpty() { - List emptyAccountsList = new ArrayList<>(); - when(accountWhitelist.getAccountAllowlist()).thenReturn(emptyAccountsList); - JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse(null, emptyAccountsList); - - JsonRpcResponse actualResponse = method.response(request); - - assertThat(actualResponse).usingRecursiveComparison().isEqualTo(expectedResponse); - } -} diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermGetNodesWhitelistTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermGetNodesWhitelistTest.java deleted file mode 100644 index 9981cb27e7..0000000000 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermGetNodesWhitelistTest.java +++ /dev/null @@ -1,124 +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.ethereum.api.jsonrpc.internal.methods.permissioning; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -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.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.api.jsonrpc.internal.response.RpcErrorType; -import org.hyperledger.besu.ethereum.permissioning.NodeLocalConfigPermissioningController; - -import java.util.Collections; -import java.util.List; -import java.util.Optional; - -import org.assertj.core.api.Assertions; -import org.assertj.core.util.Lists; -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; - -@Deprecated -@ExtendWith(MockitoExtension.class) -public class PermGetNodesWhitelistTest { - - private PermGetNodesWhitelist method; - private static final String METHOD_NAME = "perm_getNodesWhitelist"; - - private final String enode1 = - "enode://6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@192.168.0.10:4567"; - private final String enode2 = - "enode://6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@192.168.0.11:4567"; - private final String enode3 = - "enode://6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@192.168.0.12:4567"; - - @Mock private NodeLocalConfigPermissioningController nodeLocalConfigPermissioningController; - - @BeforeEach - public void setUp() { - method = new PermGetNodesWhitelist(Optional.of(nodeLocalConfigPermissioningController)); - } - - @Test - public void shouldReturnCorrectMethodName() { - assertThat(method.getName()).isEqualTo(METHOD_NAME); - } - - @Test - public void shouldReturnSuccessResponseWhenListPopulated() { - final JsonRpcRequestContext request = buildRequest(); - final JsonRpcResponse expected = - new JsonRpcSuccessResponse( - request.getRequest().getId(), Lists.newArrayList(enode1, enode2, enode3)); - - when(nodeLocalConfigPermissioningController.getNodesAllowlist()) - .thenReturn(buildNodesList(enode1, enode2, enode3)); - - final JsonRpcResponse actual = method.response(request); - - assertThat(actual).usingRecursiveComparison().isEqualTo(expected); - - verify(nodeLocalConfigPermissioningController, times(1)).getNodesAllowlist(); - verifyNoMoreInteractions(nodeLocalConfigPermissioningController); - } - - @Test - public void shouldReturnSuccessResponseWhenListSetAndEmpty() { - final JsonRpcRequestContext request = buildRequest(); - final JsonRpcResponse expected = - new JsonRpcSuccessResponse(request.getRequest().getId(), Collections.emptyList()); - - when(nodeLocalConfigPermissioningController.getNodesAllowlist()).thenReturn(buildNodesList()); - - final JsonRpcResponse actual = method.response(request); - - assertThat(actual).usingRecursiveComparison().isEqualTo(expected); - - verify(nodeLocalConfigPermissioningController, times(1)).getNodesAllowlist(); - verifyNoMoreInteractions(nodeLocalConfigPermissioningController); - } - - @Test - public void shouldFailWhenP2pDisabled() { - method = new PermGetNodesWhitelist(Optional.empty()); - - final JsonRpcRequestContext request = buildRequest(); - final JsonRpcResponse expectedResponse = - new JsonRpcErrorResponse( - request.getRequest().getId(), RpcErrorType.NODE_ALLOWLIST_NOT_ENABLED); - - Assertions.assertThat(method.response(request)) - .usingRecursiveComparison() - .isEqualTo(expectedResponse); - } - - private JsonRpcRequestContext buildRequest() { - return new JsonRpcRequestContext(new JsonRpcRequest("2.0", METHOD_NAME, new Object[] {})); - } - - private List buildNodesList(final String... enodes) { - return Lists.newArrayList(enodes); - } -} diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermRemoveAccountsFromWhitelistTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermRemoveAccountsFromWhitelistTest.java deleted file mode 100644 index 582ef1d32a..0000000000 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermRemoveAccountsFromWhitelistTest.java +++ /dev/null @@ -1,137 +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.ethereum.api.jsonrpc.internal.methods.permissioning; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.catchThrowable; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.when; - -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.exception.InvalidJsonRpcParameters; -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.api.jsonrpc.internal.response.RpcErrorType; -import org.hyperledger.besu.ethereum.permissioning.AccountLocalConfigPermissioningController; -import org.hyperledger.besu.ethereum.permissioning.AllowlistOperationResult; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -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; - -@Deprecated -@ExtendWith(MockitoExtension.class) -public class PermRemoveAccountsFromWhitelistTest { - - @Mock private AccountLocalConfigPermissioningController accountWhitelist; - private PermRemoveAccountsFromWhitelist method; - - @BeforeEach - public void before() { - method = new PermRemoveAccountsFromWhitelist(java.util.Optional.of(accountWhitelist)); - } - - @Test - public void getNameShouldReturnExpectedName() { - assertThat(method.getName()).isEqualTo("perm_removeAccountsFromWhitelist"); - } - - @Test - public void whenAccountsAreRemovedFromWhitelistShouldReturnSuccess() { - List accounts = Arrays.asList("0x0", "0x1"); - JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse(null); - when(accountWhitelist.removeAccounts(eq(accounts))) - .thenReturn(AllowlistOperationResult.SUCCESS); - - JsonRpcResponse actualResponse = method.response(request(accounts)); - - assertThat(actualResponse).usingRecursiveComparison().isEqualTo(expectedResponse); - } - - @Test - public void whenAccountIsInvalidShouldReturnInvalidAccountErrorResponse() { - JsonRpcResponse expectedResponse = - new JsonRpcErrorResponse(null, RpcErrorType.ACCOUNT_ALLOWLIST_INVALID_ENTRY); - when(accountWhitelist.removeAccounts(any())) - .thenReturn(AllowlistOperationResult.ERROR_INVALID_ENTRY); - - JsonRpcResponse actualResponse = method.response(request(new ArrayList<>())); - - assertThat(actualResponse).usingRecursiveComparison().isEqualTo(expectedResponse); - } - - @Test - public void whenAccountIsAbsentShouldReturnAbsentAccountErrorResponse() { - JsonRpcResponse expectedResponse = - new JsonRpcErrorResponse(null, RpcErrorType.ACCOUNT_ALLOWLIST_ABSENT_ENTRY); - when(accountWhitelist.removeAccounts(any())) - .thenReturn(AllowlistOperationResult.ERROR_ABSENT_ENTRY); - - JsonRpcResponse actualResponse = method.response(request(new ArrayList<>())); - - assertThat(actualResponse).usingRecursiveComparison().isEqualTo(expectedResponse); - } - - @Test - public void whenInputHasDuplicatedAccountsShouldReturnDuplicatedEntryErrorResponse() { - JsonRpcResponse expectedResponse = - new JsonRpcErrorResponse(null, RpcErrorType.ACCOUNT_ALLOWLIST_DUPLICATED_ENTRY); - when(accountWhitelist.removeAccounts(any())) - .thenReturn(AllowlistOperationResult.ERROR_DUPLICATED_ENTRY); - - JsonRpcResponse actualResponse = method.response(request(new ArrayList<>())); - - assertThat(actualResponse).usingRecursiveComparison().isEqualTo(expectedResponse); - } - - @Test - public void whenEmptyListOnRequestShouldReturnEmptyEntryErrorResponse() { - JsonRpcResponse expectedResponse = - new JsonRpcErrorResponse(null, RpcErrorType.ACCOUNT_ALLOWLIST_EMPTY_ENTRY); - - when(accountWhitelist.removeAccounts(eq(new ArrayList<>()))) - .thenReturn(AllowlistOperationResult.ERROR_EMPTY_ENTRY); - - JsonRpcResponse actualResponse = method.response(request(new ArrayList<>())); - - assertThat(actualResponse).usingRecursiveComparison().isEqualTo(expectedResponse); - } - - @Test - public void whenEmptyParamOnRequestShouldThrowInvalidJsonRpcException() { - JsonRpcRequestContext request = - new JsonRpcRequestContext( - new JsonRpcRequest("2.0", "perm_removeAccountsFromWhitelist", new Object[] {})); - - final Throwable thrown = catchThrowable(() -> method.response(request)); - assertThat(thrown) - .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage("Invalid accounts list parameter"); - } - - private JsonRpcRequestContext request(final List accounts) { - return new JsonRpcRequestContext( - new JsonRpcRequest("2.0", "perm_removeAccountsFromWhitelist", new Object[] {accounts})); - } -} diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermRemoveNodesFromWhitelistTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermRemoveNodesFromWhitelistTest.java deleted file mode 100644 index 45630a25ad..0000000000 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermRemoveNodesFromWhitelistTest.java +++ /dev/null @@ -1,200 +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.ethereum.api.jsonrpc.internal.methods.permissioning; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.hyperledger.besu.ethereum.permissioning.NodeLocalConfigPermissioningController.NodesAllowlistResult; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -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.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.api.jsonrpc.internal.response.RpcErrorType; -import org.hyperledger.besu.ethereum.permissioning.AllowlistOperationResult; -import org.hyperledger.besu.ethereum.permissioning.NodeLocalConfigPermissioningController; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Optional; - -import org.assertj.core.api.Assertions; -import org.assertj.core.util.Lists; -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; - -@Deprecated -@ExtendWith(MockitoExtension.class) -public class PermRemoveNodesFromWhitelistTest { - - private PermRemoveNodesFromWhitelist method; - private static final String METHOD_NAME = "perm_removeNodesFromWhitelist"; - - private final String enode1 = - "enode://6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@192.168.0.10:4567"; - private final String enode2 = - "enode://6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@192.168.0.10:4567"; - private final String enode3 = - "enode://6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@192.168.0.10:4567"; - private final String badEnode = "enod://dog@cat:fish"; - - @Mock private NodeLocalConfigPermissioningController nodeLocalConfigPermissioningController; - - @BeforeEach - public void setUp() { - method = new PermRemoveNodesFromWhitelist(Optional.of(nodeLocalConfigPermissioningController)); - } - - @Test - public void shouldReturnCorrectMethodName() { - assertThat(method.getName()).isEqualTo(METHOD_NAME); - } - - @Test - public void shouldThrowInvalidJsonRpcParametersExceptionWhenBadEnode() { - final JsonRpcRequestContext request = buildRequest(Lists.newArrayList(badEnode)); - final JsonRpcResponse expected = - new JsonRpcErrorResponse( - request.getRequest().getId(), RpcErrorType.NODE_ALLOWLIST_INVALID_ENTRY); - - when(nodeLocalConfigPermissioningController.removeNodes(eq(Lists.newArrayList(badEnode)))) - .thenThrow(IllegalArgumentException.class); - - final JsonRpcResponse actual = method.response(request); - - assertThat(actual).usingRecursiveComparison().isEqualTo(expected); - } - - @Test - public void shouldThrowInvalidJsonRpcParametersExceptionWhenEmptyList() { - final JsonRpcRequestContext request = buildRequest(Collections.emptyList()); - final JsonRpcResponse expected = - new JsonRpcErrorResponse( - request.getRequest().getId(), RpcErrorType.NODE_ALLOWLIST_EMPTY_ENTRY); - - when(nodeLocalConfigPermissioningController.removeNodes(Collections.emptyList())) - .thenReturn(new NodesAllowlistResult(AllowlistOperationResult.ERROR_EMPTY_ENTRY)); - - final JsonRpcResponse actual = method.response(request); - - assertThat(actual).usingRecursiveComparison().isEqualTo(expected); - } - - @Test - public void shouldRemoveSingleValidNode() { - final JsonRpcRequestContext request = buildRequest(Lists.newArrayList(enode1)); - final JsonRpcResponse expected = new JsonRpcSuccessResponse(request.getRequest().getId()); - - when(nodeLocalConfigPermissioningController.removeNodes(any())) - .thenReturn(new NodesAllowlistResult(AllowlistOperationResult.SUCCESS)); - - final JsonRpcResponse actual = method.response(request); - - assertThat(actual).usingRecursiveComparison().isEqualTo(expected); - - verify(nodeLocalConfigPermissioningController, times(1)).removeNodes(any()); - verifyNoMoreInteractions(nodeLocalConfigPermissioningController); - } - - @Test - public void shouldRemoveMultipleValidNodes() { - final JsonRpcRequestContext request = buildRequest(Lists.newArrayList(enode1, enode2, enode3)); - final JsonRpcResponse expected = new JsonRpcSuccessResponse(request.getRequest().getId()); - - when(nodeLocalConfigPermissioningController.removeNodes(any())) - .thenReturn(new NodesAllowlistResult(AllowlistOperationResult.SUCCESS)); - - final JsonRpcResponse actual = method.response(request); - - assertThat(actual).usingRecursiveComparison().isEqualTo(expected); - - verify(nodeLocalConfigPermissioningController, times(1)).removeNodes(any()); - verifyNoMoreInteractions(nodeLocalConfigPermissioningController); - } - - @Test - public void shouldFailWhenP2pDisabled() { - method = new PermRemoveNodesFromWhitelist(Optional.empty()); - final JsonRpcRequestContext request = buildRequest(Lists.newArrayList(enode1, enode2, enode3)); - final JsonRpcResponse expectedResponse = - new JsonRpcErrorResponse( - request.getRequest().getId(), RpcErrorType.NODE_ALLOWLIST_NOT_ENABLED); - - Assertions.assertThat(method.response(request)) - .usingRecursiveComparison() - .isEqualTo(expectedResponse); - } - - @Test - public void whenRequestContainsDuplicatedNodesShouldReturnDuplicatedEntryError() { - final JsonRpcRequestContext request = buildRequest(Lists.newArrayList(enode1, enode1)); - final JsonRpcResponse expected = - new JsonRpcErrorResponse( - request.getRequest().getId(), RpcErrorType.NODE_ALLOWLIST_DUPLICATED_ENTRY); - - when(nodeLocalConfigPermissioningController.removeNodes(any())) - .thenReturn(new NodesAllowlistResult(AllowlistOperationResult.ERROR_DUPLICATED_ENTRY)); - - final JsonRpcResponse actual = method.response(request); - - assertThat(actual).usingRecursiveComparison().isEqualTo(expected); - } - - @Test - public void whenRequestContainsEmptyListOfNodesShouldReturnEmptyEntryError() { - final JsonRpcRequestContext request = buildRequest(new ArrayList<>()); - final JsonRpcResponse expected = - new JsonRpcErrorResponse( - request.getRequest().getId(), RpcErrorType.NODE_ALLOWLIST_EMPTY_ENTRY); - - when(nodeLocalConfigPermissioningController.removeNodes(eq(new ArrayList<>()))) - .thenReturn(new NodesAllowlistResult(AllowlistOperationResult.ERROR_EMPTY_ENTRY)); - - final JsonRpcResponse actual = method.response(request); - - assertThat(actual).usingRecursiveComparison().isEqualTo(expected); - } - - @Test - public void shouldReturnCantRemoveBootnodeWhenRemovingBootnode() { - final JsonRpcRequestContext request = buildRequest(Lists.newArrayList(enode1)); - final JsonRpcResponse expected = - new JsonRpcErrorResponse( - request.getRequest().getId(), RpcErrorType.NODE_ALLOWLIST_FIXED_NODE_CANNOT_BE_REMOVED); - - when(nodeLocalConfigPermissioningController.removeNodes(any())) - .thenReturn( - new NodesAllowlistResult(AllowlistOperationResult.ERROR_FIXED_NODE_CANNOT_BE_REMOVED)); - - final JsonRpcResponse actual = method.response(request); - - assertThat(actual).usingRecursiveComparison().isEqualTo(expected); - } - - private JsonRpcRequestContext buildRequest(final List enodeList) { - return new JsonRpcRequestContext( - new JsonRpcRequest("2.0", METHOD_NAME, new Object[] {enodeList})); - } -} diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/PermJsonRpcMethodsTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/PermJsonRpcMethodsTest.java index a8f06f5265..7484730a30 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/PermJsonRpcMethodsTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/PermJsonRpcMethodsTest.java @@ -16,30 +16,19 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.methods; import static org.assertj.core.api.Assertions.assertThat; import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod.PERM_ADD_ACCOUNTS_TO_ALLOWLIST; -import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod.PERM_ADD_ACCOUNTS_TO_WHITELIST; import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod.PERM_ADD_NODES_TO_ALLOWLIST; -import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod.PERM_ADD_NODES_TO_WHITELIST; import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod.PERM_GET_ACCOUNTS_ALLOWLIST; -import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod.PERM_GET_ACCOUNTS_WHITELIST; import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod.PERM_GET_NODES_ALLOWLIST; -import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod.PERM_GET_NODES_WHITELIST; import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod.PERM_REMOVE_ACCOUNTS_FROM_ALLOWLIST; -import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod.PERM_REMOVE_ACCOUNTS_FROM_WHITELIST; import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod.PERM_REMOVE_NODES_FROM_ALLOWLIST; -import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod.PERM_REMOVE_NODES_FROM_WHITELIST; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.permissioning.PermAddAccountsToAllowlist; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.permissioning.PermAddAccountsToWhitelist; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.permissioning.PermAddNodesToAllowlist; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.permissioning.PermGetAccountsAllowlist; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.permissioning.PermGetAccountsWhitelist; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.permissioning.PermGetNodesAllowlist; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.permissioning.PermGetNodesWhitelist; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.permissioning.PermRemoveAccountsFromAllowlist; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.permissioning.PermRemoveAccountsFromWhitelist; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.permissioning.PermRemoveNodesFromAllowlist; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.permissioning.PermRemoveNodesFromWhitelist; import org.hyperledger.besu.ethereum.permissioning.AccountLocalConfigPermissioningController; import org.hyperledger.besu.ethereum.permissioning.NodeLocalConfigPermissioningController; @@ -88,27 +77,4 @@ public class PermJsonRpcMethodsTest { assertThat(rpcMethods.get(PERM_REMOVE_NODES_FROM_ALLOWLIST.getMethodName())) .isInstanceOf(PermRemoveNodesFromAllowlist.class); } - - @Deprecated - @Test - public void whitelistMethodsPresent() { - final Map rpcMethods = permJsonRpcMethods.create(); - assertThat(rpcMethods.size()).isEqualTo(13); - - // Account methods x 3 - assertThat(rpcMethods.get(PERM_GET_ACCOUNTS_WHITELIST.getMethodName())) - .isInstanceOf(PermGetAccountsWhitelist.class); - assertThat(rpcMethods.get(PERM_ADD_ACCOUNTS_TO_WHITELIST.getMethodName())) - .isInstanceOf(PermAddAccountsToWhitelist.class); - assertThat(rpcMethods.get(PERM_REMOVE_ACCOUNTS_FROM_WHITELIST.getMethodName())) - .isInstanceOf(PermRemoveAccountsFromWhitelist.class); - - // Node methods x 3 - assertThat(rpcMethods.get(PERM_GET_NODES_WHITELIST.getMethodName())) - .isInstanceOf(PermGetNodesWhitelist.class); - assertThat(rpcMethods.get(PERM_ADD_NODES_TO_WHITELIST.getMethodName())) - .isInstanceOf(PermAddNodesToAllowlist.class); - assertThat(rpcMethods.get(PERM_REMOVE_NODES_FROM_WHITELIST.getMethodName())) - .isInstanceOf(PermRemoveNodesFromWhitelist.class); - } } From a844684701504e99c59970f87703951126a23777 Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Wed, 31 Jul 2024 21:56:13 +1000 Subject: [PATCH 077/259] 5098 branch 3 update invalid address hash params (#7403) * 5098: Add RpcErrorTypes Signed-off-by: Matilda Clerke * 5098: Modify InvalidJsonRpcParameters and InvalidJsonRpcRequestException, apply spotless Signed-off-by: Matilda Clerke * 5098: Modify InvalidJsonRpcParameters and InvalidJsonRpcRequestException, apply spotless Signed-off-by: Matilda Clerke * 5098: Add JsonRpcParameterException for later use Signed-off-by: Matilda Clerke * 5098: Update locations for RpcErrorType.INVALID_ACCOUNTS_PARAMS Signed-off-by: Matilda Clerke * 5098: Address review comments, apply spotless Signed-off-by: Matilda Clerke * 5098: Update with changes from branch 1 Signed-off-by: Matilda Clerke * 5098: Update code to use RpcErrorType.INVALID_ADDRESS_HASH_PARAMS Signed-off-by: Matilda Clerke * 5098: apply spotless Signed-off-by: Matilda Clerke * 5098: apply spotless Signed-off-by: Matilda Clerke * 5098: Update plugin-api gradle hash Signed-off-by: Matilda Clerke * 5098: Add comment on INVALID_PARAMS_ERROR_CODE Signed-off-by: Matilda Clerke * 5098: Apply spotless on latest changes Signed-off-by: Matilda Clerke * 5098: Fix broken unit test Signed-off-by: Matilda Clerke * 5098: Fix broken unit test Signed-off-by: Matilda Clerke --------- Signed-off-by: Matilda Clerke --- .../jsonrpc/internal/methods/DebugAccountRange.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugAccountRange.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugAccountRange.java index 4ca5cb0685..47fe7738b9 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugAccountRange.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugAccountRange.java @@ -17,9 +17,11 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameterOrBlockHash; 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.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.DebugAccountRangeAtResult; import org.hyperledger.besu.ethereum.api.query.BlockWithMetadata; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; @@ -58,7 +60,13 @@ public class DebugAccountRange implements JsonRpcMethod { public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { final BlockParameterOrBlockHash blockParameterOrBlockHash = requestContext.getRequiredParameter(0, BlockParameterOrBlockHash.class); - final String addressHash = requestContext.getRequiredParameter(2, String.class); + final String addressHash; + try { + addressHash = requestContext.getRequiredParameter(2, String.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid address hash parameter", RpcErrorType.INVALID_ADDRESS_HASH_PARAMS, e); + } final int maxResults = requestContext.getRequiredParameter(3, Integer.TYPE); final Optional blockHashOptional = hashFromParameter(blockParameterOrBlockHash); From b634b9c66c36906791e84673ecb18dc23e20e03d Mon Sep 17 00:00:00 2001 From: Matt Whitehead Date: Wed, 31 Jul 2024 16:15:59 +0100 Subject: [PATCH 078/259] Update deps for CVEs (#7412) Signed-off-by: Matthew Whitehead --- gradle/verification-metadata.xml | 16 ++++++++++++++++ gradle/versions.gradle | 4 ++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index 950e0ee866..c7f3039dff 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -1084,6 +1084,14 @@ + + + + + + + + @@ -1385,6 +1393,14 @@ + + + + + + + + diff --git a/gradle/versions.gradle b/gradle/versions.gradle index 6d176ba7e3..9ad95a2074 100644 --- a/gradle/versions.gradle +++ b/gradle/versions.gradle @@ -43,7 +43,7 @@ dependencyManagement { dependency 'com.google.guava:guava:33.0.0-jre' - dependency 'com.graphql-java:graphql-java:21.3' + dependency 'com.graphql-java:graphql-java:21.5' dependency 'com.splunk.logging:splunk-library-javalogging:1.11.8' @@ -53,7 +53,7 @@ dependencyManagement { dependency 'commons-io:commons-io:2.15.1' - dependency 'dnsjava:dnsjava:3.5.3' + dependency 'dnsjava:dnsjava:3.6.0' dependencySet(group: 'info.picocli', version: '4.7.5') { entry 'picocli' From 9d92ae87dfcda0a1b417a6072983b76d8e174206 Mon Sep 17 00:00:00 2001 From: Usman Saleem Date: Thu, 1 Aug 2024 01:39:44 +1000 Subject: [PATCH 079/259] feat: Expose set finalized/safe block in plugin-api BlockchainService (#7382) * feat: Expose set finalized and safe block in plugin-api BlockchainService * check for poa network before setting finalized block * changelog * Add BlockchainService set finalized acceptance test --------- Signed-off-by: Usman Saleem --- CHANGELOG.md | 1 + acceptance-tests/test-plugins/build.gradle | 1 + .../TestBlockchainServiceFinalizedPlugin.java | 149 +++++++++++++++++ ...kchainServiceFinalizedBlockPluginTest.java | 158 ++++++++++++++++++ .../besu/services/BlockchainServiceImpl.java | 34 +++- plugin-api/build.gradle | 2 +- .../plugin/services/BlockchainService.java | 20 +++ 7 files changed, 363 insertions(+), 2 deletions(-) create mode 100644 acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestBlockchainServiceFinalizedPlugin.java create mode 100644 acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/plugins/BlockchainServiceFinalizedBlockPluginTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 498b3c1edd..c5d782ba25 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ - Remove long-deprecated `perm*whitelist*` methods [#7401](https://github.com/hyperledger/besu/pull/7401) ### Additions and Improvements +- Expose set finalized/safe block in plugin api BlockchainService. These method can be used by plugins to set finalized/safe block for a PoA network (such as QBFT, IBFT and Clique).[#7382](https://github.com/hyperledger/besu/pull/7382) ### Bug fixes diff --git a/acceptance-tests/test-plugins/build.gradle b/acceptance-tests/test-plugins/build.gradle index c31175cee8..19a45d218a 100644 --- a/acceptance-tests/test-plugins/build.gradle +++ b/acceptance-tests/test-plugins/build.gradle @@ -7,6 +7,7 @@ dependencies { implementation project(':datatypes') implementation project(':ethereum:core') implementation project(':ethereum:rlp') + implementation project(':ethereum:api') implementation project(':plugin-api') implementation 'com.google.auto.service:auto-service' implementation 'info.picocli:picocli' diff --git a/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestBlockchainServiceFinalizedPlugin.java b/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestBlockchainServiceFinalizedPlugin.java new file mode 100644 index 0000000000..a61b80ab8e --- /dev/null +++ b/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestBlockchainServiceFinalizedPlugin.java @@ -0,0 +1,149 @@ +/* + * 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.plugins; + +import org.hyperledger.besu.datatypes.Hash; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; +import org.hyperledger.besu.plugin.BesuContext; +import org.hyperledger.besu.plugin.BesuPlugin; +import org.hyperledger.besu.plugin.data.BlockContext; +import org.hyperledger.besu.plugin.services.BlockchainService; +import org.hyperledger.besu.plugin.services.RpcEndpointService; +import org.hyperledger.besu.plugin.services.exception.PluginRpcEndpointException; +import org.hyperledger.besu.plugin.services.rpc.PluginRpcRequest; + +import java.util.Optional; + +import com.google.auto.service.AutoService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@AutoService(BesuPlugin.class) +public class TestBlockchainServiceFinalizedPlugin implements BesuPlugin { + private static final Logger LOG = + LoggerFactory.getLogger(TestBlockchainServiceFinalizedPlugin.class); + private static final String RPC_NAMESPACE = "updater"; + private static final String RPC_METHOD_FINALIZED_BLOCK = "updateFinalizedBlockV1"; + private static final String RPC_METHOD_SAFE_BLOCK = "updateSafeBlockV1"; + + @Override + public void register(final BesuContext besuContext) { + LOG.trace("Registering plugin ..."); + + final RpcEndpointService rpcEndpointService = + besuContext + .getService(RpcEndpointService.class) + .orElseThrow( + () -> + new RuntimeException( + "Failed to obtain RpcEndpointService from the BesuContext.")); + + final BlockchainService blockchainService = + besuContext + .getService(BlockchainService.class) + .orElseThrow( + () -> + new RuntimeException( + "Failed to obtain BlockchainService from the BesuContext.")); + + final FinalizationUpdaterRpcMethod rpcMethod = + new FinalizationUpdaterRpcMethod(blockchainService); + rpcEndpointService.registerRPCEndpoint( + RPC_NAMESPACE, RPC_METHOD_FINALIZED_BLOCK, rpcMethod::setFinalizedBlock); + rpcEndpointService.registerRPCEndpoint( + RPC_NAMESPACE, RPC_METHOD_SAFE_BLOCK, rpcMethod::setSafeBlock); + } + + @Override + public void start() { + LOG.trace("Starting plugin ..."); + } + + @Override + public void stop() { + LOG.trace("Stopping plugin ..."); + } + + static class FinalizationUpdaterRpcMethod { + private final BlockchainService blockchainService; + private final JsonRpcParameter parameterParser = new JsonRpcParameter(); + + FinalizationUpdaterRpcMethod(final BlockchainService blockchainService) { + this.blockchainService = blockchainService; + } + + Boolean setFinalizedBlock(final PluginRpcRequest request) { + return setFinalizedOrSafeBlock(request, true); + } + + Boolean setSafeBlock(final PluginRpcRequest request) { + return setFinalizedOrSafeBlock(request, false); + } + + private Boolean setFinalizedOrSafeBlock( + final PluginRpcRequest request, final boolean isFinalized) { + final Long blockNumberToSet = parseResult(request); + + // lookup finalized block by number in local chain + final Optional finalizedBlock = + blockchainService.getBlockByNumber(blockNumberToSet); + if (finalizedBlock.isEmpty()) { + throw new PluginRpcEndpointException( + RpcErrorType.BLOCK_NOT_FOUND, + "Block not found in the local chain: " + blockNumberToSet); + } + + try { + final Hash blockHash = finalizedBlock.get().getBlockHeader().getBlockHash(); + if (isFinalized) { + blockchainService.setFinalizedBlock(blockHash); + } else { + blockchainService.setSafeBlock(blockHash); + } + } catch (final IllegalArgumentException e) { + throw new PluginRpcEndpointException( + RpcErrorType.BLOCK_NOT_FOUND, + "Block not found in the local chain: " + blockNumberToSet); + } catch (final UnsupportedOperationException e) { + throw new PluginRpcEndpointException( + RpcErrorType.METHOD_NOT_ENABLED, + "Method not enabled for PoS network: setFinalizedBlock"); + } catch (final Exception e) { + throw new PluginRpcEndpointException( + RpcErrorType.INTERNAL_ERROR, "Error setting finalized block: " + blockNumberToSet); + } + + return Boolean.TRUE; + } + + private Long parseResult(final PluginRpcRequest request) { + Long blockNumber; + try { + final Object[] params = request.getParams(); + blockNumber = parameterParser.required(params, 0, Long.class); + } catch (final Exception e) { + throw new PluginRpcEndpointException(RpcErrorType.INVALID_PARAMS, e.getMessage()); + } + + if (blockNumber <= 0) { + throw new PluginRpcEndpointException( + RpcErrorType.INVALID_PARAMS, "Block number must be greater than 0"); + } + + return blockNumber; + } + } +} diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/plugins/BlockchainServiceFinalizedBlockPluginTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/plugins/BlockchainServiceFinalizedBlockPluginTest.java new file mode 100644 index 0000000000..dd620844b1 --- /dev/null +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/plugins/BlockchainServiceFinalizedBlockPluginTest.java @@ -0,0 +1,158 @@ +/* + * 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.plugins; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.hyperledger.besu.config.JsonUtil; +import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBase; +import org.hyperledger.besu.tests.acceptance.dsl.node.BesuNode; + +import java.io.IOException; +import java.util.List; +import java.util.stream.Collectors; + +import com.fasterxml.jackson.databind.node.ObjectNode; +import okhttp3.MediaType; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +public class BlockchainServiceFinalizedBlockPluginTest extends AcceptanceTestBase { + + private BesuNode pluginNode; + private BesuNode minerNode; + private OkHttpClient client; + protected static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); + + @BeforeEach + public void setUp() throws Exception { + minerNode = besu.createMinerNode("minerNode"); + pluginNode = + besu.createPluginsNode("node1", List.of("testPlugins"), List.of("--rpc-http-api=UPDATER")); + cluster.start(minerNode, pluginNode); + client = new OkHttpClient(); + } + + @Test + @DisplayName("Calling update{Finalized/Safe}BlockV1 will set block") + public void canUpdateFinalizedBlock() throws IOException { + pluginNode.verify(blockchain.minimumHeight(5)); + + // RPC Call. Set the safe block number to 3 + final ObjectNode resultJson = callTestMethod("updater_updateSafeBlockV1", List.of(3L)); + assertThat(resultJson.get("result").asBoolean()).isTrue(); + + // RPC Call. Set the finalized block number to 4 + final ObjectNode finalizedResultJson = + callTestMethod("updater_updateFinalizedBlockV1", List.of(4L)); + assertThat(finalizedResultJson.get("result").asBoolean()).isTrue(); + + final ObjectNode blockNumberSafeResult = + callTestMethod("eth_getBlockByNumber", List.of("SAFE", true)); + assertThat(blockNumberSafeResult.get("result").get("number").asText()).isEqualTo("0x3"); + + // Verify the value was set + final ObjectNode blockNumberFinalizedResult = + callTestMethod("eth_getBlockByNumber", List.of("FINALIZED", true)); + assertThat(blockNumberFinalizedResult.get("result").get("number").asText()).isEqualTo("0x4"); + } + + @Test + @DisplayName("Calling update{Finalized/Safe}BlockV1 with non-existing block number returns error") + public void nonExistingBlockNumberReturnsError() throws IOException { + pluginNode.verify(blockchain.minimumHeight(5)); + + final ObjectNode[] resultsJson = new ObjectNode[2]; + resultsJson[0] = callTestMethod("updater_updateFinalizedBlockV1", List.of(250L)); + resultsJson[1] = callTestMethod("updater_updateSafeBlockV1", List.of(250L)); + + for (int i = 0; i < resultsJson.length; i++) { + assertThat(resultsJson[i].get("error").get("code").asInt()).isEqualTo(-32000); + assertThat(resultsJson[i].get("error").get("message").asText()).isEqualTo("Block not found"); + assertThat(resultsJson[i].get("error").get("data").asText()) + .isEqualTo("Block not found in the local chain: 250"); + } + } + + @ParameterizedTest(name = "{index} - blockNumber={0}") + @ValueSource(longs = {-1, 0}) + @DisplayName("Calling update{Finalized/Safe}BlockV1 with block number <= 0 returns error") + public void invalidBlockNumberReturnsError(final long blockNumber) throws IOException { + pluginNode.verify(blockchain.minimumHeight(5)); + + final ObjectNode[] resultsJson = new ObjectNode[2]; + resultsJson[0] = callTestMethod("updater_updateFinalizedBlockV1", List.of(blockNumber)); + resultsJson[1] = callTestMethod("updater_updateSafeBlockV1", List.of(blockNumber)); + + for (int i = 0; i < resultsJson.length; i++) { + assertThat(resultsJson[i].get("error").get("code").asInt()).isEqualTo(-32602); + assertThat(resultsJson[i].get("error").get("message").asText()).isEqualTo("Invalid params"); + assertThat(resultsJson[i].get("error").get("data").asText()) + .isEqualTo("Block number must be greater than 0"); + } + } + + @Test + @DisplayName("Calling update{Finalized/Safe}BlockV1 with invalid block number type returns error") + public void invalidBlockNumberTypeReturnsError() throws IOException { + pluginNode.verify(blockchain.minimumHeight(5)); + + final ObjectNode[] resultsJson = new ObjectNode[2]; + resultsJson[0] = callTestMethod("updater_updateFinalizedBlockV1", List.of("testblock")); + resultsJson[1] = callTestMethod("updater_updateSafeBlockV1", List.of("testblock")); + + for (int i = 0; i < resultsJson.length; i++) { + assertThat(resultsJson[i].get("error").get("code").asInt()).isEqualTo(-32602); + assertThat(resultsJson[i].get("error").get("message").asText()).isEqualTo("Invalid params"); + assertThat(resultsJson[i].get("error").get("data").asText()) + .isEqualTo( + "Invalid json rpc parameter at index 0. Supplied value was: 'testblock' of type: 'java.lang.String' - expected type: 'java.lang.Long'"); + } + } + + private ObjectNode callTestMethod(final String method, final List params) + throws IOException { + String format = + String.format( + "{\"jsonrpc\":\"2.0\",\"method\":\"%s\",\"params\":[%s],\"id\":42}", + method, + params.stream().map(value -> "\"" + value + "\"").collect(Collectors.joining(","))); + + RequestBody body = RequestBody.create(format, JSON); + + final String resultString = + client + .newCall( + new Request.Builder() + .post(body) + .url( + "http://" + + pluginNode.getHostName() + + ":" + + pluginNode.getJsonRpcPort().get() + + "/") + .build()) + .execute() + .body() + .string(); + return JsonUtil.objectNodeFromString(resultString); + } +} diff --git a/besu/src/main/java/org/hyperledger/besu/services/BlockchainServiceImpl.java b/besu/src/main/java/org/hyperledger/besu/services/BlockchainServiceImpl.java index d9e5dbb9ef..1f014ee061 100644 --- a/besu/src/main/java/org/hyperledger/besu/services/BlockchainServiceImpl.java +++ b/besu/src/main/java/org/hyperledger/besu/services/BlockchainServiceImpl.java @@ -20,6 +20,7 @@ import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.chain.MutableBlockchain; import org.hyperledger.besu.ethereum.core.Block; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; +import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; import org.hyperledger.besu.ethereum.mainnet.feemarket.BaseFeeMarket; import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; import org.hyperledger.besu.plugin.Unstable; @@ -46,7 +47,7 @@ public class BlockchainServiceImpl implements BlockchainService { public BlockchainServiceImpl() {} /** - * Instantiates a new Blockchain service. + * Initialize the Blockchain service. * * @param protocolContext the protocol context * @param protocolSchedule the protocol schedule @@ -135,6 +136,37 @@ public class BlockchainServiceImpl implements BlockchainService { return blockchain.getFinalized(); } + @Override + public void setFinalizedBlock(final Hash blockHash) { + final var protocolSpec = getProtocolSpec(blockHash); + + if (protocolSpec.isPoS()) { + throw new UnsupportedOperationException( + "Marking block as finalized is not supported for PoS networks"); + } + blockchain.setFinalized(blockHash); + } + + @Override + public void setSafeBlock(final Hash blockHash) { + final var protocolSpec = getProtocolSpec(blockHash); + + if (protocolSpec.isPoS()) { + throw new UnsupportedOperationException( + "Marking block as safe is not supported for PoS networks"); + } + + blockchain.setSafeBlock(blockHash); + } + + private ProtocolSpec getProtocolSpec(final Hash blockHash) { + return blockchain + .getBlockByHash(blockHash) + .map(Block::getHeader) + .map(protocolSchedule::getByBlockHeader) + .orElseThrow(() -> new IllegalArgumentException("Block not found: " + blockHash)); + } + private static BlockContext blockContext( final Supplier blockHeaderSupplier, final Supplier blockBodySupplier) { diff --git a/plugin-api/build.gradle b/plugin-api/build.gradle index c7203e2f88..cc4b3237b5 100644 --- a/plugin-api/build.gradle +++ b/plugin-api/build.gradle @@ -70,7 +70,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 = 'o0IuPVpCvE3YUzuZgVf4NP74q1ECpkbAkeC6u/Nr8yU=' + knownHash = 'tXFd8EcMJtD+ZSLJxWJLYRZD0d3njRz+3Ubey2zFM2A=' } check.dependsOn('checkAPIChanges') diff --git a/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/BlockchainService.java b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/BlockchainService.java index 69a2e6a822..84a573aadc 100644 --- a/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/BlockchainService.java +++ b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/BlockchainService.java @@ -87,4 +87,24 @@ public interface BlockchainService extends BesuService { * @return the block hash of the finalized block */ Optional getFinalizedBlock(); + + /** + * Set the finalized block for non-PoS networks + * + * @param blockHash Hash of the finalized block + * @throws IllegalArgumentException if the block hash is not on the chain + * @throws UnsupportedOperationException if the network is a PoS network + */ + void setFinalizedBlock(Hash blockHash) + throws IllegalArgumentException, UnsupportedOperationException; + + /** + * Set the safe block for non-PoS networks + * + * @param blockHash Hash of the finalized block + * @throws IllegalArgumentException if the block hash is not on the chain + * @throws UnsupportedOperationException if the network is a PoS network + */ + void setSafeBlock(Hash blockHash) throws IllegalArgumentException, UnsupportedOperationException; + ; } From a7ab1773e427c1a3dd001c1940227c8158f420fd Mon Sep 17 00:00:00 2001 From: Fabio Di Fabio Date: Wed, 31 Jul 2024 18:46:16 +0200 Subject: [PATCH 080/259] In process RPC service (#7395) Signed-off-by: Fabio Di Fabio --- CHANGELOG.md | 3 +- .../tests/acceptance/dsl/node/BesuNode.java | 8 ++ .../dsl/node/ThreadBesuNodeRunner.java | 9 ++- .../configuration/BesuNodeConfiguration.java | 8 ++ .../BesuNodeConfigurationBuilder.java | 11 +++ .../node/configuration/BesuNodeFactory.java | 17 +++- .../NodeConfigurationFactory.java | 12 +++ .../acceptance/dsl/privacy/PrivacyNode.java | 1 + .../miner/MinerGetMinGasPriceTransaction.java | 42 ++++++++++ .../miner/MinerRequestFactory.java | 5 ++ .../transaction/miner/MinerTransactions.java | 4 + .../TestInProcessRpcServicePlugin.java | 81 +++++++++++++++++++ .../InProcessRpcServicePluginTest.java | 51 ++++++++++++ .../java/org/hyperledger/besu/Runner.java | 15 ++++ .../org/hyperledger/besu/RunnerBuilder.java | 46 +++++++++++ .../org/hyperledger/besu/cli/BesuCommand.java | 12 +++ .../options/unstable/InProcessRpcOptions.java | 73 +++++++++++++++++ .../besu/services/RpcEndpointServiceImpl.java | 61 ++++++++++++++ .../hyperledger/besu/RunnerBuilderTest.java | 7 ++ .../java/org/hyperledger/besu/RunnerTest.java | 2 + .../besu/cli/CommandTestAbstract.java | 1 + .../jsonrpc/InProcessRpcConfiguration.java | 36 +++++++++ .../internal/response/JsonRpcResponse.java | 6 +- plugin-api/build.gradle | 2 +- .../plugin/services/RpcEndpointService.java | 10 +++ .../plugin/services/rpc/PluginRpcRequest.java | 2 +- .../services/rpc/PluginRpcResponse.java | 27 +++++++ .../besu/plugin/services/rpc/RpcResponse.java | 26 ++++++ 28 files changed, 568 insertions(+), 10 deletions(-) create mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/miner/MinerGetMinGasPriceTransaction.java create mode 100644 acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestInProcessRpcServicePlugin.java create mode 100644 acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/plugins/InProcessRpcServicePluginTest.java create mode 100644 besu/src/main/java/org/hyperledger/besu/cli/options/unstable/InProcessRpcOptions.java create mode 100644 ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/InProcessRpcConfiguration.java create mode 100644 plugin-api/src/main/java/org/hyperledger/besu/plugin/services/rpc/PluginRpcResponse.java create mode 100644 plugin-api/src/main/java/org/hyperledger/besu/plugin/services/rpc/RpcResponse.java diff --git a/CHANGELOG.md b/CHANGELOG.md index c5d782ba25..0db9e9df3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ ### Additions and Improvements - Expose set finalized/safe block in plugin api BlockchainService. These method can be used by plugins to set finalized/safe block for a PoA network (such as QBFT, IBFT and Clique).[#7382](https://github.com/hyperledger/besu/pull/7382) +- In process RPC service [#7395](https://github.com/hyperledger/besu/pull/7395) ### Bug fixes @@ -44,7 +45,7 @@ - Force bonsai-limit-trie-logs-enabled=false when sync-mode=FULL instead of startup error [#7357](https://github.com/hyperledger/besu/pull/7357) - `--Xbonsai-parallel-tx-processing-enabled` option enables executing transactions in parallel during block processing for Bonsai nodes - Reduce default trie log pruning window size from 30,000 to 5,000 [#7365](https://github.com/hyperledger/besu/pull/7365) -- Add option `--poa-discovery-retry-bootnodes` for PoA networks to always use bootnodes during peer refresh, not just on first start [#7314](https://github.com/hyperledger/besu/pull/7314) +- Add option `--poa-discovery-retry-bootnodes` for PoA networks to always use bootnodes during peer refresh, not just on first start [#7314](https://github.com/hyperledger/besu/pull/7314) ### Bug fixes - Fix `eth_call` deserialization to correctly ignore unknown fields in the transaction object. [#7323](https://github.com/hyperledger/besu/pull/7323) 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 5f30941f23..1ae27d6261 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 @@ -23,6 +23,7 @@ import org.hyperledger.besu.crypto.KeyPair; import org.hyperledger.besu.crypto.KeyPairUtil; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.ethereum.api.ApiConfiguration; +import org.hyperledger.besu.ethereum.api.jsonrpc.InProcessRpcConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.ipc.JsonRpcIpcConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.websocket.WebSocketConfiguration; @@ -109,6 +110,7 @@ public class BesuNode implements NodeConfiguration, RunnableNode, AutoCloseable private final Optional engineRpcConfiguration; private final WebSocketConfiguration webSocketConfiguration; private final JsonRpcIpcConfiguration jsonRpcIpcConfiguration; + private final InProcessRpcConfiguration inProcessRpcConfiguration; private final MetricsConfiguration metricsConfiguration; private final DataStorageConfiguration dataStorageConfiguration; private Optional permissioningConfiguration; @@ -143,6 +145,7 @@ public class BesuNode implements NodeConfiguration, RunnableNode, AutoCloseable final Optional engineRpcConfiguration, final WebSocketConfiguration webSocketConfiguration, final JsonRpcIpcConfiguration jsonRpcIpcConfiguration, + final InProcessRpcConfiguration inProcessRpcConfiguration, final MetricsConfiguration metricsConfiguration, final Optional permissioningConfiguration, final ApiConfiguration apiConfiguration, @@ -193,6 +196,7 @@ public class BesuNode implements NodeConfiguration, RunnableNode, AutoCloseable this.engineRpcConfiguration = engineRpcConfiguration; this.webSocketConfiguration = webSocketConfiguration; this.jsonRpcIpcConfiguration = jsonRpcIpcConfiguration; + this.inProcessRpcConfiguration = inProcessRpcConfiguration; this.metricsConfiguration = metricsConfiguration; this.permissioningConfiguration = permissioningConfiguration; this.apiConfiguration = apiConfiguration; @@ -624,6 +628,10 @@ public class BesuNode implements NodeConfiguration, RunnableNode, AutoCloseable return jsonRpcIpcConfiguration; } + InProcessRpcConfiguration inProcessRpcConfiguration() { + return inProcessRpcConfiguration; + } + Optional wsRpcListenHost() { return Optional.of(webSocketConfiguration().getHost()); } 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 0448d324e6..459fe49efb 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 @@ -29,6 +29,7 @@ import org.hyperledger.besu.cryptoservices.NodeKey; import org.hyperledger.besu.ethereum.GasLimitCalculator; import org.hyperledger.besu.ethereum.api.ApiConfiguration; import org.hyperledger.besu.ethereum.api.graphql.GraphQLConfiguration; +import org.hyperledger.besu.ethereum.api.jsonrpc.InProcessRpcConfiguration; import org.hyperledger.besu.ethereum.core.ImmutableMiningParameters; import org.hyperledger.besu.ethereum.core.plugins.PluginConfiguration; import org.hyperledger.besu.ethereum.eth.EthProtocolConfiguration; @@ -236,6 +237,8 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner { .transactionPoolValidatorService(transactionPoolValidatorServiceImpl) .build(); + final InProcessRpcConfiguration inProcessRpcConfiguration = node.inProcessRpcConfiguration(); + final int maxPeers = 25; builder @@ -297,7 +300,8 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner { .besuPluginContext(besuPluginContext) .autoLogBloomCaching(false) .storageProvider(storageProvider) - .rpcEndpointService(rpcEndpointServiceImpl); + .rpcEndpointService(rpcEndpointServiceImpl) + .inProcessRpcConfiguration(inProcessRpcConfiguration); node.engineRpcConfiguration().ifPresent(runnerBuilder::engineJsonRpcConfiguration); besuPluginContext.beforeExternalServices(); @@ -313,6 +317,9 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner { besuController.getTransactionPool(), besuController.getSyncState(), besuController.getProtocolContext().getBadBlockManager())); + + rpcEndpointServiceImpl.init(runner.getInProcessRpcMethods()); + besuPluginContext.startPlugins(); runner.startEthereumMainLoop(); diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeConfiguration.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeConfiguration.java index 7bffe9d775..c77a6c8ac7 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeConfiguration.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeConfiguration.java @@ -17,6 +17,7 @@ package org.hyperledger.besu.tests.acceptance.dsl.node.configuration; import org.hyperledger.besu.cli.config.NetworkName; import org.hyperledger.besu.crypto.KeyPair; import org.hyperledger.besu.ethereum.api.ApiConfiguration; +import org.hyperledger.besu.ethereum.api.jsonrpc.InProcessRpcConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.ipc.JsonRpcIpcConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.websocket.WebSocketConfiguration; @@ -45,6 +46,7 @@ public class BesuNodeConfiguration { private final Optional engineRpcConfiguration; private final WebSocketConfiguration webSocketConfiguration; private final JsonRpcIpcConfiguration jsonRpcIpcConfiguration; + private final InProcessRpcConfiguration inProcessRpcConfiguration; private final MetricsConfiguration metricsConfiguration; private final Optional permissioningConfiguration; private final ApiConfiguration apiConfiguration; @@ -81,6 +83,7 @@ public class BesuNodeConfiguration { final Optional engineRpcConfiguration, final WebSocketConfiguration webSocketConfiguration, final JsonRpcIpcConfiguration jsonRpcIpcConfiguration, + final InProcessRpcConfiguration inProcessRpcConfiguration, final MetricsConfiguration metricsConfiguration, final Optional permissioningConfiguration, final ApiConfiguration apiConfiguration, @@ -114,6 +117,7 @@ public class BesuNodeConfiguration { this.engineRpcConfiguration = engineRpcConfiguration; this.webSocketConfiguration = webSocketConfiguration; this.jsonRpcIpcConfiguration = jsonRpcIpcConfiguration; + this.inProcessRpcConfiguration = inProcessRpcConfiguration; this.metricsConfiguration = metricsConfiguration; this.permissioningConfiguration = permissioningConfiguration; this.apiConfiguration = apiConfiguration; @@ -171,6 +175,10 @@ public class BesuNodeConfiguration { return jsonRpcIpcConfiguration; } + public InProcessRpcConfiguration getInProcessRpcConfiguration() { + return inProcessRpcConfiguration; + } + public MetricsConfiguration getMetricsConfiguration() { return metricsConfiguration; } diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeConfigurationBuilder.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeConfigurationBuilder.java index 86fb8ab5ca..d8b5e0f904 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeConfigurationBuilder.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeConfigurationBuilder.java @@ -24,6 +24,8 @@ import org.hyperledger.besu.cli.config.NetworkName; import org.hyperledger.besu.crypto.KeyPair; import org.hyperledger.besu.ethereum.api.ApiConfiguration; import org.hyperledger.besu.ethereum.api.ImmutableApiConfiguration; +import org.hyperledger.besu.ethereum.api.jsonrpc.ImmutableInProcessRpcConfiguration; +import org.hyperledger.besu.ethereum.api.jsonrpc.InProcessRpcConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis; import org.hyperledger.besu.ethereum.api.jsonrpc.authentication.JwtAlgorithm; @@ -70,6 +72,8 @@ public class BesuNodeConfigurationBuilder { private JsonRpcConfiguration engineRpcConfiguration = JsonRpcConfiguration.createEngineDefault(); private WebSocketConfiguration webSocketConfiguration = WebSocketConfiguration.createDefault(); private JsonRpcIpcConfiguration jsonRpcIpcConfiguration = new JsonRpcIpcConfiguration(); + private InProcessRpcConfiguration inProcessRpcConfiguration = + ImmutableInProcessRpcConfiguration.builder().build(); private MetricsConfiguration metricsConfiguration = MetricsConfiguration.builder().build(); private Optional permissioningConfiguration = Optional.empty(); private ApiConfiguration apiConfiguration = ImmutableApiConfiguration.builder().build(); @@ -258,6 +262,12 @@ public class BesuNodeConfigurationBuilder { return this; } + public BesuNodeConfigurationBuilder inProcessRpcConfiguration( + final InProcessRpcConfiguration inProcessRpcConfiguration) { + this.inProcessRpcConfiguration = inProcessRpcConfiguration; + return this; + } + public BesuNodeConfigurationBuilder metricsConfiguration( final MetricsConfiguration metricsConfiguration) { this.metricsConfiguration = metricsConfiguration; @@ -516,6 +526,7 @@ public class BesuNodeConfigurationBuilder { Optional.of(engineRpcConfiguration), webSocketConfiguration, jsonRpcIpcConfiguration, + inProcessRpcConfiguration, metricsConfiguration, permissioningConfiguration, apiConfiguration, diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeFactory.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeFactory.java index 1ea29388bd..ed4a28422d 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeFactory.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeFactory.java @@ -16,6 +16,8 @@ package org.hyperledger.besu.tests.acceptance.dsl.node.configuration; import static java.util.Arrays.asList; import static java.util.stream.Collectors.toList; +import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis.ADMIN; +import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis.IBFT; import org.hyperledger.besu.crypto.KeyPair; import org.hyperledger.besu.datatypes.Wei; @@ -43,6 +45,7 @@ import java.net.URI; import java.net.URISyntaxException; import java.nio.file.Paths; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Optional; import java.util.Set; @@ -64,6 +67,7 @@ public class BesuNodeFactory { config.getEngineRpcConfiguration(), config.getWebSocketConfiguration(), config.getJsonRpcIpcConfiguration(), + config.getInProcessRpcConfiguration(), config.getMetricsConfiguration(), config.getPermissioningConfiguration(), config.getApiConfiguration(), @@ -330,12 +334,20 @@ public class BesuNodeFactory { } public BesuNode createPluginsNode( - final String name, final List plugins, final List extraCLIOptions) + final String name, + final List plugins, + final List extraCLIOptions, + final String... extraRpcApis) throws IOException { + + final List enableRpcApis = new ArrayList<>(Arrays.asList(extraRpcApis)); + enableRpcApis.addAll(List.of(IBFT.name(), ADMIN.name())); + return create( new BesuNodeConfigurationBuilder() .name(name) - .jsonRpcConfiguration(node.createJsonRpcWithIbft2AdminEnabledConfig()) + .jsonRpcConfiguration( + node.createJsonRpcWithRpcApiEnabledConfig(enableRpcApis.toArray(String[]::new))) .webSocketConfiguration(node.createWebSocketEnabledConfig()) .plugins(plugins) .extraCLIOptions(extraCLIOptions) @@ -394,6 +406,7 @@ public class BesuNodeFactory { .miningEnabled() .jsonRpcConfiguration(node.createJsonRpcWithCliqueEnabledConfig(extraRpcApis)) .webSocketConfiguration(node.createWebSocketEnabledConfig()) + .inProcessRpcConfiguration(node.createInProcessRpcConfiguration(extraRpcApis)) .devMode(false) .jsonRpcTxPool() .genesisConfigProvider( diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/NodeConfigurationFactory.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/NodeConfigurationFactory.java index 219d15d1ad..c2e82c0f83 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/NodeConfigurationFactory.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/NodeConfigurationFactory.java @@ -22,6 +22,8 @@ import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis.IBFT; import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis.MINER; import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis.QBFT; +import org.hyperledger.besu.ethereum.api.jsonrpc.ImmutableInProcessRpcConfiguration; +import org.hyperledger.besu.ethereum.api.jsonrpc.InProcessRpcConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.websocket.WebSocketConfiguration; import org.hyperledger.besu.tests.acceptance.dsl.node.RunnableNode; @@ -94,4 +96,14 @@ public class NodeConfigurationFactory { jsonRpcConfig.setRpcApis(rpcApis); return jsonRpcConfig; } + + public InProcessRpcConfiguration createInProcessRpcConfiguration(final Set extraRpcApis) { + final Set rpcApis = + new HashSet<>(ImmutableInProcessRpcConfiguration.DEFAULT_IN_PROCESS_RPC_APIS); + rpcApis.addAll(extraRpcApis); + return ImmutableInProcessRpcConfiguration.builder() + .inProcessRpcApis(rpcApis) + .isEnabled(true) + .build(); + } } diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/PrivacyNode.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/PrivacyNode.java index 32a5a0fbf4..520cd7d574 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/PrivacyNode.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/PrivacyNode.java @@ -106,6 +106,7 @@ public class PrivacyNode implements AutoCloseable { besuConfig.getEngineRpcConfiguration(), besuConfig.getWebSocketConfiguration(), besuConfig.getJsonRpcIpcConfiguration(), + besuConfig.getInProcessRpcConfiguration(), besuConfig.getMetricsConfiguration(), besuConfig.getPermissioningConfiguration(), besuConfig.getApiConfiguration(), diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/miner/MinerGetMinGasPriceTransaction.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/miner/MinerGetMinGasPriceTransaction.java new file mode 100644 index 0000000000..991e9f7bc4 --- /dev/null +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/miner/MinerGetMinGasPriceTransaction.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.tests.acceptance.dsl.transaction.miner; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; +import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; + +import java.io.IOException; +import java.math.BigInteger; + +import org.web3j.protocol.core.methods.response.EthGasPrice; + +public class MinerGetMinGasPriceTransaction implements Transaction { + + @Override + public BigInteger execute(final NodeRequests node) { + try { + final EthGasPrice result = node.miner().minerGetMinGasPrice().send(); + assertThat(result).isNotNull(); + assertThat(result.hasError()).isFalse(); + + return result.getGasPrice(); + + } catch (final IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/miner/MinerRequestFactory.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/miner/MinerRequestFactory.java index 26be9d3a96..5c8b5ef6c1 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/miner/MinerRequestFactory.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/miner/MinerRequestFactory.java @@ -16,6 +16,7 @@ package org.hyperledger.besu.tests.acceptance.dsl.transaction.miner; import org.web3j.protocol.Web3jService; import org.web3j.protocol.core.Request; +import org.web3j.protocol.core.methods.response.EthGasPrice; public class MinerRequestFactory { @@ -40,4 +41,8 @@ public class MinerRequestFactory { web3jService, org.web3j.protocol.core.methods.response.VoidResponse.class); } + + Request minerGetMinGasPrice() { + return new Request<>("miner_getMinGasPrice", null, web3jService, EthGasPrice.class); + } } diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/miner/MinerTransactions.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/miner/MinerTransactions.java index e5cacd4e7a..a8d24515a9 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/miner/MinerTransactions.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/miner/MinerTransactions.java @@ -23,4 +23,8 @@ public class MinerTransactions { public MinerStopTransaction minerStop() { return new MinerStopTransaction(); } + + public MinerGetMinGasPriceTransaction minerGetMinGasPrice() { + return new MinerGetMinGasPriceTransaction(); + } } diff --git a/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestInProcessRpcServicePlugin.java b/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestInProcessRpcServicePlugin.java new file mode 100644 index 0000000000..3ebced0df9 --- /dev/null +++ b/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestInProcessRpcServicePlugin.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.tests.acceptance.plugins; + +import org.hyperledger.besu.datatypes.Wei; +import org.hyperledger.besu.plugin.BesuContext; +import org.hyperledger.besu.plugin.BesuPlugin; +import org.hyperledger.besu.plugin.services.PicoCLIOptions; +import org.hyperledger.besu.plugin.services.RpcEndpointService; +import org.hyperledger.besu.plugin.services.rpc.RpcResponseType; + +import com.google.auto.service.AutoService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import picocli.CommandLine; + +@AutoService(BesuPlugin.class) +public class TestInProcessRpcServicePlugin implements BesuPlugin { + private static final Logger LOG = LoggerFactory.getLogger(TestInProcessRpcServicePlugin.class); + + private RpcEndpointService rpcEndpointService; + + @CommandLine.Option(names = {"--plugin-test-set-min-gas-price"}) + long minGasPrice = -1; + + @Override + public void register(final BesuContext context) { + final PicoCLIOptions cmdlineOptions = + context + .getService(PicoCLIOptions.class) + .orElseThrow( + () -> + new IllegalStateException( + "Failed to obtain PicoCLI options from the BesuContext")); + + cmdlineOptions.addPicoCLIOptions("test", this); + + rpcEndpointService = + context + .getService(RpcEndpointService.class) + .orElseThrow( + () -> + new RuntimeException( + "Failed to obtain RpcEndpointService from the BesuContext.")); + } + + @Override + public void start() { + LOG.info("TestInProcessRpcServicePlugin minGasPrice option: {}", minGasPrice); + if (minGasPrice >= 0) { + callSetMinGasPrice(minGasPrice); + } + } + + @Override + public void stop() {} + + private void callSetMinGasPrice(final long minGasPrice) { + LOG.info("Setting minGasPrice via in-process RPC service"); + final var minGasPriceWei = Wei.of(minGasPrice); + final var resp = + rpcEndpointService.call( + "miner_setMinGasPrice", new Object[] {minGasPriceWei.toShortHexString()}); + LOG.info("miner_setMinGasPrice response: {}", resp); + if (!resp.getType().equals(RpcResponseType.SUCCESS)) { + throw new RuntimeException("Internal setMinGasPrice method failed: " + resp); + } + } +} diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/plugins/InProcessRpcServicePluginTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/plugins/InProcessRpcServicePluginTest.java new file mode 100644 index 0000000000..4dbf8fd5d1 --- /dev/null +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/plugins/InProcessRpcServicePluginTest.java @@ -0,0 +1,51 @@ +/* + * 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.plugins; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBase; +import org.hyperledger.besu.tests.acceptance.dsl.node.BesuNode; + +import java.math.BigInteger; +import java.util.List; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class InProcessRpcServicePluginTest extends AcceptanceTestBase { + private static final long MIN_GAS_PRICE = 123456; + private BesuNode node; + + @BeforeEach + public void setUp() throws Exception { + node = + besu.createPluginsNode( + "node1", + List.of("testPlugins"), + List.of( + "--Xin-process-rpc-enabled=true", + "--Xin-process-rpc-apis=MINER", + "--plugin-test-set-min-gas-price=" + MIN_GAS_PRICE), + "MINER"); + cluster.start(node); + } + + @Test + public void smokeTest() { + final var currMinGasPrice = node.execute(minerTransactions.minerGetMinGasPrice()); + assertThat(currMinGasPrice).isEqualTo(BigInteger.valueOf(MIN_GAS_PRICE)); + } +} diff --git a/besu/src/main/java/org/hyperledger/besu/Runner.java b/besu/src/main/java/org/hyperledger/besu/Runner.java index eed35a03a9..609dab117f 100644 --- a/besu/src/main/java/org/hyperledger/besu/Runner.java +++ b/besu/src/main/java/org/hyperledger/besu/Runner.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.controller.BesuController; import org.hyperledger.besu.ethereum.api.graphql.GraphQLHttpService; import org.hyperledger.besu.ethereum.api.jsonrpc.EngineJsonRpcService; import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcHttpService; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.ipc.JsonRpcIpcService; import org.hyperledger.besu.ethereum.api.jsonrpc.websocket.WebSocketService; import org.hyperledger.besu.ethereum.api.query.cache.AutoTransactionLogBloomCachingService; @@ -39,6 +40,7 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardOpenOption; +import java.util.Map; import java.util.Optional; import java.util.Properties; import java.util.concurrent.CompletableFuture; @@ -69,6 +71,7 @@ public class Runner implements AutoCloseable { private final Optional engineJsonRpc; private final Optional metrics; private final Optional ipcJsonRpc; + private final Map inProcessRpcMethods; private final Optional pidPath; private final Optional webSocketRpc; private final TransactionPoolEvictionService transactionPoolEvictionService; @@ -90,6 +93,7 @@ public class Runner implements AutoCloseable { * @param graphQLHttp the graph ql http * @param webSocketRpc the web socket rpc * @param ipcJsonRpc the ipc json rpc + * @param inProcessRpcMethods the in-process rpc methods * @param stratumServer the stratum server * @param metrics the metrics * @param ethStatsService the eth stats service @@ -108,6 +112,7 @@ public class Runner implements AutoCloseable { final Optional graphQLHttp, final Optional webSocketRpc, final Optional ipcJsonRpc, + final Map inProcessRpcMethods, final Optional stratumServer, final Optional metrics, final Optional ethStatsService, @@ -125,6 +130,7 @@ public class Runner implements AutoCloseable { this.engineJsonRpc = engineJsonRpc; this.webSocketRpc = webSocketRpc; this.ipcJsonRpc = ipcJsonRpc; + this.inProcessRpcMethods = inProcessRpcMethods; this.metrics = metrics; this.ethStatsService = ethStatsService; this.besuController = besuController; @@ -413,6 +419,15 @@ public class Runner implements AutoCloseable { } } + /** + * Get the RPC methods that can be called in-process + * + * @return RPC methods by name + */ + public Map getInProcessRpcMethods() { + return inProcessRpcMethods; + } + /** * Gets local enode. * diff --git a/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java b/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java index d0c434fc81..e34c0115fe 100644 --- a/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java @@ -34,6 +34,7 @@ import org.hyperledger.besu.ethereum.api.graphql.GraphQLDataFetchers; import org.hyperledger.besu.ethereum.api.graphql.GraphQLHttpService; import org.hyperledger.besu.ethereum.api.graphql.GraphQLProvider; import org.hyperledger.besu.ethereum.api.jsonrpc.EngineJsonRpcService; +import org.hyperledger.besu.ethereum.api.jsonrpc.InProcessRpcConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcHttpService; import org.hyperledger.besu.ethereum.api.jsonrpc.authentication.AuthenticationService; @@ -178,6 +179,7 @@ public class RunnerBuilder { private Optional engineJsonRpcConfiguration = Optional.empty(); private GraphQLConfiguration graphQLConfiguration; private WebSocketConfiguration webSocketConfiguration; + private InProcessRpcConfiguration inProcessRpcConfiguration; private ApiConfiguration apiConfiguration; private Path dataDir; private Optional pidPath = Optional.empty(); @@ -414,6 +416,18 @@ public class RunnerBuilder { return this; } + /** + * Add In-Process RPC configuration. + * + * @param inProcessRpcConfiguration the in-process RPC configuration + * @return the runner builder + */ + public RunnerBuilder inProcessRpcConfiguration( + final InProcessRpcConfiguration inProcessRpcConfiguration) { + this.inProcessRpcConfiguration = inProcessRpcConfiguration; + return this; + } + /** * Add Api configuration. * @@ -1082,6 +1096,37 @@ public class RunnerBuilder { jsonRpcIpcService = Optional.empty(); } + final Map inProcessRpcMethods; + if (inProcessRpcConfiguration.isEnabled()) { + inProcessRpcMethods = + jsonRpcMethods( + protocolSchedule, + context, + besuController, + peerNetwork, + blockchainQueries, + synchronizer, + transactionPool, + miningParameters, + miningCoordinator, + metricsSystem, + supportedCapabilities, + inProcessRpcConfiguration.getInProcessRpcApis(), + filterManager, + accountLocalConfigPermissioningController, + nodeLocalConfigPermissioningController, + privacyParameters, + jsonRpcConfiguration, + webSocketConfiguration, + metricsConfiguration, + natService, + besuPluginContext.getNamedPlugins(), + dataDir, + rpcEndpointServiceImpl); + } else { + inProcessRpcMethods = Map.of(); + } + return new Runner( vertx, networkRunner, @@ -1091,6 +1136,7 @@ public class RunnerBuilder { graphQLHttpService, webSocketService, jsonRpcIpcService, + inProcessRpcMethods, stratumServer, metricsService, ethStatsService, 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 d300fbea45..9c2b014ec0 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java @@ -63,6 +63,7 @@ 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; @@ -107,6 +108,7 @@ import org.hyperledger.besu.enclave.EnclaveFactory; import org.hyperledger.besu.ethereum.GasLimitCalculator; import org.hyperledger.besu.ethereum.api.ApiConfiguration; import org.hyperledger.besu.ethereum.api.graphql.GraphQLConfiguration; +import org.hyperledger.besu.ethereum.api.jsonrpc.InProcessRpcConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis; import org.hyperledger.besu.ethereum.api.jsonrpc.authentication.JwtAlgorithm; @@ -660,6 +662,10 @@ public class BesuCommand implements DefaultCommandValues, Runnable { @CommandLine.ArgGroup(validate = false, heading = "@|bold JSON-RPC Websocket Options|@%n") RpcWebsocketOptions rpcWebsocketOptions = new RpcWebsocketOptions(); + // In-Process RPC Options + @CommandLine.ArgGroup(validate = false, heading = "@|bold In-Process RPC Options|@%n") + InProcessRpcOptions inProcessRpcOptions = InProcessRpcOptions.create(); + // Privacy Options Group @CommandLine.ArgGroup(validate = false, heading = "@|bold Privacy Options|@%n") PrivacyOptionGroup privacyOptionGroup = new PrivacyOptionGroup(); @@ -926,6 +932,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { private GraphQLConfiguration graphQLConfiguration; private WebSocketConfiguration webSocketConfiguration; private JsonRpcIpcConfiguration jsonRpcIpcConfiguration; + private InProcessRpcConfiguration inProcessRpcConfiguration; private ApiConfiguration apiConfiguration; private MetricsConfiguration metricsConfiguration; private Optional permissioningConfiguration; @@ -1353,6 +1360,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { engineJsonRpcConfiguration, webSocketConfiguration, jsonRpcIpcConfiguration, + inProcessRpcConfiguration, apiConfiguration, metricsConfiguration, permissioningConfiguration, @@ -1370,6 +1378,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { besuController.getProtocolContext().getWorldStateArchive(), besuController.getProtocolSchedule(), apiConfiguration.getGasCap())); + rpcEndpointServiceImpl.init(runner.getInProcessRpcMethods()); besuPluginContext.addService( BesuEvents.class, @@ -1810,6 +1819,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { unstableIpcOptions.isEnabled(), unstableIpcOptions.getIpcPath(), unstableIpcOptions.getRpcIpcApis()); + inProcessRpcConfiguration = inProcessRpcOptions.toDomainObject(); apiConfiguration = apiConfigurationOptions.apiConfiguration(); dataStorageConfiguration = getDataStorageConfiguration(); // hostsWhitelist is a hidden option. If it is specified, add the list to hostAllowlist @@ -2321,6 +2331,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { final JsonRpcConfiguration engineJsonRpcConfiguration, final WebSocketConfiguration webSocketConfiguration, final JsonRpcIpcConfiguration jsonRpcIpcConfiguration, + final InProcessRpcConfiguration inProcessRpcConfiguration, final ApiConfiguration apiConfiguration, final MetricsConfiguration metricsConfiguration, final Optional permissioningConfiguration, @@ -2353,6 +2364,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { .engineJsonRpcConfiguration(engineJsonRpcConfiguration) .webSocketConfiguration(webSocketConfiguration) .jsonRpcIpcConfiguration(jsonRpcIpcConfiguration) + .inProcessRpcConfiguration(inProcessRpcConfiguration) .apiConfiguration(apiConfiguration) .pidPath(pidPath) .dataDir(dataDir()) diff --git a/besu/src/main/java/org/hyperledger/besu/cli/options/unstable/InProcessRpcOptions.java b/besu/src/main/java/org/hyperledger/besu/cli/options/unstable/InProcessRpcOptions.java new file mode 100644 index 0000000000..9adeb37db7 --- /dev/null +++ b/besu/src/main/java/org/hyperledger/besu/cli/options/unstable/InProcessRpcOptions.java @@ -0,0 +1,73 @@ +/* + * 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.unstable; + +import static org.hyperledger.besu.ethereum.api.jsonrpc.InProcessRpcConfiguration.DEFAULT_IN_PROCESS_RPC_APIS; +import static org.hyperledger.besu.ethereum.api.jsonrpc.InProcessRpcConfiguration.DEFAULT_IN_PROCESS_RPC_ENABLED; + +import org.hyperledger.besu.cli.options.CLIOptions; +import org.hyperledger.besu.cli.util.CommandLineUtils; +import org.hyperledger.besu.ethereum.api.jsonrpc.ImmutableInProcessRpcConfiguration; +import org.hyperledger.besu.ethereum.api.jsonrpc.InProcessRpcConfiguration; + +import java.util.List; +import java.util.Set; + +import picocli.CommandLine; + +/** The in process RPC options. */ +public class InProcessRpcOptions implements CLIOptions { + + /** Default constructor. */ + InProcessRpcOptions() {} + + /** + * Create ipc options. + * + * @return the ipc options + */ + public static InProcessRpcOptions create() { + return new InProcessRpcOptions(); + } + + @CommandLine.Option( + names = {"--Xin-process-rpc-enabled"}, + hidden = true, + description = "Set to enalbe in-process RPC method call service (default: ${DEFAULT-VALUE})") + private final Boolean enabled = DEFAULT_IN_PROCESS_RPC_ENABLED; + + @CommandLine.Option( + names = {"--Xin-process-rpc-api", "--Xin-process-rpc-apis"}, + hidden = true, + paramLabel = "", + split = " {0,1}, {0,1}", + arity = "1..*", + description = + "Comma separated list of APIs to enable on in-process RPC method call service (default: ${DEFAULT-VALUE})") + private final Set inProcessRpcApis = DEFAULT_IN_PROCESS_RPC_APIS; + + @Override + public InProcessRpcConfiguration toDomainObject() { + return ImmutableInProcessRpcConfiguration.builder() + .isEnabled(enabled) + .inProcessRpcApis(inProcessRpcApis) + .build(); + } + + @Override + public List getCLIOptions() { + return CommandLineUtils.getCLIOptions(this, new InProcessRpcOptions()); + } +} diff --git a/besu/src/main/java/org/hyperledger/besu/services/RpcEndpointServiceImpl.java b/besu/src/main/java/org/hyperledger/besu/services/RpcEndpointServiceImpl.java index f31323b91b..dcfe29146e 100644 --- a/besu/src/main/java/org/hyperledger/besu/services/RpcEndpointServiceImpl.java +++ b/besu/src/main/java/org/hyperledger/besu/services/RpcEndpointServiceImpl.java @@ -17,25 +17,48 @@ package org.hyperledger.besu.services; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; +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.methods.PluginJsonRpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; import org.hyperledger.besu.plugin.services.RpcEndpointService; import org.hyperledger.besu.plugin.services.rpc.PluginRpcRequest; +import org.hyperledger.besu.plugin.services.rpc.PluginRpcResponse; +import org.hyperledger.besu.plugin.services.rpc.RpcResponseType; +import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.Locale; import java.util.Map; +import java.util.NoSuchElementException; import java.util.function.Function; import java.util.stream.Collectors; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** The RPC endpoint service implementation. */ public class RpcEndpointServiceImpl implements RpcEndpointService { + private static final Logger LOG = LoggerFactory.getLogger(RpcEndpointServiceImpl.class); + private final Map> rpcMethods = new HashMap<>(); + private Map inProcessRpcMethods; /** Default Constructor. */ public RpcEndpointServiceImpl() {} + /** + * Init the service + * + * @param inProcessRpcMethods set of RPC methods that can be called + */ + public void init(final Map inProcessRpcMethods) { + this.inProcessRpcMethods = inProcessRpcMethods; + } + @Override public void registerRPCEndpoint( final String namespace, @@ -48,6 +71,44 @@ public class RpcEndpointServiceImpl implements RpcEndpointService { rpcMethods.put(namespace + "_" + functionName, function); } + @Override + public PluginRpcResponse call(final String methodName, final Object[] params) { + checkNotNull( + inProcessRpcMethods, + "Service not initialized yet, this method must be called after plugin 'beforeExternalServices' call completes"); + + LOG.atTrace() + .setMessage("Calling method:{} with params:{}") + .addArgument(methodName) + .addArgument(() -> Arrays.toString(params)) + .log(); + + final var method = inProcessRpcMethods.get(methodName); + + if (method == null) { + throw new NoSuchElementException("Unknown or not enabled method: " + methodName); + } + + final var requestContext = + new JsonRpcRequestContext(new JsonRpcRequest("2.0", methodName, params)); + final var response = method.response(requestContext); + return new PluginRpcResponse() { + @Override + public Object getResult() { + return switch (response.getType()) { + case NONE, UNAUTHORIZED -> null; + case SUCCESS -> ((JsonRpcSuccessResponse) response).getResult(); + case ERROR -> ((JsonRpcErrorResponse) response).getError(); + }; + } + + @Override + public RpcResponseType getType() { + return response.getType(); + } + }; + } + /** * Gets plugin methods. * diff --git a/besu/src/test/java/org/hyperledger/besu/RunnerBuilderTest.java b/besu/src/test/java/org/hyperledger/besu/RunnerBuilderTest.java index c177064080..c7180b958c 100644 --- a/besu/src/test/java/org/hyperledger/besu/RunnerBuilderTest.java +++ b/besu/src/test/java/org/hyperledger/besu/RunnerBuilderTest.java @@ -38,6 +38,7 @@ import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.api.ImmutableApiConfiguration; import org.hyperledger.besu.ethereum.api.graphql.GraphQLConfiguration; +import org.hyperledger.besu.ethereum.api.jsonrpc.InProcessRpcConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.ipc.JsonRpcIpcConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.websocket.WebSocketConfiguration; @@ -163,6 +164,7 @@ public final class RunnerBuilderTest { .graphQLConfiguration(mock(GraphQLConfiguration.class)) .webSocketConfiguration(mock(WebSocketConfiguration.class)) .jsonRpcIpcConfiguration(mock(JsonRpcIpcConfiguration.class)) + .inProcessRpcConfiguration(mock(InProcessRpcConfiguration.class)) .metricsConfiguration(mock(MetricsConfiguration.class)) .vertx(vertx) .dataDir(dataDir.getRoot()) @@ -208,6 +210,7 @@ public final class RunnerBuilderTest { .graphQLConfiguration(mock(GraphQLConfiguration.class)) .webSocketConfiguration(mock(WebSocketConfiguration.class)) .jsonRpcIpcConfiguration(mock(JsonRpcIpcConfiguration.class)) + .inProcessRpcConfiguration(mock(InProcessRpcConfiguration.class)) .metricsConfiguration(mock(MetricsConfiguration.class)) .vertx(Vertx.vertx()) .dataDir(dataDir.getRoot()) @@ -267,6 +270,7 @@ public final class RunnerBuilderTest { .graphQLConfiguration(mock(GraphQLConfiguration.class)) .webSocketConfiguration(mock(WebSocketConfiguration.class)) .jsonRpcIpcConfiguration(mock(JsonRpcIpcConfiguration.class)) + .inProcessRpcConfiguration(mock(InProcessRpcConfiguration.class)) .metricsConfiguration(mock(MetricsConfiguration.class)) .vertx(Vertx.vertx()) .dataDir(dataDir.getRoot()) @@ -309,6 +313,7 @@ public final class RunnerBuilderTest { .engineJsonRpcConfiguration(engineConf) .webSocketConfiguration(wsRpc) .jsonRpcIpcConfiguration(mock(JsonRpcIpcConfiguration.class)) + .inProcessRpcConfiguration(mock(InProcessRpcConfiguration.class)) .graphQLConfiguration(mock(GraphQLConfiguration.class)) .metricsConfiguration(mock(MetricsConfiguration.class)) .vertx(Vertx.vertx()) @@ -351,6 +356,7 @@ public final class RunnerBuilderTest { .engineJsonRpcConfiguration(engineConf) .webSocketConfiguration(wsRpc) .jsonRpcIpcConfiguration(mock(JsonRpcIpcConfiguration.class)) + .inProcessRpcConfiguration(mock(InProcessRpcConfiguration.class)) .graphQLConfiguration(mock(GraphQLConfiguration.class)) .metricsConfiguration(mock(MetricsConfiguration.class)) .vertx(Vertx.vertx()) @@ -395,6 +401,7 @@ public final class RunnerBuilderTest { .graphQLConfiguration(mock(GraphQLConfiguration.class)) .webSocketConfiguration(defaultWebSockConfig) .jsonRpcIpcConfiguration(mock(JsonRpcIpcConfiguration.class)) + .inProcessRpcConfiguration(mock(InProcessRpcConfiguration.class)) .metricsConfiguration(mock(MetricsConfiguration.class)) .vertx(Vertx.vertx()) .dataDir(dataDir.getRoot()) diff --git a/besu/src/test/java/org/hyperledger/besu/RunnerTest.java b/besu/src/test/java/org/hyperledger/besu/RunnerTest.java index e10d547581..5b2a56078f 100644 --- a/besu/src/test/java/org/hyperledger/besu/RunnerTest.java +++ b/besu/src/test/java/org/hyperledger/besu/RunnerTest.java @@ -36,6 +36,7 @@ import org.hyperledger.besu.ethereum.GasLimitCalculator; import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.api.ImmutableApiConfiguration; import org.hyperledger.besu.ethereum.api.graphql.GraphQLConfiguration; +import org.hyperledger.besu.ethereum.api.jsonrpc.ImmutableInProcessRpcConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.ipc.JsonRpcIpcConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.websocket.WebSocketConfiguration; @@ -211,6 +212,7 @@ public final class RunnerTest { .graphQLConfiguration(graphQLConfiguration()) .webSocketConfiguration(wsRpcConfiguration()) .jsonRpcIpcConfiguration(new JsonRpcIpcConfiguration()) + .inProcessRpcConfiguration(ImmutableInProcessRpcConfiguration.builder().build()) .metricsConfiguration(metricsConfiguration()) .dataDir(dbAhead) .pidPath(pidPath) 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 c77ced5c6f..f6fa2e4798 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/CommandTestAbstract.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/CommandTestAbstract.java @@ -332,6 +332,7 @@ public abstract class CommandTestAbstract { when(mockRunnerBuilder.graphQLConfiguration(any())).thenReturn(mockRunnerBuilder); when(mockRunnerBuilder.webSocketConfiguration(any())).thenReturn(mockRunnerBuilder); when(mockRunnerBuilder.jsonRpcIpcConfiguration(any())).thenReturn(mockRunnerBuilder); + when(mockRunnerBuilder.inProcessRpcConfiguration(any())).thenReturn(mockRunnerBuilder); when(mockRunnerBuilder.apiConfiguration(any())).thenReturn(mockRunnerBuilder); when(mockRunnerBuilder.dataDir(any())).thenReturn(mockRunnerBuilder); when(mockRunnerBuilder.bannedNodeIds(any())).thenReturn(mockRunnerBuilder); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/InProcessRpcConfiguration.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/InProcessRpcConfiguration.java new file mode 100644 index 0000000000..e59d06a21f --- /dev/null +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/InProcessRpcConfiguration.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.ethereum.api.jsonrpc; + +import java.util.HashSet; +import java.util.Set; + +import org.immutables.value.Value; + +@Value.Immutable +public interface InProcessRpcConfiguration { + boolean DEFAULT_IN_PROCESS_RPC_ENABLED = false; + Set DEFAULT_IN_PROCESS_RPC_APIS = new HashSet<>(RpcApis.DEFAULT_RPC_APIS); + + @Value.Default + default boolean isEnabled() { + return DEFAULT_IN_PROCESS_RPC_ENABLED; + } + + @Value.Default + default Set getInProcessRpcApis() { + return DEFAULT_IN_PROCESS_RPC_APIS; + } +} diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/response/JsonRpcResponse.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/response/JsonRpcResponse.java index 6817d2cfbb..5fb82187b6 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/response/JsonRpcResponse.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/response/JsonRpcResponse.java @@ -14,16 +14,14 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.response; -import org.hyperledger.besu.plugin.services.rpc.RpcResponseType; +import org.hyperledger.besu.plugin.services.rpc.RpcResponse; import com.fasterxml.jackson.annotation.JsonGetter; -public interface JsonRpcResponse { +public interface JsonRpcResponse extends RpcResponse { @JsonGetter("jsonrpc") default String getVersion() { return "2.0"; } - - RpcResponseType getType(); } diff --git a/plugin-api/build.gradle b/plugin-api/build.gradle index cc4b3237b5..e49297ab7b 100644 --- a/plugin-api/build.gradle +++ b/plugin-api/build.gradle @@ -70,7 +70,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 = 'tXFd8EcMJtD+ZSLJxWJLYRZD0d3njRz+3Ubey2zFM2A=' + knownHash = 'I851CCOs00yYpW10qIGIak1bKbYhKFQkV2wyCYELHKY=' } check.dependsOn('checkAPIChanges') diff --git a/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/RpcEndpointService.java b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/RpcEndpointService.java index a1b69a7c7f..512d9877c7 100644 --- a/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/RpcEndpointService.java +++ b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/RpcEndpointService.java @@ -15,6 +15,7 @@ package org.hyperledger.besu.plugin.services; import org.hyperledger.besu.plugin.services.rpc.PluginRpcRequest; +import org.hyperledger.besu.plugin.services.rpc.PluginRpcResponse; import java.util.function.Function; @@ -54,4 +55,13 @@ public interface RpcEndpointService extends BesuService { */ void registerRPCEndpoint( String namespace, String functionName, Function function); + + /** + * Allow to call any of the enabled in-process RPC methods + * + * @param methodName the method to invoke + * @param params the list of parameters accepted by the method + * @return the result of the method + */ + PluginRpcResponse call(String methodName, Object[] params); } diff --git a/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/rpc/PluginRpcRequest.java b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/rpc/PluginRpcRequest.java index c360f35edc..eab35b4b04 100644 --- a/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/rpc/PluginRpcRequest.java +++ b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/rpc/PluginRpcRequest.java @@ -1,5 +1,5 @@ /* - * Copyright ConsenSys AG. + * 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 diff --git a/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/rpc/PluginRpcResponse.java b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/rpc/PluginRpcResponse.java new file mode 100644 index 0000000000..7096a8a422 --- /dev/null +++ b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/rpc/PluginRpcResponse.java @@ -0,0 +1,27 @@ +/* + * 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.services.rpc; + +/** The interface Plugin rpc response. */ +public interface PluginRpcResponse extends RpcResponse { + + /** + * Get the result, unfortunately there is no typing yet, so call must know how to interact with + * the response + * + * @return the result + */ + Object getResult(); +} diff --git a/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/rpc/RpcResponse.java b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/rpc/RpcResponse.java new file mode 100644 index 0000000000..3fafbb1d10 --- /dev/null +++ b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/rpc/RpcResponse.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.plugin.services.rpc; + +/** Represent a Json RPC response */ +public interface RpcResponse { + + /** + * Get the response type + * + * @return the response type + */ + RpcResponseType getType(); +} From 53f8ff9389309eeb0db1f37ad8eb35f2afaf12ba Mon Sep 17 00:00:00 2001 From: Simon Dudley Date: Thu, 1 Aug 2024 14:11:51 +1000 Subject: [PATCH 081/259] Add comments to make deprecated trie log pruning option names clear (#7416) Signed-off-by: Simon Dudley --- .../besu/cli/options/stable/DataStorageOptions.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) 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 index a0403c3942..6f5c037c0d 100644 --- 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 @@ -69,20 +69,26 @@ public class DataStorageOptions implements CLIOptions 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", - "--Xbonsai-trie-log-pruning-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"}, + 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; From b5552e5137cd0f79318b1647b535ec2154ed0a37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Bojarski?= <54240434+letypequividelespoubelles@users.noreply.github.com> Date: Thu, 1 Aug 2024 10:07:45 +0530 Subject: [PATCH 082/259] fix(doc): tiny typo (#7388) Signed-off-by: Francois Bojarski Co-authored-by: Sally MacFarlane --- .../hyperledger/besu/evm/operation/AbstractCallOperation.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCallOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCallOperation.java index 762030bf3b..68ded6793e 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCallOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCallOperation.java @@ -197,7 +197,7 @@ public abstract class AbstractCallOperation extends AbstractOperation { if (value(frame).compareTo(balance) > 0 || frame.getDepth() >= 1024) { frame.expandMemory(inputDataOffset(frame), inputDataLength(frame)); frame.expandMemory(outputDataOffset(frame), outputDataLength(frame)); - // For the following, we either increment the gas or return zero so weo don't get double + // For the following, we either increment the gas or return zero, so we don't get double // charged. If we return zero then the traces don't have the right per-opcode cost. frame.incrementRemainingGas(gasAvailableForChildCall(frame) + cost); frame.popStackItems(getStackItemsConsumed()); From b727c958bfb7a2f4e814a7b5535572ce224cd68b Mon Sep 17 00:00:00 2001 From: Gaurav Ahuja Date: Thu, 1 Aug 2024 10:43:30 +0530 Subject: [PATCH 083/259] Make GeneralStateTestCaseEipSpec constructor public for use in linea-tracer/arithmetization (#7411) Signed-off-by: Gaurav Ahuja --- .../ethereum/referencetests/GeneralStateTestCaseEipSpec.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/GeneralStateTestCaseEipSpec.java b/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/GeneralStateTestCaseEipSpec.java index ddf6ac2eb1..9d9b278551 100644 --- a/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/GeneralStateTestCaseEipSpec.java +++ b/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/GeneralStateTestCaseEipSpec.java @@ -50,7 +50,7 @@ public class GeneralStateTestCaseEipSpec { private final int valueIndex; private final String expectException; - GeneralStateTestCaseEipSpec( + public GeneralStateTestCaseEipSpec( final String fork, final List> transactionSuppliers, final ReferenceTestWorldState initialWorldState, From 9cb8b06e4bef85fdf155ad2d96d96bc7793b52e0 Mon Sep 17 00:00:00 2001 From: ahamlat Date: Thu, 1 Aug 2024 17:00:16 +0200 Subject: [PATCH 084/259] Add integration tests on block processing (#7378) Add a block processing integration test to verify that sequential and parallel execution have the same behaviour Signed-off-by: Ameziane H Co-authored-by: Simon Dudley --- .../core/ExecutionContextTestFixture.java | 23 +- ...AbstractBlockProcessorIntegrationTest.java | 794 ++++++++++++++++++ .../contractUsedInBlockProcessingIT.sol | 56 ++ .../besu/ethereum/mainnet/genesis-bp-it.json | 48 ++ 4 files changed, 918 insertions(+), 3 deletions(-) create mode 100644 ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/AbstractBlockProcessorIntegrationTest.java create mode 100644 ethereum/core/src/test/resources/org/hyperledger/besu/ethereum/mainnet/contractUsedInBlockProcessingIT.sol create mode 100644 ethereum/core/src/test/resources/org/hyperledger/besu/ethereum/mainnet/genesis-bp-it.json diff --git a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/ExecutionContextTestFixture.java b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/ExecutionContextTestFixture.java index 91ab41b636..511b94d3ae 100644 --- a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/ExecutionContextTestFixture.java +++ b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/ExecutionContextTestFixture.java @@ -14,6 +14,7 @@ */ package org.hyperledger.besu.ethereum.core; +import static org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider.createBonsaiInMemoryWorldStateArchive; import static org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider.createInMemoryWorldStateArchive; import org.hyperledger.besu.config.GenesisConfigFile; @@ -31,10 +32,12 @@ import org.hyperledger.besu.ethereum.storage.keyvalue.VariablesKeyValueStorage; import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; +import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; import org.hyperledger.besu.plugin.services.storage.KeyValueStorage; import org.hyperledger.besu.services.kvstore.InMemoryKeyValueStorage; import java.math.BigInteger; +import java.util.Optional; import java.util.function.Function; public class ExecutionContextTestFixture { @@ -52,7 +55,8 @@ public class ExecutionContextTestFixture { final GenesisConfigFile genesisConfigFile, final ProtocolSchedule protocolSchedule, final KeyValueStorage blockchainKeyValueStorage, - final KeyValueStorage variablesKeyValueStorage) { + final KeyValueStorage variablesKeyValueStorage, + final Optional dataStorageFormat) { final GenesisState genesisState = GenesisState.fromConfig(genesisConfigFile, protocolSchedule); this.genesis = genesisState.getBlock(); this.blockchainKeyValueStorage = blockchainKeyValueStorage; @@ -67,7 +71,9 @@ public class ExecutionContextTestFixture { false), new NoOpMetricsSystem(), 0); - this.stateArchive = createInMemoryWorldStateArchive(); + if (dataStorageFormat.isPresent() && dataStorageFormat.get().equals(DataStorageFormat.BONSAI)) + this.stateArchive = createBonsaiInMemoryWorldStateArchive(blockchain); + else this.stateArchive = createInMemoryWorldStateArchive(); this.protocolSchedule = protocolSchedule; this.protocolContext = new ProtocolContext(blockchain, stateArchive, null, new BadBlockManager()); @@ -115,6 +121,7 @@ public class ExecutionContextTestFixture { private KeyValueStorage variablesKeyValueStorage; private KeyValueStorage blockchainKeyValueStorage; private ProtocolSchedule protocolSchedule; + private Optional dataStorageFormat = Optional.empty(); public Builder(final GenesisConfigFile genesisConfigFile) { this.genesisConfigFile = genesisConfigFile; @@ -135,6 +142,11 @@ public class ExecutionContextTestFixture { return this; } + public Builder dataStorageFormat(final DataStorageFormat dataStorageFormat) { + this.dataStorageFormat = Optional.of(dataStorageFormat); + return this; + } + public ExecutionContextTestFixture build() { if (protocolSchedule == null) { protocolSchedule = @@ -157,8 +169,13 @@ public class ExecutionContextTestFixture { if (variablesKeyValueStorage == null) { variablesKeyValueStorage = new InMemoryKeyValueStorage(); } + return new ExecutionContextTestFixture( - genesisConfigFile, protocolSchedule, variablesKeyValueStorage, blockchainKeyValueStorage); + genesisConfigFile, + protocolSchedule, + variablesKeyValueStorage, + blockchainKeyValueStorage, + dataStorageFormat); } } } diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/AbstractBlockProcessorIntegrationTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/AbstractBlockProcessorIntegrationTest.java new file mode 100644 index 0000000000..c9e43327d9 --- /dev/null +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/AbstractBlockProcessorIntegrationTest.java @@ -0,0 +1,794 @@ +/* + * 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.junit.jupiter.api.Assertions.assertTrue; + +import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.crypto.KeyPair; +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.Hash; +import org.hyperledger.besu.datatypes.TransactionType; +import org.hyperledger.besu.datatypes.Wei; +import org.hyperledger.besu.ethereum.BlockProcessingResult; +import org.hyperledger.besu.ethereum.chain.DefaultBlockchain; +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.ExecutionContextTestFixture; +import org.hyperledger.besu.ethereum.core.MutableWorldState; +import org.hyperledger.besu.ethereum.core.Transaction; +import org.hyperledger.besu.ethereum.mainnet.parallelization.MainnetParallelBlockProcessor; +import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.BonsaiAccount; +import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; +import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; +import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; + +import java.math.BigInteger; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.stream.Stream; + +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; +import org.apache.tuweni.units.bigints.UInt256; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.web3j.abi.FunctionEncoder; +import org.web3j.abi.datatypes.Function; +import org.web3j.abi.datatypes.Type; +import org.web3j.abi.datatypes.generated.Uint256; + +@SuppressWarnings("rawtypes") +class AbstractBlockProcessorIntegrationTest { + + private static final String ACCOUNT_GENESIS_1 = "0x627306090abab3a6e1400e9345bc60c78a8bef57"; + private static final String ACCOUNT_GENESIS_2 = "0x7f2d653f56ea8de6ffa554c7a0cd4e03af79f3eb"; + + private static final String ACCOUNT_2 = "0x0000000000000000000000000000000000000002"; + private static final String ACCOUNT_3 = "0x0000000000000000000000000000000000000003"; + private static final String ACCOUNT_4 = "0x0000000000000000000000000000000000000004"; + private static final String ACCOUNT_5 = "0x0000000000000000000000000000000000000005"; + private static final String ACCOUNT_6 = "0x0000000000000000000000000000000000000006"; + private static final String CONTRACT_ADDRESS = "0x00000000000000000000000000000000000fffff"; + + private static final KeyPair ACCOUNT_GENESIS_1_KEYPAIR = + generateKeyPair("c87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3"); + + private static final KeyPair ACCOUNT_GENESIS_2_KEYPAIR = + generateKeyPair("fc5141e75bf622179f8eedada7fab3e2e6b3e3da8eb9df4f46d84df22df7430e"); + + private WorldStateArchive worldStateArchive; + private DefaultBlockchain blockchain; + private Address coinbase; + + @BeforeEach + public void setUp() { + final ExecutionContextTestFixture contextTestFixture = + ExecutionContextTestFixture.builder( + GenesisConfigFile.fromResource( + "/org/hyperledger/besu/ethereum/mainnet/genesis-bp-it.json")) + .dataStorageFormat(DataStorageFormat.BONSAI) + .build(); + final BlockHeader blockHeader = new BlockHeaderTestFixture().number(0L).buildHeader(); + coinbase = blockHeader.getCoinbase(); + worldStateArchive = contextTestFixture.getStateArchive(); + blockchain = (DefaultBlockchain) contextTestFixture.getBlockchain(); + } + + private static Stream blockProcessorProvider() { + final ExecutionContextTestFixture contextTestFixture = + ExecutionContextTestFixture.builder( + GenesisConfigFile.fromResource( + "/org/hyperledger/besu/ethereum/mainnet/genesis-bp-it.json")) + .dataStorageFormat(DataStorageFormat.BONSAI) + .build(); + final ProtocolSchedule protocolSchedule = contextTestFixture.getProtocolSchedule(); + final BlockHeader blockHeader = new BlockHeaderTestFixture().number(0L).buildHeader(); + final MainnetTransactionProcessor transactionProcessor = + protocolSchedule.getByBlockHeader(blockHeader).getTransactionProcessor(); + + final BlockProcessor sequentialBlockProcessor = + new MainnetBlockProcessor( + transactionProcessor, + protocolSchedule + .getByBlockHeader(new BlockHeaderTestFixture().number(0L).buildHeader()) + .getTransactionReceiptFactory(), + Wei.of(2_000_000_000_000_000L), + BlockHeader::getCoinbase, + false, + protocolSchedule); + + final BlockProcessor parallelBlockProcessor = + new MainnetParallelBlockProcessor( + transactionProcessor, + protocolSchedule + .getByBlockHeader(new BlockHeaderTestFixture().number(0L).buildHeader()) + .getTransactionReceiptFactory(), + Wei.of(2_000_000_000_000_000L), + BlockHeader::getCoinbase, + false, + protocolSchedule, + new NoOpMetricsSystem()); + + return Stream.of( + Arguments.of("sequential", sequentialBlockProcessor), + Arguments.of("parallel", parallelBlockProcessor)); + } + + @ParameterizedTest(name = "{index}: {0}") + @MethodSource("blockProcessorProvider") + void testBlockProcessingWithTransfers( + final String ignoredName, final BlockProcessor blockProcessor) { + processSimpleTransfers(blockProcessor); + } + + @ParameterizedTest(name = "{index}: {0}") + @MethodSource("blockProcessorProvider") + void testProcessConflictedSimpleTransfersSameSender( + final String ignoredName, final BlockProcessor blockProcessor) { + processConflictedSimpleTransfersSameSender(blockProcessor); + } + + @ParameterizedTest(name = "{index}: {0}") + @MethodSource("blockProcessorProvider") + void testProcessConflictedSimpleTransfersSameAddressReceiverAndSender( + final String ignoredName, final BlockProcessor blockProcessor) { + processConflictedSimpleTransfersSameAddressReceiverAndSender(blockProcessor); + } + + @ParameterizedTest(name = "{index}: {0}") + @MethodSource("blockProcessorProvider") + void testProcessConflictedSimpleTransfersWithCoinbase( + final String ignoredName, final BlockProcessor blockProcessor) { + processConflictedSimpleTransfersWithCoinbase(blockProcessor); + } + + @ParameterizedTest(name = "{index}: {0}") + @MethodSource("blockProcessorProvider") + void testProcessContractSlotUpdateThenReadTx( + final String ignoredName, final BlockProcessor blockProcessor) { + processContractSlotUpdateThenReadTx(blockProcessor); + } + + @ParameterizedTest(name = "{index}: {0}") + @MethodSource("blockProcessorProvider") + void testProcessSlotReadThenUpdateTx( + final String ignoredName, final BlockProcessor blockProcessor) { + processSlotReadThenUpdateTx(blockProcessor); + } + + @ParameterizedTest(name = "{index}: {0}") + @MethodSource("blockProcessorProvider") + void testProcessAccountReadThenUpdateTx( + final String ignoredName, final BlockProcessor blockProcessor) { + processAccountReadThenUpdateTx(blockProcessor); + } + + @ParameterizedTest(name = "{index}: {0}") + @MethodSource("blockProcessorProvider") + void testProcessAccountUpdateThenReadTx( + final String ignoredName, final BlockProcessor blockProcessor) { + processAccountUpdateThenReadTx(blockProcessor); + } + + @ParameterizedTest(name = "{index}: {0}") + @MethodSource("blockProcessorProvider") + void testProcessAccountReadThenUpdateTxWithTwoAccounts( + final String ignoredName, final BlockProcessor blockProcessor) { + processAccountReadThenUpdateTxWithTwoAccounts(blockProcessor); + } + + @ParameterizedTest(name = "{index}: {0}") + @MethodSource("blockProcessorProvider") + void testProcessAccountUpdateThenReadTeTxWithTwoAccounts( + final String ignoredName, final BlockProcessor blockProcessor) { + processAccountUpdateThenReadTxWithTwoAccounts(blockProcessor); + } + + private void processSimpleTransfers(final BlockProcessor blockProcessor) { + // Create two non conflicted transactions + Transaction transactionTransfer1 = // ACCOUNT_GENESIS_1 -> ACCOUNT_2 + createTransferTransaction( + 0, 1_000_000_000_000_000_000L, 300000L, 5L, 7L, ACCOUNT_2, ACCOUNT_GENESIS_1_KEYPAIR); + Transaction transactionTransfer2 = // ACCOUNT_GENESIS_2 -> ACCOUNT_3 + createTransferTransaction( + 0, 2_000_000_000_000_000_000L, 300000L, 5L, 7L, ACCOUNT_3, ACCOUNT_GENESIS_2_KEYPAIR); + + MutableWorldState worldState = worldStateArchive.getMutable(); + BonsaiAccount senderAccount1 = (BonsaiAccount) worldState.get(transactionTransfer1.getSender()); + BonsaiAccount senderAccount2 = (BonsaiAccount) worldState.get(transactionTransfer2.getSender()); + + Block blockWithTransactions = + createBlockWithTransactions( + "0x4ca6e755674a1df696e5365361a0c352422934ba3ad0a74c9e6b0b56e4f80b4c", + transactionTransfer1, + transactionTransfer2); + + BlockProcessingResult blockProcessingResult = + blockProcessor.processBlock(blockchain, worldState, blockWithTransactions); + + BonsaiAccount updatedSenderAccount1 = + (BonsaiAccount) worldState.get(transactionTransfer1.getSender()); + BonsaiAccount updatedSenderAccount2 = + (BonsaiAccount) worldState.get(transactionTransfer2.getSender()); + + BonsaiAccount updatedAccount0x2 = + (BonsaiAccount) worldState.get(Address.fromHexStringStrict(ACCOUNT_2)); + BonsaiAccount updatedAccount0x3 = + (BonsaiAccount) worldState.get(Address.fromHexStringStrict(ACCOUNT_3)); + + assertTrue(blockProcessingResult.isSuccessful()); + assertThat(updatedAccount0x2.getBalance()).isEqualTo(Wei.of(1_000_000_000_000_000_000L)); + assertThat(updatedAccount0x3.getBalance()).isEqualTo(Wei.of(2_000_000_000_000_000_000L)); + assertThat(updatedSenderAccount1.getBalance()).isLessThan(senderAccount1.getBalance()); + assertThat(updatedSenderAccount2.getBalance()).isLessThan(senderAccount2.getBalance()); + } + + private void processConflictedSimpleTransfersSameSender(final BlockProcessor blockProcessor) { + // Create three transactions with the same sender + Transaction transferTransaction1 = // ACCOUNT_GENESIS_1 -> ACCOUNT_4 + createTransferTransaction( + 0, 1_000_000_000_000_000_000L, 300000L, 5L, 7L, ACCOUNT_4, ACCOUNT_GENESIS_1_KEYPAIR); + Transaction transferTransaction2 = // ACCOUNT_GENESIS_1 -> ACCOUNT_5 + createTransferTransaction( + 1, 2_000_000_000_000_000_000L, 300000L, 5L, 7L, ACCOUNT_5, ACCOUNT_GENESIS_1_KEYPAIR); + Transaction transferTransaction3 = // ACCOUNT_GENESIS_1 -> ACCOUNT_6 + createTransferTransaction( + 2, 3_000_000_000_000_000_000L, 300000L, 5L, 7L, ACCOUNT_6, ACCOUNT_GENESIS_1_KEYPAIR); + + MutableWorldState worldState = worldStateArchive.getMutable(); + BonsaiAccount senderAccount = (BonsaiAccount) worldState.get(transferTransaction1.getSender()); + + Block blockWithTransactions = + createBlockWithTransactions( + "0x7420935ee980cb06060f119ee3ee3dcd5a96989985938a3b3ca096558ad61484", + transferTransaction1, + transferTransaction2, + transferTransaction3); + + BlockProcessingResult blockProcessingResult = + blockProcessor.processBlock(blockchain, worldState, blockWithTransactions); + + BonsaiAccount updatedSenderAccount = + (BonsaiAccount) worldState.get(transferTransaction1.getSender()); + + BonsaiAccount updatedAccount0x4 = + (BonsaiAccount) worldState.get(Address.fromHexStringStrict(ACCOUNT_4)); + BonsaiAccount updatedAccount0x5 = + (BonsaiAccount) worldState.get(Address.fromHexStringStrict(ACCOUNT_5)); + BonsaiAccount updatedAccount0x6 = + (BonsaiAccount) worldState.get(Address.fromHexStringStrict(ACCOUNT_6)); + + assertTrue(blockProcessingResult.isSuccessful()); + assertThat(updatedAccount0x4.getBalance()).isEqualTo(Wei.of(1_000_000_000_000_000_000L)); + assertThat(updatedAccount0x5.getBalance()).isEqualTo(Wei.of(2_000_000_000_000_000_000L)); + assertThat(updatedAccount0x6.getBalance()).isEqualTo(Wei.of(3_000_000_000_000_000_000L)); + + assertThat(updatedSenderAccount.getBalance()).isLessThan(senderAccount.getBalance()); + } + + private void processConflictedSimpleTransfersSameAddressReceiverAndSender( + final BlockProcessor blockProcessor) { + // Create conflicted transfer transactions + Transaction transferTransaction1 = + createTransferTransaction( + 0, + 1_000_000_000_000_000_000L, + 300000L, + 5L, + 7L, + ACCOUNT_GENESIS_2, + ACCOUNT_GENESIS_1_KEYPAIR); // ACCOUNT_GENESIS_1 -> ACCOUNT_GENESIS_2 + Transaction transferTransaction2 = + createTransferTransaction( + 0, + 2_000_000_000_000_000_000L, + 300000L, + 5L, + 7L, + ACCOUNT_2, + ACCOUNT_GENESIS_2_KEYPAIR); // ACCOUNT_GENESIS_2 -> ACCOUNT_2 + + MutableWorldState worldState = worldStateArchive.getMutable(); + BonsaiAccount transferTransaction1Sender = + (BonsaiAccount) worldState.get(transferTransaction1.getSender()); + + Block blockWithTransactions = + createBlockWithTransactions( + "0x5c0158e79b66c86cf5e5256390b95add0c2e6891c24e72d71b9dbea5845fea72", + transferTransaction1, + transferTransaction2); + + BlockProcessingResult blockProcessingResult = + blockProcessor.processBlock(blockchain, worldState, blockWithTransactions); + + BonsaiAccount updatedSenderAccount1 = + (BonsaiAccount) worldState.get(transferTransaction1.getSender()); + BonsaiAccount updatedGenesisAccount1 = + (BonsaiAccount) worldState.get(Address.fromHexStringStrict(ACCOUNT_GENESIS_1)); + BonsaiAccount updatedGenesisAccount2 = + (BonsaiAccount) worldState.get(Address.fromHexStringStrict(ACCOUNT_GENESIS_2)); + BonsaiAccount updatedAccount0x2 = + (BonsaiAccount) worldState.get(Address.fromHexStringStrict(ACCOUNT_2)); + + assertTrue(blockProcessingResult.isSuccessful()); + assertThat(updatedGenesisAccount1.getBalance()) + .isEqualTo( + Wei.of( + UInt256.fromHexString( + ("0x00000000000000000000000000000000000000000000003627e8f7123739c1c8")))); + assertThat(updatedGenesisAccount2.getBalance()) + .isEqualTo( + Wei.of( + UInt256.fromHexString( + ("0x00000000000000000000000000000000000000000000003627e8f7123739c024")))); + assertThat(updatedAccount0x2.getBalance()).isEqualTo(Wei.of(2_000_000_000_000_000_000L)); + assertThat(updatedSenderAccount1.getBalance()) + .isLessThan(transferTransaction1Sender.getBalance()); + } + + private void processConflictedSimpleTransfersWithCoinbase(final BlockProcessor blockProcessor) { + // Create conflicted transactions using coinbase + Transaction transferTransaction1 = + createTransferTransaction( + 0, + 1_000_000_000_000_000_000L, + 300000L, + 5L, + 7L, + ACCOUNT_2, + ACCOUNT_GENESIS_1_KEYPAIR); // ACCOUNT_GENESIS_1 -> ACCOUNT_2 + Transaction transferTransaction2 = + createTransferTransaction( + 0, + 2_000_000_000_000_000_000L, + 300000L, + 5L, + 7L, + coinbase.toHexString(), + ACCOUNT_GENESIS_2_KEYPAIR); // ACCOUNT_GENESIS_2 -> COINBASE + + MutableWorldState worldState = worldStateArchive.getMutable(); + BonsaiAccount transferTransaction1Sender = + (BonsaiAccount) worldState.get(transferTransaction1.getSender()); + Block blockWithTransactions = + createBlockWithTransactions( + "0xd9544f389692face27352d23494dd1446d9af025067bc11b29e0eb83e258676a", + transferTransaction1, + transferTransaction2); + + BlockProcessingResult blockProcessingResult = + blockProcessor.processBlock(blockchain, worldState, blockWithTransactions); + + BonsaiAccount updatedSenderAccount1 = + (BonsaiAccount) worldState.get(transferTransaction1.getSender()); + + BonsaiAccount updatedAccount0x2 = + (BonsaiAccount) worldState.get(Address.fromHexStringStrict(ACCOUNT_2)); + + BonsaiAccount updatedCoinbase = (BonsaiAccount) worldState.get(coinbase); + + assertTrue(blockProcessingResult.isSuccessful()); + assertThat(updatedAccount0x2.getBalance()).isEqualTo(Wei.of(1_000_000_000_000_000_000L)); + assertThat(updatedCoinbase.getBalance()) + .isEqualTo( + Wei.of( + UInt256.fromHexString( + ("0x0000000000000000000000000000000000000000000000001bc8886498566008")))); + + assertThat(updatedSenderAccount1.getBalance()) + .isLessThan(transferTransaction1Sender.getBalance()); + } + + void processContractSlotUpdateThenReadTx(final BlockProcessor blockProcessor) { + Address contractAddress = Address.fromHexStringStrict(CONTRACT_ADDRESS); + + // create conflicted transactions on the same slot (update then read) + Transaction setSlot1Transaction = + createContractUpdateSlotTransaction( + 0, contractAddress, "setSlot1", ACCOUNT_GENESIS_1_KEYPAIR, Optional.of(100)); + Transaction getSlot1Transaction = + createContractUpdateSlotTransaction( + 0, contractAddress, "getSlot1", ACCOUNT_GENESIS_2_KEYPAIR, Optional.empty()); + Transaction setSlot3Transaction = + createContractUpdateSlotTransaction( + 1, contractAddress, "setSlot2", ACCOUNT_GENESIS_1_KEYPAIR, Optional.of(200)); + Transaction setSlot4Transaction = + createContractUpdateSlotTransaction( + 2, contractAddress, "setSlot3", ACCOUNT_GENESIS_1_KEYPAIR, Optional.of(300)); + + Block blockWithTransactions = + createBlockWithTransactions( + "0x51d59f64426ea986b1323aa22b9881c83f67947b4f90c2c302b21d3f8c459aff", + setSlot1Transaction, + getSlot1Transaction, + setSlot3Transaction, + setSlot4Transaction); + + MutableWorldState worldState = worldStateArchive.getMutable(); + BlockProcessingResult blockProcessingResult = + blockProcessor.processBlock(blockchain, worldState, blockWithTransactions); + + assertTrue(blockProcessingResult.isSuccessful()); + + // Verify the state + assertContractStorage(worldState, contractAddress, 0, 100); + assertContractStorage(worldState, contractAddress, 1, 200); + assertContractStorage(worldState, contractAddress, 2, 300); + } + + void processSlotReadThenUpdateTx(final BlockProcessor blockProcessor) { + Address contractAddress = Address.fromHexStringStrict(CONTRACT_ADDRESS); + + Transaction getSlot1Transaction = + createContractUpdateSlotTransaction( + 0, contractAddress, "getSlot1", ACCOUNT_GENESIS_1_KEYPAIR, Optional.empty()); + Transaction setSlot1Transaction = + createContractUpdateSlotTransaction( + 0, contractAddress, "setSlot1", ACCOUNT_GENESIS_2_KEYPAIR, Optional.of(1000)); + Transaction setSlo2Transaction = + createContractUpdateSlotTransaction( + 1, contractAddress, "setSlot2", ACCOUNT_GENESIS_1_KEYPAIR, Optional.of(2000)); + Transaction setSlot3Transaction = + createContractUpdateSlotTransaction( + 2, contractAddress, "setSlot3", ACCOUNT_GENESIS_1_KEYPAIR, Optional.of(3000)); + + Block blockWithTransactions = + createBlockWithTransactions( + "0xdf21d4fef211d7a905022dc87f2a68f4bf9cb273fcf9745cfa7f7c2f258c03f3", + getSlot1Transaction, + setSlot1Transaction, + setSlo2Transaction, + setSlot3Transaction); + MutableWorldState worldState = worldStateArchive.getMutable(); + + BlockProcessingResult blockProcessingResult = + blockProcessor.processBlock(blockchain, worldState, blockWithTransactions); + + assertTrue(blockProcessingResult.isSuccessful()); + + // Verify the state + assertContractStorage(worldState, contractAddress, 0, 1000); + assertContractStorage(worldState, contractAddress, 1, 2000); + assertContractStorage(worldState, contractAddress, 2, 3000); + } + + void processAccountReadThenUpdateTx(final BlockProcessor blockProcessor) { + Address contractAddress = Address.fromHexStringStrict(CONTRACT_ADDRESS); + Transaction transactionTransfer = // ACCOUNT_GENESIS_1 -> CONTRACT_ADDRESS + createTransferTransaction( + 0, + 1_000_000_000_000_000_000L, + 300000L, + 5L, + 7L, + CONTRACT_ADDRESS, + ACCOUNT_GENESIS_1_KEYPAIR); + Transaction getcontractBalanceTransaction = + createContractReadAccountTransaction( + 1, contractAddress, "getBalance", ACCOUNT_GENESIS_1_KEYPAIR, ACCOUNT_2); + + Transaction sendEthFromContractTransaction = + createContractUpdateAccountTransaction( + 0, + contractAddress, + "transferTo", + ACCOUNT_GENESIS_2_KEYPAIR, + ACCOUNT_2, + 500_000_000_000_000_000L); + + Block blockWithTransactions = + createBlockWithTransactions( + "0x91966cdde619acb05a1d9fef2f8801432a30edde7131f1f194002b0a766026c7", + transactionTransfer, + getcontractBalanceTransaction, + sendEthFromContractTransaction); + MutableWorldState worldState = worldStateArchive.getMutable(); + + BlockProcessingResult blockProcessingResult = + blockProcessor.processBlock(blockchain, worldState, blockWithTransactions); + + assertTrue(blockProcessingResult.isSuccessful()); + + // Verify the state + BonsaiAccount contractAccount = (BonsaiAccount) worldState.get(contractAddress); + BonsaiAccount updatedAccount0x2 = + (BonsaiAccount) worldState.get(Address.fromHexStringStrict(ACCOUNT_2)); + assertThat(contractAccount.getBalance()).isEqualTo(Wei.of(500_000_000_000_000_000L)); + assertThat(updatedAccount0x2.getBalance()).isEqualTo(Wei.of(500_000_000_000_000_000L)); + } + + void processAccountUpdateThenReadTx(final BlockProcessor blockProcessor) { + Address contractAddress = Address.fromHexStringStrict(CONTRACT_ADDRESS); + Transaction transactionTransfer = + createTransferTransaction( + 0, + 1_000_000_000_000_000_000L, + 300000L, + 5L, + 7L, + CONTRACT_ADDRESS, + ACCOUNT_GENESIS_1_KEYPAIR); + + Transaction sendEthFromContractTransaction = + createContractUpdateAccountTransaction( + 1, + contractAddress, + "transferTo", + ACCOUNT_GENESIS_1_KEYPAIR, + ACCOUNT_2, + 500_000_000_000_000_000L); + + Transaction getcontractBalanceTransaction = + createContractReadAccountTransaction( + 0, contractAddress, "getBalance", ACCOUNT_GENESIS_2_KEYPAIR, ACCOUNT_2); + + Block blockWithTransactions = + createBlockWithTransactions( + "0x375af730c0f9e04666659fc419fda74cc0cb29936607c08adf21d3b236c6b7f6", + transactionTransfer, + sendEthFromContractTransaction, + getcontractBalanceTransaction); + MutableWorldState worldState = worldStateArchive.getMutable(); + + BlockProcessingResult blockProcessingResult = + blockProcessor.processBlock(blockchain, worldState, blockWithTransactions); + assertTrue(blockProcessingResult.isSuccessful()); + + // Verify the state + BonsaiAccount contractAccount = (BonsaiAccount) worldState.get(contractAddress); + BonsaiAccount updatedAccount0x2 = + (BonsaiAccount) worldState.get(Address.fromHexStringStrict(ACCOUNT_2)); + + assertThat(contractAccount.getBalance()).isEqualTo(Wei.of(500_000_000_000_000_000L)); + assertThat(updatedAccount0x2.getBalance()).isEqualTo(Wei.of(500_000_000_000_000_000L)); + } + + void processAccountReadThenUpdateTxWithTwoAccounts(final BlockProcessor blockProcessor) { + Address contractAddress = Address.fromHexStringStrict(CONTRACT_ADDRESS); + Transaction transactionTransfer = // ACCOUNT_GENESIS_1 -> CONTRACT_ADDRESS + createTransferTransaction( + 0, + 1_000_000_000_000_000_000L, + 300000L, + 5L, + 7L, + CONTRACT_ADDRESS, + ACCOUNT_GENESIS_1_KEYPAIR); + Transaction getcontractBalanceTransaction = + createContractReadAccountTransaction( + 1, contractAddress, "getBalance", ACCOUNT_GENESIS_1_KEYPAIR, ACCOUNT_2); + + Transaction sendEthFromContractTransaction = + createContractUpdateAccountTransaction( + 0, + contractAddress, + "transferTo", + ACCOUNT_GENESIS_2_KEYPAIR, + ACCOUNT_3, + 500_000_000_000_000_000L); + + Block blockWithTransactions = + createBlockWithTransactions( + "0x3c2366a28dadbcef39ba04cde7bc30a5dccfce1e478a5c2602f5a28ab9498e6c", + transactionTransfer, + getcontractBalanceTransaction, + sendEthFromContractTransaction); + MutableWorldState worldState = worldStateArchive.getMutable(); + + BlockProcessingResult blockProcessingResult = + blockProcessor.processBlock(blockchain, worldState, blockWithTransactions); + + assertTrue(blockProcessingResult.isSuccessful()); + + // Verify the state + BonsaiAccount contractAccount = (BonsaiAccount) worldState.get(contractAddress); + BonsaiAccount updatedAccount0x3 = + (BonsaiAccount) worldState.get(Address.fromHexStringStrict(ACCOUNT_3)); + assertThat(contractAccount.getBalance()).isEqualTo(Wei.of(500_000_000_000_000_000L)); + assertThat(updatedAccount0x3.getBalance()).isEqualTo(Wei.of(500_000_000_000_000_000L)); + } + + void processAccountUpdateThenReadTxWithTwoAccounts(final BlockProcessor blockProcessor) { + Address contractAddress = Address.fromHexStringStrict(CONTRACT_ADDRESS); + Transaction transactionTransfer = // ACCOUNT_GENESIS_1 -> CONTRACT_ADDRESS + createTransferTransaction( + 0, + 1_000_000_000_000_000_000L, + 300000L, + 5L, + 7L, + CONTRACT_ADDRESS, + ACCOUNT_GENESIS_1_KEYPAIR); + + Transaction sendEthFromContractTransaction = + createContractUpdateAccountTransaction( + 0, + contractAddress, + "transferTo", + ACCOUNT_GENESIS_2_KEYPAIR, + ACCOUNT_3, + 500_000_000_000_000_000L); + + Transaction getcontractBalanceTransaction = + createContractReadAccountTransaction( + 1, contractAddress, "getBalance", ACCOUNT_GENESIS_1_KEYPAIR, ACCOUNT_2); + + Block blockWithTransactions = + createBlockWithTransactions( + "0x3c2366a28dadbcef39ba04cde7bc30a5dccfce1e478a5c2602f5a28ab9498e6c", + transactionTransfer, + sendEthFromContractTransaction, + getcontractBalanceTransaction); + MutableWorldState worldState = worldStateArchive.getMutable(); + + BlockProcessingResult blockProcessingResult = + blockProcessor.processBlock(blockchain, worldState, blockWithTransactions); + + assertTrue(blockProcessingResult.isSuccessful()); + + // Verify the state + BonsaiAccount contractAccount = (BonsaiAccount) worldState.get(contractAddress); + BonsaiAccount updatedAccount0x3 = + (BonsaiAccount) worldState.get(Address.fromHexStringStrict(ACCOUNT_3)); + assertThat(contractAccount.getBalance()).isEqualTo(Wei.of(500_000_000_000_000_000L)); + assertThat(updatedAccount0x3.getBalance()).isEqualTo(Wei.of(500_000_000_000_000_000L)); + } + + private static KeyPair generateKeyPair(final String privateKeyHex) { + final KeyPair keyPair = + SignatureAlgorithmFactory.getInstance() + .createKeyPair( + SECPPrivateKey.create( + Bytes32.fromHexString(privateKeyHex), SignatureAlgorithm.ALGORITHM)); + return keyPair; + } + + private Transaction createContractUpdateSlotTransaction( + final int nonce, + final Address contractAddress, + final String methodSignature, + final KeyPair keyPair, + final Optional value) { + Bytes payload = encodeFunctionCall(methodSignature, value); + return Transaction.builder() + .type(TransactionType.EIP1559) + .nonce(nonce) + .maxPriorityFeePerGas(Wei.of(5)) + .maxFeePerGas(Wei.of(7)) + .gasLimit(3000000L) + .to(contractAddress) + .value(Wei.ZERO) + .payload(payload) + .chainId(BigInteger.valueOf(42)) + .signAndBuild(keyPair); + } + + private Transaction createContractReadAccountTransaction( + final int nonce, + final Address contractAddress, + final String methodSignature, + final KeyPair keyPair, + final String address) { + Bytes payload = encodeFunctionCall(methodSignature, address); + return Transaction.builder() + .type(TransactionType.EIP1559) + .nonce(nonce) + .maxPriorityFeePerGas(Wei.of(5)) + .maxFeePerGas(Wei.of(7)) + .gasLimit(3000000L) + .to(contractAddress) + .value(Wei.ZERO) + .payload(payload) + .chainId(BigInteger.valueOf(42)) + .signAndBuild(keyPair); + } + + private Transaction createContractUpdateAccountTransaction( + final int nonce, + final Address contractAddress, + final String methodSignature, + final KeyPair keyPair, + final String address, + final long value) { + Bytes payload = encodeFunctionCall(methodSignature, address, value); + return Transaction.builder() + .type(TransactionType.EIP1559) + .nonce(nonce) + .maxPriorityFeePerGas(Wei.of(5)) + .maxFeePerGas(Wei.of(7)) + .gasLimit(3000000L) + .to(contractAddress) + .value(Wei.ZERO) + .payload(payload) + .chainId(BigInteger.valueOf(42)) + .signAndBuild(keyPair); + } + + private Bytes encodeFunctionCall(final String methodSignature, final Optional value) { + List inputParameters = + value.isPresent() ? Arrays.asList(new Uint256(value.get())) : List.of(); + Function function = new Function(methodSignature, inputParameters, List.of()); + return Bytes.fromHexString(FunctionEncoder.encode(function)); + } + + private Bytes encodeFunctionCall(final String methodSignature, final String address) { + List inputParameters = Arrays.asList(new org.web3j.abi.datatypes.Address(address)); + Function function = new Function(methodSignature, inputParameters, List.of()); + return Bytes.fromHexString(FunctionEncoder.encode(function)); + } + + private Bytes encodeFunctionCall( + final String methodSignature, final String address, final long value) { + List inputParameters = + Arrays.asList(new org.web3j.abi.datatypes.Address(address), new Uint256(value)); + Function function = new Function(methodSignature, inputParameters, List.of()); + return Bytes.fromHexString(FunctionEncoder.encode(function)); + } + + private Block createBlockWithTransactions( + final String stateRoot, final Transaction... transactions) { + BlockHeader blockHeader = + new BlockHeaderTestFixture() + .number(1L) + .stateRoot(Hash.fromHexString(stateRoot)) + .gasLimit(30_000_000L) + .baseFeePerGas(Wei.of(5)) + .buildHeader(); + BlockBody blockBody = new BlockBody(Arrays.asList(transactions), Collections.emptyList()); + return new Block(blockHeader, blockBody); + } + + private void assertContractStorage( + final MutableWorldState worldState, + final Address contractAddress, + final int slot, + final int expectedValue) { + BonsaiAccount contractAccount = (BonsaiAccount) worldState.get(contractAddress); + UInt256 actualValue = contractAccount.getStorageValue(UInt256.valueOf(slot)); + assertThat(actualValue).isEqualTo(UInt256.valueOf(expectedValue)); + } + + private Transaction createTransferTransaction( + final long nonce, + final long value, + final long gasLimit, + final long maxPriorityFeePerGas, + final long maxFeePerGas, + final String hexAddress, + final KeyPair keyPair) { + return Transaction.builder() + .type(TransactionType.EIP1559) + .nonce(nonce) + .maxPriorityFeePerGas(Wei.of(maxPriorityFeePerGas)) + .maxFeePerGas(Wei.of(maxFeePerGas)) + .gasLimit(gasLimit) + .to(Address.fromHexStringStrict(hexAddress)) + .value(Wei.of(value)) + .payload(Bytes.EMPTY) + .chainId(BigInteger.valueOf(42)) + .signAndBuild(keyPair); + } +} diff --git a/ethereum/core/src/test/resources/org/hyperledger/besu/ethereum/mainnet/contractUsedInBlockProcessingIT.sol b/ethereum/core/src/test/resources/org/hyperledger/besu/ethereum/mainnet/contractUsedInBlockProcessingIT.sol new file mode 100644 index 0000000000..496ae67202 --- /dev/null +++ b/ethereum/core/src/test/resources/org/hyperledger/besu/ethereum/mainnet/contractUsedInBlockProcessingIT.sol @@ -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 + */ +pragma solidity ^0.8.19; + +contract SimpleStorage { + uint256 private slot1; //0x0 + uint256 private slot2; //0x1 + uint256 private slot3; //0x2 + + function setSlot1(uint256 value) public { + slot1 = value; + } + + function setSlot2(uint256 value) public { + slot2 = value; + } + + function setSlot3(uint256 value) public { + slot3 = value; + } + + function getSlot1() public view returns (uint256) { + return slot1; + } + + function getSlot2() public view returns (uint256) { + return slot2; + } + + function getSlot3() public view returns (uint256) { + return slot3; + } + + function getBalance(address account) public view returns (uint256) { + return account.balance; + } + + function transferTo(address payable recipient, uint256 amount) public payable { + require(amount <= address(this).balance, "Insufficient balance in contract"); + recipient.transfer(amount); + } + + receive() external payable {} +} diff --git a/ethereum/core/src/test/resources/org/hyperledger/besu/ethereum/mainnet/genesis-bp-it.json b/ethereum/core/src/test/resources/org/hyperledger/besu/ethereum/mainnet/genesis-bp-it.json new file mode 100644 index 0000000000..72fbc561ec --- /dev/null +++ b/ethereum/core/src/test/resources/org/hyperledger/besu/ethereum/mainnet/genesis-bp-it.json @@ -0,0 +1,48 @@ +{ + "config": { + "chainId":42, + "homesteadBlock":0, + "eip150Block":0, + "eip155Block":0, + "eip158Block":0, + "byzantiumBlock":0, + "constantinopleBlock":0, + "petersburgBlock":0, + "istanbulBlock":0, + "muirGlacierBlock":0, + "berlinBlock":0, + "londonBlock":0, + "shanghaiTime": 0, + "terminalTotalDifficulty":0, + "cancunTime":0 + }, + "coinbase": "0x0000000000000000000000000000000000000000", + "difficulty": "0x0000001", + "extraData": "", + "gasLimit": "0x1C9C380", + "nonce": "0x0000000000000107", + "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "timestamp": "0x00", + "alloc": { + "627306090abab3a6e1400e9345bc60c78a8bef57": { + "balance": "0x3635C9ADC5DEA00000", + "privateKey": "c87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3", + "comment": "private key and this comment are ignored. In a real chain, the private key should NOT be stored" + }, + "7f2d653f56ea8de6ffa554c7a0cd4e03af79f3eb": { + "balance": "0x3635C9ADC5DEA00000", + "privateKey": "fc5141e75bf622179f8eedada7fab3e2e6b3e3da8eb9df4f46d84df22df7430e", + "comment": "private key and this comment are ignored. In a real chain, the private key should NOT be stored" + },"0x00000000000000000000000000000000000fffff": { + "balance": "0", + "code": "60806040526004361061007e575f3560e01c8063713ba21b1161004d578063713ba21b14610121578063bad4ba0b14610149578063cda7be6114610171578063f8b2cb4f1461019b57610085565b8063250976e7146100895780632ccb1b30146100b35780635e8ad6c7146100cf5780636c190cd1146100f757610085565b3661008557005b5f80fd5b348015610094575f80fd5b5061009d6101d7565b6040516100aa91906102d1565b60405180910390f35b6100cd60048036038101906100c89190610372565b6101e0565b005b3480156100da575f80fd5b506100f560048036038101906100f091906103b0565b61026b565b005b348015610102575f80fd5b5061010b610274565b60405161011891906102d1565b60405180910390f35b34801561012c575f80fd5b50610147600480360381019061014291906103b0565b61027d565b005b348015610154575f80fd5b5061016f600480360381019061016a91906103b0565b610287565b005b34801561017c575f80fd5b50610185610291565b60405161019291906102d1565b60405180910390f35b3480156101a6575f80fd5b506101c160048036038101906101bc9190610416565b610299565b6040516101ce91906102d1565b60405180910390f35b5f600254905090565b47811115610223576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161021a9061049b565b60405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff166108fc8290811502906040515f60405180830381858888f19350505050158015610266573d5f803e3d5ffd5b505050565b805f8190555050565b5f600154905090565b8060018190555050565b8060028190555050565b5f8054905090565b5f8173ffffffffffffffffffffffffffffffffffffffff16319050919050565b5f819050919050565b6102cb816102b9565b82525050565b5f6020820190506102e45f8301846102c2565b92915050565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610317826102ee565b9050919050565b6103278161030d565b8114610331575f80fd5b50565b5f813590506103428161031e565b92915050565b610351816102b9565b811461035b575f80fd5b50565b5f8135905061036c81610348565b92915050565b5f8060408385031215610388576103876102ea565b5b5f61039585828601610334565b92505060206103a68582860161035e565b9150509250929050565b5f602082840312156103c5576103c46102ea565b5b5f6103d28482850161035e565b91505092915050565b5f6103e5826102ee565b9050919050565b6103f5816103db565b81146103ff575f80fd5b50565b5f81359050610410816103ec565b92915050565b5f6020828403121561042b5761042a6102ea565b5b5f61043884828501610402565b91505092915050565b5f82825260208201905092915050565b7f496e73756666696369656e742062616c616e636520696e20636f6e74726163745f82015250565b5f610485602083610441565b915061049082610451565b602082019050919050565b5f6020820190508181035f8301526104b281610479565b905091905056fea264697066735822122023baf1931f9dfdc95c00818838ff0de5f17ac26981187c1407ae4f1d111ff57464736f6c634300081a0033", + "comment": "This bytecode corresponds to the smart contract contractUsedInBlockProcessingIT.sol, visible in the resource files", + "storage": { + "0x0": "0x2a", + "0x1": "0x54", + "0x2": "0x7e" + } + } + } +} \ No newline at end of file From 14d280986066f7690c347c812ac90f9becc8a4ed Mon Sep 17 00:00:00 2001 From: Guido Vranken Date: Thu, 1 Aug 2024 19:36:45 +0200 Subject: [PATCH 085/259] Small fuzzing fixes (#7418) * Addresses an issue in the Fluent API where certain EVM bytecode could lead to executions that mismatch canonical execution. * Uses LOG.debug instead of System.out.println to prevent console spam during fuzzing. Signed-off-by: Guido Vranken --- .../main/java/org/hyperledger/besu/evm/fluent/EVMExecutor.java | 1 + .../besu/evm/precompile/KZGPointEvalPrecompiledContract.java | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) 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 08b7a067a1..ee80bc2d77 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 @@ -755,6 +755,7 @@ public class EVMExecutor { }) .process(messageFrame, tracer); } + initialMessageFrame.getSelfDestructs().forEach(worldUpdater::deleteAccount); if (commitWorldState) { worldUpdater.commit(); } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/precompile/KZGPointEvalPrecompiledContract.java b/evm/src/main/java/org/hyperledger/besu/evm/precompile/KZGPointEvalPrecompiledContract.java index 2428da2dc2..b6baf9dd01 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/precompile/KZGPointEvalPrecompiledContract.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/precompile/KZGPointEvalPrecompiledContract.java @@ -140,7 +140,7 @@ public class KZGPointEvalPrecompiledContract implements PrecompiledContract { null, Optional.of(ExceptionalHaltReason.PRECOMPILE_ERROR)); } } catch (RuntimeException kzgFailed) { - System.out.println(kzgFailed.getMessage()); + LOG.debug("Native KZG failed", kzgFailed); return PrecompileContractResult.halt( null, Optional.of(ExceptionalHaltReason.PRECOMPILE_ERROR)); From e3bc2489908031762fb4dddf1047ffe917bfffc4 Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Fri, 2 Aug 2024 13:05:33 +1000 Subject: [PATCH 086/259] 5098 branch 4 update invalid address params (#7405) * 5098: Add RpcErrorTypes Signed-off-by: Matilda Clerke * 5098: Modify InvalidJsonRpcParameters and InvalidJsonRpcRequestException, apply spotless Signed-off-by: Matilda Clerke * 5098: Modify InvalidJsonRpcParameters and InvalidJsonRpcRequestException, apply spotless Signed-off-by: Matilda Clerke * 5098: Add JsonRpcParameterException for later use Signed-off-by: Matilda Clerke * 5098: Update locations for RpcErrorType.INVALID_ACCOUNTS_PARAMS Signed-off-by: Matilda Clerke * 5098: Address review comments, apply spotless Signed-off-by: Matilda Clerke * 5098: Update with changes from branch 1 Signed-off-by: Matilda Clerke * 5098: Update code to use RpcErrorType.INVALID_ADDRESS_HASH_PARAMS Signed-off-by: Matilda Clerke * 5098: apply spotless Signed-off-by: Matilda Clerke * 5098: apply spotless Signed-off-by: Matilda Clerke * 5098: Update plugin-api gradle hash Signed-off-by: Matilda Clerke * 5098: Add comment on INVALID_PARAMS_ERROR_CODE Signed-off-by: Matilda Clerke * 5098: Apply spotless on latest changes Signed-off-by: Matilda Clerke * 5098: Update code to use RpcErrorType.INVALID_ADDRESS_PARAMS Signed-off-by: Matilda Clerke * 5098: Fix broken unit test Signed-off-by: Matilda Clerke * 5098: Fix broken unit test Signed-off-by: Matilda Clerke * 5098: Add index to exception messages Signed-off-by: Matilda Clerke * 5098: apoply spotless Signed-off-by: Matilda Clerke * 5098: Update BaseJsonRpcProcessor to utilise RpcErrorType from InvalidJsonRpcParameters Signed-off-by: Matilda Clerke --------- Signed-off-by: Matilda Clerke Co-authored-by: Sally MacFarlane --- .../clique/jsonrpc/methods/Discard.java | 10 +++++++++- .../clique/jsonrpc/methods/Propose.java | 9 ++++++++- .../clique/jsonrpc/methods/DiscardTest.java | 2 +- .../methods/IbftDiscardValidatorVote.java | 10 +++++++++- .../methods/IbftProposeValidatorVote.java | 10 +++++++++- .../methods/IbftDiscardValidatorVoteTest.java | 4 ++-- .../methods/IbftProposeValidatorVoteTest.java | 4 ++-- .../methods/QbftDiscardValidatorVote.java | 11 ++++++++++- .../methods/QbftProposeValidatorVote.java | 11 ++++++++++- .../methods/QbftDiscardValidatorVoteTest.java | 4 ++-- .../methods/QbftProposeValidatorVoteTest.java | 4 ++-- .../execution/BaseJsonRpcProcessor.java | 8 ++++++-- .../internal/methods/DebugAccountAt.java | 9 ++++++++- .../internal/methods/DebugStorageRangeAt.java | 10 +++++++++- .../internal/methods/EthGetBalance.java | 10 +++++++++- .../jsonrpc/internal/methods/EthGetCode.java | 10 +++++++++- .../jsonrpc/internal/methods/EthGetProof.java | 9 ++++++++- .../internal/methods/EthGetStorageAt.java | 10 +++++++++- .../methods/EthGetTransactionCount.java | 18 ++++++++++++++++-- .../methods/miner/MinerSetCoinbase.java | 4 ++++ .../methods/priv/PrivFindPrivacyGroup.java | 10 +++++++++- .../privacy/methods/priv/PrivGetCode.java | 10 +++++++++- .../priv/PrivGetEeaTransactionCount.java | 9 ++++++++- .../methods/priv/PrivGetTransactionCount.java | 9 ++++++++- .../privx/PrivxFindFlexiblePrivacyGroup.java | 10 +++++++++- .../internal/methods/EthGetProofTest.java | 2 +- .../methods/miner/MinerSetCoinbaseTest.java | 2 +- 27 files changed, 187 insertions(+), 32 deletions(-) diff --git a/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/Discard.java b/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/Discard.java index 4fb3af6cd4..467164e8c0 100644 --- a/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/Discard.java +++ b/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/Discard.java @@ -20,9 +20,11 @@ import org.hyperledger.besu.consensus.common.validator.ValidatorProvider; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; 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.api.jsonrpc.internal.response.RpcErrorType; /** The Discard Json RPC method. */ public class Discard implements JsonRpcMethod { @@ -46,7 +48,13 @@ public class Discard implements JsonRpcMethod { public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { checkState( validatorProvider.getVoteProviderAtHead().isPresent(), "Clique requires a vote provider"); - final Address address = requestContext.getRequiredParameter(0, Address.class); + final Address address; + try { + address = requestContext.getRequiredParameter(0, Address.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid address parameter (index 0)", RpcErrorType.INVALID_ADDRESS_PARAMS, e); + } validatorProvider.getVoteProviderAtHead().get().discardVote(address); return new JsonRpcSuccessResponse(requestContext.getRequest().getId(), true); } diff --git a/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/Propose.java b/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/Propose.java index 0e278dee95..f2b81d56e3 100644 --- a/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/Propose.java +++ b/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/Propose.java @@ -21,6 +21,7 @@ import org.hyperledger.besu.consensus.common.validator.ValidatorProvider; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; @@ -49,7 +50,13 @@ public class Propose implements JsonRpcMethod { public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { checkState( validatorProvider.getVoteProviderAtHead().isPresent(), "Clique requires a vote provider"); - final Address address = requestContext.getRequiredParameter(0, Address.class); + final Address address; + try { + address = requestContext.getRequiredParameter(0, Address.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid address parameter (index 0)", RpcErrorType.INVALID_ADDRESS_PARAMS, e); + } final Boolean auth = requestContext.getRequiredParameter(1, Boolean.class); if (address.equals(CliqueBlockInterface.NO_VOTE_SUBJECT)) { return new JsonRpcErrorResponse( diff --git a/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/DiscardTest.java b/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/DiscardTest.java index 038f97e1e7..80220a3f04 100644 --- a/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/DiscardTest.java +++ b/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/DiscardTest.java @@ -121,7 +121,7 @@ public class DiscardTest { final Discard discard = new Discard(validatorProvider); assertThatThrownBy(() -> discard.response(requestWithParams())) - .hasMessage("Missing required json rpc parameter at index 0") + .hasMessage("Invalid address parameter (index 0)") .isInstanceOf(InvalidJsonRpcParameters.class); } diff --git a/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftDiscardValidatorVote.java b/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftDiscardValidatorVote.java index 2fdc60c129..7e6c001088 100644 --- a/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftDiscardValidatorVote.java +++ b/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftDiscardValidatorVote.java @@ -20,9 +20,11 @@ import org.hyperledger.besu.consensus.common.validator.ValidatorProvider; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; 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.api.jsonrpc.internal.response.RpcErrorType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -50,7 +52,13 @@ public class IbftDiscardValidatorVote implements JsonRpcMethod { public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { checkState( validatorProvider.getVoteProviderAtHead().isPresent(), "Ibft requires a vote provider"); - final Address validatorAddress = requestContext.getRequiredParameter(0, Address.class); + final Address validatorAddress; + try { + validatorAddress = requestContext.getRequiredParameter(0, Address.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid validator address parameter (index 0)", RpcErrorType.INVALID_ADDRESS_PARAMS, e); + } LOG.trace("Received RPC rpcName={} address={}", getName(), validatorAddress); validatorProvider.getVoteProviderAtHead().get().discardVote(validatorAddress); diff --git a/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftProposeValidatorVote.java b/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftProposeValidatorVote.java index fe89961410..a29187b513 100644 --- a/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftProposeValidatorVote.java +++ b/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftProposeValidatorVote.java @@ -21,9 +21,11 @@ import org.hyperledger.besu.consensus.common.validator.VoteType; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; 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.api.jsonrpc.internal.response.RpcErrorType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -51,7 +53,13 @@ public class IbftProposeValidatorVote implements JsonRpcMethod { public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { checkState( validatorProvider.getVoteProviderAtHead().isPresent(), "Ibft requires a vote provider"); - final Address validatorAddress = requestContext.getRequiredParameter(0, Address.class); + final Address validatorAddress; + try { + validatorAddress = requestContext.getRequiredParameter(0, Address.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid address parameter (index 0)", RpcErrorType.INVALID_ADDRESS_PARAMS, e); + } final Boolean add = requestContext.getRequiredParameter(1, Boolean.class); LOG.trace( "Received RPC rpcName={} voteType={} address={}", diff --git a/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftDiscardValidatorVoteTest.java b/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftDiscardValidatorVoteTest.java index da0a35ab2f..7a25ab67b8 100644 --- a/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftDiscardValidatorVoteTest.java +++ b/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftDiscardValidatorVoteTest.java @@ -56,14 +56,14 @@ public class IbftDiscardValidatorVoteTest { public void exceptionWhenNoParamsSupplied() { assertThatThrownBy(() -> method.response(requestWithParams())) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage("Missing required json rpc parameter at index 0"); + .hasMessage("Invalid validator address parameter (index 0)"); } @Test public void exceptionWhenInvalidAddressParameterSupplied() { assertThatThrownBy(() -> method.response(requestWithParams("InvalidAddress"))) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Invalid json rpc parameter at index 0"); + .hasMessageContaining("Invalid validator address parameter (index 0)"); } @Test diff --git a/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftProposeValidatorVoteTest.java b/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftProposeValidatorVoteTest.java index d667bb173b..d0df723d54 100644 --- a/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftProposeValidatorVoteTest.java +++ b/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftProposeValidatorVoteTest.java @@ -56,7 +56,7 @@ public class IbftProposeValidatorVoteTest { public void exceptionWhenNoParamsSupplied() { assertThatThrownBy(() -> method.response(requestWithParams())) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage("Missing required json rpc parameter at index 0"); + .hasMessage("Invalid address parameter (index 0)"); } @Test @@ -70,7 +70,7 @@ public class IbftProposeValidatorVoteTest { public void exceptionWhenNoAddressSupplied() { assertThatThrownBy(() -> method.response(requestWithParams("true"))) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Invalid json rpc parameter at index 0"); + .hasMessageContaining("Invalid address parameter (index 0)"); } @Test diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftDiscardValidatorVote.java b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftDiscardValidatorVote.java index 7e9a3b973f..98856caaa6 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftDiscardValidatorVote.java +++ b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftDiscardValidatorVote.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.consensus.common.validator.ValidatorProvider; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; @@ -49,7 +50,15 @@ public class QbftDiscardValidatorVote implements JsonRpcMethod { @Override public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { if (validatorProvider.getVoteProviderAtHead().isPresent()) { - final Address validatorAddress = requestContext.getRequiredParameter(0, Address.class); + final Address validatorAddress; + try { + validatorAddress = requestContext.getRequiredParameter(0, Address.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid validator address parameter (index 0)", + RpcErrorType.INVALID_ADDRESS_PARAMS, + e); + } LOG.trace("Received RPC rpcName={} address={}", getName(), validatorAddress); validatorProvider.getVoteProviderAtHead().get().discardVote(validatorAddress); diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftProposeValidatorVote.java b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftProposeValidatorVote.java index 160ca144d6..9eefbb8d13 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftProposeValidatorVote.java +++ b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftProposeValidatorVote.java @@ -19,6 +19,7 @@ import org.hyperledger.besu.consensus.common.validator.VoteType; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; @@ -50,7 +51,15 @@ public class QbftProposeValidatorVote implements JsonRpcMethod { @Override public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { if (validatorProvider.getVoteProviderAtHead().isPresent()) { - final Address validatorAddress = requestContext.getRequiredParameter(0, Address.class); + final Address validatorAddress; + try { + validatorAddress = requestContext.getRequiredParameter(0, Address.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid validator address parameter (index 0)", + RpcErrorType.INVALID_ADDRESS_PARAMS, + e); + } final Boolean add = requestContext.getRequiredParameter(1, Boolean.class); LOG.trace( "Received RPC rpcName={} voteType={} address={}", diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftDiscardValidatorVoteTest.java b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftDiscardValidatorVoteTest.java index 0716fd42d2..c8ce419569 100644 --- a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftDiscardValidatorVoteTest.java +++ b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftDiscardValidatorVoteTest.java @@ -58,14 +58,14 @@ public class QbftDiscardValidatorVoteTest { public void exceptionWhenNoParamsSupplied() { assertThatThrownBy(() -> method.response(requestWithParams())) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage("Missing required json rpc parameter at index 0"); + .hasMessage("Invalid validator address parameter (index 0)"); } @Test public void exceptionWhenInvalidAddressParameterSupplied() { assertThatThrownBy(() -> method.response(requestWithParams("InvalidAddress"))) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Invalid json rpc parameter at index 0"); + .hasMessageContaining("Invalid validator address parameter (index 0)"); } @Test diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftProposeValidatorVoteTest.java b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftProposeValidatorVoteTest.java index fa3f89036e..62f7dc6169 100644 --- a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftProposeValidatorVoteTest.java +++ b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftProposeValidatorVoteTest.java @@ -58,7 +58,7 @@ public class QbftProposeValidatorVoteTest { public void exceptionWhenNoParamsSupplied() { assertThatThrownBy(() -> method.response(requestWithParams())) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage("Missing required json rpc parameter at index 0"); + .hasMessage("Invalid validator address parameter (index 0)"); } @Test @@ -72,7 +72,7 @@ public class QbftProposeValidatorVoteTest { public void exceptionWhenNoAddressSupplied() { assertThatThrownBy(() -> method.response(requestWithParams("true"))) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Invalid json rpc parameter at index 0"); + .hasMessageContaining("Invalid validator address parameter"); } @Test diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/execution/BaseJsonRpcProcessor.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/execution/BaseJsonRpcProcessor.java index 3d82388648..db6481b46a 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/execution/BaseJsonRpcProcessor.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/execution/BaseJsonRpcProcessor.java @@ -43,8 +43,12 @@ public class BaseJsonRpcProcessor implements JsonRpcProcessor { try { return method.response(request); } catch (final InvalidJsonRpcParameters e) { - LOG.debug("Invalid Params for method: {}", method.getName(), e); - return new JsonRpcErrorResponse(id, RpcErrorType.INVALID_PARAMS); + LOG.debug( + "Invalid Params for method: {}, error: {}", + method.getName(), + e.getRpcErrorType().getMessage(), + e); + return new JsonRpcErrorResponse(id, e.getRpcErrorType()); } catch (final MultiTenancyValidationException e) { return new JsonRpcUnauthorizedResponse(id, RpcErrorType.UNAUTHORIZED); } catch (final RuntimeException e) { diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugAccountAt.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugAccountAt.java index f4a56f05eb..8fafd5ec3d 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugAccountAt.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugAccountAt.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameterOrBlockHash; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.BlockTrace; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.BlockTracer; @@ -73,7 +74,13 @@ public class DebugAccountAt extends AbstractBlockParameterOrBlockHashMethod { protected Object resultByBlockHash( final JsonRpcRequestContext requestContext, final Hash blockHash) { final Integer txIndex = requestContext.getRequiredParameter(1, Integer.class); - final Address address = requestContext.getRequiredParameter(2, Address.class); + final Address address; + try { + address = requestContext.getRequiredParameter(2, Address.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid address parameter (index 2)", RpcErrorType.INVALID_ADDRESS_PARAMS, e); + } Optional> block = blockchainQueries.get().blockByHash(blockHash); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStorageRangeAt.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStorageRangeAt.java index 0ea50b41ac..72110852b7 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStorageRangeAt.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStorageRangeAt.java @@ -18,12 +18,14 @@ import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameterOrBlockHash; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.BlockReplay; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.Tracer; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.Tracer.TraceableState; 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.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.DebugStorageRangeAtResult; import org.hyperledger.besu.ethereum.api.query.BlockWithMetadata; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; @@ -70,7 +72,13 @@ public class DebugStorageRangeAt implements JsonRpcMethod { final BlockParameterOrBlockHash blockParameterOrBlockHash = requestContext.getRequiredParameter(0, BlockParameterOrBlockHash.class); final int transactionIndex = requestContext.getRequiredParameter(1, Integer.class); - final Address accountAddress = requestContext.getRequiredParameter(2, Address.class); + final Address accountAddress; + try { + accountAddress = requestContext.getRequiredParameter(2, Address.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid account address parameter (index 2)", RpcErrorType.INVALID_ADDRESS_PARAMS, e); + } final Hash startKey = Hash.fromHexStringLenient(requestContext.getRequiredParameter(3, String.class)); final int limit = requestContext.getRequiredParameter(4, Integer.class); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBalance.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBalance.java index 8b658d2753..449de64261 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBalance.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBalance.java @@ -18,7 +18,9 @@ import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameterOrBlockHash; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.Quantity; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; @@ -46,7 +48,13 @@ public class EthGetBalance extends AbstractBlockParameterOrBlockHashMethod { @Override protected String resultByBlockHash(final JsonRpcRequestContext request, final Hash blockHash) { - final Address address = request.getRequiredParameter(0, Address.class); + final Address address; + try { + address = request.getRequiredParameter(0, Address.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid address parameter (index 0)", RpcErrorType.INVALID_ADDRESS_PARAMS, e); + } return blockchainQueries .get() .accountBalance(address, blockHash) diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetCode.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetCode.java index 2417b422fa..9002b6d89c 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetCode.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetCode.java @@ -18,7 +18,9 @@ import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameterOrBlockHash; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; import java.util.function.Supplier; @@ -48,7 +50,13 @@ public class EthGetCode extends AbstractBlockParameterOrBlockHashMethod { @Override protected String resultByBlockHash(final JsonRpcRequestContext request, final Hash blockHash) { - final Address address = request.getRequiredParameter(0, Address.class); + final Address address; + try { + address = request.getRequiredParameter(0, Address.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid address parameter (index 0)", RpcErrorType.INVALID_ADDRESS_PARAMS, e); + } return getBlockchainQueries().getCode(address, blockHash).map(Bytes::toString).orElse(null); } } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetProof.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetProof.java index 96602e23a9..67a0792408 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetProof.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetProof.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameterOrBlockHash; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; @@ -55,7 +56,13 @@ public class EthGetProof extends AbstractBlockParameterOrBlockHashMethod { protected Object resultByBlockHash( final JsonRpcRequestContext requestContext, final Hash blockHash) { - final Address address = requestContext.getRequiredParameter(0, Address.class); + final Address address; + try { + address = requestContext.getRequiredParameter(0, Address.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid address parameter (index 0)", RpcErrorType.INVALID_ADDRESS_PARAMS, e); + } final List storageKeys = getStorageKeys(requestContext); final Blockchain blockchain = getBlockchainQueries().getBlockchain(); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetStorageAt.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetStorageAt.java index e2741233f6..efec2ee1d6 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetStorageAt.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetStorageAt.java @@ -18,8 +18,10 @@ import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameterOrBlockHash; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.UInt256Parameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; import org.apache.tuweni.units.bigints.UInt256; @@ -42,7 +44,13 @@ public class EthGetStorageAt extends AbstractBlockParameterOrBlockHashMethod { @Override protected String resultByBlockHash(final JsonRpcRequestContext request, final Hash blockHash) { - final Address address = request.getRequiredParameter(0, Address.class); + final Address address; + try { + address = request.getRequiredParameter(0, Address.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid address parameter (index 0)", RpcErrorType.INVALID_ADDRESS_PARAMS, e); + } final UInt256 position = request.getRequiredParameter(1, UInt256Parameter.class).getValue(); return blockchainQueries .get() diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionCount.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionCount.java index 053588e89a..a03d90ea29 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionCount.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionCount.java @@ -18,7 +18,9 @@ import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameterOrBlockHash; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.Quantity; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool; @@ -55,7 +57,13 @@ public class EthGetTransactionCount extends AbstractBlockParameterOrBlockHashMet @Override protected Object pendingResult(final JsonRpcRequestContext request) { - final Address address = request.getRequiredParameter(0, Address.class); + final Address address; + try { + address = request.getRequiredParameter(0, Address.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid address parameter (index 0)", RpcErrorType.INVALID_ADDRESS_PARAMS, e); + } final long pendingNonce = transactionPoolSupplier.get().getNextNonceForSender(address).orElse(0); final long latestNonce = @@ -72,7 +80,13 @@ public class EthGetTransactionCount extends AbstractBlockParameterOrBlockHashMet @Override protected String resultByBlockHash(final JsonRpcRequestContext request, final Hash blockHash) { - final Address address = request.getRequiredParameter(0, Address.class); + final Address address; + try { + address = request.getRequiredParameter(0, Address.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid address parameter (index 0)", RpcErrorType.INVALID_ADDRESS_PARAMS, e); + } final long transactionCount = getBlockchainQueries().getTransactionCount(address, blockHash); return Quantity.create(transactionCount); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetCoinbase.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetCoinbase.java index eda085d77c..d6676a6074 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetCoinbase.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetCoinbase.java @@ -17,6 +17,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.miner; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; @@ -46,6 +47,9 @@ public class MinerSetCoinbase implements JsonRpcMethod { } catch (final UnsupportedOperationException ex) { return new JsonRpcErrorResponse( requestContext.getRequest().getId(), RpcErrorType.INVALID_REQUEST); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid address parameter (index 0)", RpcErrorType.INVALID_ADDRESS_PARAMS, e); } } } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivFindPrivacyGroup.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivFindPrivacyGroup.java index c09e21dc2a..8f0e829084 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivFindPrivacyGroup.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivFindPrivacyGroup.java @@ -19,11 +19,13 @@ import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErr import org.hyperledger.besu.enclave.types.PrivacyGroup; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.PrivacyIdProvider; 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.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.privacy.MultiTenancyValidationException; import org.hyperledger.besu.ethereum.privacy.PrivacyController; @@ -55,7 +57,13 @@ public class PrivFindPrivacyGroup implements JsonRpcMethod { public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { LOG.trace("Executing {}", RpcMethod.PRIV_FIND_PRIVACY_GROUP.getMethodName()); - final String[] addresses = requestContext.getRequiredParameter(0, String[].class); + final String[] addresses; + try { + addresses = requestContext.getRequiredParameter(0, String[].class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid address parameters (index 0)", RpcErrorType.INVALID_ADDRESS_PARAMS, e); + } LOG.trace("Finding a privacy group with members {}", Arrays.toString(addresses)); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetCode.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetCode.java index b7cafd8cab..56318da37e 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetCode.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetCode.java @@ -17,9 +17,11 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.AbstractBlockParameterMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.PrivacyIdProvider; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; import org.hyperledger.besu.ethereum.privacy.PrivacyController; @@ -53,7 +55,13 @@ public class PrivGetCode extends AbstractBlockParameterMethod { protected String resultByBlockNumber( final JsonRpcRequestContext request, final long blockNumber) { final String privacyGroupId = request.getRequiredParameter(0, String.class); - final Address address = request.getRequiredParameter(1, Address.class); + final Address address; + try { + address = request.getRequiredParameter(1, Address.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid address parameter (index 1)", RpcErrorType.INVALID_ADDRESS_PARAMS, e); + } final String privacyUserId = privacyIdProvider.getPrivacyUserId(request.getUser()); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetEeaTransactionCount.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetEeaTransactionCount.java index 3ec2d87b6a..cd107b2e71 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetEeaTransactionCount.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetEeaTransactionCount.java @@ -20,6 +20,7 @@ import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErr import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.PrivacyIdProvider; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; @@ -65,7 +66,13 @@ public class PrivGetEeaTransactionCount implements JsonRpcMethod { requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAMS); } - final Address address = requestContext.getRequiredParameter(0, Address.class); + final Address address; + try { + address = requestContext.getRequiredParameter(0, Address.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid address parameter (index 0)", RpcErrorType.INVALID_ADDRESS_PARAMS, e); + } final String privateFrom = requestContext.getRequiredParameter(1, String.class); final String[] privateFor = requestContext.getRequiredParameter(2, String[].class); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetTransactionCount.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetTransactionCount.java index 31cac2b8b3..c796d35d5f 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetTransactionCount.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetTransactionCount.java @@ -19,6 +19,7 @@ import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErr import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.PrivacyIdProvider; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; @@ -56,7 +57,13 @@ public class PrivGetTransactionCount implements JsonRpcMethod { requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAMS); } - final Address address = requestContext.getRequiredParameter(0, Address.class); + final Address address; + try { + address = requestContext.getRequiredParameter(0, Address.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid address parameter (index 0)", RpcErrorType.INVALID_ADDRESS_PARAMS, e); + } final String privacyGroupId = requestContext.getRequiredParameter(1, String.class); try { diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/privx/PrivxFindFlexiblePrivacyGroup.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/privx/PrivxFindFlexiblePrivacyGroup.java index 0275626add..e6cf056989 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/privx/PrivxFindFlexiblePrivacyGroup.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/privx/PrivxFindFlexiblePrivacyGroup.java @@ -19,11 +19,13 @@ import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErr import org.hyperledger.besu.enclave.types.PrivacyGroup; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.PrivacyIdProvider; 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.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.privacy.MultiTenancyValidationException; import org.hyperledger.besu.ethereum.privacy.PrivacyController; @@ -54,7 +56,13 @@ public class PrivxFindFlexiblePrivacyGroup implements JsonRpcMethod { public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { LOG.trace("Executing {}", RpcMethod.PRIVX_FIND_PRIVACY_GROUP.getMethodName()); - final String[] addresses = requestContext.getRequiredParameter(0, String[].class); + final String[] addresses; + try { + addresses = requestContext.getRequiredParameter(0, String[].class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid address parameters (index 0)", RpcErrorType.INVALID_ADDRESS_PARAMS, e); + } LOG.trace("Finding a privacy group with members {}", Arrays.toString(addresses)); diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetProofTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetProofTest.java index 2106b86744..344ee39d80 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetProofTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetProofTest.java @@ -111,7 +111,7 @@ class EthGetProofTest { Assertions.assertThatThrownBy(() -> method.response(request)) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Missing required json rpc parameter at index 0"); + .hasMessageContaining("Invalid address parameter (index 0)"); } @Test diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetCoinbaseTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetCoinbaseTest.java index a50a9576b0..20abf9e9c1 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetCoinbaseTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetCoinbaseTest.java @@ -62,7 +62,7 @@ public class MinerSetCoinbaseTest { assertThat(thrown) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage("Missing required json rpc parameter at index 0"); + .hasMessage("Invalid address parameter (index 0)"); } @Test From a6a0271ae24bd824a30bafd0629e3fcb6f3602b7 Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Thu, 1 Aug 2024 22:32:32 -0600 Subject: [PATCH 087/259] EOF validation updates (#7419) * Ensure forward calls stack height range is preserved. * add subcontainer and top container size checks Signed-off-by: Danno Ferrin --- .../besu/evmtool/PrettyPrintSubCommand.java | 5 +++++ .../besu/evmtool/pretty-print/dangling-data.json | 8 ++++++++ .../hyperledger/besu/evm/code/CodeV1Validation.java | 2 ++ .../org/hyperledger/besu/evm/code/EOFLayout.java | 7 +++++-- .../org/hyperledger/besu/evm/code/CodeV1Test.java | 9 +++++++-- .../org/hyperledger/besu/evm/code/EOFLayoutTest.java | 12 ++++++++++++ 6 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/pretty-print/dangling-data.json 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 465f2c4895..2e1656b13d 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 @@ -110,6 +110,11 @@ public class PrettyPrintSubCommand implements Runnable { if (validatedCode instanceof CodeInvalid codeInvalid) { parentCommand.out.println("EOF code is invalid - " + codeInvalid.getInvalidReason()); } + if (layout.container().size() != container.size()) { + parentCommand.out.println( + "EOF code is invalid - dangling data after container - " + + container.slice(layout.container().size()).toHexString()); + } } else { parentCommand.out.println("EOF layout is invalid - " + layout.invalidReason()); } diff --git a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/pretty-print/dangling-data.json b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/pretty-print/dangling-data.json new file mode 100644 index 0000000000..27833a1bb9 --- /dev/null +++ b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/pretty-print/dangling-data.json @@ -0,0 +1,8 @@ +{ + "cli": [ + "pretty-print", + "ef00010100040200010001040000000080000000ff" + ], + "stdin": "", + "stdout": "EOF layout is invalid - Dangling data after end of all sections\n" +} \ No newline at end of file diff --git a/evm/src/main/java/org/hyperledger/besu/evm/code/CodeV1Validation.java b/evm/src/main/java/org/hyperledger/besu/evm/code/CodeV1Validation.java index 3c85bd1eb2..f968bbf36a 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/code/CodeV1Validation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/code/CodeV1Validation.java @@ -486,6 +486,8 @@ public class CodeV1Validation implements EOFValidator { "Code that was not forward referenced in section 0x%x pc %d", codeSectionToValidate, currentPC); } + currentMin = min(stack_min[currentPC], currentMin); + currentMax = max(stack_max[currentPC], currentMax); if (stackInputs > currentMin) { return format( diff --git a/evm/src/main/java/org/hyperledger/besu/evm/code/EOFLayout.java b/evm/src/main/java/org/hyperledger/besu/evm/code/EOFLayout.java index 1249e475b4..39723f7fd3 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/code/EOFLayout.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/code/EOFLayout.java @@ -191,6 +191,7 @@ public record EOFLayout( * strict and excess data is in the container * @return the eof layout */ + @SuppressWarnings("ReferenceEquality") public static EOFLayout parseEOF(final Bytes container, final boolean strictSize) { Queue parseQueue = new ArrayDeque<>(); parseQueue.add(new EOFParseStep(container, strictSize, -1, null, null)); @@ -213,8 +214,10 @@ public record EOFLayout( + " - " + parsedContainer.invalidReason); } - if (step.container.size() < parsedContainer.container.size()) { - return invalidLayout(container, parsedContainer.version, "excess data in subcontainer"); + // This ReferenceEquality check is correct + if ((strictSize || result != parsedContainer) + && step.container.size() != parsedContainer.container.size()) { + return invalidLayout(container, parsedContainer.version, "subcontainer size mismatch"); } if (step.index >= 0) { step.parentSubcontainers[step.index] = parsedContainer; diff --git a/evm/src/test/java/org/hyperledger/besu/evm/code/CodeV1Test.java b/evm/src/test/java/org/hyperledger/besu/evm/code/CodeV1Test.java index f32a3f4866..08cbbedf75 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/code/CodeV1Test.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/code/CodeV1Test.java @@ -30,7 +30,7 @@ import org.junit.jupiter.params.provider.MethodSource; import org.junit.jupiter.params.provider.ValueSource; /** - * These tests focus on code only validations, which are checked within the code runs themselves. + * These tests focus on code-only validations, which are checked within the code runs themselves. * Tests that depend on the EOF container (such as CallF into other sections) are in EOFLayoutTest. */ class CodeV1Test { @@ -520,7 +520,12 @@ class CodeV1Test { "Stack underflow", "Operation 0x50 requires stack of 1 but may only have 0 items", 0, - List.of(List.of("50 00", 0, 0x80, 1)))); + List.of(List.of("50 00", 0, 0x80, 1))), + Arguments.of( + "double rjumpi", + "Operation 0xF3 requires stack of 2 but may only have 1 items", + 0, + List.of(List.of("5f 5f e10005 5f 5f e10000 f3", 0, 0x80, 1)))); } static Stream stackRJumpForward() { diff --git a/evm/src/test/java/org/hyperledger/besu/evm/code/EOFLayoutTest.java b/evm/src/test/java/org/hyperledger/besu/evm/code/EOFLayoutTest.java index 145adfb2dd..006fe1632b 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/code/EOFLayoutTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/code/EOFLayoutTest.java @@ -333,6 +333,18 @@ public class EOFLayoutTest { null, 1 }, + { + "EF00 01 010004 0200010001 0300010015 040000 00 00800000 00 (EF0001 010004 0200010001 040000 00 00800000 00ff)", + "dangling data in subcontainer", + "subcontainer size mismatch", + 1 + }, + { + "EF00 01 010004 0200010001 0300010014 040000 00 00800000 00 (EF0001 010004 0200010001 040000 00 00800000 00ff)", + "dangling data in container", + "Dangling data after end of all sections", + 1 + }, }); } From 419995248bb559294e989d06de0944651a959d89 Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Fri, 2 Aug 2024 15:50:49 +1000 Subject: [PATCH 088/259] 5098: Update already merged RpcErrorTypes to include index in exception message (#7420) Signed-off-by: Matilda Clerke --- .../api/jsonrpc/internal/methods/DebugAccountRange.java | 2 +- .../methods/permissioning/PermAddAccountsToAllowlist.java | 2 +- .../methods/permissioning/PermRemoveAccountsFromAllowlist.java | 2 +- .../methods/permissioning/PermAddAccountsToAllowlistTest.java | 2 +- .../permissioning/PermRemoveAccountsFromAllowlistTest.java | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugAccountRange.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugAccountRange.java index 47fe7738b9..32ed9c5611 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugAccountRange.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugAccountRange.java @@ -65,7 +65,7 @@ public class DebugAccountRange implements JsonRpcMethod { addressHash = requestContext.getRequiredParameter(2, String.class); } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException throw new InvalidJsonRpcParameters( - "Invalid address hash parameter", RpcErrorType.INVALID_ADDRESS_HASH_PARAMS, e); + "Invalid address hash parameter (index 2)", RpcErrorType.INVALID_ADDRESS_HASH_PARAMS, e); } final int maxResults = requestContext.getRequiredParameter(3, Integer.TYPE); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermAddAccountsToAllowlist.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermAddAccountsToAllowlist.java index 407edcd8fe..f3407ba10d 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermAddAccountsToAllowlist.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermAddAccountsToAllowlist.java @@ -50,7 +50,7 @@ public class PermAddAccountsToAllowlist implements JsonRpcMethod { accountsList = requestContext.getRequiredParameter(0, List.class); } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException throw new InvalidJsonRpcParameters( - "Invalid accounts list parameter", RpcErrorType.INVALID_ACCOUNT_PARAMS, e); + "Invalid accounts list parameter (index 0)", RpcErrorType.INVALID_ACCOUNT_PARAMS, e); } if (allowlistController.isPresent()) { diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermRemoveAccountsFromAllowlist.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermRemoveAccountsFromAllowlist.java index bd0176dbd3..a39acd5e9c 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermRemoveAccountsFromAllowlist.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermRemoveAccountsFromAllowlist.java @@ -50,7 +50,7 @@ public class PermRemoveAccountsFromAllowlist implements JsonRpcMethod { accountsList = requestContext.getRequiredParameter(0, List.class); } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException throw new InvalidJsonRpcParameters( - "Invalid accounts list parameter", RpcErrorType.INVALID_ACCOUNT_PARAMS, e); + "Invalid accounts list parameter (index 0)", RpcErrorType.INVALID_ACCOUNT_PARAMS, e); } if (allowlistController.isPresent()) { diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermAddAccountsToAllowlistTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermAddAccountsToAllowlistTest.java index 4a3300d16c..a87a6487fb 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermAddAccountsToAllowlistTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermAddAccountsToAllowlistTest.java @@ -125,7 +125,7 @@ public class PermAddAccountsToAllowlistTest { final Throwable thrown = catchThrowable(() -> method.response(request)); assertThat(thrown) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage("Invalid accounts list parameter"); + .hasMessage("Invalid accounts list parameter (index 0)"); } private JsonRpcRequestContext request(final List accounts) { diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermRemoveAccountsFromAllowlistTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermRemoveAccountsFromAllowlistTest.java index 2e8218752e..af3fc2ee6a 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermRemoveAccountsFromAllowlistTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermRemoveAccountsFromAllowlistTest.java @@ -126,7 +126,7 @@ public class PermRemoveAccountsFromAllowlistTest { final Throwable thrown = catchThrowable(() -> method.response(request)); assertThat(thrown) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage("Invalid accounts list parameter"); + .hasMessage("Invalid accounts list parameter (index 0)"); } private JsonRpcRequestContext request(final List accounts) { From 1958df9651a986856acc0cc78fcba5d0517d51d6 Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Fri, 2 Aug 2024 16:17:18 +1000 Subject: [PATCH 089/259] 5098 branch 5 update invalid auth params (#7406) * 5098: Add RpcErrorTypes Signed-off-by: Matilda Clerke * 5098: Modify InvalidJsonRpcParameters and InvalidJsonRpcRequestException, apply spotless Signed-off-by: Matilda Clerke * 5098: Modify InvalidJsonRpcParameters and InvalidJsonRpcRequestException, apply spotless Signed-off-by: Matilda Clerke * 5098: Add JsonRpcParameterException for later use Signed-off-by: Matilda Clerke * 5098: Update locations for RpcErrorType.INVALID_ACCOUNTS_PARAMS Signed-off-by: Matilda Clerke * 5098: Address review comments, apply spotless Signed-off-by: Matilda Clerke * 5098: Update with changes from branch 1 Signed-off-by: Matilda Clerke * 5098: Update code to use RpcErrorType.INVALID_ADDRESS_HASH_PARAMS Signed-off-by: Matilda Clerke * 5098: apply spotless Signed-off-by: Matilda Clerke * 5098: apply spotless Signed-off-by: Matilda Clerke * 5098: Update plugin-api gradle hash Signed-off-by: Matilda Clerke * 5098: Add comment on INVALID_PARAMS_ERROR_CODE Signed-off-by: Matilda Clerke * 5098: Apply spotless on latest changes Signed-off-by: Matilda Clerke * 5098: Update code to use RpcErrorType.INVALID_ADDRESS_PARAMS Signed-off-by: Matilda Clerke * 5098: Fix broken unit test Signed-off-by: Matilda Clerke * 5098: Fix broken unit test Signed-off-by: Matilda Clerke * 5098: Update with usage of RpcErrorType.INVALID_AUTH_PARAMS Signed-off-by: Matilda Clerke * 5098: Add index to exception messages Signed-off-by: Matilda Clerke * 5098: apoply spotless Signed-off-by: Matilda Clerke * 5098: Update BaseJsonRpcProcessor to utilise RpcErrorType from InvalidJsonRpcParameters Signed-off-by: Matilda Clerke * 5098: Include parameter index in INVALID_AUTH_PARAMS Signed-off-by: Matilda Clerke * 5098: Rename INVALID_AUTH_PARAMS to INVALID_PROPOSAL_PARAMS Signed-off-by: Matilda Clerke --------- Signed-off-by: Matilda Clerke Signed-off-by: Matilda-Clerke Co-authored-by: Sally MacFarlane --- .../besu/consensus/clique/jsonrpc/methods/Propose.java | 8 +++++++- .../api/jsonrpc/execution/TracedJsonRpcProcessor.java | 2 +- .../api/jsonrpc/internal/response/RpcErrorType.java | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/Propose.java b/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/Propose.java index f2b81d56e3..6e198a84fe 100644 --- a/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/Propose.java +++ b/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/Propose.java @@ -57,7 +57,13 @@ public class Propose implements JsonRpcMethod { throw new InvalidJsonRpcParameters( "Invalid address parameter (index 0)", RpcErrorType.INVALID_ADDRESS_PARAMS, e); } - final Boolean auth = requestContext.getRequiredParameter(1, Boolean.class); + final Boolean auth; + try { + auth = requestContext.getRequiredParameter(1, Boolean.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid auth parameter (index 1)", RpcErrorType.INVALID_PROPOSAL_PARAMS, e); + } if (address.equals(CliqueBlockInterface.NO_VOTE_SUBJECT)) { return new JsonRpcErrorResponse( requestContext.getRequest().getId(), RpcErrorType.INVALID_REQUEST); 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 eba3827bfa..822c6ac895 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 @@ -60,7 +60,6 @@ public class TracedJsonRpcProcessor implements JsonRpcProcessor { case INVALID_ACCOUNT_PARAMS: case INVALID_ADDRESS_HASH_PARAMS: case INVALID_ADDRESS_PARAMS: - case INVALID_AUTH_PARAMS: case INVALID_BLOB_COUNT: case INVALID_BLOB_GAS_USED_PARAMS: case INVALID_BLOCK_PARAMS: @@ -104,6 +103,7 @@ public class TracedJsonRpcProcessor implements JsonRpcProcessor { case INVALID_PRIVACY_GROUP_PARAMS: case INVALID_PRIVATE_FROM_PARAMS: case INVALID_PRIVATE_FOR_PARAMS: + case INVALID_PROPOSAL_PARAMS: case INVALID_REMOTE_CAPABILITIES_PARAMS: case INVALID_REWARD_PERCENTILES_PARAMS: case INVALID_SEALER_ID_PARAMS: 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 309fe49862..d46dc900c5 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 @@ -31,7 +31,6 @@ public enum RpcErrorType implements RpcMethodError { INVALID_ACCOUNT_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid account params"), INVALID_ADDRESS_HASH_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid address hash params"), INVALID_ADDRESS_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid address params"), - INVALID_AUTH_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid auth params"), INVALID_BLOB_COUNT( INVALID_PARAMS_ERROR_CODE, "Invalid blob count (blob transactions must have at least one blob)"), @@ -89,6 +88,7 @@ public enum RpcErrorType implements RpcMethodError { INVALID_PRIVACY_GROUP_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid privacy group params"), INVALID_PRIVATE_FROM_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid private from params"), INVALID_PRIVATE_FOR_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid private for params"), + INVALID_PROPOSAL_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid proposal params"), INVALID_REMOTE_CAPABILITIES_PARAMS( INVALID_PARAMS_ERROR_CODE, "Invalid remote capabilities params"), INVALID_REWARD_PERCENTILES_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid reward percentiles params"), From 2ddfc2cbfb0ed9e5dd151c7e7df385d1aceafd18 Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Fri, 2 Aug 2024 18:04:40 +1000 Subject: [PATCH 090/259] 5098 branch 6 update invalid blob count (#7407) * 5098: Add RpcErrorTypes Signed-off-by: Matilda Clerke --------- Signed-off-by: Matilda Clerke Signed-off-by: Matilda-Clerke Co-authored-by: Sally MacFarlane --- .../internal/methods/engine/AbstractEngineNewPayload.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 543c965c80..68adb2ab69 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 @@ -466,7 +466,7 @@ public abstract class AbstractEngineNewPayload extends ExecutionEngineJsonRpcMet // blob transactions must have at least one blob if (versionedHashes.isEmpty()) { return ValidationResult.invalid( - RpcErrorType.INVALID_PARAMS, "There must be at least one blob"); + RpcErrorType.INVALID_BLOB_COUNT, "There must be at least one blob"); } transactionVersionedHashes.addAll(versionedHashes.get()); } @@ -505,7 +505,7 @@ public abstract class AbstractEngineNewPayload extends ExecutionEngineJsonRpcMet if (protocolSpec.getGasCalculator().blobGasCost(transactionVersionedHashes.size()) > protocolSpec.getGasLimitCalculator().currentBlobGasLimit()) { return ValidationResult.invalid( - RpcErrorType.INVALID_PARAMS, + RpcErrorType.INVALID_BLOB_COUNT, String.format("Invalid Blob Count: %d", transactionVersionedHashes.size())); } return ValidationResult.valid(); From 38a025b8708f2c8f0daa31db1f30e995d9d15dd8 Mon Sep 17 00:00:00 2001 From: Justin Florentine Date: Fri, 2 Aug 2024 13:01:58 -0400 Subject: [PATCH 091/259] Dagger controller tests (#7341) * daggerize PrivacyReorgTest * inline as many dagger bits into tests as possible * refactored to use inner classes * BesuComponent can now be provided --------- Signed-off-by: Justin Florentine Signed-off-by: Sally MacFarlane Co-authored-by: Sally MacFarlane --- .../perm/AllowListContainsKeyAndValue.java | 6 + .../dsl/node/ThreadBesuNodeRunner.java | 376 ++++++++++++------ .../acceptance/dsl/privacy/PrivacyNode.java | 2 +- ...ClusterThreadNodeRunnerAcceptanceTest.java | 2 +- besu/build.gradle | 2 + .../controller/BesuControllerBuilder.java | 1 + .../besu/services/BlockchainServiceImpl.java | 2 + .../services/PermissioningServiceImpl.java | 2 + .../besu/services/RpcEndpointServiceImpl.java | 2 + .../services/SecurityModuleServiceImpl.java | 7 +- .../besu/services/StorageServiceImpl.java | 2 + .../TransactionPoolValidatorServiceImpl.java | 6 +- .../TransactionSelectionServiceImpl.java | 6 +- .../TransactionSimulationServiceImpl.java | 2 + .../besu/FlexGroupPrivacyTest.java | 168 ++++++++ .../hyperledger/besu/PrivacyReorgTest.java | 151 +++++-- .../org/hyperledger/besu/PrivacyTest.java | 171 ++++---- .../java/org/hyperledger/besu/RunnerTest.java | 3 + .../chainexport/RlpBlockExporterTest.java | 3 + .../chainimport/JsonBlockImporterTest.java | 3 + .../chainimport/RlpBlockImporterTest.java | 5 + .../besu/components/EnclaveModule.java | 98 +++++ .../besu/components/GenesisConfigModule.java | 38 ++ .../components/MockBesuCommandModule.java | 50 +++ .../components/NoOpMetricsSystemModule.java | 40 ++ .../components/PrivacyParametersModule.java | 47 +++ .../besu/components/PrivacyTestModule.java | 111 ++++++ .../AbstractBftBesuControllerBuilderTest.java | 2 + .../CliqueBesuControllerBuilderTest.java | 2 + .../MergeBesuControllerBuilderTest.java | 2 + .../besu/ethereum/p2p/peers/EnodeURLImpl.java | 13 +- 31 files changed, 1064 insertions(+), 261 deletions(-) create mode 100644 besu/src/test/java/org/hyperledger/besu/FlexGroupPrivacyTest.java create mode 100644 besu/src/test/java/org/hyperledger/besu/components/EnclaveModule.java create mode 100644 besu/src/test/java/org/hyperledger/besu/components/GenesisConfigModule.java create mode 100644 besu/src/test/java/org/hyperledger/besu/components/MockBesuCommandModule.java create mode 100644 besu/src/test/java/org/hyperledger/besu/components/NoOpMetricsSystemModule.java create mode 100644 besu/src/test/java/org/hyperledger/besu/components/PrivacyParametersModule.java create mode 100644 besu/src/test/java/org/hyperledger/besu/components/PrivacyTestModule.java diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/perm/AllowListContainsKeyAndValue.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/perm/AllowListContainsKeyAndValue.java index a2ffc9b36d..0913fd227f 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/perm/AllowListContainsKeyAndValue.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/perm/AllowListContainsKeyAndValue.java @@ -24,11 +24,16 @@ import org.hyperledger.besu.tests.acceptance.dsl.node.Node; import java.nio.file.Path; import java.util.Collection; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + public class AllowListContainsKeyAndValue implements Condition { private final ALLOWLIST_TYPE allowlistType; private final Collection allowlistValues; private final Path configFilePath; + private static final Logger LOG = LoggerFactory.getLogger(AllowListContainsKeyAndValue.class); + public AllowListContainsKeyAndValue( final ALLOWLIST_TYPE allowlistType, final Collection allowlistValues, @@ -47,6 +52,7 @@ public class AllowListContainsKeyAndValue implements Condition { allowlistType, allowlistValues, configFilePath); } catch (final Exception e) { result = false; + LOG.error("Error verifying allowlist contains key and value", e); } assertThat(result).isTrue(); } 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 459fe49efb..7e8d435c72 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 @@ -18,8 +18,13 @@ import static org.hyperledger.besu.controller.BesuController.DATABASE_PATH; import org.hyperledger.besu.Runner; import org.hyperledger.besu.RunnerBuilder; +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.config.EthNetworkConfig; import org.hyperledger.besu.cli.config.NetworkName; +import org.hyperledger.besu.components.BesuComponent; import org.hyperledger.besu.config.GenesisConfigFile; import org.hyperledger.besu.controller.BesuController; import org.hyperledger.besu.controller.BesuControllerBuilder; @@ -31,23 +36,28 @@ import org.hyperledger.besu.ethereum.api.ApiConfiguration; import org.hyperledger.besu.ethereum.api.graphql.GraphQLConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.InProcessRpcConfiguration; import org.hyperledger.besu.ethereum.core.ImmutableMiningParameters; +import org.hyperledger.besu.ethereum.core.MiningParameters; import org.hyperledger.besu.ethereum.core.plugins.PluginConfiguration; import org.hyperledger.besu.ethereum.eth.EthProtocolConfiguration; import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration; +import org.hyperledger.besu.ethereum.eth.transactions.BlobCacheModule; import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration; import org.hyperledger.besu.ethereum.p2p.peers.EnodeURLImpl; 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.trie.diffbased.bonsai.cache.BonsaiCachedMerkleTrieLoaderModule; import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; import org.hyperledger.besu.evm.internal.EvmConfiguration; -import org.hyperledger.besu.metrics.MetricsSystemFactory; +import org.hyperledger.besu.metrics.MetricsSystemModule; import org.hyperledger.besu.metrics.ObservableMetricsSystem; +import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration; import org.hyperledger.besu.plugin.data.EnodeURL; import org.hyperledger.besu.plugin.services.BesuConfiguration; import org.hyperledger.besu.plugin.services.BesuEvents; import org.hyperledger.besu.plugin.services.BlockchainService; +import org.hyperledger.besu.plugin.services.MetricsSystem; import org.hyperledger.besu.plugin.services.PermissioningService; import org.hyperledger.besu.plugin.services.PicoCLIOptions; import org.hyperledger.besu.plugin.services.PrivacyPluginService; @@ -71,17 +81,27 @@ import org.hyperledger.besu.services.StorageServiceImpl; 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 java.io.File; +import java.io.IOException; +import java.nio.file.Files; import java.nio.file.Path; import java.time.Clock; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; +import dagger.Component; +import dagger.Module; +import dagger.Provides; import io.opentelemetry.api.GlobalOpenTelemetry; import io.vertx.core.Vertx; import org.slf4j.Logger; @@ -97,59 +117,6 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner { private final Map besuPluginContextMap = new ConcurrentHashMap<>(); - private BesuPluginContextImpl buildPluginContext( - final BesuNode node, - final StorageServiceImpl storageService, - final SecurityModuleServiceImpl securityModuleService, - final TransactionSimulationServiceImpl transactionSimulationServiceImpl, - final TransactionSelectionServiceImpl transactionSelectionServiceImpl, - final TransactionPoolValidatorServiceImpl transactionPoolValidatorServiceImpl, - final BlockchainServiceImpl blockchainServiceImpl, - final RpcEndpointServiceImpl rpcEndpointServiceImpl, - final BesuConfiguration commonPluginConfiguration, - final PermissioningServiceImpl permissioningService) { - final CommandLine commandLine = new CommandLine(CommandSpec.create()); - final BesuPluginContextImpl besuPluginContext = new BesuPluginContextImpl(); - besuPluginContext.addService(StorageService.class, storageService); - besuPluginContext.addService(SecurityModuleService.class, securityModuleService); - besuPluginContext.addService(PicoCLIOptions.class, new PicoCLIOptionsImpl(commandLine)); - besuPluginContext.addService(RpcEndpointService.class, rpcEndpointServiceImpl); - besuPluginContext.addService( - TransactionSelectionService.class, transactionSelectionServiceImpl); - besuPluginContext.addService( - TransactionPoolValidatorService.class, transactionPoolValidatorServiceImpl); - besuPluginContext.addService( - TransactionSimulationService.class, transactionSimulationServiceImpl); - besuPluginContext.addService(BlockchainService.class, blockchainServiceImpl); - besuPluginContext.addService(BesuConfiguration.class, commonPluginConfiguration); - - final Path pluginsPath; - final String pluginDir = System.getProperty("besu.plugins.dir"); - if (pluginDir == null || pluginDir.isEmpty()) { - pluginsPath = node.homeDirectory().resolve("plugins"); - final File pluginsDirFile = pluginsPath.toFile(); - if (!pluginsDirFile.isDirectory()) { - pluginsDirFile.mkdirs(); - pluginsDirFile.deleteOnExit(); - } - System.setProperty("besu.plugins.dir", pluginsPath.toString()); - } else { - pluginsPath = Path.of(pluginDir); - } - - besuPluginContext.addService(BesuConfiguration.class, commonPluginConfiguration); - besuPluginContext.addService(PermissioningService.class, permissioningService); - besuPluginContext.addService(PrivacyPluginService.class, new PrivacyPluginServiceImpl()); - - besuPluginContext.registerPlugins(new PluginConfiguration(pluginsPath)); - - commandLine.parseArgs(node.getConfiguration().getExtraCLIOptions().toArray(new String[0])); - - // register built-in plugins - new RocksDBPlugin().register(besuPluginContext); - return besuPluginContext; - } - @Override public void startNode(final BesuNode node) { @@ -162,8 +129,9 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner { throw new UnsupportedOperationException("commands are not supported with thread runner"); } - final StorageServiceImpl storageService = new StorageServiceImpl(); - final SecurityModuleServiceImpl securityModuleService = new SecurityModuleServiceImpl(); + AcceptanceTestBesuComponent component = + DaggerThreadBesuNodeRunner_AcceptanceTestBesuComponent.create(); + final TransactionSimulationServiceImpl transactionSimulationServiceImpl = new TransactionSimulationServiceImpl(); final TransactionSelectionServiceImpl transactionSelectionServiceImpl = @@ -186,49 +154,22 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner { .withMiningParameters(miningParameters); final BesuPluginContextImpl besuPluginContext = - besuPluginContextMap.computeIfAbsent( - node, - n -> - buildPluginContext( - node, - storageService, - securityModuleService, - transactionSimulationServiceImpl, - transactionSelectionServiceImpl, - transactionPoolValidatorServiceImpl, - blockchainServiceImpl, - rpcEndpointServiceImpl, - commonPluginConfiguration, - permissioningService)); + besuPluginContextMap.computeIfAbsent(node, n -> component.getBesuPluginContext()); GlobalOpenTelemetry.resetForTest(); - final ObservableMetricsSystem metricsSystem = - MetricsSystemFactory.create(node.getMetricsConfiguration()); + final ObservableMetricsSystem metricsSystem = component.getObservableMetricsSystem(); final List bootnodes = node.getConfiguration().getBootnodes().stream() .map(EnodeURLImpl::fromURI) .collect(Collectors.toList()); - final NetworkName network = node.getNetwork() == null ? NetworkName.DEV : node.getNetwork(); - final EthNetworkConfig.Builder networkConfigBuilder = - new EthNetworkConfig.Builder(EthNetworkConfig.getNetworkConfig(network)) - .setBootNodes(bootnodes); + + final EthNetworkConfig.Builder networkConfigBuilder = component.ethNetworkConfigBuilder(); + networkConfigBuilder.setBootNodes(bootnodes); node.getConfiguration() .getGenesisConfig() .map(GenesisConfigFile::fromConfig) .ifPresent(networkConfigBuilder::setGenesisConfigFile); final EthNetworkConfig ethNetworkConfig = networkConfigBuilder.build(); - final SynchronizerConfiguration synchronizerConfiguration = - new SynchronizerConfiguration.Builder().build(); - final BesuControllerBuilder builder = - new BesuController.Builder() - .fromEthNetworkConfig(ethNetworkConfig, synchronizerConfiguration.getSyncMode()); - - final KeyValueStorageProvider storageProvider = - new KeyValueStorageProviderBuilder() - .withStorageFactory(storageService.getByName("rocksdb").get()) - .withCommonConfiguration(commonPluginConfiguration) - .withMetricsSystem(metricsSystem) - .build(); final TransactionPoolConfiguration txPoolConfig = ImmutableTransactionPoolConfiguration.builder() @@ -237,35 +178,20 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner { .transactionPoolValidatorService(transactionPoolValidatorServiceImpl) .build(); + final BesuControllerBuilder builder = component.besuControllerBuilder(); + builder.isRevertReasonEnabled(node.isRevertReasonEnabled()); + builder.networkConfiguration(node.getNetworkingConfiguration()); + builder.transactionPoolConfiguration(txPoolConfig); + builder.dataDirectory(dataDir); + builder.nodeKey(new NodeKey(new KeyPairSecurityModule(KeyPairUtil.loadKeyPair(dataDir)))); + builder.privacyParameters(node.getPrivacyParameters()); final InProcessRpcConfiguration inProcessRpcConfiguration = node.inProcessRpcConfiguration(); - final int maxPeers = 25; - - builder - .synchronizerConfiguration(new SynchronizerConfiguration.Builder().build()) - .dataDirectory(node.homeDirectory()) - .miningParameters(miningParameters) - .privacyParameters(node.getPrivacyParameters()) - .nodeKey(new NodeKey(new KeyPairSecurityModule(KeyPairUtil.loadKeyPair(dataDir)))) - .metricsSystem(metricsSystem) - .transactionPoolConfiguration(txPoolConfig) - .dataStorageConfiguration(DataStorageConfiguration.DEFAULT_FOREST_CONFIG) - .ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig()) - .clock(Clock.systemUTC()) - .isRevertReasonEnabled(node.isRevertReasonEnabled()) - .storageProvider(storageProvider) - .gasLimitCalculator(GasLimitCalculator.constant()) - .evmConfiguration(EvmConfiguration.DEFAULT) - .maxPeers(maxPeers) - .maxRemotelyInitiatedPeers(15) - .networkConfiguration(node.getNetworkingConfiguration()) - .randomPeerPriority(false); - node.getGenesisConfig() .map(GenesisConfigFile::fromConfig) .ifPresent(builder::genesisConfigFile); - final BesuController besuController = builder.build(); + final BesuController besuController = component.besuController(); initTransactionSimulationService( transactionSimulationServiceImpl, besuController, node.getApiConfiguration()); @@ -299,11 +225,10 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner { .collect(Collectors.toList())) .besuPluginContext(besuPluginContext) .autoLogBloomCaching(false) - .storageProvider(storageProvider) + .storageProvider(besuController.getStorageProvider()) .rpcEndpointService(rpcEndpointServiceImpl) .inProcessRpcConfiguration(inProcessRpcConfiguration); node.engineRpcConfiguration().ifPresent(runnerBuilder::engineJsonRpcConfiguration); - besuPluginContext.beforeExternalServices(); final Runner runner = runnerBuilder.build(); @@ -396,4 +321,229 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner { public String getConsoleContents() { throw new RuntimeException("Console contents can only be captured in process execution"); } + + @Module + @SuppressWarnings("CloseableProvides") + static class BesuControllerModule { + @Provides + @Singleton + public SynchronizerConfiguration provideSynchronizationConfiguration() { + final SynchronizerConfiguration synchronizerConfiguration = + SynchronizerConfiguration.builder().build(); + return synchronizerConfiguration; + } + + @Singleton + @Provides + public BesuControllerBuilder provideBesuControllerBuilder( + final EthNetworkConfig ethNetworkConfig, + final SynchronizerConfiguration synchronizerConfiguration) { + + final BesuControllerBuilder builder = + new BesuController.Builder() + .fromEthNetworkConfig(ethNetworkConfig, synchronizerConfiguration.getSyncMode()); + return builder; + } + + @Provides + public BesuController provideBesuController( + final SynchronizerConfiguration synchronizerConfiguration, + final BesuControllerBuilder builder, + final ObservableMetricsSystem metricsSystem, + final KeyValueStorageProvider storageProvider, + final MiningParameters miningParameters) { + + builder + .synchronizerConfiguration(synchronizerConfiguration) + .metricsSystem(metricsSystem) + .dataStorageConfiguration(DataStorageConfiguration.DEFAULT_FOREST_CONFIG) + .ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig()) + .clock(Clock.systemUTC()) + .storageProvider(storageProvider) + .gasLimitCalculator(GasLimitCalculator.constant()) + .evmConfiguration(EvmConfiguration.DEFAULT) + .maxPeers(25) + .maxRemotelyInitiatedPeers(15) + .miningParameters(miningParameters) + .randomPeerPriority(false) + .besuComponent(null); + return builder.build(); + } + + @Provides + @Singleton + public EthNetworkConfig.Builder provideEthNetworkConfigBuilder() { + final EthNetworkConfig.Builder networkConfigBuilder = + new EthNetworkConfig.Builder(EthNetworkConfig.getNetworkConfig(NetworkName.DEV)); + return networkConfigBuilder; + } + + @Provides + public EthNetworkConfig provideEthNetworkConfig( + final EthNetworkConfig.Builder networkConfigBuilder) { + + final EthNetworkConfig ethNetworkConfig = networkConfigBuilder.build(); + return ethNetworkConfig; + } + + @Provides + @Named("besuPluginContext") + public BesuPluginContextImpl providePluginContext( + final StorageServiceImpl storageService, + final SecurityModuleServiceImpl securityModuleService, + final TransactionSimulationServiceImpl transactionSimulationServiceImpl, + final TransactionSelectionServiceImpl transactionSelectionServiceImpl, + final TransactionPoolValidatorServiceImpl transactionPoolValidatorServiceImpl, + final BlockchainServiceImpl blockchainServiceImpl, + final RpcEndpointServiceImpl rpcEndpointServiceImpl, + final BesuConfiguration commonPluginConfiguration, + final PermissioningServiceImpl permissioningService) { + final CommandLine commandLine = new CommandLine(CommandSpec.create()); + final BesuPluginContextImpl besuPluginContext = new BesuPluginContextImpl(); + besuPluginContext.addService(StorageService.class, storageService); + besuPluginContext.addService(SecurityModuleService.class, securityModuleService); + besuPluginContext.addService(PicoCLIOptions.class, new PicoCLIOptionsImpl(commandLine)); + besuPluginContext.addService(RpcEndpointService.class, rpcEndpointServiceImpl); + besuPluginContext.addService( + TransactionSelectionService.class, transactionSelectionServiceImpl); + besuPluginContext.addService( + TransactionPoolValidatorService.class, transactionPoolValidatorServiceImpl); + besuPluginContext.addService( + TransactionSimulationService.class, transactionSimulationServiceImpl); + besuPluginContext.addService(BlockchainService.class, blockchainServiceImpl); + besuPluginContext.addService(BesuConfiguration.class, commonPluginConfiguration); + + final Path pluginsPath; + final String pluginDir = System.getProperty("besu.plugins.dir"); + if (pluginDir == null || pluginDir.isEmpty()) { + // pluginsPath = node.homeDirectory().resolve("plugins"); + pluginsPath = commonPluginConfiguration.getDataPath().resolve("plugins"); + final File pluginsDirFile = pluginsPath.toFile(); + if (!pluginsDirFile.isDirectory()) { + pluginsDirFile.mkdirs(); + pluginsDirFile.deleteOnExit(); + } + System.setProperty("besu.plugins.dir", pluginsPath.toString()); + } else { + pluginsPath = Path.of(pluginDir); + } + + besuPluginContext.addService(BesuConfiguration.class, commonPluginConfiguration); + besuPluginContext.addService(PermissioningService.class, permissioningService); + besuPluginContext.addService(PrivacyPluginService.class, new PrivacyPluginServiceImpl()); + + besuPluginContext.registerPlugins(new PluginConfiguration(pluginsPath)); + + // register built-in plugins + new RocksDBPlugin().register(besuPluginContext); + return besuPluginContext; + } + + @Provides + public KeyValueStorageProvider provideKeyValueStorageProvider( + final BesuConfiguration commonPluginConfiguration, final MetricsSystem metricsSystem) { + + final StorageServiceImpl storageService = new StorageServiceImpl(); + storageService.registerKeyValueStorage( + new InMemoryStoragePlugin.InMemoryKeyValueStorageFactory("memory")); + final KeyValueStorageProvider storageProvider = + new KeyValueStorageProviderBuilder() + .withStorageFactory(storageService.getByName("memory").get()) + .withCommonConfiguration(commonPluginConfiguration) + .withMetricsSystem(metricsSystem) + .build(); + + return storageProvider; + } + + @Provides + public MiningParameters provideMiningParameters( + final TransactionSelectionServiceImpl transactionSelectionServiceImpl) { + final var miningParameters = + ImmutableMiningParameters.builder() + .transactionSelectionService(transactionSelectionServiceImpl) + .build(); + + return miningParameters; + } + + @Provides + Path provideDataDir() { + try { + return Files.createTempDirectory("acctest"); + } catch (final IOException e) { + throw new RuntimeException("Unable to create temporary data directory", e); + } + } + + @Provides + @Inject + BesuConfiguration provideBesuConfiguration(final Path dataDir) { + final BesuConfigurationImpl commonPluginConfiguration = new BesuConfigurationImpl(); + commonPluginConfiguration.init( + dataDir, dataDir.resolve(DATABASE_PATH), DataStorageConfiguration.DEFAULT_FOREST_CONFIG); + return commonPluginConfiguration; + } + + @Provides + TransactionPoolConfiguration provideTransactionPoolConfiguration( + final BesuNode node, + final TransactionPoolValidatorServiceImpl transactionPoolValidatorServiceImpl) { + return ImmutableTransactionPoolConfiguration.builder() + .from(node.getTransactionPoolConfiguration()) + .strictTransactionReplayProtectionEnabled(node.isStrictTxReplayProtectionEnabled()) + .transactionPoolValidatorService(transactionPoolValidatorServiceImpl) + .build(); + } + } + + @Module + static class MockBesuCommandModule { + + @Provides + BesuCommand provideBesuCommand(final AcceptanceTestBesuComponent component) { + final BesuCommand besuCommand = + new BesuCommand( + component, + RlpBlockImporter::new, + JsonBlockImporter::new, + RlpBlockExporter::new, + new RunnerBuilder(), + new BesuController.Builder(), + Optional.ofNullable(component.getBesuPluginContext()).orElse(null), + System.getenv()); + besuCommand.toCommandLine(); + return besuCommand; + } + + @Provides + @Singleton + MetricsConfiguration provideMetricsConfiguration() { + return MetricsConfiguration.builder().build(); + } + + @Provides + @Named("besuCommandLogger") + @Singleton + Logger provideBesuCommandLogger() { + return LoggerFactory.getLogger(MockBesuCommandModule.class); + } + } + + @Singleton + @Component( + modules = { + ThreadBesuNodeRunner.BesuControllerModule.class, + ThreadBesuNodeRunner.MockBesuCommandModule.class, + BonsaiCachedMerkleTrieLoaderModule.class, + MetricsSystemModule.class, + BlobCacheModule.class + }) + public interface AcceptanceTestBesuComponent extends BesuComponent { + BesuController besuController(); + + BesuControllerBuilder besuControllerBuilder(); // TODO: needing this sucks + + EthNetworkConfig.Builder ethNetworkConfigBuilder(); + } } diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/PrivacyNode.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/PrivacyNode.java index 520cd7d574..d54bf90872 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/PrivacyNode.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/PrivacyNode.java @@ -276,7 +276,7 @@ public class PrivacyNode implements AutoCloseable { final Path dataLocation, final Path dbLocation) { final var besuConfiguration = new BesuConfigurationImpl(); besuConfiguration - .init(dataLocation, dbLocation, null) + .init(dataLocation, dbLocation, besuConfig.getDataStorageConfiguration()) .withMiningParameters(besuConfig.getMiningParameters()); return new PrivacyKeyValueStorageProviderBuilder() .withStorageFactory( diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bootstrap/ClusterThreadNodeRunnerAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bootstrap/ClusterThreadNodeRunnerAcceptanceTest.java index 8fbd0d3d62..39cc5ad26f 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bootstrap/ClusterThreadNodeRunnerAcceptanceTest.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bootstrap/ClusterThreadNodeRunnerAcceptanceTest.java @@ -38,7 +38,7 @@ public class ClusterThreadNodeRunnerAcceptanceTest extends AcceptanceTestBase { final BesuNodeRunner besuNodeRunner = new ThreadBesuNodeRunner(); noDiscoveryCluster = new Cluster(clusterConfiguration, net, besuNodeRunner); final BesuNode noDiscoveryNode = besu.createNodeWithNoDiscovery("noDiscovery"); - fullNode = besu.createArchiveNode("node2"); + fullNode = besu.createArchiveNode("archive"); noDiscoveryCluster.start(noDiscoveryNode, fullNode); } diff --git a/besu/build.gradle b/besu/build.gradle index 286ca7a30f..7eef4a216c 100644 --- a/besu/build.gradle +++ b/besu/build.gradle @@ -104,6 +104,8 @@ dependencies { testImplementation 'org.mockito:mockito-core' testImplementation 'org.testcontainers:testcontainers' testImplementation 'tech.pegasys.discovery:discovery' + testImplementation 'com.google.dagger:dagger' annotationProcessor 'com.google.dagger:dagger-compiler' + testAnnotationProcessor 'com.google.dagger:dagger-compiler' } 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 ddb75fcded..6bb3fb117c 100644 --- a/besu/src/main/java/org/hyperledger/besu/controller/BesuControllerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/controller/BesuControllerBuilder.java @@ -552,6 +552,7 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides checkNotNull(evmConfiguration, "Missing evm config"); checkNotNull(networkingConfiguration, "Missing network configuration"); checkNotNull(dataStorageConfiguration, "Missing data storage configuration"); + prepForBuild(); final ProtocolSchedule protocolSchedule = createProtocolSchedule(); diff --git a/besu/src/main/java/org/hyperledger/besu/services/BlockchainServiceImpl.java b/besu/src/main/java/org/hyperledger/besu/services/BlockchainServiceImpl.java index 1f014ee061..f10ebcce47 100644 --- a/besu/src/main/java/org/hyperledger/besu/services/BlockchainServiceImpl.java +++ b/besu/src/main/java/org/hyperledger/besu/services/BlockchainServiceImpl.java @@ -34,6 +34,7 @@ import java.util.List; import java.util.Optional; import java.util.function.Supplier; import java.util.stream.Collectors; +import javax.inject.Inject; /** The Blockchain service implementation. */ @Unstable @@ -44,6 +45,7 @@ public class BlockchainServiceImpl implements BlockchainService { private MutableBlockchain blockchain; /** Instantiates a new Blockchain service implementation. */ + @Inject public BlockchainServiceImpl() {} /** diff --git a/besu/src/main/java/org/hyperledger/besu/services/PermissioningServiceImpl.java b/besu/src/main/java/org/hyperledger/besu/services/PermissioningServiceImpl.java index eda202f6d4..e43bf1c054 100644 --- a/besu/src/main/java/org/hyperledger/besu/services/PermissioningServiceImpl.java +++ b/besu/src/main/java/org/hyperledger/besu/services/PermissioningServiceImpl.java @@ -19,6 +19,7 @@ import org.hyperledger.besu.plugin.services.permissioning.NodeConnectionPermissi import org.hyperledger.besu.plugin.services.permissioning.NodeMessagePermissioningProvider; import java.util.List; +import javax.inject.Inject; import com.google.common.collect.Lists; @@ -29,6 +30,7 @@ public class PermissioningServiceImpl implements PermissioningService { Lists.newArrayList(); /** Default Constructor. */ + @Inject public PermissioningServiceImpl() {} @Override diff --git a/besu/src/main/java/org/hyperledger/besu/services/RpcEndpointServiceImpl.java b/besu/src/main/java/org/hyperledger/besu/services/RpcEndpointServiceImpl.java index dcfe29146e..5d7df73b2e 100644 --- a/besu/src/main/java/org/hyperledger/besu/services/RpcEndpointServiceImpl.java +++ b/besu/src/main/java/org/hyperledger/besu/services/RpcEndpointServiceImpl.java @@ -36,6 +36,7 @@ import java.util.Map; import java.util.NoSuchElementException; import java.util.function.Function; import java.util.stream.Collectors; +import javax.inject.Inject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -48,6 +49,7 @@ public class RpcEndpointServiceImpl implements RpcEndpointService { private Map inProcessRpcMethods; /** Default Constructor. */ + @Inject public RpcEndpointServiceImpl() {} /** diff --git a/besu/src/main/java/org/hyperledger/besu/services/SecurityModuleServiceImpl.java b/besu/src/main/java/org/hyperledger/besu/services/SecurityModuleServiceImpl.java index c3905c304b..5605fe49b5 100644 --- a/besu/src/main/java/org/hyperledger/besu/services/SecurityModuleServiceImpl.java +++ b/besu/src/main/java/org/hyperledger/besu/services/SecurityModuleServiceImpl.java @@ -21,15 +21,18 @@ import java.util.Map; import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Supplier; +import javax.inject.Inject; /** The Security module service implementation. */ public class SecurityModuleServiceImpl implements SecurityModuleService { - private final Map> securityModuleSuppliers = - new ConcurrentHashMap<>(); /** Default Constructor. */ + @Inject public SecurityModuleServiceImpl() {} + private final Map> securityModuleSuppliers = + new ConcurrentHashMap<>(); + @Override public void register(final String name, final Supplier securityModuleSupplier) { securityModuleSuppliers.put(name, securityModuleSupplier); diff --git a/besu/src/main/java/org/hyperledger/besu/services/StorageServiceImpl.java b/besu/src/main/java/org/hyperledger/besu/services/StorageServiceImpl.java index 6629da690e..dd5d822ccc 100644 --- a/besu/src/main/java/org/hyperledger/besu/services/StorageServiceImpl.java +++ b/besu/src/main/java/org/hyperledger/besu/services/StorageServiceImpl.java @@ -23,6 +23,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; +import javax.inject.Inject; /** The Storage service implementation. */ public class StorageServiceImpl implements StorageService { @@ -31,6 +32,7 @@ public class StorageServiceImpl implements StorageService { private final Map factories; /** Instantiates a new Storage service. */ + @Inject public StorageServiceImpl() { this.segments = List.of(KeyValueSegmentIdentifier.values()); this.factories = new ConcurrentHashMap<>(); diff --git a/besu/src/main/java/org/hyperledger/besu/services/TransactionPoolValidatorServiceImpl.java b/besu/src/main/java/org/hyperledger/besu/services/TransactionPoolValidatorServiceImpl.java index 1e1f94fb32..46af0a6ea5 100644 --- a/besu/src/main/java/org/hyperledger/besu/services/TransactionPoolValidatorServiceImpl.java +++ b/besu/src/main/java/org/hyperledger/besu/services/TransactionPoolValidatorServiceImpl.java @@ -19,15 +19,17 @@ import org.hyperledger.besu.plugin.services.txvalidator.PluginTransactionPoolVal import org.hyperledger.besu.plugin.services.txvalidator.PluginTransactionPoolValidatorFactory; import java.util.Optional; +import javax.inject.Inject; /** The Transaction pool validator service implementation. */ public class TransactionPoolValidatorServiceImpl implements TransactionPoolValidatorService { - private Optional factory = Optional.empty(); - /** Default Constructor. */ + @Inject public TransactionPoolValidatorServiceImpl() {} + private Optional factory = Optional.empty(); + @Override public PluginTransactionPoolValidator createTransactionValidator() { return factory diff --git a/besu/src/main/java/org/hyperledger/besu/services/TransactionSelectionServiceImpl.java b/besu/src/main/java/org/hyperledger/besu/services/TransactionSelectionServiceImpl.java index 8595a3c030..c7049c9aa0 100644 --- a/besu/src/main/java/org/hyperledger/besu/services/TransactionSelectionServiceImpl.java +++ b/besu/src/main/java/org/hyperledger/besu/services/TransactionSelectionServiceImpl.java @@ -19,15 +19,17 @@ import org.hyperledger.besu.plugin.services.txselection.PluginTransactionSelecto import org.hyperledger.besu.plugin.services.txselection.PluginTransactionSelectorFactory; import java.util.Optional; +import javax.inject.Inject; /** The Transaction Selection service implementation. */ public class TransactionSelectionServiceImpl implements TransactionSelectionService { - private Optional factory = Optional.empty(); - /** Default Constructor. */ + @Inject public TransactionSelectionServiceImpl() {} + private Optional factory = Optional.empty(); + @Override public PluginTransactionSelector createPluginTransactionSelector() { return factory diff --git a/besu/src/main/java/org/hyperledger/besu/services/TransactionSimulationServiceImpl.java b/besu/src/main/java/org/hyperledger/besu/services/TransactionSimulationServiceImpl.java index 54cce205a3..8ec00e8170 100644 --- a/besu/src/main/java/org/hyperledger/besu/services/TransactionSimulationServiceImpl.java +++ b/besu/src/main/java/org/hyperledger/besu/services/TransactionSimulationServiceImpl.java @@ -30,6 +30,7 @@ import org.hyperledger.besu.plugin.data.TransactionSimulationResult; import org.hyperledger.besu.plugin.services.TransactionSimulationService; import java.util.Optional; +import javax.inject.Inject; /** TransactionSimulationServiceImpl */ @Unstable @@ -43,6 +44,7 @@ public class TransactionSimulationServiceImpl implements TransactionSimulationSe private TransactionSimulator transactionSimulator; /** Create an instance to be configured */ + @Inject public TransactionSimulationServiceImpl() {} /** diff --git a/besu/src/test/java/org/hyperledger/besu/FlexGroupPrivacyTest.java b/besu/src/test/java/org/hyperledger/besu/FlexGroupPrivacyTest.java new file mode 100644 index 0000000000..a246d18d2f --- /dev/null +++ b/besu/src/test/java/org/hyperledger/besu/FlexGroupPrivacyTest.java @@ -0,0 +1,168 @@ +/* + * 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; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.hyperledger.besu.ethereum.core.PrivacyParameters.FLEXIBLE_PRIVACY; + +import org.hyperledger.besu.components.BesuComponent; +import org.hyperledger.besu.components.BesuPluginContextModule; +import org.hyperledger.besu.components.MockBesuCommandModule; +import org.hyperledger.besu.components.NoOpMetricsSystemModule; +import org.hyperledger.besu.components.PrivacyTestModule; +import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.controller.BesuController; +import org.hyperledger.besu.cryptoservices.NodeKeyUtils; +import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.enclave.EnclaveFactory; +import org.hyperledger.besu.ethereum.GasLimitCalculator; +import org.hyperledger.besu.ethereum.core.BlockHeader; +import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture; +import org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider; +import org.hyperledger.besu.ethereum.core.MiningParameters; +import org.hyperledger.besu.ethereum.core.PrivacyParameters; +import org.hyperledger.besu.ethereum.eth.EthProtocolConfiguration; +import org.hyperledger.besu.ethereum.eth.sync.SyncMode; +import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration; +import org.hyperledger.besu.ethereum.eth.transactions.BlobCacheModule; +import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration; +import org.hyperledger.besu.ethereum.p2p.config.NetworkingConfiguration; +import org.hyperledger.besu.ethereum.privacy.storage.PrivacyStorageProvider; +import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.cache.BonsaiCachedMerkleTrieLoaderModule; +import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; +import org.hyperledger.besu.evm.internal.EvmConfiguration; +import org.hyperledger.besu.evm.precompile.PrecompiledContract; +import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; +import org.hyperledger.besu.testutil.TestClock; + +import java.math.BigInteger; +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.file.Path; +import javax.inject.Named; +import javax.inject.Singleton; + +import dagger.Component; +import dagger.Module; +import dagger.Provides; +import io.vertx.core.Vertx; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; + +class FlexGroupPrivacyTest { + + private final Vertx vertx = Vertx.vertx(); + + @AfterEach + public void cleanUp() { + vertx.close(); + } + + @Test + void flexibleEnabledPrivacy() { + final BesuController besuController = + DaggerFlexGroupPrivacyTest_FlexGroupPrivacyTestComponent.builder() + .build() + .getBesuController(); + + final PrecompiledContract flexiblePrecompiledContract = + getPrecompile(besuController, FLEXIBLE_PRIVACY); + + assertThat(flexiblePrecompiledContract.getName()).isEqualTo("FlexiblePrivacy"); + } + + private PrecompiledContract getPrecompile( + final BesuController besuController, final Address defaultPrivacy) { + return besuController + .getProtocolSchedule() + .getByBlockHeader(blockHeader(0)) + .getPrecompileContractRegistry() + .get(defaultPrivacy); + } + + private BlockHeader blockHeader(final long number) { + return new BlockHeaderTestFixture().number(number).buildHeader(); + } + + @Singleton + @Component( + modules = { + FlexGroupPrivacyParametersModule.class, + FlexGroupPrivacyTest.PrivacyTestBesuControllerModule.class, + PrivacyTestModule.class, + MockBesuCommandModule.class, + BonsaiCachedMerkleTrieLoaderModule.class, + NoOpMetricsSystemModule.class, + BesuPluginContextModule.class, + BlobCacheModule.class + }) + interface FlexGroupPrivacyTestComponent extends BesuComponent { + BesuController getBesuController(); + } + + @Module + static class FlexGroupPrivacyParametersModule { + + @Provides + PrivacyParameters providePrivacyParameters( + final PrivacyStorageProvider storageProvider, final Vertx vertx) { + try { + return new PrivacyParameters.Builder() + .setEnabled(true) + .setEnclaveUrl(new URI("http://127.0.0.1:8000")) + .setStorageProvider(storageProvider) + .setEnclaveFactory(new EnclaveFactory(vertx)) + .setFlexiblePrivacyGroupsEnabled(true) + .build(); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + } + } + + @Module + static class PrivacyTestBesuControllerModule { + + @Provides + @Singleton + @SuppressWarnings("CloseableProvides") + BesuController provideBesuController( + final PrivacyParameters privacyParameters, + final DataStorageConfiguration dataStorageConfiguration, + final FlexGroupPrivacyTestComponent context, + @Named("dataDir") final Path dataDir) { + + return new BesuController.Builder() + .fromGenesisFile(GenesisConfigFile.mainnet(), SyncMode.FULL) + .synchronizerConfiguration(SynchronizerConfiguration.builder().build()) + .ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig()) + .storageProvider(new InMemoryKeyValueStorageProvider()) + .networkId(BigInteger.ONE) + .miningParameters(MiningParameters.newDefault()) + .dataStorageConfiguration(dataStorageConfiguration) + .nodeKey(NodeKeyUtils.generate()) + .metricsSystem(new NoOpMetricsSystem()) + .dataDirectory(dataDir) + .clock(TestClock.fixed()) + .privacyParameters(privacyParameters) + .transactionPoolConfiguration(TransactionPoolConfiguration.DEFAULT) + .gasLimitCalculator(GasLimitCalculator.constant()) + .evmConfiguration(EvmConfiguration.DEFAULT) + .networkConfiguration(NetworkingConfiguration.create()) + .besuComponent(context) + .build(); + } + } +} diff --git a/besu/src/test/java/org/hyperledger/besu/PrivacyReorgTest.java b/besu/src/test/java/org/hyperledger/besu/PrivacyReorgTest.java index ceb0be40fe..6298b70a95 100644 --- a/besu/src/test/java/org/hyperledger/besu/PrivacyReorgTest.java +++ b/besu/src/test/java/org/hyperledger/besu/PrivacyReorgTest.java @@ -21,6 +21,12 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import org.hyperledger.besu.components.BesuComponent; +import org.hyperledger.besu.components.BesuPluginContextModule; +import org.hyperledger.besu.components.EnclaveModule; +import org.hyperledger.besu.components.MockBesuCommandModule; +import org.hyperledger.besu.components.NoOpMetricsSystemModule; +import org.hyperledger.besu.components.PrivacyTestModule; import org.hyperledger.besu.config.GenesisConfigFile; import org.hyperledger.besu.controller.BesuController; import org.hyperledger.besu.crypto.KeyPair; @@ -47,7 +53,9 @@ import org.hyperledger.besu.ethereum.core.Transaction; import org.hyperledger.besu.ethereum.eth.EthProtocolConfiguration; import org.hyperledger.besu.ethereum.eth.sync.SyncMode; import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration; +import org.hyperledger.besu.ethereum.eth.transactions.BlobCacheModule; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration; +import org.hyperledger.besu.ethereum.mainnet.BlockImportResult; import org.hyperledger.besu.ethereum.mainnet.HeaderValidationMode; import org.hyperledger.besu.ethereum.p2p.config.NetworkingConfiguration; import org.hyperledger.besu.ethereum.privacy.PrivateStateRootResolver; @@ -56,6 +64,7 @@ import org.hyperledger.besu.ethereum.privacy.storage.PrivacyGroupHeadBlockMap; import org.hyperledger.besu.ethereum.privacy.storage.PrivacyStorageProvider; import org.hyperledger.besu.ethereum.privacy.storage.PrivateStateStorage; import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; +import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.cache.BonsaiCachedMerkleTrieLoaderModule; import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.evm.log.LogsBloomFilter; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; @@ -70,19 +79,21 @@ import java.nio.file.Path; import java.util.Collections; import java.util.Optional; import java.util.function.Supplier; +import javax.inject.Named; +import javax.inject.Singleton; import com.google.common.base.Suppliers; +import dagger.Component; +import dagger.Module; +import dagger.Provides; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.io.TempDir; @SuppressWarnings("rawtypes") public class PrivacyReorgTest { - @TempDir private Path folder; - private static final Supplier SIGNATURE_ALGORITHM = Suppliers.memoize(SignatureAlgorithmFactory::getInstance); @@ -130,11 +141,15 @@ public class PrivacyReorgTest { .signAndBuild(KEY_PAIR); private final BlockDataGenerator gen = new BlockDataGenerator(); - private BesuController besuController; - private PrivateStateRootResolver privateStateRootResolver; private PrivacyParameters privacyParameters; private Enclave mockEnclave; private Transaction privacyMarkerTransaction; + private final PrivacyReorgTestComponent component = + DaggerPrivacyReorgTest_PrivacyReorgTestComponent.create(); + + private final BesuController besuController = component.getBesuController(); + private final PrivateStateRootResolver privateStateRootResolver = + component.getPrivacyParameters().getPrivateStateRootResolver(); @BeforeEach public void setUp() throws IOException { @@ -174,29 +189,6 @@ public class PrivacyReorgTest { .build(); privacyParameters.setPrivacyUserId(ENCLAVE_PUBLIC_KEY.toBase64String()); - - privateStateRootResolver = - new PrivateStateRootResolver(privacyParameters.getPrivateStateStorage()); - - besuController = - new BesuController.Builder() - .fromGenesisFile( - GenesisConfigFile.fromResource("/privacy_reorg_genesis.json"), SyncMode.FULL) - .synchronizerConfiguration(SynchronizerConfiguration.builder().build()) - .ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig()) - .storageProvider(new InMemoryKeyValueStorageProvider()) - .networkId(BigInteger.ONE) - .miningParameters(MiningParameters.newDefault()) - .nodeKey(NodeKeyUtils.generate()) - .metricsSystem(new NoOpMetricsSystem()) - .dataDirectory(folder) - .clock(TestClock.fixed()) - .privacyParameters(privacyParameters) - .transactionPoolConfiguration(TransactionPoolConfiguration.DEFAULT) - .gasLimitCalculator(GasLimitCalculator.constant()) - .evmConfiguration(EvmConfiguration.DEFAULT) - .networkConfiguration(NetworkingConfiguration.create()) - .build(); } @Test @@ -204,7 +196,8 @@ public class PrivacyReorgTest { // Setup an initial blockchain with one private transaction final ProtocolContext protocolContext = besuController.getProtocolContext(); final DefaultBlockchain blockchain = (DefaultBlockchain) protocolContext.getBlockchain(); - final PrivateStateStorage privateStateStorage = privacyParameters.getPrivateStateStorage(); + final PrivateStateStorage privateStateStorage = + component.getPrivacyParameters().getPrivateStateStorage(); final Block firstBlock = gen.block( @@ -244,7 +237,7 @@ public class PrivacyReorgTest { // Setup an initial blockchain with one private transaction final ProtocolContext protocolContext = besuController.getProtocolContext(); final DefaultBlockchain blockchain = (DefaultBlockchain) protocolContext.getBlockchain(); - + assertThat(blockchain.getChainHeadBlockNumber()).isEqualTo(0); final Block firstBlock = gen.block( getBlockOptionsWithTransaction( @@ -252,8 +245,9 @@ public class PrivacyReorgTest { privacyMarkerTransaction, FIRST_BLOCK_WITH_SINGLE_TRANSACTION_STATE_ROOT)); - appendBlock(besuController, blockchain, protocolContext, firstBlock); - + var importResult = appendBlock(besuController, blockchain, protocolContext, firstBlock); + assertThat(importResult.isImported()).isTrue(); + assertThat(blockchain.getChainHeadBlockNumber()).isEqualTo(1); // Check that the private state root is not the empty state assertPrivateStateRoot( privateStateRootResolver, blockchain, STATE_ROOT_AFTER_TRANSACTION_APPENDED_TO_EMPTY_STATE); @@ -394,12 +388,12 @@ public class PrivacyReorgTest { } @SuppressWarnings("unchecked") - private void appendBlock( + private BlockImportResult appendBlock( final BesuController besuController, final DefaultBlockchain blockchain, final ProtocolContext protocolContext, final Block block) { - besuController + return besuController .getProtocolSchedule() .getByBlockHeader(blockchain.getChainHeadHeader()) .getBlockImporter() @@ -487,4 +481,93 @@ public class PrivacyReorgTest { .hasOmmers(false) .setLogsBloom(LogsBloomFilter.empty()); } + + @Singleton + @Component( + modules = { + PrivacyReorgTest.PrivacyReorgParametersModule.class, + PrivacyReorgTest.PrivacyReorgTestBesuControllerModule.class, + PrivacyReorgTest.PrivacyReorgTestGenesisConfigModule.class, + EnclaveModule.class, + PrivacyTestModule.class, + MockBesuCommandModule.class, + NoOpMetricsSystemModule.class, + BonsaiCachedMerkleTrieLoaderModule.class, + BlobCacheModule.class, + BesuPluginContextModule.class + }) + interface PrivacyReorgTestComponent extends BesuComponent { + + BesuController getBesuController(); + + PrivacyParameters getPrivacyParameters(); + } + + @Module + static class PrivacyReorgParametersModule { + + // TODO: copypasta, get this from the enclave factory + private static final Bytes ENCLAVE_PUBLIC_KEY = + Bytes.fromBase64String("A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo="); + + @Provides + PrivacyParameters providePrivacyReorgParameters( + final PrivacyStorageProvider storageProvider, final EnclaveFactory enclaveFactory) { + + PrivacyParameters retval = + new PrivacyParameters.Builder() + .setEnabled(true) + .setStorageProvider(storageProvider) + .setEnclaveUrl(URI.create("http//1.1.1.1:1234")) + .setEnclaveFactory(enclaveFactory) + .build(); + retval.setPrivacyUserId(ENCLAVE_PUBLIC_KEY.toBase64String()); + return retval; + } + } + + @Module + static class PrivacyReorgTestBesuControllerModule { + + @Provides + @Singleton + @SuppressWarnings("CloseableProvides") + BesuController provideBesuController( + final PrivacyParameters privacyParameters, + final GenesisConfigFile genesisConfigFile, + final PrivacyReorgTestComponent context, + final @Named("dataDir") Path dataDir) { + + // dataStorageConfiguration default + // named privacyReorgParams + BesuController retval = + new BesuController.Builder() + .fromGenesisFile(genesisConfigFile, SyncMode.FULL) + .synchronizerConfiguration(SynchronizerConfiguration.builder().build()) + .ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig()) + .storageProvider(new InMemoryKeyValueStorageProvider()) + .networkId(BigInteger.ONE) + .miningParameters(MiningParameters.newDefault()) + .nodeKey(NodeKeyUtils.generate()) + .metricsSystem(new NoOpMetricsSystem()) + .dataDirectory(dataDir) + .clock(TestClock.fixed()) + .privacyParameters(privacyParameters) + .transactionPoolConfiguration(TransactionPoolConfiguration.DEFAULT) + .gasLimitCalculator(GasLimitCalculator.constant()) + .evmConfiguration(EvmConfiguration.DEFAULT) + .networkConfiguration(NetworkingConfiguration.create()) + .besuComponent(context) + .build(); + return retval; + } + } + + @Module + static class PrivacyReorgTestGenesisConfigModule { + @Provides + GenesisConfigFile providePrivacyReorgGenesisConfigFile() { + return GenesisConfigFile.fromResource("/privacy_reorg_genesis.json"); + } + } } diff --git a/besu/src/test/java/org/hyperledger/besu/PrivacyTest.java b/besu/src/test/java/org/hyperledger/besu/PrivacyTest.java index dc5b7003c8..4d488ced3b 100644 --- a/besu/src/test/java/org/hyperledger/besu/PrivacyTest.java +++ b/besu/src/test/java/org/hyperledger/besu/PrivacyTest.java @@ -1,5 +1,5 @@ /* - * Copyright ConsenSys AG. + * 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 @@ -16,18 +16,17 @@ package org.hyperledger.besu; import static org.assertj.core.api.Assertions.assertThat; import static org.hyperledger.besu.ethereum.core.PrivacyParameters.DEFAULT_PRIVACY; -import static org.hyperledger.besu.ethereum.core.PrivacyParameters.FLEXIBLE_PRIVACY; -import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_BACKGROUND_THREAD_COUNT; -import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_CACHE_CAPACITY; -import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_IS_HIGH_SPEC; -import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_MAX_OPEN_FILES; - -import org.hyperledger.besu.cli.config.EthNetworkConfig; -import org.hyperledger.besu.cli.config.NetworkName; + +import org.hyperledger.besu.components.BesuComponent; +import org.hyperledger.besu.components.BesuPluginContextModule; +import org.hyperledger.besu.components.MockBesuCommandModule; +import org.hyperledger.besu.components.NoOpMetricsSystemModule; +import org.hyperledger.besu.components.PrivacyParametersModule; +import org.hyperledger.besu.components.PrivacyTestModule; +import org.hyperledger.besu.config.GenesisConfigFile; import org.hyperledger.besu.controller.BesuController; import org.hyperledger.besu.cryptoservices.NodeKeyUtils; import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.enclave.EnclaveFactory; import org.hyperledger.besu.ethereum.GasLimitCalculator; import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture; @@ -37,126 +36,47 @@ import org.hyperledger.besu.ethereum.core.PrivacyParameters; import org.hyperledger.besu.ethereum.eth.EthProtocolConfiguration; import org.hyperledger.besu.ethereum.eth.sync.SyncMode; import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration; +import org.hyperledger.besu.ethereum.eth.transactions.BlobCacheModule; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration; import org.hyperledger.besu.ethereum.p2p.config.NetworkingConfiguration; -import org.hyperledger.besu.ethereum.privacy.storage.PrivacyStorageProvider; -import org.hyperledger.besu.ethereum.privacy.storage.keyvalue.PrivacyKeyValueStorageProviderBuilder; -import org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier; +import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.cache.BonsaiCachedMerkleTrieLoaderModule; import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.evm.precompile.PrecompiledContract; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; -import org.hyperledger.besu.plugin.services.storage.rocksdb.RocksDBKeyValuePrivacyStorageFactory; -import org.hyperledger.besu.plugin.services.storage.rocksdb.RocksDBKeyValueStorageFactory; -import org.hyperledger.besu.plugin.services.storage.rocksdb.RocksDBMetricsFactory; -import org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBFactoryConfiguration; -import org.hyperledger.besu.services.BesuConfigurationImpl; import org.hyperledger.besu.testutil.TestClock; -import java.io.IOException; import java.math.BigInteger; -import java.net.URI; -import java.net.URISyntaxException; -import java.nio.file.Files; import java.nio.file.Path; -import java.util.Arrays; +import javax.inject.Named; +import javax.inject.Singleton; +import dagger.Component; +import dagger.Module; +import dagger.Provides; import io.vertx.core.Vertx; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.io.TempDir; -public class PrivacyTest { +class PrivacyTest { private final Vertx vertx = Vertx.vertx(); - @TempDir private Path dataDir; - @AfterEach public void cleanUp() { vertx.close(); } @Test - public void defaultPrivacy() throws IOException, URISyntaxException { - final BesuController besuController = setUpControllerWithPrivacyEnabled(false); + void defaultPrivacy() { + final BesuController besuController = + DaggerPrivacyTest_PrivacyTestComponent.builder().build().getBesuController(); final PrecompiledContract precompiledContract = getPrecompile(besuController, DEFAULT_PRIVACY); assertThat(precompiledContract.getName()).isEqualTo("Privacy"); } - @Test - public void flexibleEnabledPrivacy() throws IOException, URISyntaxException { - final BesuController besuController = setUpControllerWithPrivacyEnabled(true); - - final PrecompiledContract flexiblePrecompiledContract = - getPrecompile(besuController, FLEXIBLE_PRIVACY); - - assertThat(flexiblePrecompiledContract.getName()).isEqualTo("FlexiblePrivacy"); - } - - private BesuController setUpControllerWithPrivacyEnabled(final boolean flexibleEnabled) - throws IOException, URISyntaxException { - final Path dbDir = Files.createTempDirectory(dataDir, "database"); - final var miningParameters = MiningParameters.newDefault(); - final var dataStorageConfiguration = DataStorageConfiguration.DEFAULT_FOREST_CONFIG; - final PrivacyParameters privacyParameters = - new PrivacyParameters.Builder() - .setEnabled(true) - .setEnclaveUrl(new URI("http://127.0.0.1:8000")) - .setStorageProvider( - createKeyValueStorageProvider( - dataDir, dbDir, dataStorageConfiguration, miningParameters)) - .setEnclaveFactory(new EnclaveFactory(vertx)) - .setFlexiblePrivacyGroupsEnabled(flexibleEnabled) - .build(); - return new BesuController.Builder() - .fromEthNetworkConfig(EthNetworkConfig.getNetworkConfig(NetworkName.MAINNET), SyncMode.FULL) - .synchronizerConfiguration(SynchronizerConfiguration.builder().build()) - .ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig()) - .storageProvider(new InMemoryKeyValueStorageProvider()) - .networkId(BigInteger.ONE) - .miningParameters(miningParameters) - .dataStorageConfiguration(dataStorageConfiguration) - .nodeKey(NodeKeyUtils.generate()) - .metricsSystem(new NoOpMetricsSystem()) - .dataDirectory(dataDir) - .clock(TestClock.fixed()) - .privacyParameters(privacyParameters) - .transactionPoolConfiguration(TransactionPoolConfiguration.DEFAULT) - .gasLimitCalculator(GasLimitCalculator.constant()) - .evmConfiguration(EvmConfiguration.DEFAULT) - .networkConfiguration(NetworkingConfiguration.create()) - .build(); - } - - private PrivacyStorageProvider createKeyValueStorageProvider( - final Path dataDir, - final Path dbDir, - final DataStorageConfiguration dataStorageConfiguration, - final MiningParameters miningParameters) { - final var besuConfiguration = new BesuConfigurationImpl(); - besuConfiguration - .init(dataDir, dbDir, dataStorageConfiguration) - .withMiningParameters(miningParameters); - return new PrivacyKeyValueStorageProviderBuilder() - .withStorageFactory( - new RocksDBKeyValuePrivacyStorageFactory( - new RocksDBKeyValueStorageFactory( - () -> - new RocksDBFactoryConfiguration( - DEFAULT_MAX_OPEN_FILES, - DEFAULT_BACKGROUND_THREAD_COUNT, - DEFAULT_CACHE_CAPACITY, - DEFAULT_IS_HIGH_SPEC), - Arrays.asList(KeyValueSegmentIdentifier.values()), - RocksDBMetricsFactory.PRIVATE_ROCKS_DB_METRICS))) - .withCommonConfiguration(besuConfiguration) - .withMetricsSystem(new NoOpMetricsSystem()) - .build(); - } - private PrecompiledContract getPrecompile( final BesuController besuController, final Address defaultPrivacy) { return besuController @@ -169,4 +89,55 @@ public class PrivacyTest { private BlockHeader blockHeader(final long number) { return new BlockHeaderTestFixture().number(number).buildHeader(); } + + @Singleton + @Component( + modules = { + PrivacyParametersModule.class, + PrivacyTest.PrivacyTestBesuControllerModule.class, + PrivacyTestModule.class, + MockBesuCommandModule.class, + BonsaiCachedMerkleTrieLoaderModule.class, + NoOpMetricsSystemModule.class, + BesuPluginContextModule.class, + BlobCacheModule.class + }) + interface PrivacyTestComponent extends BesuComponent { + + BesuController getBesuController(); + } + + @Module + static class PrivacyTestBesuControllerModule { + + @Provides + @Singleton + @SuppressWarnings("CloseableProvides") + BesuController provideBesuController( + final PrivacyParameters privacyParameters, + final DataStorageConfiguration dataStorageConfiguration, + final PrivacyTestComponent context, + @Named("dataDir") final Path dataDir) { + + return new BesuController.Builder() + .fromGenesisFile(GenesisConfigFile.mainnet(), SyncMode.FULL) + .synchronizerConfiguration(SynchronizerConfiguration.builder().build()) + .ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig()) + .storageProvider(new InMemoryKeyValueStorageProvider()) + .networkId(BigInteger.ONE) + .miningParameters(MiningParameters.newDefault()) + .dataStorageConfiguration(dataStorageConfiguration) + .nodeKey(NodeKeyUtils.generate()) + .metricsSystem(new NoOpMetricsSystem()) + .dataDirectory(dataDir) + .clock(TestClock.fixed()) + .privacyParameters(privacyParameters) + .transactionPoolConfiguration(TransactionPoolConfiguration.DEFAULT) + .gasLimitCalculator(GasLimitCalculator.constant()) + .evmConfiguration(EvmConfiguration.DEFAULT) + .networkConfiguration(NetworkingConfiguration.create()) + .besuComponent(context) + .build(); + } + } } diff --git a/besu/src/test/java/org/hyperledger/besu/RunnerTest.java b/besu/src/test/java/org/hyperledger/besu/RunnerTest.java index 5b2a56078f..5fefc7ef22 100644 --- a/besu/src/test/java/org/hyperledger/besu/RunnerTest.java +++ b/besu/src/test/java/org/hyperledger/besu/RunnerTest.java @@ -22,8 +22,10 @@ import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_CACHE_CAPACITY; import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_IS_HIGH_SPEC; import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_MAX_OPEN_FILES; +import static org.mockito.Mockito.mock; 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; @@ -483,6 +485,7 @@ public final class RunnerTest { .evmConfiguration(EvmConfiguration.DEFAULT) .networkConfiguration(NetworkingConfiguration.create()) .randomPeerPriority(Boolean.FALSE) + .besuComponent(mock(BesuComponent.class)) .maxPeers(25) .maxRemotelyInitiatedPeers(15) .build(); diff --git a/besu/src/test/java/org/hyperledger/besu/chainexport/RlpBlockExporterTest.java b/besu/src/test/java/org/hyperledger/besu/chainexport/RlpBlockExporterTest.java index 05057f15c8..bbc7dea1ab 100644 --- a/besu/src/test/java/org/hyperledger/besu/chainexport/RlpBlockExporterTest.java +++ b/besu/src/test/java/org/hyperledger/besu/chainexport/RlpBlockExporterTest.java @@ -16,10 +16,12 @@ package org.hyperledger.besu.chainexport; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.Mockito.mock; import org.hyperledger.besu.chainimport.RlpBlockImporter; import org.hyperledger.besu.cli.config.EthNetworkConfig; import org.hyperledger.besu.cli.config.NetworkName; +import org.hyperledger.besu.components.BesuComponent; import org.hyperledger.besu.controller.BesuController; import org.hyperledger.besu.cryptoservices.NodeKeyUtils; import org.hyperledger.besu.ethereum.GasLimitCalculator; @@ -102,6 +104,7 @@ public final class RlpBlockExporterTest { .gasLimitCalculator(GasLimitCalculator.constant()) .evmConfiguration(EvmConfiguration.DEFAULT) .networkConfiguration(NetworkingConfiguration.create()) + .besuComponent(mock(BesuComponent.class)) .build(); } diff --git a/besu/src/test/java/org/hyperledger/besu/chainimport/JsonBlockImporterTest.java b/besu/src/test/java/org/hyperledger/besu/chainimport/JsonBlockImporterTest.java index 73015afd00..7b1a4bc7d2 100644 --- a/besu/src/test/java/org/hyperledger/besu/chainimport/JsonBlockImporterTest.java +++ b/besu/src/test/java/org/hyperledger/besu/chainimport/JsonBlockImporterTest.java @@ -17,7 +17,9 @@ package org.hyperledger.besu.chainimport; import static java.nio.charset.StandardCharsets.UTF_8; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.Mockito.mock; +import org.hyperledger.besu.components.BesuComponent; import org.hyperledger.besu.config.GenesisConfigFile; import org.hyperledger.besu.config.JsonUtil; import org.hyperledger.besu.controller.BesuController; @@ -463,6 +465,7 @@ public abstract class JsonBlockImporterTest { .gasLimitCalculator(GasLimitCalculator.constant()) .evmConfiguration(EvmConfiguration.DEFAULT) .networkConfiguration(NetworkingConfiguration.create()) + .besuComponent(mock(BesuComponent.class)) .build(); } } 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 e37b8a5fd0..7d4fabb222 100644 --- a/besu/src/test/java/org/hyperledger/besu/chainimport/RlpBlockImporterTest.java +++ b/besu/src/test/java/org/hyperledger/besu/chainimport/RlpBlockImporterTest.java @@ -16,9 +16,11 @@ package org.hyperledger.besu.chainimport; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +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.controller.BesuController; import org.hyperledger.besu.cryptoservices.NodeKeyUtils; @@ -77,6 +79,7 @@ public final class RlpBlockImporterTest { .gasLimitCalculator(GasLimitCalculator.constant()) .evmConfiguration(EvmConfiguration.DEFAULT) .networkConfiguration(NetworkingConfiguration.create()) + .besuComponent(mock(BesuComponent.class)) .build(); final RlpBlockImporter.ImportResult result = rlpBlockImporter.importBlockchain(source, targetController, false); @@ -110,6 +113,7 @@ public final class RlpBlockImporterTest { .gasLimitCalculator(GasLimitCalculator.constant()) .evmConfiguration(EvmConfiguration.DEFAULT) .networkConfiguration(NetworkingConfiguration.create()) + .besuComponent(mock(BesuComponent.class)) .build(); assertThatThrownBy( @@ -140,6 +144,7 @@ public final class RlpBlockImporterTest { .gasLimitCalculator(GasLimitCalculator.constant()) .evmConfiguration(EvmConfiguration.DEFAULT) .networkConfiguration(NetworkingConfiguration.create()) + .besuComponent(mock(BesuComponent.class)) .build(); final RlpBlockImporter.ImportResult result = diff --git a/besu/src/test/java/org/hyperledger/besu/components/EnclaveModule.java b/besu/src/test/java/org/hyperledger/besu/components/EnclaveModule.java new file mode 100644 index 0000000000..20f9c1bf49 --- /dev/null +++ b/besu/src/test/java/org/hyperledger/besu/components/EnclaveModule.java @@ -0,0 +1,98 @@ +/* + * 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.components; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.hyperledger.besu.crypto.KeyPair; +import org.hyperledger.besu.crypto.SignatureAlgorithm; +import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; +import org.hyperledger.besu.datatypes.Wei; +import org.hyperledger.besu.enclave.Enclave; +import org.hyperledger.besu.enclave.EnclaveFactory; +import org.hyperledger.besu.enclave.types.ReceiveResponse; +import org.hyperledger.besu.ethereum.privacy.PrivateTransaction; +import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; +import org.hyperledger.besu.plugin.data.Restriction; + +import java.math.BigInteger; +import java.nio.charset.StandardCharsets; +import java.util.Collections; +import java.util.function.Supplier; + +import com.google.common.base.Suppliers; +import dagger.Module; +import dagger.Provides; +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; + +@Module +public class EnclaveModule { + + private static final Supplier SIGNATURE_ALGORITHM = + Suppliers.memoize(SignatureAlgorithmFactory::getInstance); + + private static final Bytes ENCLAVE_PUBLIC_KEY = + Bytes.fromBase64String("A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo="); + + private static final Bytes32 PRIVACY_GROUP_BYTES32 = + Bytes32.fromHexString("0xf250d523ae9164722b06ca25cfa2a7f3c45df96b09e215236f886c876f715bfa"); + + private static final Bytes MOCK_PAYLOAD = + Bytes.fromHexString( + "0x608060405234801561001057600080fd5b5060008054600160a060020a03191633179055610199806100326000396000f3fe6080604052600436106100565763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416633fa4f245811461005b5780636057361d1461008257806367e404ce146100ae575b600080fd5b34801561006757600080fd5b506100706100ec565b60408051918252519081900360200190f35b34801561008e57600080fd5b506100ac600480360360208110156100a557600080fd5b50356100f2565b005b3480156100ba57600080fd5b506100c3610151565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b60025490565b604080513381526020810183905281517fc9db20adedc6cf2b5d25252b101ab03e124902a73fcb12b753f3d1aaa2d8f9f5929181900390910190a16002556001805473ffffffffffffffffffffffffffffffffffffffff191633179055565b60015473ffffffffffffffffffffffffffffffffffffffff169056fea165627a7a72305820c7f729cb24e05c221f5aa913700793994656f233fe2ce3b9fd9a505ea17e8d8a0029"); + + private static final KeyPair KEY_PAIR = + SIGNATURE_ALGORITHM + .get() + .createKeyPair( + SIGNATURE_ALGORITHM + .get() + .createPrivateKey( + new BigInteger( + "8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63", 16))); + + private static final PrivateTransaction PRIVATE_TRANSACTION = + PrivateTransaction.builder() + .chainId(BigInteger.valueOf(1337)) + .gasLimit(1000) + .gasPrice(Wei.ZERO) + .nonce(0) + .payload(MOCK_PAYLOAD) + .to(null) + .privateFrom(ENCLAVE_PUBLIC_KEY) + .privateFor(Collections.singletonList(ENCLAVE_PUBLIC_KEY)) + .restriction(Restriction.RESTRICTED) + .value(Wei.ZERO) + .signAndBuild(KEY_PAIR); + + @Provides + EnclaveFactory provideMockableEnclaveFactory() { + Enclave mockEnclave = mock(Enclave.class); + final BytesValueRLPOutput rlpOutput = new BytesValueRLPOutput(); + PRIVATE_TRANSACTION.writeTo(rlpOutput); + when(mockEnclave.receive(any())) + .thenReturn( + new ReceiveResponse( + rlpOutput.encoded().toBase64String().getBytes(StandardCharsets.UTF_8), + PRIVACY_GROUP_BYTES32.toBase64String(), + ENCLAVE_PUBLIC_KEY.toBase64String())); + EnclaveFactory enclaveFactory = mock(EnclaveFactory.class); + when(enclaveFactory.createVertxEnclave(any())).thenReturn(mockEnclave); + return enclaveFactory; + } +} diff --git a/besu/src/test/java/org/hyperledger/besu/components/GenesisConfigModule.java b/besu/src/test/java/org/hyperledger/besu/components/GenesisConfigModule.java new file mode 100644 index 0000000000..ae82b8b928 --- /dev/null +++ b/besu/src/test/java/org/hyperledger/besu/components/GenesisConfigModule.java @@ -0,0 +1,38 @@ +/* + * 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.components; + +import org.hyperledger.besu.config.GenesisConfigFile; + +import javax.inject.Named; + +import dagger.Module; +import dagger.Provides; + +@Module +public class GenesisConfigModule { + + @Named("default") + @Provides + GenesisConfigFile provideDefaultGenesisConfigFile() { + return GenesisConfigFile.DEFAULT; + } + + @Named("mainnet") + @Provides + GenesisConfigFile provideMainnetGenesisConfigFile() { + return GenesisConfigFile.mainnet(); + } +} diff --git a/besu/src/test/java/org/hyperledger/besu/components/MockBesuCommandModule.java b/besu/src/test/java/org/hyperledger/besu/components/MockBesuCommandModule.java new file mode 100644 index 0000000000..743b4ee8de --- /dev/null +++ b/besu/src/test/java/org/hyperledger/besu/components/MockBesuCommandModule.java @@ -0,0 +1,50 @@ +/* + * 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.components; + +import static org.mockito.Mockito.mock; + +import org.hyperledger.besu.cli.BesuCommand; +import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration; + +import javax.inject.Named; +import javax.inject.Singleton; + +import dagger.Module; +import dagger.Provides; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Module +public class MockBesuCommandModule { + + @Provides + BesuCommand provideBesuCommand() { + return mock(BesuCommand.class); + } + + @Provides + @Singleton + MetricsConfiguration provideMetricsConfiguration() { + return MetricsConfiguration.builder().build(); + } + + @Provides + @Named("besuCommandLogger") + @Singleton + Logger provideBesuCommandLogger() { + return LoggerFactory.getLogger(MockBesuCommandModule.class); + } +} diff --git a/besu/src/test/java/org/hyperledger/besu/components/NoOpMetricsSystemModule.java b/besu/src/test/java/org/hyperledger/besu/components/NoOpMetricsSystemModule.java new file mode 100644 index 0000000000..e7807e3d75 --- /dev/null +++ b/besu/src/test/java/org/hyperledger/besu/components/NoOpMetricsSystemModule.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.components; + +import org.hyperledger.besu.metrics.ObservableMetricsSystem; +import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; +import org.hyperledger.besu.plugin.services.MetricsSystem; + +import javax.inject.Singleton; + +import dagger.Module; +import dagger.Provides; + +@Module +public class NoOpMetricsSystemModule { + + @Provides + @Singleton + MetricsSystem provideMetricsSystem() { + return new NoOpMetricsSystem(); + } + + @Provides + @Singleton + ObservableMetricsSystem provideObservableMetricsSystem() { + return new NoOpMetricsSystem(); + } +} diff --git a/besu/src/test/java/org/hyperledger/besu/components/PrivacyParametersModule.java b/besu/src/test/java/org/hyperledger/besu/components/PrivacyParametersModule.java new file mode 100644 index 0000000000..0b8fcf744f --- /dev/null +++ b/besu/src/test/java/org/hyperledger/besu/components/PrivacyParametersModule.java @@ -0,0 +1,47 @@ +/* + * 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.components; + +import org.hyperledger.besu.enclave.EnclaveFactory; +import org.hyperledger.besu.ethereum.core.PrivacyParameters; +import org.hyperledger.besu.ethereum.privacy.storage.PrivacyStorageProvider; + +import java.net.URI; +import java.net.URISyntaxException; + +import dagger.Module; +import dagger.Provides; +import io.vertx.core.Vertx; + +/** Provides a general use PrivacyParameters instance for testing. */ +@Module +public class PrivacyParametersModule { + + @Provides + PrivacyParameters providePrivacyParameters( + final PrivacyStorageProvider storageProvider, final Vertx vertx) { + try { + return new PrivacyParameters.Builder() + .setEnabled(true) + .setEnclaveUrl(new URI("http://127.0.0.1:8000")) + .setStorageProvider(storageProvider) + .setEnclaveFactory(new EnclaveFactory(vertx)) + .setFlexiblePrivacyGroupsEnabled(false) + .build(); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + } +} diff --git a/besu/src/test/java/org/hyperledger/besu/components/PrivacyTestModule.java b/besu/src/test/java/org/hyperledger/besu/components/PrivacyTestModule.java new file mode 100644 index 0000000000..13cafe1ab4 --- /dev/null +++ b/besu/src/test/java/org/hyperledger/besu/components/PrivacyTestModule.java @@ -0,0 +1,111 @@ +/* + * 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.components; + +import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_BACKGROUND_THREAD_COUNT; +import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_CACHE_CAPACITY; +import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_IS_HIGH_SPEC; +import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_MAX_OPEN_FILES; + +import org.hyperledger.besu.ethereum.privacy.storage.PrivacyStorageProvider; +import org.hyperledger.besu.ethereum.privacy.storage.keyvalue.PrivacyKeyValueStorageProviderBuilder; +import org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier; +import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; +import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; +import org.hyperledger.besu.plugin.services.storage.rocksdb.RocksDBKeyValuePrivacyStorageFactory; +import org.hyperledger.besu.plugin.services.storage.rocksdb.RocksDBKeyValueStorageFactory; +import org.hyperledger.besu.plugin.services.storage.rocksdb.RocksDBMetricsFactory; +import org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBFactoryConfiguration; +import org.hyperledger.besu.services.BesuConfigurationImpl; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Arrays; +import javax.inject.Named; +import javax.inject.Singleton; + +import dagger.Module; +import dagger.Provides; +import io.vertx.core.Vertx; + +@Module +public class PrivacyTestModule { + + @Provides + @Named("dataDir") + Path provideDataDir() { + try { + return Files.createTempDirectory("PrivacyTestDatadir"); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Provides + Vertx provideVertx() { + return Vertx.vertx(); + } + + @Provides + DataStorageConfiguration provideDataStorageConfiguration() { + return DataStorageConfiguration.DEFAULT_FOREST_CONFIG; + } + + @Provides + @Singleton + @Named("dbDir") + Path provideDbDir(@Named("dataDir") final Path dataDir) { + try { + final Path dbDir = Files.createTempDirectory(dataDir, "database"); + return dbDir; + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Provides + @Singleton + @Named("flexibleEnabled") + Boolean provideFlexibleEnabled() { + return true; + } + + @Provides + @Singleton + @SuppressWarnings("CloseableProvides") + PrivacyStorageProvider provideKeyValueStorageProvider( + @Named("dbDir") final Path dbDir, + final DataStorageConfiguration dataStorageConfiguration, + @Named("dataDir") final Path dataDir) { + final var besuConfiguration = new BesuConfigurationImpl(); + besuConfiguration.init(dataDir, dbDir, dataStorageConfiguration); + return new PrivacyKeyValueStorageProviderBuilder() + .withStorageFactory( + new RocksDBKeyValuePrivacyStorageFactory( + new RocksDBKeyValueStorageFactory( + () -> + new RocksDBFactoryConfiguration( + DEFAULT_MAX_OPEN_FILES, + DEFAULT_BACKGROUND_THREAD_COUNT, + DEFAULT_CACHE_CAPACITY, + DEFAULT_IS_HIGH_SPEC), + Arrays.asList(KeyValueSegmentIdentifier.values()), + RocksDBMetricsFactory.PRIVATE_ROCKS_DB_METRICS))) + .withCommonConfiguration(besuConfiguration) + .withMetricsSystem(new NoOpMetricsSystem()) + .build(); + } +} diff --git a/besu/src/test/java/org/hyperledger/besu/controller/AbstractBftBesuControllerBuilderTest.java b/besu/src/test/java/org/hyperledger/besu/controller/AbstractBftBesuControllerBuilderTest.java index 731fd2ac56..c7caf62ec2 100644 --- a/besu/src/test/java/org/hyperledger/besu/controller/AbstractBftBesuControllerBuilderTest.java +++ b/besu/src/test/java/org/hyperledger/besu/controller/AbstractBftBesuControllerBuilderTest.java @@ -19,6 +19,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.mock; +import org.hyperledger.besu.components.BesuComponent; import org.hyperledger.besu.config.CheckpointConfigOptions; import org.hyperledger.besu.config.GenesisConfigFile; import org.hyperledger.besu.config.GenesisConfigOptions; @@ -157,6 +158,7 @@ public abstract class AbstractBftBesuControllerBuilderTest { .storageProvider(storageProvider) .gasLimitCalculator(gasLimitCalculator) .evmConfiguration(EvmConfiguration.DEFAULT) + .besuComponent(mock(BesuComponent.class)) .networkConfiguration(NetworkingConfiguration.create()); } diff --git a/besu/src/test/java/org/hyperledger/besu/controller/CliqueBesuControllerBuilderTest.java b/besu/src/test/java/org/hyperledger/besu/controller/CliqueBesuControllerBuilderTest.java index 82f98ba826..aa79b944a1 100644 --- a/besu/src/test/java/org/hyperledger/besu/controller/CliqueBesuControllerBuilderTest.java +++ b/besu/src/test/java/org/hyperledger/besu/controller/CliqueBesuControllerBuilderTest.java @@ -20,6 +20,7 @@ import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import org.hyperledger.besu.components.BesuComponent; import org.hyperledger.besu.config.CheckpointConfigOptions; import org.hyperledger.besu.config.GenesisConfigFile; import org.hyperledger.besu.config.GenesisConfigOptions; @@ -190,6 +191,7 @@ public class CliqueBesuControllerBuilderTest { .storageProvider(storageProvider) .gasLimitCalculator(gasLimitCalculator) .evmConfiguration(EvmConfiguration.DEFAULT) + .besuComponent(mock(BesuComponent.class)) .networkConfiguration(NetworkingConfiguration.create()); } diff --git a/besu/src/test/java/org/hyperledger/besu/controller/MergeBesuControllerBuilderTest.java b/besu/src/test/java/org/hyperledger/besu/controller/MergeBesuControllerBuilderTest.java index 0e4948ddd5..c788f41710 100644 --- a/besu/src/test/java/org/hyperledger/besu/controller/MergeBesuControllerBuilderTest.java +++ b/besu/src/test/java/org/hyperledger/besu/controller/MergeBesuControllerBuilderTest.java @@ -23,6 +23,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; +import org.hyperledger.besu.components.BesuComponent; import org.hyperledger.besu.config.CheckpointConfigOptions; import org.hyperledger.besu.config.GenesisConfigFile; import org.hyperledger.besu.config.GenesisConfigOptions; @@ -190,6 +191,7 @@ public class MergeBesuControllerBuilderTest { .storageProvider(storageProvider) .evmConfiguration(EvmConfiguration.DEFAULT) .networkConfiguration(NetworkingConfiguration.create()) + .besuComponent(mock(BesuComponent.class)) .networkId(networkId); } diff --git a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/peers/EnodeURLImpl.java b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/peers/EnodeURLImpl.java index e1d158f3fc..e087edd431 100644 --- a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/peers/EnodeURLImpl.java +++ b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/peers/EnodeURLImpl.java @@ -381,10 +381,11 @@ public class EnodeURLImpl implements EnodeURL { return ipAddress(ip, EnodeDnsConfiguration.dnsDisabled()); } - public Builder ipAddress(final String ip, final EnodeDnsConfiguration enodeDnsConfiguration) { + public Builder ipAddress( + final String hostField, final EnodeDnsConfiguration enodeDnsConfiguration) { if (enodeDnsConfiguration.dnsEnabled()) { try { - this.ip = InetAddress.getByName(ip); + this.ip = InetAddress.getByName(hostField); if (enodeDnsConfiguration.updateEnabled()) { if (this.ip.isLoopbackAddress()) { this.ip = InetAddress.getLocalHost(); @@ -398,10 +399,10 @@ public class EnodeURLImpl implements EnodeURL { this.ip = InetAddresses.forString("127.0.0.1"); } } - } else if (InetAddresses.isUriInetAddress(ip)) { - this.ip = InetAddresses.forUriString(ip); - } else if (InetAddresses.isInetAddress(ip)) { - this.ip = InetAddresses.forString(ip); + } else if (InetAddresses.isUriInetAddress(hostField)) { + this.ip = InetAddresses.forUriString(hostField); + } else if (InetAddresses.isInetAddress(hostField)) { + this.ip = InetAddresses.forString(hostField); } else { throw new IllegalArgumentException("Invalid ip address."); } From 541aacd200a4ad545fa9f50ed3a9a6374f5c3143 Mon Sep 17 00:00:00 2001 From: leeli Date: Mon, 5 Aug 2024 12:20:30 +0200 Subject: [PATCH 092/259] redirect the path in readme (#7422) Signed-off-by: Lee Co-authored-by: daniellehrner --- .../tests/simple-permissioning-smart-contract/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acceptance-tests/tests/simple-permissioning-smart-contract/README.md b/acceptance-tests/tests/simple-permissioning-smart-contract/README.md index 40dc739ed5..c6a92e2cff 100644 --- a/acceptance-tests/tests/simple-permissioning-smart-contract/README.md +++ b/acceptance-tests/tests/simple-permissioning-smart-contract/README.md @@ -18,7 +18,7 @@ cd acceptance-tests/simple-permissioning-smart-contract * Also this truffle.js uses address and private key generated by Ganache with default mnemonic "candy maple cake sugar pudding cream honey rich smooth crumble sweet treat" * To run the Truffle example with Besu, you need Besu running - * [check out and build Besu](../../README.md) + * [check out and build Besu](../../../README.md) * run Besu (either in IDE or via command line), with mining and RPC enabled. * Run Truffle migrate against Ganache From 7433c8c25a5c73440c668553befa5fc6363b0c6f Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Tue, 6 Aug 2024 01:23:01 -0600 Subject: [PATCH 093/259] Update newling handling in fuzzing CLI tools (#7428) * Fuzzing initcode fix Make sure each response has a newline Signed-off-by: Danno Ferrin * correct blank line handling Signed-off-by: Danno Ferrin * correct blank line handling Signed-off-by: Danno Ferrin --------- Signed-off-by: Danno Ferrin --- .../besu/evmtool/CodeValidateSubCommand.java | 18 ++++++++++++------ .../besu/evmtool/code-validate/initcode.json | 2 +- 2 files changed, 13 insertions(+), 7 deletions(-) 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 3bc2d41d02..962fc2804b 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 @@ -39,6 +39,7 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; import org.apache.tuweni.bytes.Bytes; +import org.web3j.utils.Strings; import picocli.CommandLine; import picocli.CommandLine.ParentCommand; @@ -107,7 +108,10 @@ public class CodeValidateSubCommand implements Runnable { } } else { for (String code : cliCode) { - parentCommand.out.print(considerCode(code)); + String validation = considerCode(code); + if (!Strings.isBlank(validation)) { + parentCommand.out.println(validation); + } } } parentCommand.out.flush(); @@ -116,7 +120,10 @@ public class CodeValidateSubCommand implements Runnable { private void checkCodeFromBufferedReader(final BufferedReader in) { try { for (String code = in.readLine(); code != null; code = in.readLine()) { - parentCommand.out.print(considerCode(code)); + String validation = considerCode(code); + if (!Strings.isBlank(validation)) { + parentCommand.out.println(validation); + } } } catch (IOException e) { throw new RuntimeException(e); @@ -142,7 +149,7 @@ public class CodeValidateSubCommand implements Runnable { Bytes.fromHexString( hexCode.replaceAll("(^|\n)#[^\n]*($|\n)", "").replaceAll("[^0-9A-Za-z]", "")); } catch (RuntimeException re) { - return "err: hex string -" + re + "\n"; + return "err: hex string -" + re; } if (codeBytes.isEmpty()) { return ""; @@ -150,7 +157,7 @@ public class CodeValidateSubCommand implements Runnable { EOFLayout layout = evm.parseEOF(codeBytes); if (!layout.isValid()) { - return "err: layout - " + layout.invalidReason() + "\n"; + return "err: layout - " + layout.invalidReason(); } Code code = evm.getCodeUncached(codeBytes); @@ -165,8 +172,7 @@ public class CodeValidateSubCommand implements Runnable { .mapToObj(code::getCodeSection) .map(cs -> code.getBytes().slice(cs.getEntryPoint(), cs.getLength())) .map(Bytes::toUnprefixedHexString) - .collect(Collectors.joining(",")) - + "\n"; + .collect(Collectors.joining(",")); } } } diff --git a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/code-validate/initcode.json b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/code-validate/initcode.json index c119235cdc..5ecd5511a5 100644 --- a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/code-validate/initcode.json +++ b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/code-validate/initcode.json @@ -3,5 +3,5 @@ "code-validate" ], "stdin": "ef000101000402000100060300010014040000000080000260006000ee00ef00010100040200010001040000000080000000", - "stdout": "err: code is valid initcode. Runtime code expected" + "stdout": "err: code is valid initcode. Runtime code expected\n" } From a92fdbb44c4c20416643903d9fa288ffdc4929b6 Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Tue, 6 Aug 2024 18:37:29 -0600 Subject: [PATCH 094/259] EVMTool Docker Support (#7430) A few fixes that re-enable docker support for evm tool * evmtool is the entrypoint * turn off some noisy logging * ensure EOF respects the create flag Signed-off-by: Danno Ferrin --- CHANGELOG.md | 1 + ethereum/evmtool/src/main/docker/Dockerfile | 2 +- .../org/hyperledger/besu/evmtool/EvmTool.java | 2 +- .../besu/evmtool/EvmToolCommand.java | 14 +++++++++++++- .../besu/evmtool/trace/create-eof-error.json | 15 +++++++++++++++ .../org/hyperledger/besu/evmtool/trace/eof.json | 17 +++++++++++++++++ .../besu/evmtool/trace/initcode-error.json | 14 ++++++++++++++ 7 files changed, 62 insertions(+), 3 deletions(-) create mode 100644 ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/create-eof-error.json create mode 100644 ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/eof.json create mode 100644 ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/initcode-error.json diff --git a/CHANGELOG.md b/CHANGELOG.md index 0db9e9df3f..bae9c5b77c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ - In process RPC service [#7395](https://github.com/hyperledger/besu/pull/7395) ### Bug fixes +- Correct entrypoint in Docker evmtool [#7430](https://github.com/hyperledger/besu/pull/7430) ## 24.7.1 diff --git a/ethereum/evmtool/src/main/docker/Dockerfile b/ethereum/evmtool/src/main/docker/Dockerfile index 9d7b48d3cb..b16407be29 100644 --- a/ethereum/evmtool/src/main/docker/Dockerfile +++ b/ethereum/evmtool/src/main/docker/Dockerfile @@ -24,7 +24,7 @@ WORKDIR /opt/besu-evmtool COPY --chown=besu:besu besu-evmtool /opt/besu-evmtool/ ENV PATH="/opt/besu-evmtool/bin:${PATH}" -ENTRYPOINT ["evm"] +ENTRYPOINT ["evmtool"] # Build-time metadata as defined at http://label-schema.org ARG BUILD_DATE diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EvmTool.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EvmTool.java index dec0555640..1263207028 100644 --- a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EvmTool.java +++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EvmTool.java @@ -28,7 +28,7 @@ public final class EvmTool { * @param args The command line arguments. */ public static void main(final String... args) { - LogConfigurator.setLevel("", "DEBUG"); + LogConfigurator.setLevel("", "OFF"); final EvmToolCommand evmToolCommand = new EvmToolCommand(); evmToolCommand.execute(args); 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 898f1dd4b6..989c6e0b7f 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 @@ -15,6 +15,7 @@ package org.hyperledger.besu.evmtool; import static java.nio.charset.StandardCharsets.UTF_8; +import static org.hyperledger.besu.evm.code.EOFLayout.EOFContainerMode.INITCODE; import static picocli.CommandLine.ScopeType.INHERIT; import org.hyperledger.besu.cli.config.NetworkName; @@ -34,6 +35,7 @@ import org.hyperledger.besu.evm.Code; import org.hyperledger.besu.evm.EVM; import org.hyperledger.besu.evm.EvmSpecVersion; import org.hyperledger.besu.evm.code.CodeInvalid; +import org.hyperledger.besu.evm.code.CodeV1; import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.log.LogsBloomFilter; import org.hyperledger.besu.evm.tracing.OperationTracer; @@ -418,11 +420,21 @@ public class EvmToolCommand implements Runnable { if (codeBytes.isEmpty() && !createTransaction) { codeBytes = component.getWorldState().get(receiver).getCode(); } - Code code = evm.getCodeForCreation(codeBytes); + Code code = + createTransaction ? evm.getCodeForCreation(codeBytes) : evm.getCodeUncached(codeBytes); if (!code.isValid()) { out.println(((CodeInvalid) code).getInvalidReason()); return; + } else if (code.getEofVersion() == 1 + && createTransaction + != INITCODE.equals(((CodeV1) code).getEofLayout().containerMode().get())) { + out.println( + createTransaction + ? "--create requires EOF in INITCODE mode" + : "To evaluate INITCODE mode EOF code use the --create flag"); + return; } + final Stopwatch stopwatch = Stopwatch.createUnstarted(); long lastTime = 0; do { 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 new file mode 100644 index 0000000000..58402eeaa4 --- /dev/null +++ b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/create-eof-error.json @@ -0,0 +1,15 @@ +{ + "cli": [ + "--notime", + "--json", + "--create", + "--code", + "ef00010100040200010001040000000080000000c0de471fe5", + "--coinbase", + "4444588443C3A91288C5002483449ABA1054192B", + "--fork", + "CancunEOF" + ], + "stdin": "", + "stdout": "EOF Code Invalid : STOP is only a valid opcode in containers used for runtime operations.\n" +} \ 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 new file mode 100644 index 0000000000..ff9bf415e6 --- /dev/null +++ b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/eof.json @@ -0,0 +1,17 @@ +{ + "cli": [ + "--notime", + "--json", + "--code", + "ef00010100040200010001040000000080000000", + "--coinbase", + "4444588443C3A91288C5002483449ABA1054192B", + "--fork", + "CancunEOF" + ], + "stdin": "", + "stdout": [ + {"pc":0,"section":0,"op":0,"gas":"0x2540be400","gasCost":"0x0","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"STOP"}, + {"gasUser":"0x0","gasTotal":"0x0","output":"0x"} + ] +} \ 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 new file mode 100644 index 0000000000..b88134778e --- /dev/null +++ b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/initcode-error.json @@ -0,0 +1,14 @@ +{ + "cli": [ + "--notime", + "--json", + "--code", + "ef00010100040200010009030001001404000000008000035f355f5fa15f5fee00ef00010100040200010001040000000080000000", + "--coinbase", + "4444588443C3A91288C5002483449ABA1054192B", + "--fork", + "CancunEOF" + ], + "stdin": "", + "stdout": "To evaluate INITCODE mode EOF code use the --create flag\n" +} \ No newline at end of file From 745d353027ff2998b22413ad6ca6bba7a2180699 Mon Sep 17 00:00:00 2001 From: Lucas Saldanha Date: Fri, 9 Aug 2024 09:41:07 +1200 Subject: [PATCH 095/259] Restore previous behaviour for preMergeBesuControllerBuilder (#7431) --- CHANGELOG.md | 1 + .../besu/controller/TransitionBesuControllerBuilder.java | 9 ++++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bae9c5b77c..6a97946652 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ ### Bug fixes - Correct entrypoint in Docker evmtool [#7430](https://github.com/hyperledger/besu/pull/7430) +- Fix behaviour when starting in a pre-merge network [#7431](https://github.com/hyperledger/besu/pull/7431) ## 24.7.1 diff --git a/besu/src/main/java/org/hyperledger/besu/controller/TransitionBesuControllerBuilder.java b/besu/src/main/java/org/hyperledger/besu/controller/TransitionBesuControllerBuilder.java index d7b701b4c5..251ffba1c2 100644 --- a/besu/src/main/java/org/hyperledger/besu/controller/TransitionBesuControllerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/controller/TransitionBesuControllerBuilder.java @@ -30,6 +30,7 @@ import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.blockcreation.MiningCoordinator; import org.hyperledger.besu.ethereum.chain.Blockchain; import org.hyperledger.besu.ethereum.chain.MutableBlockchain; +import org.hyperledger.besu.ethereum.core.ImmutableMiningParameters; import org.hyperledger.besu.ethereum.core.MiningParameters; import org.hyperledger.besu.ethereum.core.PrivacyParameters; import org.hyperledger.besu.ethereum.eth.EthProtocolConfiguration; @@ -129,7 +130,13 @@ public class TransitionBesuControllerBuilder extends BesuControllerBuilder { transitionProtocolSchedule.getPreMergeSchedule(), protocolContext, transactionPool, - MiningParameters.MINING_DISABLED, + ImmutableMiningParameters.builder() + .from(miningParameters) + .mutableInitValues( + ImmutableMiningParameters.MutableInitValues.builder() + .isMiningEnabled(false) + .build()) + .build(), syncState, ethProtocolManager), mergeBesuControllerBuilder.createTransitionMiningCoordinator( From 8fc80ade8d2bdc9d4da84a896dcec317e112b416 Mon Sep 17 00:00:00 2001 From: sirawt <31649128+MASDXI@users.noreply.github.com> Date: Mon, 12 Aug 2024 07:23:33 +0700 Subject: [PATCH 096/259] chore: fix some typos (#7438) Signed-off-by: MASDXI --- .../besu/controller/TransitionBesuControllerBuilder.java | 6 +++--- .../hyperledger/besu/services/RlpConverterServiceImpl.java | 2 +- .../besu/ethereum/privacy/PrivateStateGenesisAllocator.java | 6 +++--- .../main/java/org/hyperledger/besu/evm/EvmSpecVersion.java | 2 +- .../java/org/hyperledger/besu/evm/fluent/EVMExecutor.java | 2 +- .../besu/nat/kubernetes/KubernetesNatManager.java | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/besu/src/main/java/org/hyperledger/besu/controller/TransitionBesuControllerBuilder.java b/besu/src/main/java/org/hyperledger/besu/controller/TransitionBesuControllerBuilder.java index 251ffba1c2..ee2611d9c8 100644 --- a/besu/src/main/java/org/hyperledger/besu/controller/TransitionBesuControllerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/controller/TransitionBesuControllerBuilder.java @@ -413,9 +413,9 @@ public class TransitionBesuControllerBuilder extends BesuControllerBuilder { return propagateConfig(z -> z.dataStorageConfiguration(dataStorageConfiguration)); } - private BesuControllerBuilder propagateConfig(final Consumer toPropogate) { - toPropogate.accept(preMergeBesuControllerBuilder); - toPropogate.accept(mergeBesuControllerBuilder); + private BesuControllerBuilder propagateConfig(final Consumer toPropagate) { + toPropagate.accept(preMergeBesuControllerBuilder); + toPropagate.accept(mergeBesuControllerBuilder); return this; } } diff --git a/besu/src/main/java/org/hyperledger/besu/services/RlpConverterServiceImpl.java b/besu/src/main/java/org/hyperledger/besu/services/RlpConverterServiceImpl.java index 53b3541a5b..d7a7b1ce66 100644 --- a/besu/src/main/java/org/hyperledger/besu/services/RlpConverterServiceImpl.java +++ b/besu/src/main/java/org/hyperledger/besu/services/RlpConverterServiceImpl.java @@ -25,7 +25,7 @@ import org.hyperledger.besu.plugin.services.rlp.RlpConverterService; import org.apache.tuweni.bytes.Bytes; -/** RLP Serialiaztion/Deserialization service. */ +/** RLP Serialization/Deserialization service. */ public class RlpConverterServiceImpl implements RlpConverterService { private final BlockHeaderFunctions blockHeaderFunctions; diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateStateGenesisAllocator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateStateGenesisAllocator.java index f1a022fa7c..e011329c07 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateStateGenesisAllocator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateStateGenesisAllocator.java @@ -95,13 +95,13 @@ public class PrivateStateGenesisAllocator { managementContract.setCode(FlexibleGroupManagement.DEFAULT_GROUP_MANAGEMENT_RUNTIME_BYTECODE); // inject proxy - final MutableAccount procyContract = + final MutableAccount proxyContract = privateWorldStateUpdater.createAccount(FLEXIBLE_PRIVACY_PROXY); // this is the code for the proxy contract - procyContract.setCode(FlexibleGroupManagement.PROXY_RUNTIME_BYTECODE); + proxyContract.setCode(FlexibleGroupManagement.PROXY_RUNTIME_BYTECODE); // manually set the management contract address so the proxy can trust it - procyContract.setStorageValue( + proxyContract.setStorageValue( UInt256.ZERO, UInt256.fromBytes(Bytes32.leftPad(DEFAULT_FLEXIBLE_PRIVACY_MANAGEMENT))); } 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 8dc536c7bf..5368a7fd74 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/EvmSpecVersion.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/EvmSpecVersion.java @@ -63,7 +63,7 @@ public enum EvmSpecVersion { PRAGUE_EOF(0x6000, 0xc000, 1, false, "PragueEOF", "Prague + EOF. In Development"), /** Osaka evm spec version. */ OSAKA(0x6000, 0xc000, 1, false, "Osaka", "Placeholder"), - /** Amstedam evm spec version. */ + /** Amsterdam evm spec version. */ AMSTERDAM(0x6000, 0xc000, 1, false, "Amsterdam", "Placeholder"), /** Bogota evm spec version. */ BOGOTA(0x6000, 0xc000, 1, false, "Bogota", "Placeholder"), 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 ee80bc2d77..a046198043 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 @@ -1225,7 +1225,7 @@ public class EVMExecutor { } /** - * Returns the ChaindD this executor is using + * Returns the ChainID this executor is using * * @return the current chain ID */ 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 0cf6bc4f76..f8af2bdddb 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 @@ -42,7 +42,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * This class describes the behaviour of the Kubernetes NAT manager. Kubernetes Nat manager add + * This class describes the behavior of the Kubernetes NAT manager. Kubernetes Nat manager add * support for Kubernetes’s NAT implementation when Besu is being run from a Kubernetes cluster */ public class KubernetesNatManager extends AbstractNatManager { From 067be8cccc0b28f4675c6b465e05fe22005bd528 Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Mon, 12 Aug 2024 10:46:29 +1000 Subject: [PATCH 097/259] 5098 branch 7 update invalid blob gas used params (#7408) * 5098: Add RpcErrorTypes Signed-off-by: Matilda Clerke --------- Signed-off-by: Matilda Clerke Signed-off-by: Matilda-Clerke Co-authored-by: Sally MacFarlane --- .../internal/methods/engine/AbstractEngineNewPayload.java | 2 +- .../internal/methods/engine/EngineNewPayloadV2.java | 2 +- .../internal/methods/engine/EngineNewPayloadV3.java | 5 ++++- .../internal/methods/engine/EngineNewPayloadV4.java | 8 ++++++-- .../internal/methods/engine/EngineNewPayloadV2Test.java | 5 +++-- .../internal/methods/engine/EngineNewPayloadV3Test.java | 2 +- 6 files changed, 16 insertions(+), 8 deletions(-) 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 68adb2ab69..c548507710 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 @@ -497,7 +497,7 @@ public abstract class AbstractEngineNewPayload extends ExecutionEngineJsonRpcMet if (header.getBlobGasUsed().isPresent() && maybeVersionedHashes.isPresent()) { if (!validateBlobGasUsed(header, maybeVersionedHashes.get(), protocolSpec)) { return ValidationResult.invalid( - RpcErrorType.INVALID_PARAMS, + RpcErrorType.INVALID_BLOB_GAS_USED_PARAMS, "Payload BlobGasUsed does not match calculated BlobGasUsed"); } } 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 08a6b6b3d0..640d8dc603 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 @@ -56,7 +56,7 @@ public class EngineNewPayloadV2 extends AbstractEngineNewPayload { final Optional maybeBeaconBlockRootParam) { if (payloadParameter.getBlobGasUsed() != null) { return ValidationResult.invalid( - RpcErrorType.INVALID_PARAMS, "non-null BlobGasUsed pre-cancun"); + RpcErrorType.INVALID_BLOB_GAS_USED_PARAMS, "Missing blob gas used field"); } if (payloadParameter.getExcessBlobGas() != null) { return ValidationResult.invalid( 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 8f7a32899e..1ca232b773 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,10 @@ public class EngineNewPayloadV3 extends AbstractEngineNewPayload { final EnginePayloadParameter payloadParameter, final Optional> maybeVersionedHashParam, final Optional maybeBeaconBlockRootParam) { - if (payloadParameter.getBlobGasUsed() == null || payloadParameter.getExcessBlobGas() == null) { + if (payloadParameter.getBlobGasUsed() == null) { + return ValidationResult.invalid( + RpcErrorType.INVALID_BLOB_GAS_USED_PARAMS, "Missing blob gas used field"); + } else if (payloadParameter.getExcessBlobGas() == null) { return ValidationResult.invalid(RpcErrorType.INVALID_PARAMS, "Missing blob gas fields"); } else if (maybeVersionedHashParam == null || maybeVersionedHashParam.isEmpty()) { return ValidationResult.invalid( 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 93060821f8..8b073a9555 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,8 +55,12 @@ public class EngineNewPayloadV4 extends AbstractEngineNewPayload { final EnginePayloadParameter payloadParameter, final Optional> maybeVersionedHashParam, final Optional maybeBeaconBlockRootParam) { - if (payloadParameter.getBlobGasUsed() == null || payloadParameter.getExcessBlobGas() == null) { - return ValidationResult.invalid(RpcErrorType.INVALID_PARAMS, "Missing blob gas fields"); + if (payloadParameter.getBlobGasUsed() == null) { + return ValidationResult.invalid( + RpcErrorType.INVALID_BLOB_GAS_USED_PARAMS, "Missing blob gas used field"); + } else if (payloadParameter.getExcessBlobGas() == null) { + return ValidationResult.invalid( + RpcErrorType.INVALID_PARAMS, "non-null ExcessBlobGas pre-cancun"); } else if (maybeVersionedHashParam == null || maybeVersionedHashParam.isEmpty()) { return ValidationResult.invalid( RpcErrorType.INVALID_PARAMS, "Missing versioned hashes field"); 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 412dc6f892..afee556eda 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 @@ -17,6 +17,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.methods.ExecutionEngineJsonRpcMethod.EngineStatus.INVALID; import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.WithdrawalParameterTestFixture.WITHDRAWAL_PARAM_1; +import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType.INVALID_BLOB_GAS_USED_PARAMS; import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType.INVALID_PARAMS; import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.mock; @@ -149,8 +150,8 @@ public class EngineNewPayloadV2Test extends AbstractEngineNewPayloadTest { var resp = resp(mockEnginePayload(blockHeader, Collections.emptyList(), List.of(), null, null, null)); final JsonRpcError jsonRpcError = fromErrorResp(resp); - assertThat(jsonRpcError.getCode()).isEqualTo(INVALID_PARAMS.getCode()); - assertThat(jsonRpcError.getData()).isEqualTo("non-null BlobGasUsed pre-cancun"); + assertThat(jsonRpcError.getCode()).isEqualTo(INVALID_BLOB_GAS_USED_PARAMS.getCode()); + assertThat(jsonRpcError.getData()).isEqualTo("Missing blob gas used field"); verify(engineCallListener, times(1)).executionEngineCalled(); } 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 c19bb8fbcb..8202588817 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 @@ -198,7 +198,7 @@ public class EngineNewPayloadV3Test extends EngineNewPayloadV2Test { final JsonRpcError jsonRpcError = fromErrorResp(resp); assertThat(jsonRpcError.getCode()).isEqualTo(INVALID_PARAMS.getCode()); - assertThat(jsonRpcError.getData()).isEqualTo("Missing blob gas fields"); + assertThat(jsonRpcError.getData()).isEqualTo("Missing blob gas used field"); verify(engineCallListener, times(1)).executionEngineCalled(); } From bca34cb61f0acf3f1ab163e85ce3c3e0ef7ebe69 Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Mon, 12 Aug 2024 14:16:53 +1000 Subject: [PATCH 098/259] 5098 branch 8 update invalid block params (#7409) * 5098: Add RpcErrorTypes Signed-off-by: Matilda Clerke * 5098: Modify InvalidJsonRpcParameters and InvalidJsonRpcRequestException, apply spotless Signed-off-by: Matilda Clerke * 5098: Modify InvalidJsonRpcParameters and InvalidJsonRpcRequestException, apply spotless Signed-off-by: Matilda Clerke * 5098: Add JsonRpcParameterException for later use Signed-off-by: Matilda Clerke * 5098: Update locations for RpcErrorType.INVALID_ACCOUNTS_PARAMS Signed-off-by: Matilda Clerke * 5098: Address review comments, apply spotless Signed-off-by: Matilda Clerke * 5098: Update with changes from branch 1 Signed-off-by: Matilda Clerke * 5098: Update code to use RpcErrorType.INVALID_ADDRESS_HASH_PARAMS Signed-off-by: Matilda Clerke * 5098: apply spotless Signed-off-by: Matilda Clerke * 5098: apply spotless Signed-off-by: Matilda Clerke * 5098: Update plugin-api gradle hash Signed-off-by: Matilda Clerke * 5098: Add comment on INVALID_PARAMS_ERROR_CODE Signed-off-by: Matilda Clerke * 5098: Apply spotless on latest changes Signed-off-by: Matilda Clerke * 5098: Update code to use RpcErrorType.INVALID_ADDRESS_PARAMS Signed-off-by: Matilda Clerke * 5098: Fix broken unit test Signed-off-by: Matilda Clerke * 5098: Fix broken unit test Signed-off-by: Matilda Clerke * 5098: Update with usage of RpcErrorType.INVALID_AUTH_PARAMS Signed-off-by: Matilda Clerke * 5098: Update with usage of RpcErrorType.INVALID_BLOB_COUNT Signed-off-by: Matilda Clerke * 5098: Update with usage of RpcErrorType.INVALID_BLOB_GAS_USED_PARAMS Signed-off-by: Matilda Clerke * 5098: Update with usage of RpcErrorType.INVALID_BLOCK_PARAMS Signed-off-by: Matilda Clerke * 5098: Update with usage of RpcErrorType.INVALID_BLOCK_PARAMS Signed-off-by: Matilda Clerke * 5098: Update with usage of RpcErrorType.INVALID_BLOCK_PARAMS Signed-off-by: Matilda Clerke * 5098: Fix broken integration test Signed-off-by: Matilda Clerke * 5098: Add index to exception messages Signed-off-by: Matilda Clerke * 5098: apoply spotless Signed-off-by: Matilda Clerke * 5098: Update BaseJsonRpcProcessor to utilise RpcErrorType from InvalidJsonRpcParameters Signed-off-by: Matilda Clerke * 5098: Include parameter index in INVALID_AUTH_PARAMS Signed-off-by: Matilda Clerke * 5098: Include parameter index in INVALID_BLOCK_PARAMS Signed-off-by: Matilda Clerke * 5098: Fix broken integration test Signed-off-by: Matilda Clerke * 5098: Rename INVALID_AUTH_PARAMS to INVALID_PROPOSAL_PARAMS Signed-off-by: Matilda Clerke * 5098: apply spotless Signed-off-by: Matilda Clerke * 5098: Fix broken unit test Signed-off-by: Matilda Clerke * 5098: Fix broken tests Signed-off-by: Matilda Clerke * 5098: Fix broken tests Signed-off-by: Matilda Clerke * 5098: Fix broken tests Signed-off-by: Matilda Clerke * 5098: Fix broken tests Signed-off-by: Matilda Clerke --------- Signed-off-by: Matilda Clerke Signed-off-by: Matilda-Clerke Co-authored-by: Sally MacFarlane --- .../jsonrpc/methods/CliqueGetSigners.java | 10 ++++++++-- .../IbftGetValidatorsByBlockNumber.java | 9 ++++++++- .../QbftGetValidatorsByBlockNumber.java | 9 ++++++++- .../EthGetBlockByNumberIntegrationTest.java | 8 +++----- .../jsonrpc/internal/DebugReplayBlock.java | 9 ++++++++- .../methods/AbstractTraceByBlock.java | 11 ++++++++-- .../methods/AdminGenerateLogBloomCache.java | 20 +++++++++++++++---- .../internal/methods/DebugAccountAt.java | 7 ++++++- .../internal/methods/DebugAccountRange.java | 12 +++++++++-- .../internal/methods/DebugGetRawBlock.java | 8 +++++++- .../internal/methods/DebugGetRawHeader.java | 8 +++++++- .../internal/methods/DebugGetRawReceipts.java | 9 ++++++++- .../internal/methods/DebugSetHead.java | 9 ++++++++- .../internal/methods/DebugStorageRangeAt.java | 10 ++++++++-- .../internal/methods/DebugTraceBlock.java | 8 ++++++-- .../methods/DebugTraceBlockByNumber.java | 9 ++++++++- .../internal/methods/DebugTraceCall.java | 11 ++++++++-- .../api/jsonrpc/internal/methods/EthCall.java | 8 +++++++- .../internal/methods/EthFeeHistory.java | 9 ++++++++- .../internal/methods/EthGetBalance.java | 7 ++++++- .../internal/methods/EthGetBlockByNumber.java | 9 ++++++++- .../internal/methods/EthGetBlockReceipts.java | 9 ++++++++- .../EthGetBlockTransactionCountByNumber.java | 9 ++++++++- .../jsonrpc/internal/methods/EthGetCode.java | 7 ++++++- .../methods/EthGetMinerDataByBlockNumber.java | 9 ++++++++- .../jsonrpc/internal/methods/EthGetProof.java | 7 ++++++- .../internal/methods/EthGetStorageAt.java | 7 ++++++- ...thGetTransactionByBlockNumberAndIndex.java | 9 ++++++++- .../methods/EthGetTransactionCount.java | 7 ++++++- .../EthGetUncleByBlockNumberAndIndex.java | 9 ++++++++- .../methods/EthSendRawTransaction.java | 2 +- .../jsonrpc/internal/methods/TraceBlock.java | 9 ++++++++- .../internal/methods/TraceCallMany.java | 10 ++++++++-- .../methods/TraceReplayBlockTransactions.java | 9 ++++++++- .../privacy/methods/priv/PrivCall.java | 7 ++++++- .../methods/priv/PrivDebugGetStateRoot.java | 8 +++++++- .../privacy/methods/priv/PrivGetCode.java | 7 ++++++- .../api/jsonrpc/JsonRpcHttpServiceTest.java | 2 +- .../methods/EthGetBlockByNumberTest.java | 3 +-- .../methods/EthGetBlockReceiptsTest.java | 2 +- .../EthGetMinerDataByBlockNumberTest.java | 4 ++-- .../internal/methods/EthGetProofTest.java | 2 +- .../EthGetUncleByBlockNumberAndIndexTest.java | 2 +- .../eth_call_callParamsMissing_block_8.json | 2 +- .../eth/eth_call_invalidBlockhash.json | 2 +- .../eth/eth_getBalance_invalidBlockHash.json | 2 +- .../eth/eth_getBalance_invalidParams.json | 2 +- ...ockReceipts_invalidParams_blockNumber.json | 2 +- ...th_getBlockReceipts_invalidParams_tag.json | 2 +- ...ransactionCountByNumber_invalidParams.json | 2 +- .../eth/eth_getCode_invalidBlockHash.json | 2 +- .../eth/eth_getCode_invalidParams.json | 2 +- .../eth/eth_getProof_invalidBlockHash.json | 2 +- .../eth/eth_getProof_invalidParams.json | 2 +- .../eth_getStorageAt_invalidBlockHash.json | 2 +- .../eth/eth_getStorageAt_invalidParams.json | 2 +- ...onByBlockNumberAndIndex_invalidParams.json | 2 +- ..._getTransactionCount_invalidBlockHash.json | 2 +- ...etTransactionCount_invalidBlockNumber.json | 2 +- ...h_getTransactionCount_missingArgument.json | 2 +- ...ayBlockTransactions_invalidBlockParam.json | 2 +- .../retesteth/methods/TestImportRawBlock.java | 9 ++++++++- 62 files changed, 307 insertions(+), 78 deletions(-) diff --git a/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/CliqueGetSigners.java b/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/CliqueGetSigners.java index 9f7b2d9f9d..813c296098 100644 --- a/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/CliqueGetSigners.java +++ b/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/CliqueGetSigners.java @@ -17,6 +17,7 @@ package org.hyperledger.besu.consensus.clique.jsonrpc.methods; import org.hyperledger.besu.consensus.common.validator.ValidatorProvider; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; @@ -67,8 +68,13 @@ public class CliqueGetSigners implements JsonRpcMethod { } private Optional determineBlockHeader(final JsonRpcRequestContext request) { - final Optional blockParameter = - request.getOptionalParameter(0, BlockParameter.class); + final Optional blockParameter; + try { + blockParameter = request.getOptionalParameter(0, BlockParameter.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid block parameter (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e); + } final long latest = blockchainQueries.headBlockNumber(); final long blockNumber = blockParameter.map(b -> b.getNumber().orElse(latest)).orElse(latest); return blockchainQueries.blockByNumber(blockNumber).map(BlockWithMetadata::getHeader); diff --git a/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftGetValidatorsByBlockNumber.java b/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftGetValidatorsByBlockNumber.java index 5e36ca2070..7992f0918c 100644 --- a/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftGetValidatorsByBlockNumber.java +++ b/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftGetValidatorsByBlockNumber.java @@ -17,9 +17,11 @@ package org.hyperledger.besu.consensus.ibft.jsonrpc.methods; import org.hyperledger.besu.consensus.common.BlockInterface; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.AbstractBlockParameterMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; import org.hyperledger.besu.ethereum.core.BlockHeader; @@ -50,7 +52,12 @@ public class IbftGetValidatorsByBlockNumber extends AbstractBlockParameterMethod @Override protected BlockParameter blockParameter(final JsonRpcRequestContext request) { - return request.getRequiredParameter(0, BlockParameter.class); + try { + return request.getRequiredParameter(0, BlockParameter.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid block parameter (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e); + } } @Override diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftGetValidatorsByBlockNumber.java b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftGetValidatorsByBlockNumber.java index 804ecc6b5a..7a64a7ab22 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftGetValidatorsByBlockNumber.java +++ b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftGetValidatorsByBlockNumber.java @@ -18,9 +18,11 @@ import org.hyperledger.besu.consensus.common.validator.ValidatorProvider; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.AbstractBlockParameterMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; import org.hyperledger.besu.ethereum.core.BlockHeader; @@ -50,7 +52,12 @@ public class QbftGetValidatorsByBlockNumber extends AbstractBlockParameterMethod @Override protected BlockParameter blockParameter(final JsonRpcRequestContext request) { - return request.getRequiredParameter(0, BlockParameter.class); + try { + return request.getRequiredParameter(0, BlockParameter.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid block parameter (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e); + } } @Override diff --git a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/frontier/EthGetBlockByNumberIntegrationTest.java b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/frontier/EthGetBlockByNumberIntegrationTest.java index a7c3aa254e..9f76609fd7 100644 --- a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/frontier/EthGetBlockByNumberIntegrationTest.java +++ b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/frontier/EthGetBlockByNumberIntegrationTest.java @@ -410,7 +410,7 @@ public class EthGetBlockByNumberIntegrationTest { assertThat(thrown) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Invalid json rpc parameter at index 0"); + .hasMessageContaining("Invalid block parameter"); } /** The Tag | Quantity is the first parameter, either a String or a number */ @@ -422,7 +422,7 @@ public class EthGetBlockByNumberIntegrationTest { assertThat(thrown) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Invalid json rpc parameter at index 0"); + .hasMessageContaining("Invalid block parameter"); } /** @@ -437,7 +437,6 @@ public class EthGetBlockByNumberIntegrationTest { assertThat(thrown) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasNoCause() .hasMessage("Missing required json rpc parameter at index 1"); } @@ -453,8 +452,7 @@ public class EthGetBlockByNumberIntegrationTest { assertThat(thrown) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasNoCause() - .hasMessage("Missing required json rpc parameter at index 0"); + .hasMessage("Invalid block parameter (index 0)"); } private JsonRpcRequestContext requestWithParams(final Object... params) { diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/DebugReplayBlock.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/DebugReplayBlock.java index e55a8c4785..6dbf9f586f 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/DebugReplayBlock.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/DebugReplayBlock.java @@ -19,10 +19,12 @@ import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErr import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.AbstractBlockParameterMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; import org.hyperledger.besu.ethereum.core.Block; import org.hyperledger.besu.ethereum.mainnet.HeaderValidationMode; @@ -56,7 +58,12 @@ public class DebugReplayBlock extends AbstractBlockParameterMethod { @Override protected BlockParameter blockParameter(final JsonRpcRequestContext request) { - return request.getRequiredParameter(0, BlockParameter.class); + try { + return request.getRequiredParameter(0, BlockParameter.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid block parameter (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e); + } } @Override diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AbstractTraceByBlock.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AbstractTraceByBlock.java index 4fd98cd4fe..a596521175 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AbstractTraceByBlock.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AbstractTraceByBlock.java @@ -17,9 +17,11 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.TraceTypeParameter.TraceType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.TraceTypeParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.TransactionTrace; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.TraceCallResult; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.tracing.diff.StateDiffGenerator; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.tracing.diff.StateDiffTrace; @@ -62,8 +64,13 @@ public abstract class AbstractTraceByBlock extends AbstractBlockParameterMethod @Override protected BlockParameter blockParameter(final JsonRpcRequestContext request) { - final Optional maybeBlockParameter = - request.getOptionalParameter(2, BlockParameter.class); + final Optional maybeBlockParameter; + try { + maybeBlockParameter = request.getOptionalParameter(2, BlockParameter.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid block parameter (index 2)", RpcErrorType.INVALID_BLOCK_PARAMS, e); + } if (maybeBlockParameter.isPresent()) { return maybeBlockParameter.get(); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminGenerateLogBloomCache.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminGenerateLogBloomCache.java index fd197110b6..437f7f5821 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminGenerateLogBloomCache.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminGenerateLogBloomCache.java @@ -16,9 +16,11 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; 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.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; import java.util.Optional; @@ -38,8 +40,13 @@ public class AdminGenerateLogBloomCache implements JsonRpcMethod { @Override public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { - final Optional startBlockParam = - requestContext.getOptionalParameter(0, BlockParameter.class); + final Optional startBlockParam; + try { + startBlockParam = requestContext.getOptionalParameter(0, BlockParameter.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid start block parameter (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e); + } final long startBlock; if (startBlockParam.isEmpty() || startBlockParam.get().isEarliest()) { startBlock = 0; @@ -50,8 +57,13 @@ public class AdminGenerateLogBloomCache implements JsonRpcMethod { startBlock = Long.MAX_VALUE; } - final Optional stopBlockParam = - requestContext.getOptionalParameter(1, BlockParameter.class); + final Optional stopBlockParam; + try { + stopBlockParam = requestContext.getOptionalParameter(1, BlockParameter.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid stop block parameter (index 1)", RpcErrorType.INVALID_BLOCK_PARAMS, e); + } final long stopBlock; if (stopBlockParam.isEmpty()) { if (startBlockParam.isEmpty()) { diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugAccountAt.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugAccountAt.java index 8fafd5ec3d..550a25982d 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugAccountAt.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugAccountAt.java @@ -67,7 +67,12 @@ public class DebugAccountAt extends AbstractBlockParameterOrBlockHashMethod { @Override protected BlockParameterOrBlockHash blockParameterOrBlockHash( final JsonRpcRequestContext requestContext) { - return requestContext.getRequiredParameter(0, BlockParameterOrBlockHash.class); + try { + return requestContext.getRequiredParameter(0, BlockParameterOrBlockHash.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid block or block hash parameter (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e); + } } @Override diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugAccountRange.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugAccountRange.java index 32ed9c5611..c891bde56a 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugAccountRange.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugAccountRange.java @@ -58,8 +58,16 @@ public class DebugAccountRange implements JsonRpcMethod { @Override public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { - final BlockParameterOrBlockHash blockParameterOrBlockHash = - requestContext.getRequiredParameter(0, BlockParameterOrBlockHash.class); + final BlockParameterOrBlockHash blockParameterOrBlockHash; + try { + blockParameterOrBlockHash = + requestContext.getRequiredParameter(0, BlockParameterOrBlockHash.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid block parameter or block hash parameter (index 0)", + RpcErrorType.INVALID_BLOCK_PARAMS, + e); + } final String addressHash; try { addressHash = requestContext.getRequiredParameter(2, String.class); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugGetRawBlock.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugGetRawBlock.java index cec275e5a6..28d886bd81 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugGetRawBlock.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugGetRawBlock.java @@ -16,6 +16,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; @@ -37,7 +38,12 @@ public class DebugGetRawBlock extends AbstractBlockParameterMethod { @Override protected BlockParameter blockParameter(final JsonRpcRequestContext request) { - return request.getRequiredParameter(0, BlockParameter.class); + try { + return request.getRequiredParameter(0, BlockParameter.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid block parameter (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e); + } } @Override diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugGetRawHeader.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugGetRawHeader.java index 05ef0eb53d..e2f2c89e1a 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugGetRawHeader.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugGetRawHeader.java @@ -16,6 +16,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; @@ -37,7 +38,12 @@ public class DebugGetRawHeader extends AbstractBlockParameterMethod { @Override protected BlockParameter blockParameter(final JsonRpcRequestContext request) { - return request.getRequiredParameter(0, BlockParameter.class); + try { + return request.getRequiredParameter(0, BlockParameter.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid block parameter (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e); + } } @Override diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugGetRawReceipts.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugGetRawReceipts.java index 7965480c6f..cddba5086e 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugGetRawReceipts.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugGetRawReceipts.java @@ -17,7 +17,9 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameterOrBlockHash; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; import org.hyperledger.besu.ethereum.core.TransactionReceipt; import org.hyperledger.besu.ethereum.rlp.RLP; @@ -40,7 +42,12 @@ public class DebugGetRawReceipts extends AbstractBlockParameterOrBlockHashMethod @Override protected BlockParameterOrBlockHash blockParameterOrBlockHash( final JsonRpcRequestContext request) { - return request.getRequiredParameter(0, BlockParameterOrBlockHash.class); + try { + return request.getRequiredParameter(0, BlockParameterOrBlockHash.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid block or block hash parameter (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e); + } } @Override diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugSetHead.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugSetHead.java index 7d26eaca25..a3b423675f 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugSetHead.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugSetHead.java @@ -20,9 +20,11 @@ import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; import java.util.Optional; @@ -43,7 +45,12 @@ public class DebugSetHead extends AbstractBlockParameterMethod { @Override protected BlockParameter blockParameter(final JsonRpcRequestContext request) { - return request.getRequiredParameter(0, BlockParameter.class); + try { + return request.getRequiredParameter(0, BlockParameter.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid block parameter (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e); + } } @Override diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStorageRangeAt.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStorageRangeAt.java index 72110852b7..9f0f2f0b1e 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStorageRangeAt.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStorageRangeAt.java @@ -69,8 +69,14 @@ public class DebugStorageRangeAt implements JsonRpcMethod { @Override public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { - final BlockParameterOrBlockHash blockParameterOrBlockHash = - requestContext.getRequiredParameter(0, BlockParameterOrBlockHash.class); + final BlockParameterOrBlockHash blockParameterOrBlockHash; + try { + blockParameterOrBlockHash = + requestContext.getRequiredParameter(0, BlockParameterOrBlockHash.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid block or block hash parameter (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e); + } final int transactionIndex = requestContext.getRequiredParameter(1, Integer.class); final Address accountAddress; try { diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlock.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlock.java index 3a1dee6560..44cbf153de 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlock.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlock.java @@ -16,6 +16,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.TransactionTraceParams; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.BlockTrace; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.BlockTracer; @@ -69,9 +70,12 @@ public class DebugTraceBlock implements JsonRpcMethod { try { block = Block.readFrom(RLP.input(Bytes.fromHexString(input)), this.blockHeaderFunctions); } catch (final RLPException e) { - LOG.debug("Failed to parse block RLP", e); + LOG.debug("Failed to parse block RLP (index 0)", e); return new JsonRpcErrorResponse( - requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + requestContext.getRequest().getId(), RpcErrorType.INVALID_BLOCK_PARAMS); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid block params (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e); } final TraceOptions traceOptions = requestContext diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockByNumber.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockByNumber.java index 32d0e02f90..dce3ab1ebf 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockByNumber.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockByNumber.java @@ -17,11 +17,13 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.TransactionTraceParams; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.BlockTrace; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.BlockTracer; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.Tracer; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.DebugTraceTransactionResult; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; import org.hyperledger.besu.ethereum.debug.TraceOptions; @@ -47,7 +49,12 @@ public class DebugTraceBlockByNumber extends AbstractBlockParameterMethod { @Override protected BlockParameter blockParameter(final JsonRpcRequestContext request) { - return request.getRequiredParameter(0, BlockParameter.class); + try { + return request.getRequiredParameter(0, BlockParameter.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid block parameter (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e); + } } @Override diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceCall.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceCall.java index 0243398833..9de8108e67 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceCall.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceCall.java @@ -18,11 +18,13 @@ import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErr import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.TransactionTraceParams; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.TransactionTrace; 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.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.DebugTraceTransactionResult; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; import org.hyperledger.besu.ethereum.debug.TraceOptions; @@ -61,8 +63,13 @@ public class DebugTraceCall extends AbstractTraceCall { @Override protected BlockParameter blockParameter(final JsonRpcRequestContext request) { - final Optional maybeBlockParameter = - request.getOptionalParameter(1, BlockParameter.class); + final Optional maybeBlockParameter; + try { + maybeBlockParameter = request.getOptionalParameter(1, BlockParameter.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid block parameter (index 1)", RpcErrorType.INVALID_BLOCK_PARAMS, e); + } return maybeBlockParameter.orElse(BlockParameter.LATEST); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCall.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCall.java index c645bab453..a08b17dfc6 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCall.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCall.java @@ -22,6 +22,7 @@ import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcErrorConverter; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameterOrBlockHash; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonCallParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError; @@ -57,7 +58,12 @@ public class EthCall extends AbstractBlockParameterOrBlockHashMethod { @Override protected BlockParameterOrBlockHash blockParameterOrBlockHash( final JsonRpcRequestContext request) { - return request.getRequiredParameter(1, BlockParameterOrBlockHash.class); + try { + return request.getRequiredParameter(1, BlockParameterOrBlockHash.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid block or block hash parameters (index 1)", RpcErrorType.INVALID_BLOCK_PARAMS, e); + } } @Override 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 6bea493d31..26e414acda 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 @@ -22,6 +22,7 @@ import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.api.ApiConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.UnsignedIntParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; @@ -91,7 +92,13 @@ public class EthFeeHistory implements JsonRpcMethod { if (isInvalidBlockCount(blockCount)) { return new JsonRpcErrorResponse(requestId, RpcErrorType.INVALID_PARAMS); } - final BlockParameter highestBlock = request.getRequiredParameter(1, BlockParameter.class); + final BlockParameter highestBlock; + try { + highestBlock = request.getRequiredParameter(1, BlockParameter.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid highest block parameter (index 1)", RpcErrorType.INVALID_BLOCK_PARAMS, e); + } final Optional> maybeRewardPercentiles = request.getOptionalParameter(2, Double[].class).map(Arrays::asList); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBalance.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBalance.java index 449de64261..e863626c96 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBalance.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBalance.java @@ -43,7 +43,12 @@ public class EthGetBalance extends AbstractBlockParameterOrBlockHashMethod { @Override protected BlockParameterOrBlockHash blockParameterOrBlockHash( final JsonRpcRequestContext request) { - return request.getRequiredParameter(1, BlockParameterOrBlockHash.class); + try { + return request.getRequiredParameter(1, BlockParameterOrBlockHash.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid block or block hash parameter (index 1)", RpcErrorType.INVALID_BLOCK_PARAMS, e); + } } @Override diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByNumber.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByNumber.java index c1bdcc37dd..19ad9a51ad 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByNumber.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByNumber.java @@ -17,7 +17,9 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.BlockResult; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.BlockResultFactory; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; @@ -62,7 +64,12 @@ public class EthGetBlockByNumber extends AbstractBlockParameterMethod { @Override protected BlockParameter blockParameter(final JsonRpcRequestContext request) { - return request.getRequiredParameter(0, BlockParameter.class); + try { + return request.getRequiredParameter(0, BlockParameter.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid block parameter (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e); + } } @Override 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 54a3733286..d9592db8c1 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 @@ -17,7 +17,9 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameterOrBlockHash; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.BlockReceiptsResult; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.TransactionReceiptResult; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.TransactionReceiptRootResult; @@ -53,7 +55,12 @@ public class EthGetBlockReceipts extends AbstractBlockParameterOrBlockHashMethod @Override protected BlockParameterOrBlockHash blockParameterOrBlockHash( final JsonRpcRequestContext request) { - return request.getRequiredParameter(0, BlockParameterOrBlockHash.class); + try { + return request.getRequiredParameter(0, BlockParameterOrBlockHash.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid block or block hash parameters (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e); + } } @Override diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockTransactionCountByNumber.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockTransactionCountByNumber.java index b6819c7510..2a068a6174 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockTransactionCountByNumber.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockTransactionCountByNumber.java @@ -16,7 +16,9 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.Quantity; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; @@ -33,7 +35,12 @@ public class EthGetBlockTransactionCountByNumber extends AbstractBlockParameterM @Override protected BlockParameter blockParameter(final JsonRpcRequestContext request) { - return request.getRequiredParameter(0, BlockParameter.class); + try { + return request.getRequiredParameter(0, BlockParameter.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid block parameters (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e); + } } @Override diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetCode.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetCode.java index 9002b6d89c..8a9881a012 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetCode.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetCode.java @@ -45,7 +45,12 @@ public class EthGetCode extends AbstractBlockParameterOrBlockHashMethod { @Override protected BlockParameterOrBlockHash blockParameterOrBlockHash( final JsonRpcRequestContext request) { - return request.getRequiredParameter(1, BlockParameterOrBlockHash.class); + try { + return request.getRequiredParameter(1, BlockParameterOrBlockHash.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid block or block hash parameter (index 1)", RpcErrorType.INVALID_BLOCK_PARAMS, e); + } } @Override diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetMinerDataByBlockNumber.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetMinerDataByBlockNumber.java index 83ca008890..c2df712686 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetMinerDataByBlockNumber.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetMinerDataByBlockNumber.java @@ -17,7 +17,9 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.MinerDataResult; import org.hyperledger.besu.ethereum.api.query.BlockWithMetadata; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; @@ -40,7 +42,12 @@ public class EthGetMinerDataByBlockNumber extends AbstractBlockParameterMethod { @Override protected BlockParameter blockParameter(final JsonRpcRequestContext request) { - return request.getRequiredParameter(0, BlockParameter.class); + try { + return request.getRequiredParameter(0, BlockParameter.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid block parameter (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e); + } } @Override diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetProof.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetProof.java index 67a0792408..a20cd62f29 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetProof.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetProof.java @@ -49,7 +49,12 @@ public class EthGetProof extends AbstractBlockParameterOrBlockHashMethod { @Override protected BlockParameterOrBlockHash blockParameterOrBlockHash( final JsonRpcRequestContext request) { - return request.getRequiredParameter(2, BlockParameterOrBlockHash.class); + try { + return request.getRequiredParameter(2, BlockParameterOrBlockHash.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid block or block hash parameter (index 2)", RpcErrorType.INVALID_BLOCK_PARAMS, e); + } } @Override diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetStorageAt.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetStorageAt.java index efec2ee1d6..7b84365b56 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetStorageAt.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetStorageAt.java @@ -39,7 +39,12 @@ public class EthGetStorageAt extends AbstractBlockParameterOrBlockHashMethod { @Override protected BlockParameterOrBlockHash blockParameterOrBlockHash( final JsonRpcRequestContext request) { - return request.getRequiredParameter(2, BlockParameterOrBlockHash.class); + try { + return request.getRequiredParameter(2, BlockParameterOrBlockHash.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid block or block hash parameter (index 2)", RpcErrorType.INVALID_BLOCK_PARAMS, e); + } } @Override diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionByBlockNumberAndIndex.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionByBlockNumberAndIndex.java index ab08127ca7..6a419d35c5 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionByBlockNumberAndIndex.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionByBlockNumberAndIndex.java @@ -16,8 +16,10 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.UnsignedIntParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.TransactionCompleteResult; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; import org.hyperledger.besu.ethereum.api.query.TransactionWithMetadata; @@ -37,7 +39,12 @@ public class EthGetTransactionByBlockNumberAndIndex extends AbstractBlockParamet @Override protected BlockParameter blockParameter(final JsonRpcRequestContext request) { - return request.getRequiredParameter(0, BlockParameter.class); + try { + return request.getRequiredParameter(0, BlockParameter.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid block parameter (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e); + } } @Override diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionCount.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionCount.java index a03d90ea29..a9916099ea 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionCount.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionCount.java @@ -52,7 +52,12 @@ public class EthGetTransactionCount extends AbstractBlockParameterOrBlockHashMet @Override protected BlockParameterOrBlockHash blockParameterOrBlockHash( final JsonRpcRequestContext request) { - return request.getRequiredParameter(1, BlockParameterOrBlockHash.class); + try { + return request.getRequiredParameter(1, BlockParameterOrBlockHash.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid block or block hash parameter (index 1)", RpcErrorType.INVALID_BLOCK_PARAMS, e); + } } @Override diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetUncleByBlockNumberAndIndex.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetUncleByBlockNumberAndIndex.java index 2687982b8e..d2ac0b26af 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetUncleByBlockNumberAndIndex.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetUncleByBlockNumberAndIndex.java @@ -16,8 +16,10 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.UnsignedIntParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.BlockResult; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.UncleBlockResult; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; @@ -35,7 +37,12 @@ public class EthGetUncleByBlockNumberAndIndex extends AbstractBlockParameterMeth @Override protected BlockParameter blockParameter(final JsonRpcRequestContext request) { - return request.getRequiredParameter(0, BlockParameter.class); + try { + return request.getRequiredParameter(0, BlockParameter.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid block parameter (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e); + } } @Override diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSendRawTransaction.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSendRawTransaction.java index 5fbfc80a98..e79c0b60b7 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSendRawTransaction.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSendRawTransaction.java @@ -86,7 +86,7 @@ public class EthSendRawTransaction implements JsonRpcMethod { } catch (final RLPException e) { LOG.debug("RLPException: {} caused by {}", e.getMessage(), e.getCause()); return new JsonRpcErrorResponse( - requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + requestContext.getRequest().getId(), RpcErrorType.INVALID_BLOCK_PARAMS); } catch (final InvalidJsonRpcRequestException i) { LOG.debug("InvalidJsonRpcRequestException: {} caused by {}", i.getMessage(), i.getCause()); return new JsonRpcErrorResponse( diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceBlock.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceBlock.java index cd78d837df..5ec46e08cc 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceBlock.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceBlock.java @@ -18,10 +18,12 @@ import static org.hyperledger.besu.services.pipeline.PipelineBuilder.createPipel import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.FilterParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.Tracer; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.TransactionTrace; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.tracing.flat.FlatTraceGenerator; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.tracing.flat.RewardTraceGenerator; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; @@ -68,7 +70,12 @@ public class TraceBlock extends AbstractBlockParameterMethod { @Override protected BlockParameter blockParameter(final JsonRpcRequestContext request) { - return request.getRequiredParameter(0, BlockParameter.class); + try { + return request.getRequiredParameter(0, BlockParameter.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid block parameter (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e); + } } @Override diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceCallMany.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceCallMany.java index 3e3b0c9343..8dabd29a3e 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceCallMany.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceCallMany.java @@ -19,6 +19,7 @@ import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErr import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonCallParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.TraceCallManyParameter; @@ -63,8 +64,13 @@ public class TraceCallMany extends TraceCall implements JsonRpcMethod { @Override protected BlockParameter blockParameter(final JsonRpcRequestContext request) { - final Optional maybeBlockParameter = - request.getOptionalParameter(1, BlockParameter.class); + final Optional maybeBlockParameter; + try { + maybeBlockParameter = request.getOptionalParameter(1, BlockParameter.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid block parameter (index 1)", RpcErrorType.INVALID_BLOCK_PARAMS, e); + } return maybeBlockParameter.orElse(BlockParameter.LATEST); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceReplayBlockTransactions.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceReplayBlockTransactions.java index 058fbd4796..50e580cd86 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceReplayBlockTransactions.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceReplayBlockTransactions.java @@ -18,11 +18,13 @@ import static org.hyperledger.besu.services.pipeline.PipelineBuilder.createPipel import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.TraceBlock.ChainUpdater; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.TraceTypeParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.Tracer; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.TransactionTrace; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.TraceReplayResult; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; import org.hyperledger.besu.ethereum.api.util.ArrayNodeWrapper; @@ -70,7 +72,12 @@ public class TraceReplayBlockTransactions extends AbstractBlockParameterMethod { @Override protected BlockParameter blockParameter(final JsonRpcRequestContext request) { - return request.getRequiredParameter(0, BlockParameter.class); + try { + return request.getRequiredParameter(0, BlockParameter.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid block parameter (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e); + } } @Override diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCall.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCall.java index 31469530b0..8fe48474a8 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCall.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCall.java @@ -53,7 +53,12 @@ public class PrivCall extends AbstractBlockParameterMethod { @Override protected BlockParameter blockParameter(final JsonRpcRequestContext request) { - return request.getRequiredParameter(2, BlockParameter.class); + try { + return request.getRequiredParameter(2, BlockParameter.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid block parameter (index 2)", RpcErrorType.INVALID_BLOCK_PARAMS, e); + } } @Override diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDebugGetStateRoot.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDebugGetStateRoot.java index 6ccc9630f9..b6ea645dc3 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDebugGetStateRoot.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDebugGetStateRoot.java @@ -20,6 +20,7 @@ import org.hyperledger.besu.enclave.EnclaveClientException; import org.hyperledger.besu.enclave.types.PrivacyGroup; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.AbstractBlockParameterMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.PrivacyIdProvider; @@ -60,7 +61,12 @@ public class PrivDebugGetStateRoot extends AbstractBlockParameterMethod { @Override protected BlockParameter blockParameter(final JsonRpcRequestContext request) { - return request.getRequiredParameter(1, BlockParameter.class); + try { + return request.getRequiredParameter(1, BlockParameter.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid block parameter (index 1)", RpcErrorType.INVALID_BLOCK_PARAMS, e); + } } @Override diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetCode.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetCode.java index 56318da37e..0010b8e052 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetCode.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetCode.java @@ -48,7 +48,12 @@ public class PrivGetCode extends AbstractBlockParameterMethod { @Override protected BlockParameter blockParameter(final JsonRpcRequestContext request) { - return request.getRequiredParameter(2, BlockParameter.class); + try { + return request.getRequiredParameter(2, BlockParameter.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid block parameter (index 2)", RpcErrorType.INVALID_BLOCK_PARAMS, e); + } } @Override diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTest.java index 7c3157d223..96b9b9f779 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTest.java @@ -980,7 +980,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { // Check general format of result final String respBody = resp.body().string(); final JsonObject json = new JsonObject(respBody); - final RpcErrorType expectedError = RpcErrorType.INVALID_PARAMS; + final RpcErrorType expectedError = RpcErrorType.INVALID_BLOCK_PARAMS; testHelper.assertValidJsonRpcError( json, id, expectedError.getCode(), expectedError.getMessage()); } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByNumberTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByNumberTest.java index b12cdbe22f..e283759380 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByNumberTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByNumberTest.java @@ -129,8 +129,7 @@ public class EthGetBlockByNumberTest { public void exceptionWhenNumberParamInvalid() { assertThatThrownBy(() -> method.response(requestWithParams("invalid", "true"))) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage( - "Invalid json rpc parameter at index 0. Supplied value was: 'invalid' of type: 'java.lang.String' - expected type: 'org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter'"); + .hasMessage("Invalid block parameter (index 0)"); verifyNoMoreInteractions(blockchainQueries); } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockReceiptsTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockReceiptsTest.java index 5e8ad1455d..545b43a6e7 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockReceiptsTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockReceiptsTest.java @@ -100,7 +100,7 @@ public class EthGetBlockReceiptsTest { public void exceptionWhenNoParamsSupplied() { assertThatThrownBy(() -> method.response(requestWithParams())) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage("Missing required json rpc parameter at index 0"); + .hasMessage("Invalid block or block hash parameters (index 0)"); verifyNoMoreInteractions(blockchainQueries); } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetMinerDataByBlockNumberTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetMinerDataByBlockNumberTest.java index ca65fcf42a..9295e64da9 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetMinerDataByBlockNumberTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetMinerDataByBlockNumberTest.java @@ -103,7 +103,7 @@ public class EthGetMinerDataByBlockNumberTest { JsonRpcRequestContext requestContext = new JsonRpcRequestContext(request); assertThatThrownBy(() -> method.response(requestContext)) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage("Missing required json rpc parameter at index 0"); + .hasMessage("Invalid block parameter (index 0)"); verifyNoMoreInteractions(blockchainQueries); } @@ -114,7 +114,7 @@ public class EthGetMinerDataByBlockNumberTest { JsonRpcRequestContext requestContext = new JsonRpcRequestContext(request); assertThatThrownBy(() -> method.response(requestContext)) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Invalid json rpc parameter at index 0"); + .hasMessageContaining("Invalid block parameter"); verifyNoMoreInteractions(blockchainQueries); } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetProofTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetProofTest.java index 344ee39d80..3cf24df3d4 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetProofTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetProofTest.java @@ -129,7 +129,7 @@ class EthGetProofTest { Assertions.assertThatThrownBy(() -> method.response(request)) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Missing required json rpc parameter at index 2"); + .hasMessageContaining("Invalid block or block hash parameter"); } @Test diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetUncleByBlockNumberAndIndexTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetUncleByBlockNumberAndIndexTest.java index 59b20d5846..06c7408a84 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetUncleByBlockNumberAndIndexTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetUncleByBlockNumberAndIndexTest.java @@ -79,7 +79,7 @@ public class EthGetUncleByBlockNumberAndIndexTest { assertThat(thrown) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage("Missing required json rpc parameter at index 0"); + .hasMessage("Invalid block parameter (index 0)"); } @Test diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_call_callParamsMissing_block_8.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_call_callParamsMissing_block_8.json index 562e0f3326..70a9be13f5 100644 --- a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_call_callParamsMissing_block_8.json +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_call_callParamsMissing_block_8.json @@ -12,7 +12,7 @@ "id": 4, "error":{ "code":-32602, - "message":"Invalid params" + "message":"Invalid block, unable to parse RLP" } }, "statusCode": 200 diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_call_invalidBlockhash.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_call_invalidBlockhash.json index d6a714eb49..f00531954c 100644 --- a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_call_invalidBlockhash.json +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_call_invalidBlockhash.json @@ -17,7 +17,7 @@ "id": 3, "error" : { "code" : -32602, - "message" : "Invalid params" + "message" : "Invalid block, unable to parse RLP" } }, "statusCode": 200 diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBalance_invalidBlockHash.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBalance_invalidBlockHash.json index fa6fab6306..7e56b0a566 100644 --- a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBalance_invalidBlockHash.json +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBalance_invalidBlockHash.json @@ -13,7 +13,7 @@ "id": 28, "error" : { "code" : -32602, - "message" : "Invalid params" + "message" : "Invalid block, unable to parse RLP" } }, "statusCode": 200 diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBalance_invalidParams.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBalance_invalidParams.json index e84f3045a3..0f07f4a3bb 100644 --- a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBalance_invalidParams.json +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBalance_invalidParams.json @@ -10,7 +10,7 @@ "id": 32, "error" : { "code" : -32602, - "message" : "Invalid params" + "message" : "Invalid block, unable to parse RLP" } }, "statusCode": 200 diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBlockReceipts_invalidParams_blockNumber.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBlockReceipts_invalidParams_blockNumber.json index 91f6a6af8f..4dca011466 100644 --- a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBlockReceipts_invalidParams_blockNumber.json +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBlockReceipts_invalidParams_blockNumber.json @@ -12,7 +12,7 @@ "id": 300, "error" : { "code" : -32602, - "message" : "Invalid params" + "message" : "Invalid block, unable to parse RLP" } }, "statusCode": 200 diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBlockReceipts_invalidParams_tag.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBlockReceipts_invalidParams_tag.json index 655ff6013a..8fc9c2d805 100644 --- a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBlockReceipts_invalidParams_tag.json +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBlockReceipts_invalidParams_tag.json @@ -12,7 +12,7 @@ "id": 301, "error" : { "code" : -32602, - "message" : "Invalid params" + "message" : "Invalid block, unable to parse RLP" } }, "statusCode": 200 diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBlockTransactionCountByNumber_invalidParams.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBlockTransactionCountByNumber_invalidParams.json index 7e40d417e7..1a56a83a60 100644 --- a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBlockTransactionCountByNumber_invalidParams.json +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBlockTransactionCountByNumber_invalidParams.json @@ -10,7 +10,7 @@ "id": 248, "error": { "code" : -32602, - "message" : "Invalid params" + "message" : "Invalid block, unable to parse RLP" } }, "statusCode": 200 diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getCode_invalidBlockHash.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getCode_invalidBlockHash.json index a5e1e004af..9e715fca1d 100644 --- a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getCode_invalidBlockHash.json +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getCode_invalidBlockHash.json @@ -13,7 +13,7 @@ "id": 0, "error" : { "code" : -32602, - "message" : "Invalid params" + "message" : "Invalid block, unable to parse RLP" } }, "statusCode": 200 diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getCode_invalidParams.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getCode_invalidParams.json index 5a65b4d17c..929a0f3f35 100644 --- a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getCode_invalidParams.json +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getCode_invalidParams.json @@ -10,7 +10,7 @@ "id": 255, "error": { "code": -32602, - "message": "Invalid params" + "message": "Invalid block, unable to parse RLP" } }, "statusCode": 200 diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getProof_invalidBlockHash.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getProof_invalidBlockHash.json index 257380fdac..4fb69d437c 100644 --- a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getProof_invalidBlockHash.json +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getProof_invalidBlockHash.json @@ -14,7 +14,7 @@ "id": 28, "error" : { "code" : -32602, - "message" : "Invalid params" + "message" : "Invalid block, unable to parse RLP" } }, "statusCode": 200 diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getProof_invalidParams.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getProof_invalidParams.json index ba169f79de..095ebd2a91 100644 --- a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getProof_invalidParams.json +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getProof_invalidParams.json @@ -10,7 +10,7 @@ "id": 28, "error" : { "code" : -32602, - "message" : "Invalid params" + "message" : "Invalid block, unable to parse RLP" } }, "statusCode": 200 diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getStorageAt_invalidBlockHash.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getStorageAt_invalidBlockHash.json index 3ab3afb25e..e8fecda103 100644 --- a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getStorageAt_invalidBlockHash.json +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getStorageAt_invalidBlockHash.json @@ -14,7 +14,7 @@ "id": 341, "error" : { "code" : -32602, - "message" : "Invalid params" + "message" : "Invalid block, unable to parse RLP" } }, "statusCode": 200 diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getStorageAt_invalidParams.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getStorageAt_invalidParams.json index 99af70906a..9ad533c0c6 100644 --- a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getStorageAt_invalidParams.json +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getStorageAt_invalidParams.json @@ -10,7 +10,7 @@ "id": 342, "error" : { "code" : -32602, - "message" : "Invalid params" + "message" : "Invalid block, unable to parse RLP" } }, "statusCode": 200 diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByBlockNumberAndIndex_invalidParams.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByBlockNumberAndIndex_invalidParams.json index 8ba25d9c33..c88d01904d 100644 --- a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByBlockNumberAndIndex_invalidParams.json +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByBlockNumberAndIndex_invalidParams.json @@ -10,7 +10,7 @@ "id": 486, "error": { "code" : -32602, - "message" : "Invalid params" + "message" : "Invalid block, unable to parse RLP" } }, "statusCode": 200 diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionCount_invalidBlockHash.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionCount_invalidBlockHash.json index 52651090e9..f98c40c0d2 100644 --- a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionCount_invalidBlockHash.json +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionCount_invalidBlockHash.json @@ -13,7 +13,7 @@ "id": 487, "error" : { "code" : -32602, - "message" : "Invalid params" + "message" : "Invalid block, unable to parse RLP" } }, "statusCode": 200 diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionCount_invalidBlockNumber.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionCount_invalidBlockNumber.json index 0ad4a0d3cb..c25d81a1ab 100644 --- a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionCount_invalidBlockNumber.json +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionCount_invalidBlockNumber.json @@ -13,7 +13,7 @@ "id": 487, "error" : { "code" : -32602, - "message" : "Invalid params" + "message" : "Invalid block, unable to parse RLP" } }, "statusCode": 200 diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionCount_missingArgument.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionCount_missingArgument.json index 75437d4db8..75ca3aed1a 100644 --- a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionCount_missingArgument.json +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionCount_missingArgument.json @@ -10,7 +10,7 @@ "id": 489, "error": { "code": -32602, - "message": "Invalid params" + "message": "Invalid block, unable to parse RLP" } }, "statusCode": 200 diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/trace/specs/replay-trace-transaction/flat/trace_replayBlockTransactions_invalidBlockParam.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/trace/specs/replay-trace-transaction/flat/trace_replayBlockTransactions_invalidBlockParam.json index b67f6eb872..42967740d9 100644 --- a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/trace/specs/replay-trace-transaction/flat/trace_replayBlockTransactions_invalidBlockParam.json +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/trace/specs/replay-trace-transaction/flat/trace_replayBlockTransactions_invalidBlockParam.json @@ -13,7 +13,7 @@ "id": 415, "error": { "code": -32602, - "message": "Invalid params" + "message": "Invalid block, unable to parse RLP" } }, "statusCode": 200 diff --git a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestImportRawBlock.java b/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestImportRawBlock.java index 0652b92cdb..516dc2f55f 100644 --- a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestImportRawBlock.java +++ b/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestImportRawBlock.java @@ -16,6 +16,7 @@ package org.hyperledger.besu.ethereum.retesteth.methods; import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; @@ -52,7 +53,13 @@ public class TestImportRawBlock implements JsonRpcMethod { @Override public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { - final String input = requestContext.getRequiredParameter(0, String.class); + final String input; + try { + input = requestContext.getRequiredParameter(0, String.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid block parameter (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e); + } final ProtocolContext protocolContext = this.context.getProtocolContext(); final Block block; From 47fff38cf67c77788356767abd176e2ab7de0799 Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Mon, 12 Aug 2024 14:54:07 +1000 Subject: [PATCH 099/259] 5098 branch 9 update invalid block count params (#7410) * 5098: Add RpcErrorTypes Signed-off-by: Matilda Clerke --------- Signed-off-by: Matilda Clerke Signed-off-by: Matilda-Clerke Co-authored-by: Sally MacFarlane --- .../api/jsonrpc/internal/methods/EthFeeHistory.java | 11 +++++++++-- .../engine/EngineGetPayloadBodiesByRangeV1.java | 9 ++++++++- .../jsonrpc/internal/methods/EthFeeHistoryTest.java | 4 ++-- .../ethereum/retesteth/methods/TestMineBlocks.java | 10 +++++++++- 4 files changed, 28 insertions(+), 6 deletions(-) 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 26e414acda..92d42f2278 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 @@ -88,9 +88,15 @@ public class EthFeeHistory implements JsonRpcMethod { public JsonRpcResponse response(final JsonRpcRequestContext request) { final Object requestId = request.getRequest().getId(); - final int blockCount = request.getRequiredParameter(0, UnsignedIntParameter.class).getValue(); + final int blockCount; + try { + blockCount = request.getRequiredParameter(0, UnsignedIntParameter.class).getValue(); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid block count parameter (index 0)", RpcErrorType.INVALID_BLOCK_COUNT_PARAMS, e); + } if (isInvalidBlockCount(blockCount)) { - return new JsonRpcErrorResponse(requestId, RpcErrorType.INVALID_PARAMS); + return new JsonRpcErrorResponse(requestId, RpcErrorType.INVALID_BLOCK_COUNT_PARAMS); } final BlockParameter highestBlock; try { @@ -99,6 +105,7 @@ public class EthFeeHistory implements JsonRpcMethod { throw new InvalidJsonRpcParameters( "Invalid highest block parameter (index 1)", RpcErrorType.INVALID_BLOCK_PARAMS, e); } + final Optional> maybeRewardPercentiles = request.getOptionalParameter(2, Double[].class).map(Arrays::asList); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadBodiesByRangeV1.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadBodiesByRangeV1.java index 5fdd1657f6..88431dd89b 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadBodiesByRangeV1.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadBodiesByRangeV1.java @@ -17,6 +17,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine; import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.UnsignedLongParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; @@ -59,7 +60,13 @@ public class EngineGetPayloadBodiesByRangeV1 extends ExecutionEngineJsonRpcMetho final long startBlockNumber = request.getRequiredParameter(0, UnsignedLongParameter.class).getValue(); - final long count = request.getRequiredParameter(1, UnsignedLongParameter.class).getValue(); + final long count; + try { + count = request.getRequiredParameter(1, UnsignedLongParameter.class).getValue(); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid block count params (index 1)", RpcErrorType.INVALID_BLOCK_COUNT_PARAMS, e); + } final Object reqId = request.getRequest().getId(); LOG.atTrace() 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 a0821abf2d..0ed7e13382 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 @@ -241,11 +241,11 @@ public class EthFeeHistoryTest { assertThat( ((JsonRpcErrorResponse) feeHistoryRequest("0x0", "latest", new double[] {100.0})) .getErrorType()) - .isEqualTo(RpcErrorType.INVALID_PARAMS); + .isEqualTo(RpcErrorType.INVALID_BLOCK_COUNT_PARAMS); assertThat( ((JsonRpcErrorResponse) feeHistoryRequest("0x401", "latest", new double[] {100.0})) .getErrorType()) - .isEqualTo(RpcErrorType.INVALID_PARAMS); + .isEqualTo(RpcErrorType.INVALID_BLOCK_COUNT_PARAMS); } @Test diff --git a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestMineBlocks.java b/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestMineBlocks.java index 3060b326bb..7907cee3f7 100644 --- a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestMineBlocks.java +++ b/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestMineBlocks.java @@ -16,9 +16,11 @@ package org.hyperledger.besu.ethereum.retesteth.methods; import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; 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.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.blockcreation.PoWBlockCreator; import org.hyperledger.besu.ethereum.chain.MutableBlockchain; import org.hyperledger.besu.ethereum.core.Block; @@ -44,7 +46,13 @@ public class TestMineBlocks implements JsonRpcMethod { @Override public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { - long blocksToMine = requestContext.getRequiredParameter(0, Long.class); + long blocksToMine = 0; + try { + blocksToMine = requestContext.getRequiredParameter(0, Long.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid blocks to mine (index 0)", RpcErrorType.INVALID_BLOCK_COUNT_PARAMS, e); + } while (blocksToMine-- > 0) { if (!mineNewBlock()) { return new JsonRpcSuccessResponse(requestContext.getRequest().getId(), false); From fab239341d653b6fed62d163ae27c15a21f37da8 Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Mon, 12 Aug 2024 15:39:35 +1000 Subject: [PATCH 100/259] 5098 branch 11 update invalid block hash params (#7421) * 5098: Add RpcErrorTypes Signed-off-by: Matilda Clerke --------- Signed-off-by: Matilda Clerke Signed-off-by: Matilda-Clerke Co-authored-by: Sally MacFarlane --- .../jsonrpc/methods/CliqueGetSignersAtHash.java | 9 ++++++++- .../jsonrpc/methods/CliqueGetSignersAtHashTest.java | 2 +- .../methods/IbftGetValidatorsByBlockHash.java | 10 +++++++++- .../methods/QbftGetValidatorsByBlockHash.java | 10 +++++++++- .../AbstractBlockParameterOrBlockHashMethod.java | 2 +- .../methods/DebugStandardTraceBadBlockToFile.java | 9 ++++++++- .../methods/DebugStandardTraceBlockToFile.java | 9 ++++++++- .../internal/methods/DebugTraceBlockByHash.java | 10 +++++++++- .../jsonrpc/internal/methods/EthGetBlockByHash.java | 10 +++++++++- .../methods/EthGetBlockTransactionCountByHash.java | 12 +++++++++++- .../internal/methods/EthGetMinerDataByBlockHash.java | 10 +++++++++- .../methods/EthGetUncleByBlockHashAndIndex.java | 10 +++++++++- .../methods/EthGetUncleCountByBlockHash.java | 10 +++++++++- .../engine/EngineGetPayloadBodiesByHashV1.java | 9 ++++++++- .../ethereum/api/jsonrpc/JsonRpcHttpServiceTest.java | 10 +++++----- .../internal/methods/EthGetBlockByHashTest.java | 3 +-- .../methods/EthGetMinerDataByBlockHashTest.java | 4 ++-- .../methods/EthGetUncleByBlockHashAndIndexTest.java | 4 ++-- ...getBlockTransactionCountByHash_invalidParams.json | 2 +- 19 files changed, 119 insertions(+), 26 deletions(-) diff --git a/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/CliqueGetSignersAtHash.java b/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/CliqueGetSignersAtHash.java index 8dd7ac5c23..c683b9d485 100644 --- a/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/CliqueGetSignersAtHash.java +++ b/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/CliqueGetSignersAtHash.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.consensus.common.validator.ValidatorProvider; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; @@ -67,7 +68,13 @@ public class CliqueGetSignersAtHash implements JsonRpcMethod { } private Optional determineBlockHeader(final JsonRpcRequestContext request) { - final Hash hash = request.getRequiredParameter(0, Hash.class); + final Hash hash; + try { + hash = request.getRequiredParameter(0, Hash.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid block hash parameter (index 0)", RpcErrorType.INVALID_BLOCK_HASH_PARAMS, e); + } return blockchainQueries.blockByHash(hash).map(BlockWithMetadata::getHeader); } } diff --git a/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/CliqueGetSignersAtHashTest.java b/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/CliqueGetSignersAtHashTest.java index ee5dc0f023..3699ccf6ee 100644 --- a/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/CliqueGetSignersAtHashTest.java +++ b/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/CliqueGetSignersAtHashTest.java @@ -101,7 +101,7 @@ public class CliqueGetSignersAtHashTest { assertThat(thrown) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage("Missing required json rpc parameter at index 0"); + .hasMessage("Invalid block hash parameter (index 0)"); } @Test diff --git a/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftGetValidatorsByBlockHash.java b/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftGetValidatorsByBlockHash.java index a14eb49e87..3c3346cd43 100644 --- a/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftGetValidatorsByBlockHash.java +++ b/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftGetValidatorsByBlockHash.java @@ -18,9 +18,11 @@ import org.hyperledger.besu.consensus.common.BlockInterface; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; 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.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.chain.Blockchain; import org.hyperledger.besu.ethereum.core.BlockHeader; @@ -61,7 +63,13 @@ public class IbftGetValidatorsByBlockHash implements JsonRpcMethod { } private Object blockResult(final JsonRpcRequestContext request) { - final Hash hash = request.getRequiredParameter(0, Hash.class); + final Hash hash; + try { + hash = request.getRequiredParameter(0, Hash.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid block hash parameter (index 0)", RpcErrorType.INVALID_BLOCK_HASH_PARAMS, e); + } LOG.trace("Received RPC rpcName={} blockHash={}", getName(), hash); final Optional blockHeader = blockchain.getBlockHeader(hash); return blockHeader diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftGetValidatorsByBlockHash.java b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftGetValidatorsByBlockHash.java index 4726e81bd3..e991f7f355 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftGetValidatorsByBlockHash.java +++ b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftGetValidatorsByBlockHash.java @@ -19,9 +19,11 @@ import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; 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.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.chain.Blockchain; import org.hyperledger.besu.ethereum.core.BlockHeader; @@ -62,7 +64,13 @@ public class QbftGetValidatorsByBlockHash implements JsonRpcMethod { } private Object blockResult(final JsonRpcRequestContext request) { - final Hash hash = request.getRequiredParameter(0, Hash.class); + final Hash hash; + try { + hash = request.getRequiredParameter(0, Hash.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid block hash parameter (index 0)", RpcErrorType.INVALID_BLOCK_HASH_PARAMS, e); + } LOG.trace("Received RPC rpcName={} blockHash={}", getName(), hash); final Optional blockHeader = blockchain.getBlockHeader(hash); return blockHeader diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AbstractBlockParameterOrBlockHashMethod.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AbstractBlockParameterOrBlockHashMethod.java index 8110bf6c2c..be6ecfa82e 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AbstractBlockParameterOrBlockHashMethod.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AbstractBlockParameterOrBlockHashMethod.java @@ -123,7 +123,7 @@ public abstract class AbstractBlockParameterOrBlockHashMethod implements JsonRpc Optional blockHash = blockParameterOrBlockHash.getHash(); if (blockHash.isEmpty()) { return new JsonRpcErrorResponse( - requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + requestContext.getRequest().getId(), RpcErrorType.INVALID_BLOCK_HASH_PARAMS); } // return error if block hash does not find a block diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStandardTraceBadBlockToFile.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStandardTraceBadBlockToFile.java index 25c59e4763..7587e40c75 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStandardTraceBadBlockToFile.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStandardTraceBadBlockToFile.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.TransactionTraceParams; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.TransactionTracer; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; @@ -52,7 +53,13 @@ public class DebugStandardTraceBadBlockToFile extends DebugStandardTraceBlockToF @Override public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { - final Hash blockHash = requestContext.getRequiredParameter(0, Hash.class); + final Hash blockHash; + try { + blockHash = requestContext.getRequiredParameter(0, Hash.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid block hash parameter (index 0)", RpcErrorType.INVALID_BLOCK_HASH_PARAMS, e); + } final Optional transactionTraceParams = requestContext.getOptionalParameter(1, TransactionTraceParams.class); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStandardTraceBlockToFile.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStandardTraceBlockToFile.java index 306f4c449e..601eabeab1 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStandardTraceBlockToFile.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStandardTraceBlockToFile.java @@ -19,6 +19,7 @@ import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.Trans import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.TransactionTraceParams; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.Tracer; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.TransactionTracer; @@ -59,7 +60,13 @@ public class DebugStandardTraceBlockToFile implements JsonRpcMethod { @Override public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { - final Hash blockHash = requestContext.getRequiredParameter(0, Hash.class); + final Hash blockHash; + try { + blockHash = requestContext.getRequiredParameter(0, Hash.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid block hash parameter (index 0)", RpcErrorType.INVALID_BLOCK_HASH_PARAMS, e); + } final Optional transactionTraceParams = requestContext.getOptionalParameter(1, TransactionTraceParams.class); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockByHash.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockByHash.java index c1caaef2b9..b1216885f1 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockByHash.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockByHash.java @@ -17,12 +17,14 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.TransactionTraceParams; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.BlockTrace; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.BlockTracer; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.Tracer; 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.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.DebugTraceTransactionResult; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; import org.hyperledger.besu.ethereum.debug.TraceOptions; @@ -50,7 +52,13 @@ public class DebugTraceBlockByHash implements JsonRpcMethod { @Override public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { - final Hash blockHash = requestContext.getRequiredParameter(0, Hash.class); + final Hash blockHash; + try { + blockHash = requestContext.getRequiredParameter(0, Hash.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid block hash parameter (index 0)", RpcErrorType.INVALID_BLOCK_HASH_PARAMS, e); + } final TraceOptions traceOptions = requestContext .getOptionalParameter(1, TransactionTraceParams.class) diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByHash.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByHash.java index 04cad96291..d5f1bba01c 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByHash.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByHash.java @@ -17,8 +17,10 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; 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.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.BlockResult; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.BlockResultFactory; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; @@ -59,7 +61,13 @@ public class EthGetBlockByHash implements JsonRpcMethod { } private BlockResult blockResult(final JsonRpcRequestContext request) { - final Hash hash = request.getRequiredParameter(0, Hash.class); + final Hash hash; + try { + hash = request.getRequiredParameter(0, Hash.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid block hash parameter (index 0)", RpcErrorType.INVALID_BLOCK_HASH_PARAMS, e); + } if (isCompleteTransactions(request)) { return transactionComplete(hash); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockTransactionCountByHash.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockTransactionCountByHash.java index a965455595..e1fbd79086 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockTransactionCountByHash.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockTransactionCountByHash.java @@ -17,8 +17,10 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; 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.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.Quantity; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; @@ -37,7 +39,15 @@ public class EthGetBlockTransactionCountByHash implements JsonRpcMethod { @Override public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { - final Hash hash = requestContext.getRequiredParameter(0, Hash.class); + final Hash hash; + try { + hash = requestContext.getRequiredParameter(0, Hash.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid block header hash parameter (index 0)", + RpcErrorType.INVALID_BLOCK_HASH_PARAMS, + e); + } final Integer count = blockchain.getTransactionCount(hash); if (count == -1) { diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetMinerDataByBlockHash.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetMinerDataByBlockHash.java index 0e868d8987..8e3d55f1ea 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetMinerDataByBlockHash.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetMinerDataByBlockHash.java @@ -18,8 +18,10 @@ import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; 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.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.ImmutableMinerDataResult; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.ImmutableUncleRewardResult; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.MinerDataResult; @@ -60,7 +62,13 @@ public class EthGetMinerDataByBlockHash implements JsonRpcMethod { @Override public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { - final Hash hash = requestContext.getRequest().getRequiredParameter(0, Hash.class); + final Hash hash; + try { + hash = requestContext.getRequest().getRequiredParameter(0, Hash.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid block hash parameter (index 0)", RpcErrorType.INVALID_BLOCK_HASH_PARAMS, e); + } BlockWithMetadata block = blockchain.get().blockByHash(hash).orElse(null); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetUncleByBlockHashAndIndex.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetUncleByBlockHashAndIndex.java index 311da6b45f..93ae857a69 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetUncleByBlockHashAndIndex.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetUncleByBlockHashAndIndex.java @@ -17,9 +17,11 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.UnsignedIntParameter; 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.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.BlockResult; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.UncleBlockResult; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; @@ -44,7 +46,13 @@ public class EthGetUncleByBlockHashAndIndex implements JsonRpcMethod { } private BlockResult blockResult(final JsonRpcRequestContext requestContext) { - final Hash hash = requestContext.getRequiredParameter(0, Hash.class); + final Hash hash; + try { + hash = requestContext.getRequiredParameter(0, Hash.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid block hash parameter (index 0)", RpcErrorType.INVALID_BLOCK_HASH_PARAMS, e); + } final int index = requestContext.getRequiredParameter(1, UnsignedIntParameter.class).getValue(); return blockchain.getOmmer(hash, index).map(UncleBlockResult::build).orElse(null); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetUncleCountByBlockHash.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetUncleCountByBlockHash.java index c8efa19f30..9a5a3b225b 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetUncleCountByBlockHash.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetUncleCountByBlockHash.java @@ -17,8 +17,10 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; 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.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.Quantity; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; @@ -37,7 +39,13 @@ public class EthGetUncleCountByBlockHash implements JsonRpcMethod { @Override public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { - final Hash hash = requestContext.getRequiredParameter(0, Hash.class); + final Hash hash; + try { + hash = requestContext.getRequiredParameter(0, Hash.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid block hash parameter (index 0)", RpcErrorType.INVALID_BLOCK_HASH_PARAMS, e); + } final String result = blockchain.getOmmerCount(hash).map(Quantity::create).orElse(null); return new JsonRpcSuccessResponse(requestContext.getRequest().getId(), result); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadBodiesByHashV1.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadBodiesByHashV1.java index b564450246..0e6b62d320 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadBodiesByHashV1.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadBodiesByHashV1.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; @@ -60,7 +61,13 @@ public class EngineGetPayloadBodiesByHashV1 extends ExecutionEngineJsonRpcMethod final Object reqId = request.getRequest().getId(); - final Hash[] blockHashes = request.getRequiredParameter(0, Hash[].class); + final Hash[] blockHashes; + try { + blockHashes = request.getRequiredParameter(0, Hash[].class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid block hash parameters (index 0)", RpcErrorType.INVALID_BLOCK_HASH_PARAMS, e); + } LOG.atTrace() .setMessage("{} parameters: blockHashes {}") diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTest.java index 96b9b9f779..05284af6b8 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTest.java @@ -760,7 +760,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { assertThat(resp.code()).isEqualTo(200); // Check general format of result final JsonObject json = new JsonObject(resp.body().string()); - final RpcErrorType expectedError = RpcErrorType.INVALID_PARAMS; + final RpcErrorType expectedError = RpcErrorType.INVALID_BLOCK_HASH_PARAMS; testHelper.assertValidJsonRpcError( json, id, expectedError.getCode(), expectedError.getMessage()); } @@ -807,7 +807,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { assertThat(resp.code()).isEqualTo(200); // Check general format of result final JsonObject json = new JsonObject(resp.body().string()); - final RpcErrorType expectedError = RpcErrorType.INVALID_PARAMS; + final RpcErrorType expectedError = RpcErrorType.INVALID_BLOCK_HASH_PARAMS; testHelper.assertValidJsonRpcError( json, id, expectedError.getCode(), expectedError.getMessage()); } @@ -830,7 +830,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { assertThat(resp.code()).isEqualTo(200); // Check general format of result final JsonObject json = new JsonObject(resp.body().string()); - final RpcErrorType expectedError = RpcErrorType.INVALID_PARAMS; + final RpcErrorType expectedError = RpcErrorType.INVALID_BLOCK_HASH_PARAMS; testHelper.assertValidJsonRpcError( json, id, expectedError.getCode(), expectedError.getMessage()); } @@ -874,7 +874,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { assertThat(resp.code()).isEqualTo(200); // Check general format of result final JsonObject json = new JsonObject(resp.body().string()); - final RpcErrorType expectedError = RpcErrorType.INVALID_PARAMS; + final RpcErrorType expectedError = RpcErrorType.INVALID_BLOCK_HASH_PARAMS; testHelper.assertValidJsonRpcError( json, id, expectedError.getCode(), expectedError.getMessage()); } @@ -894,7 +894,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { assertThat(resp.code()).isEqualTo(200); // Check general format of result final JsonObject json = new JsonObject(resp.body().string()); - final RpcErrorType expectedError = RpcErrorType.INVALID_PARAMS; + final RpcErrorType expectedError = RpcErrorType.INVALID_BLOCK_HASH_PARAMS; testHelper.assertValidJsonRpcError( json, id, expectedError.getCode(), expectedError.getMessage()); } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByHashTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByHashTest.java index 1747030ba6..28043b2e09 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByHashTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByHashTest.java @@ -77,8 +77,7 @@ public class EthGetBlockByHashTest { public void exceptionWhenHashParamInvalid() { assertThatThrownBy(() -> method.response(requestWithParams("hash", "true"))) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage( - "Invalid json rpc parameter at index 0. Supplied value was: 'hash' of type: 'java.lang.String' - expected type: 'org.hyperledger.besu.datatypes.Hash'"); + .hasMessage("Invalid block hash parameter (index 0)"); verifyNoMoreInteractions(blockchainQueries); } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetMinerDataByBlockHashTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetMinerDataByBlockHashTest.java index 08737d0546..9d93dde85a 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetMinerDataByBlockHashTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetMinerDataByBlockHashTest.java @@ -109,7 +109,7 @@ public class EthGetMinerDataByBlockHashTest { JsonRpcRequestContext requestContext = new JsonRpcRequestContext(request); assertThatThrownBy(() -> method.response(requestContext)) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage("Missing required json rpc parameter at index 0"); + .hasMessage("Invalid block hash parameter (index 0)"); verifyNoMoreInteractions(blockchainQueries); } @@ -120,7 +120,7 @@ public class EthGetMinerDataByBlockHashTest { JsonRpcRequestContext requestContext = new JsonRpcRequestContext(request); assertThatThrownBy(() -> method.response(requestContext)) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Invalid json rpc parameter at index 0"); + .hasMessageContaining("Invalid block hash parameter (index 0)"); verifyNoMoreInteractions(blockchainQueries); } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetUncleByBlockHashAndIndexTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetUncleByBlockHashAndIndexTest.java index 07f8364615..fff08f81fb 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetUncleByBlockHashAndIndexTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetUncleByBlockHashAndIndexTest.java @@ -79,7 +79,7 @@ public class EthGetUncleByBlockHashAndIndexTest { assertThat(thrown) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage("Missing required json rpc parameter at index 0"); + .hasMessage("Invalid block hash parameter (index 0)"); } @Test @@ -101,7 +101,7 @@ public class EthGetUncleByBlockHashAndIndexTest { assertThat(thrown) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Invalid json rpc parameter at index 0"); + .hasMessageContaining("Invalid block hash parameter (index 0)"); } @Test diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBlockTransactionCountByHash_invalidParams.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBlockTransactionCountByHash_invalidParams.json index e05ba50cc6..07a35abf6d 100644 --- a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBlockTransactionCountByHash_invalidParams.json +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBlockTransactionCountByHash_invalidParams.json @@ -10,7 +10,7 @@ "id": 209, "error": { "code" : -32602, - "message" : "Invalid params" + "message" : "Invalid block hash params" } }, "statusCode": 200 From 2158a6829676c75931ef5522f06332965fa6c4b6 Mon Sep 17 00:00:00 2001 From: daniellehrner Date: Mon, 12 Aug 2024 11:38:59 +0200 Subject: [PATCH 101/259] Fix protocol schedule for devnets (#7429) * add `ProtocolSchedule::milestoneFor` to retrieve milestones for every hardfork in the genesis file * add `setMilestones` and `milestoneFor` to TransitionProtocolSchedule * refactored all checks for hardforks in the engine API to use hard fork ids * added tests to test that the engine API v2 endpoints return UNSUPPORTED_FORK past Cancun Signed-off-by: Daniel Lehrner --------- Signed-off-by: Daniel Lehrner Signed-off-by: Sally MacFarlane Co-authored-by: Sally MacFarlane --- CHANGELOG.md | 1 + .../merge/TransitionProtocolSchedule.java | 8 + .../AbstractEngineForkchoiceUpdated.java | 8 +- .../engine/EngineForkchoiceUpdatedV2.java | 27 +- .../engine/EngineForkchoiceUpdatedV3.java | 34 +-- .../methods/engine/EngineGetPayloadV2.java | 25 +- .../methods/engine/EngineGetPayloadV3.java | 20 +- .../methods/engine/EngineGetPayloadV4.java | 20 +- .../methods/engine/EngineNewPayloadV2.java | 13 + .../methods/engine/EngineNewPayloadV3.java | 21 +- .../methods/engine/EngineNewPayloadV4.java | 20 +- .../methods/engine/ForkSupportHelper.java | 42 ++++ .../AbstractEngineForkchoiceUpdatedTest.java | 29 ++- .../engine/AbstractScheduledApiTest.java | 31 ++- .../engine/EngineForkchoiceUpdatedV2Test.java | 46 ++++ .../engine/EngineGetPayloadV2Test.java | 33 +++ .../engine/EngineNewPayloadV2Test.java | 19 ++ .../engine/EngineNewPayloadV3Test.java | 7 + .../mainnet/DefaultProtocolSchedule.java | 15 ++ .../besu/ethereum/mainnet/HardforkId.java | 61 +++++ .../ethereum/mainnet/ProtocolSchedule.java | 9 + .../mainnet/ProtocolScheduleBuilder.java | 234 +++++++++++++----- .../mainnet/ProtocolScheduleBuilderTest.java | 44 ++++ 23 files changed, 566 insertions(+), 201 deletions(-) create mode 100644 ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/ForkSupportHelper.java create mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/HardforkId.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a97946652..e7921fac5f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ ### Bug fixes - Correct entrypoint in Docker evmtool [#7430](https://github.com/hyperledger/besu/pull/7430) +- Fix protocol schedule check for devnets [#7429](https://github.com/hyperledger/besu/pull/7429) - Fix behaviour when starting in a pre-merge network [#7431](https://github.com/hyperledger/besu/pull/7431) ## 24.7.1 diff --git a/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/TransitionProtocolSchedule.java b/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/TransitionProtocolSchedule.java index 8600344cef..f24e11bd8b 100644 --- a/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/TransitionProtocolSchedule.java +++ b/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/TransitionProtocolSchedule.java @@ -22,6 +22,7 @@ import org.hyperledger.besu.ethereum.core.Difficulty; import org.hyperledger.besu.ethereum.core.MiningParameters; import org.hyperledger.besu.ethereum.core.PermissionTransactionFilter; import org.hyperledger.besu.ethereum.core.ProcessableBlockHeader; +import org.hyperledger.besu.ethereum.mainnet.HardforkId; import org.hyperledger.besu.ethereum.mainnet.MainnetProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; @@ -241,6 +242,13 @@ public class TransitionProtocolSchedule implements ProtocolSchedule { return transitionUtils.dispatchFunctionAccordingToMergeState(ProtocolSchedule::listMilestones); } + @Override + public Optional milestoneFor(final HardforkId hardforkId) { + return mergeContext.isPostMerge() + ? transitionUtils.getPostMergeObject().milestoneFor(hardforkId) + : transitionUtils.getPreMergeObject().milestoneFor(hardforkId); + } + /** * Sets transaction filter. * diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineForkchoiceUpdated.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineForkchoiceUpdated.java index ec65ebe7a9..eec79e9a7c 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineForkchoiceUpdated.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineForkchoiceUpdated.java @@ -19,6 +19,7 @@ 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.WithdrawalsValidatorProvider.getWithdrawalsValidator; +import static org.hyperledger.besu.ethereum.mainnet.HardforkId.MainnetHardforkId.CANCUN; import org.hyperledger.besu.consensus.merge.blockcreation.MergeMiningCoordinator; import org.hyperledger.besu.consensus.merge.blockcreation.MergeMiningCoordinator.ForkchoiceResult; @@ -38,7 +39,6 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.EngineUpdateFo import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.Withdrawal; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; -import org.hyperledger.besu.ethereum.mainnet.ScheduledProtocolSpec; import org.hyperledger.besu.ethereum.mainnet.ValidationResult; import java.util.List; @@ -54,7 +54,7 @@ import org.slf4j.spi.LoggingEventBuilder; public abstract class AbstractEngineForkchoiceUpdated extends ExecutionEngineJsonRpcMethod { private static final Logger LOG = LoggerFactory.getLogger(AbstractEngineForkchoiceUpdated.class); private final MergeMiningCoordinator mergeCoordinator; - protected final Long cancunTimestamp; + protected final Optional cancunMilestone; public AbstractEngineForkchoiceUpdated( final Vertx vertx, @@ -65,9 +65,7 @@ public abstract class AbstractEngineForkchoiceUpdated extends ExecutionEngineJso super(vertx, protocolSchedule, protocolContext, engineCallListener); this.mergeCoordinator = mergeCoordinator; - Optional cancun = - protocolSchedule.hardforkFor(s -> s.fork().name().equalsIgnoreCase("Cancun")); - cancunTimestamp = cancun.map(ScheduledProtocolSpec.Hardfork::milestone).orElse(Long.MAX_VALUE); + cancunMilestone = protocolSchedule.milestoneFor(CANCUN); } protected ValidationResult validateParameter( diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineForkchoiceUpdatedV2.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineForkchoiceUpdatedV2.java index 747c63c162..1dedf2919a 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineForkchoiceUpdatedV2.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineForkchoiceUpdatedV2.java @@ -21,6 +21,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.EnginePaylo import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; +import org.hyperledger.besu.ethereum.mainnet.ValidationResult; import java.util.Optional; @@ -51,20 +52,22 @@ public class EngineForkchoiceUpdatedV2 extends AbstractEngineForkchoiceUpdated { @Override protected Optional isPayloadAttributesValid( final Object requestId, final EnginePayloadAttributesParameter payloadAttributes) { - if (payloadAttributes.getTimestamp() >= cancunTimestamp) { - if (payloadAttributes.getParentBeaconBlockRoot() == null - || payloadAttributes.getParentBeaconBlockRoot().isEmpty()) { - return Optional.of(new JsonRpcErrorResponse(requestId, RpcErrorType.UNSUPPORTED_FORK)); - } else { - return Optional.of( - new JsonRpcErrorResponse(requestId, RpcErrorType.INVALID_PAYLOAD_ATTRIBUTES)); - } - } else if (payloadAttributes.getParentBeaconBlockRoot() != null) { + + if (payloadAttributes.getParentBeaconBlockRoot() != null) { LOG.error( - "Parent beacon block root hash present in payload attributes before cancun hardfork"); + "Parent beacon block root hash present in payload attributes before Cancun hardfork"); return Optional.of(new JsonRpcErrorResponse(requestId, getInvalidPayloadAttributesError())); - } else { - return Optional.empty(); } + + return Optional.empty(); + } + + @Override + protected ValidationResult validateForkSupported(final long blockTimestamp) { + if (cancunMilestone.isPresent() && blockTimestamp >= cancunMilestone.get()) { + return ValidationResult.invalid(RpcErrorType.UNSUPPORTED_FORK); + } + + return ValidationResult.valid(); } } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineForkchoiceUpdatedV3.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineForkchoiceUpdatedV3.java index b5aebf4f5d..414d4625b2 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineForkchoiceUpdatedV3.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineForkchoiceUpdatedV3.java @@ -14,6 +14,8 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine; +import static org.hyperledger.besu.ethereum.mainnet.HardforkId.MainnetHardforkId.CANCUN; + import org.hyperledger.besu.consensus.merge.blockcreation.MergeMiningCoordinator; import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; @@ -22,7 +24,6 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.EnginePaylo import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; -import org.hyperledger.besu.ethereum.mainnet.ScheduledProtocolSpec; import org.hyperledger.besu.ethereum.mainnet.ValidationResult; import java.util.Optional; @@ -33,7 +34,6 @@ import org.slf4j.LoggerFactory; public class EngineForkchoiceUpdatedV3 extends AbstractEngineForkchoiceUpdated { - private final Optional supportedHardFork; private static final Logger LOG = LoggerFactory.getLogger(EngineForkchoiceUpdatedV3.class); public EngineForkchoiceUpdatedV3( @@ -43,11 +43,6 @@ public class EngineForkchoiceUpdatedV3 extends AbstractEngineForkchoiceUpdated { final MergeMiningCoordinator mergeCoordinator, final EngineCallListener engineCallListener) { super(vertx, protocolSchedule, protocolContext, mergeCoordinator, engineCallListener); - this.supportedHardFork = - protocolSchedule.hardforkFor( - s -> - s.fork().name().equalsIgnoreCase("Cancun") - || s.fork().name().equalsIgnoreCase("Prague")); } @Override @@ -80,18 +75,7 @@ public class EngineForkchoiceUpdatedV3 extends AbstractEngineForkchoiceUpdated { @Override protected ValidationResult validateForkSupported(final long blockTimestamp) { - if (protocolSchedule.isPresent()) { - if (supportedHardFork.isPresent() && blockTimestamp >= supportedHardFork.get().milestone()) { - return ValidationResult.valid(); - } else { - return ValidationResult.invalid( - RpcErrorType.UNSUPPORTED_FORK, - "Cancun configured to start at timestamp: " + supportedHardFork.get().milestone()); - } - } else { - return ValidationResult.invalid( - RpcErrorType.UNSUPPORTED_FORK, "Configuration error, no schedule for Cancun fork set"); - } + return ForkSupportHelper.validateForkSupported(CANCUN, cancunMilestone, blockTimestamp); } @Override @@ -101,12 +85,16 @@ public class EngineForkchoiceUpdatedV3 extends AbstractEngineForkchoiceUpdated { LOG.error( "Parent beacon block root hash not present in payload attributes after cancun hardfork"); return Optional.of(new JsonRpcErrorResponse(requestId, getInvalidPayloadAttributesError())); - } else if (payloadAttributes.getTimestamp().longValue() == 0) { + } + + if (payloadAttributes.getTimestamp() == 0) { return Optional.of(new JsonRpcErrorResponse(requestId, getInvalidPayloadAttributesError())); - } else if (payloadAttributes.getTimestamp() < supportedHardFork.get().milestone()) { + } + + if (cancunMilestone.isEmpty() || payloadAttributes.getTimestamp() < cancunMilestone.get()) { return Optional.of(new JsonRpcErrorResponse(requestId, RpcErrorType.UNSUPPORTED_FORK)); - } else { - return Optional.empty(); } + + return Optional.empty(); } } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV2.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV2.java index ade62077df..1732585f16 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV2.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV2.java @@ -14,6 +14,8 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine; +import static org.hyperledger.besu.ethereum.mainnet.HardforkId.MainnetHardforkId.CANCUN; + import org.hyperledger.besu.consensus.merge.PayloadWrapper; import org.hyperledger.besu.consensus.merge.blockcreation.MergeMiningCoordinator; import org.hyperledger.besu.ethereum.ProtocolContext; @@ -24,7 +26,6 @@ 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.BlockResultFactory; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; -import org.hyperledger.besu.ethereum.mainnet.ScheduledProtocolSpec; import org.hyperledger.besu.ethereum.mainnet.ValidationResult; import java.util.Optional; @@ -33,7 +34,7 @@ import io.vertx.core.Vertx; public class EngineGetPayloadV2 extends AbstractEngineGetPayload { - private final Optional cancun; + private final Optional cancunMilestone; public EngineGetPayloadV2( final Vertx vertx, @@ -49,7 +50,7 @@ public class EngineGetPayloadV2 extends AbstractEngineGetPayload { mergeMiningCoordinator, blockResultFactory, engineCallListener); - this.cancun = schedule.hardforkFor(s -> s.fork().name().equalsIgnoreCase("Cancun")); + cancunMilestone = schedule.milestoneFor(CANCUN); } @Override @@ -67,20 +68,10 @@ public class EngineGetPayloadV2 extends AbstractEngineGetPayload { @Override protected ValidationResult validateForkSupported(final long blockTimestamp) { - if (protocolSchedule.isPresent()) { - if (cancun.isPresent() && blockTimestamp >= cancun.get().milestone()) { - return ValidationResult.invalid( - RpcErrorType.UNSUPPORTED_FORK, - "Cancun configured to start at timestamp: " - + cancun.get().milestone() - + " please call engine_getPayloadV3"); - } else { - return ValidationResult.valid(); - } - } else { - return ValidationResult.invalid( - RpcErrorType.UNSUPPORTED_FORK, - "Configuration error, no schedule for Cancun fork set, not sure when to stop honoring use of V2"); + if (cancunMilestone.isPresent() && blockTimestamp >= cancunMilestone.get()) { + return ValidationResult.invalid(RpcErrorType.UNSUPPORTED_FORK); } + + return ValidationResult.valid(); } } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV3.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV3.java index 742a240aa0..555afb50b9 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV3.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV3.java @@ -14,6 +14,8 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine; +import static org.hyperledger.besu.ethereum.mainnet.HardforkId.MainnetHardforkId.CANCUN; + import org.hyperledger.besu.consensus.merge.PayloadWrapper; import org.hyperledger.besu.consensus.merge.blockcreation.MergeMiningCoordinator; import org.hyperledger.besu.ethereum.ProtocolContext; @@ -24,7 +26,6 @@ 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.BlockResultFactory; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; -import org.hyperledger.besu.ethereum.mainnet.ScheduledProtocolSpec; import org.hyperledger.besu.ethereum.mainnet.ValidationResult; import java.util.Optional; @@ -33,7 +34,7 @@ import io.vertx.core.Vertx; public class EngineGetPayloadV3 extends AbstractEngineGetPayload { - private final Optional cancun; + private final Optional cancunMilestone; public EngineGetPayloadV3( final Vertx vertx, @@ -49,7 +50,7 @@ public class EngineGetPayloadV3 extends AbstractEngineGetPayload { mergeMiningCoordinator, blockResultFactory, engineCallListener); - this.cancun = schedule.hardforkFor(s -> s.fork().name().equalsIgnoreCase("Cancun")); + cancunMilestone = schedule.milestoneFor(CANCUN); } @Override @@ -67,17 +68,6 @@ public class EngineGetPayloadV3 extends AbstractEngineGetPayload { @Override protected ValidationResult validateForkSupported(final long blockTimestamp) { - if (protocolSchedule.isPresent()) { - if (cancun.isPresent() && blockTimestamp >= cancun.get().milestone()) { - return ValidationResult.valid(); - } else { - return ValidationResult.invalid( - RpcErrorType.UNSUPPORTED_FORK, - "Cancun configured to start at timestamp: " + cancun.get().milestone()); - } - } else { - return ValidationResult.invalid( - RpcErrorType.UNSUPPORTED_FORK, "Configuration error, no schedule for Cancun fork set"); - } + return ForkSupportHelper.validateForkSupported(CANCUN, cancunMilestone, blockTimestamp); } } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV4.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV4.java index c5a713beea..f67a2743ea 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV4.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV4.java @@ -14,6 +14,8 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine; +import static org.hyperledger.besu.ethereum.mainnet.HardforkId.MainnetHardforkId.PRAGUE; + import org.hyperledger.besu.consensus.merge.PayloadWrapper; import org.hyperledger.besu.consensus.merge.blockcreation.MergeMiningCoordinator; import org.hyperledger.besu.ethereum.ProtocolContext; @@ -24,7 +26,6 @@ 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.BlockResultFactory; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; -import org.hyperledger.besu.ethereum.mainnet.ScheduledProtocolSpec; import org.hyperledger.besu.ethereum.mainnet.ValidationResult; import java.util.Optional; @@ -33,7 +34,7 @@ import io.vertx.core.Vertx; public class EngineGetPayloadV4 extends AbstractEngineGetPayload { - private final Optional prague; + private final Optional pragueMilestone; public EngineGetPayloadV4( final Vertx vertx, @@ -49,7 +50,7 @@ public class EngineGetPayloadV4 extends AbstractEngineGetPayload { mergeMiningCoordinator, blockResultFactory, engineCallListener); - this.prague = schedule.hardforkFor(s -> s.fork().name().equalsIgnoreCase("Prague")); + pragueMilestone = schedule.milestoneFor(PRAGUE); } @Override @@ -67,17 +68,6 @@ public class EngineGetPayloadV4 extends AbstractEngineGetPayload { @Override protected ValidationResult validateForkSupported(final long blockTimestamp) { - if (protocolSchedule.isPresent()) { - if (prague.isPresent() && blockTimestamp >= prague.get().milestone()) { - return ValidationResult.valid(); - } else { - return ValidationResult.invalid( - RpcErrorType.UNSUPPORTED_FORK, - "Prague configured to start at timestamp: " + prague.get().milestone()); - } - } else { - return ValidationResult.invalid( - RpcErrorType.UNSUPPORTED_FORK, "Configuration error, no schedule for Prague fork set"); - } + return ForkSupportHelper.validateForkSupported(PRAGUE, pragueMilestone, blockTimestamp); } } 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 640d8dc603..ba7624a493 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 @@ -14,6 +14,8 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine; +import static org.hyperledger.besu.ethereum.mainnet.HardforkId.MainnetHardforkId.CANCUN; + import org.hyperledger.besu.consensus.merge.blockcreation.MergeMiningCoordinator; import org.hyperledger.besu.datatypes.VersionedHash; import org.hyperledger.besu.ethereum.ProtocolContext; @@ -33,6 +35,7 @@ import java.util.Optional; import io.vertx.core.Vertx; public class EngineNewPayloadV2 extends AbstractEngineNewPayload { + private final Optional cancunMilestone; public EngineNewPayloadV2( final Vertx vertx, @@ -42,6 +45,7 @@ public class EngineNewPayloadV2 extends AbstractEngineNewPayload { final EthPeers ethPeers, final EngineCallListener engineCallListener) { super(vertx, protocolSchedule, protocolContext, mergeCoordinator, ethPeers, engineCallListener); + cancunMilestone = protocolSchedule.milestoneFor(CANCUN); } @Override @@ -74,4 +78,13 @@ public class EngineNewPayloadV2 extends AbstractEngineNewPayload { final ProtocolSpec protocolSpec) { return ValidationResult.valid(); } + + @Override + protected ValidationResult validateForkSupported(final long blockTimestamp) { + if (cancunMilestone.isPresent() && blockTimestamp >= cancunMilestone.get()) { + return ValidationResult.invalid(RpcErrorType.UNSUPPORTED_FORK); + } + + return ValidationResult.valid(); + } } 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 1ca232b773..c6bfb638c8 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 @@ -14,6 +14,8 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine; +import static org.hyperledger.besu.ethereum.mainnet.HardforkId.MainnetHardforkId.CANCUN; + import org.hyperledger.besu.consensus.merge.blockcreation.MergeMiningCoordinator; import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; @@ -21,7 +23,6 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.EnginePaylo import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.eth.manager.EthPeers; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; -import org.hyperledger.besu.ethereum.mainnet.ScheduledProtocolSpec; import org.hyperledger.besu.ethereum.mainnet.ValidationResult; import java.util.List; @@ -31,7 +32,7 @@ import io.vertx.core.Vertx; public class EngineNewPayloadV3 extends AbstractEngineNewPayload { - private final Optional cancun; + private final Optional cancunMilestone; public EngineNewPayloadV3( final Vertx vertx, @@ -42,7 +43,7 @@ public class EngineNewPayloadV3 extends AbstractEngineNewPayload { final EngineCallListener engineCallListener) { super( vertx, timestampSchedule, protocolContext, mergeCoordinator, ethPeers, engineCallListener); - this.cancun = timestampSchedule.hardforkFor(s -> s.fork().name().equalsIgnoreCase("Cancun")); + this.cancunMilestone = timestampSchedule.milestoneFor(CANCUN); } @Override @@ -73,18 +74,6 @@ public class EngineNewPayloadV3 extends AbstractEngineNewPayload { @Override protected ValidationResult validateForkSupported(final long blockTimestamp) { - if (protocolSchedule.isPresent()) { - if (cancun.isPresent() - && Long.compareUnsigned(blockTimestamp, cancun.get().milestone()) >= 0) { - return ValidationResult.valid(); - } else { - return ValidationResult.invalid( - RpcErrorType.UNSUPPORTED_FORK, - "Cancun configured to start at timestamp: " + cancun.get().milestone()); - } - } else { - return ValidationResult.invalid( - RpcErrorType.UNSUPPORTED_FORK, "Configuration error, no schedule for Cancun fork set"); - } + return ForkSupportHelper.validateForkSupported(CANCUN, cancunMilestone, blockTimestamp); } } 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 8b073a9555..09354fa1ba 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 @@ -14,6 +14,8 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine; +import static org.hyperledger.besu.ethereum.mainnet.HardforkId.MainnetHardforkId.PRAGUE; + import org.hyperledger.besu.consensus.merge.blockcreation.MergeMiningCoordinator; import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; @@ -21,7 +23,6 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.EnginePaylo import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.eth.manager.EthPeers; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; -import org.hyperledger.besu.ethereum.mainnet.ScheduledProtocolSpec; import org.hyperledger.besu.ethereum.mainnet.ValidationResult; import java.util.List; @@ -31,7 +32,7 @@ import io.vertx.core.Vertx; public class EngineNewPayloadV4 extends AbstractEngineNewPayload { - private final Optional prague; + private final Optional pragueMilestone; public EngineNewPayloadV4( final Vertx vertx, @@ -42,7 +43,7 @@ public class EngineNewPayloadV4 extends AbstractEngineNewPayload { final EngineCallListener engineCallListener) { super( vertx, timestampSchedule, protocolContext, mergeCoordinator, ethPeers, engineCallListener); - this.prague = timestampSchedule.hardforkFor(s -> s.fork().name().equalsIgnoreCase("prague")); + pragueMilestone = timestampSchedule.milestoneFor(PRAGUE); } @Override @@ -76,17 +77,6 @@ public class EngineNewPayloadV4 extends AbstractEngineNewPayload { @Override protected ValidationResult validateForkSupported(final long blockTimestamp) { - if (protocolSchedule.isPresent()) { - if (prague.isPresent() && blockTimestamp >= prague.get().milestone()) { - return ValidationResult.valid(); - } else { - return ValidationResult.invalid( - RpcErrorType.UNSUPPORTED_FORK, - "Prague configured to start at timestamp: " + prague.get().milestone()); - } - } else { - return ValidationResult.invalid( - RpcErrorType.UNSUPPORTED_FORK, "Configuration error, no schedule for Prague fork set"); - } + return ForkSupportHelper.validateForkSupported(PRAGUE, pragueMilestone, blockTimestamp); } } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/ForkSupportHelper.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/ForkSupportHelper.java new file mode 100644 index 0000000000..0059f3d61b --- /dev/null +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/ForkSupportHelper.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.api.jsonrpc.internal.methods.engine; + +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; +import org.hyperledger.besu.ethereum.mainnet.HardforkId; +import org.hyperledger.besu.ethereum.mainnet.ValidationResult; + +import java.util.Optional; + +public class ForkSupportHelper { + public static ValidationResult validateForkSupported( + final HardforkId hardforkId, + final Optional maybeForkMilestone, + final long blockTimestamp) { + if (maybeForkMilestone.isEmpty()) { + return ValidationResult.invalid( + RpcErrorType.UNSUPPORTED_FORK, + "Configuration error, no schedule for " + hardforkId.name() + " fork set"); + } + + if (blockTimestamp < maybeForkMilestone.get()) { + return ValidationResult.invalid( + RpcErrorType.UNSUPPORTED_FORK, + hardforkId.name() + " configured to start at timestamp: " + maybeForkMilestone.get()); + } + + return ValidationResult.valid(); + } +} diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineForkchoiceUpdatedTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineForkchoiceUpdatedTest.java index 6936f2833d..d2fb3c3741 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineForkchoiceUpdatedTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineForkchoiceUpdatedTest.java @@ -19,6 +19,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod.EngineStatus.INVALID; 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.mainnet.HardforkId.MainnetHardforkId.CANCUN; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.mock; @@ -92,6 +93,7 @@ public abstract class AbstractEngineForkchoiceUpdatedTest { private static final Vertx vertx = Vertx.vertx(); private static final Hash mockHash = Hash.hash(Bytes32.fromHexStringLenient("0x1337deadbeef")); + protected static final long CANCUN_MILESTONE = 1_000_000L; private static final EngineForkchoiceUpdatedParameter mockFcuParam = new EngineForkchoiceUpdatedParameter(mockHash, mockHash, mockHash); @@ -100,14 +102,14 @@ public abstract class AbstractEngineForkchoiceUpdatedTest { new BlockHeaderTestFixture().baseFeePerGas(Wei.ONE); @Mock private ProtocolSpec protocolSpec; - @Mock private ProtocolSchedule protocolSchedule; + @Mock protected ProtocolSchedule protocolSchedule; @Mock private ProtocolContext protocolContext; @Mock private MergeContext mergeContext; @Mock protected MergeMiningCoordinator mergeCoordinator; - @Mock private MutableBlockchain blockchain; + @Mock protected MutableBlockchain blockchain; @Mock private EngineCallListener engineCallListener; @@ -118,6 +120,7 @@ public abstract class AbstractEngineForkchoiceUpdatedTest { when(protocolSpec.getWithdrawalsValidator()) .thenReturn(new WithdrawalsValidator.ProhibitedWithdrawals()); when(protocolSchedule.getForNextBlockHeader(any(), anyLong())).thenReturn(protocolSpec); + when(protocolSchedule.milestoneFor(CANCUN)).thenReturn(Optional.of(CANCUN_MILESTONE)); this.method = methodFactory.create( vertx, protocolSchedule, protocolContext, mergeCoordinator, engineCallListener); @@ -237,7 +240,7 @@ public abstract class AbstractEngineForkchoiceUpdatedTest { var payloadParams = new EnginePayloadAttributesParameter( - String.valueOf(System.currentTimeMillis()), + String.valueOf(defaultPayloadTimestamp()), Bytes32.fromHexStringLenient("0xDEADBEEF").toHexString(), Address.ECREC.toString(), null, @@ -426,7 +429,7 @@ public abstract class AbstractEngineForkchoiceUpdatedTest { var payloadParams = new EnginePayloadAttributesParameter( - String.valueOf(System.currentTimeMillis()), + String.valueOf(defaultPayloadTimestamp()), Bytes32.fromHexStringLenient("0xDEADBEEF").toHexString(), Address.ECREC.toString(), null, @@ -488,7 +491,7 @@ public abstract class AbstractEngineForkchoiceUpdatedTest { var payloadParams = new EnginePayloadAttributesParameter( - String.valueOf(System.currentTimeMillis()), + String.valueOf(mockHeader.getTimestamp() + 1), Bytes32.fromHexStringLenient("0xDEADBEEF").toHexString(), Address.ECREC.toString(), emptyList(), @@ -513,7 +516,7 @@ public abstract class AbstractEngineForkchoiceUpdatedTest { var payloadParams = new EnginePayloadAttributesParameter( - String.valueOf(System.currentTimeMillis()), + String.valueOf(mockHeader.getTimestamp() + 1), Bytes32.fromHexStringLenient("0xDEADBEEF").toHexString(), Address.ECREC.toString(), null, @@ -557,7 +560,7 @@ public abstract class AbstractEngineForkchoiceUpdatedTest { var payloadParams = new EnginePayloadAttributesParameter( - String.valueOf(System.currentTimeMillis()), + String.valueOf(mockHeader.getTimestamp() + 1), Bytes32.fromHexStringLenient("0xDEADBEEF").toHexString(), Address.ECREC.toString(), null, @@ -593,7 +596,7 @@ public abstract class AbstractEngineForkchoiceUpdatedTest { var payloadParams = new EnginePayloadAttributesParameter( - String.valueOf(System.currentTimeMillis()), + String.valueOf(mockHeader.getTimestamp() + 1), Bytes32.fromHexStringLenient("0xDEADBEEF").toHexString(), Address.ECREC.toString(), withdrawalParameters, @@ -642,7 +645,7 @@ public abstract class AbstractEngineForkchoiceUpdatedTest { var payloadParams = new EnginePayloadAttributesParameter( - String.valueOf(System.currentTimeMillis()), + String.valueOf(mockHeader.getTimestamp() + 1), Bytes32.fromHexStringLenient("0xDEADBEEF").toHexString(), Address.ECREC.toString(), null, @@ -674,7 +677,7 @@ public abstract class AbstractEngineForkchoiceUpdatedTest { verify(engineCallListener, times(1)).executionEngineCalled(); } - private void setupValidForkchoiceUpdate(final BlockHeader mockHeader) { + protected void setupValidForkchoiceUpdate(final BlockHeader mockHeader) { when(blockchain.getBlockHeader(any())).thenReturn(Optional.of(mockHeader)); when(mergeCoordinator.getOrSyncHeadByHash(mockHeader.getHash(), Hash.ZERO)) .thenReturn(Optional.of(mockHeader)); @@ -738,7 +741,7 @@ public abstract class AbstractEngineForkchoiceUpdatedTest { return RpcErrorType.INVALID_PARAMS; } - private JsonRpcResponse resp( + protected JsonRpcResponse resp( final EngineForkchoiceUpdatedParameter forkchoiceParam, final Optional payloadParam) { return method.response( @@ -772,4 +775,8 @@ public abstract class AbstractEngineForkchoiceUpdatedTest { assertThat(errorResp.getErrorType()).isEqualTo(jsonRpcError); assertThat(errorResp.getError().getMessage()).isEqualTo(jsonRpcError.getMessage()); } + + protected long defaultPayloadTimestamp() { + return 1; + } } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractScheduledApiTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractScheduledApiTest.java index 9da345dbcd..bfe23e07e7 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractScheduledApiTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractScheduledApiTest.java @@ -14,7 +14,12 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine; -import static org.mockito.ArgumentMatchers.argThat; +import static org.hyperledger.besu.ethereum.mainnet.HardforkId.MainnetHardforkId.CANCUN; +import static org.hyperledger.besu.ethereum.mainnet.HardforkId.MainnetHardforkId.EXPERIMENTAL_EIPS; +import static org.hyperledger.besu.ethereum.mainnet.HardforkId.MainnetHardforkId.LONDON; +import static org.hyperledger.besu.ethereum.mainnet.HardforkId.MainnetHardforkId.PARIS; +import static org.hyperledger.besu.ethereum.mainnet.HardforkId.MainnetHardforkId.PRAGUE; +import static org.hyperledger.besu.ethereum.mainnet.HardforkId.MainnetHardforkId.SHANGHAI; import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.mock; @@ -67,22 +72,22 @@ public class AbstractScheduledApiTest { @BeforeEach public void before() { lenient() - .when(protocolSchedule.hardforkFor(argThat(new HardforkMatcher(londonHardfork)))) - .thenReturn(Optional.of(londonHardfork)); + .when(protocolSchedule.milestoneFor((LONDON))) + .thenReturn(Optional.of(londonHardfork.milestone())); lenient() - .when(protocolSchedule.hardforkFor(argThat(new HardforkMatcher(parisHardfork)))) - .thenReturn(Optional.of(parisHardfork)); + .when(protocolSchedule.milestoneFor(PARIS)) + .thenReturn(Optional.of(parisHardfork.milestone())); lenient() - .when(protocolSchedule.hardforkFor(argThat(new HardforkMatcher(cancunHardfork)))) - .thenReturn(Optional.of(cancunHardfork)); + .when(protocolSchedule.milestoneFor(CANCUN)) + .thenReturn(Optional.of(cancunHardfork.milestone())); lenient() - .when(protocolSchedule.hardforkFor(argThat(new HardforkMatcher(pragueHardfork)))) - .thenReturn(Optional.of(pragueHardfork)); + .when(protocolSchedule.milestoneFor(PRAGUE)) + .thenReturn(Optional.of(pragueHardfork.milestone())); lenient() - .when(protocolSchedule.hardforkFor(argThat(new HardforkMatcher(shanghaiHardfork)))) - .thenReturn(Optional.of(shanghaiHardfork)); + .when(protocolSchedule.milestoneFor(SHANGHAI)) + .thenReturn(Optional.of(shanghaiHardfork.milestone())); lenient() - .when(protocolSchedule.hardforkFor(argThat(new HardforkMatcher(experimentalHardfork)))) - .thenReturn(Optional.of(experimentalHardfork)); + .when(protocolSchedule.milestoneFor(EXPERIMENTAL_EIPS)) + .thenReturn(Optional.of(experimentalHardfork.milestone())); } } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineForkchoiceUpdatedV2Test.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineForkchoiceUpdatedV2Test.java index 550e1380d2..7ae80313a1 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineForkchoiceUpdatedV2Test.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineForkchoiceUpdatedV2Test.java @@ -15,10 +15,26 @@ 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.response.RpcErrorType.UNSUPPORTED_FORK; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import org.hyperledger.besu.consensus.merge.blockcreation.MergeMiningCoordinator; +import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.EngineForkchoiceUpdatedParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.EnginePayloadAttributesParameter; +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.RpcErrorType; +import org.hyperledger.besu.ethereum.core.BlockHeader; +import java.util.Optional; + +import org.apache.tuweni.bytes.Bytes32; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.junit.jupiter.MockitoExtension; @@ -39,6 +55,36 @@ public class EngineForkchoiceUpdatedV2Test extends AbstractEngineForkchoiceUpdat assertThat(method.getName()).isEqualTo("engine_forkchoiceUpdatedV2"); } + @Test + public void shouldReturnUnsupportedForkIfBlockTimestampIsAfterCancunMilestone() { + when(mergeCoordinator.updateForkChoice( + any(BlockHeader.class), any(Hash.class), any(Hash.class))) + .thenReturn(mock(MergeMiningCoordinator.ForkchoiceResult.class)); + + BlockHeader mockHeader = blockHeaderBuilder.timestamp(CANCUN_MILESTONE + 1).buildHeader(); + setupValidForkchoiceUpdate(mockHeader); + + final EngineForkchoiceUpdatedParameter param = + new EngineForkchoiceUpdatedParameter(mockHeader.getBlockHash(), Hash.ZERO, Hash.ZERO); + + final EnginePayloadAttributesParameter payloadParams = + new EnginePayloadAttributesParameter( + String.valueOf(mockHeader.getTimestamp()), + Bytes32.fromHexStringLenient("0xDEADBEEF").toHexString(), + Address.ECREC.toString(), + null, + null); + + final JsonRpcResponse resp = resp(param, Optional.of(payloadParams)); + + final JsonRpcError jsonRpcError = + Optional.of(resp) + .map(JsonRpcErrorResponse.class::cast) + .map(JsonRpcErrorResponse::getError) + .get(); + assertThat(jsonRpcError.getCode()).isEqualTo(UNSUPPORTED_FORK.getCode()); + } + @Override protected String getMethodName() { return RpcMethod.ENGINE_FORKCHOICE_UPDATED_V2.getMethodName(); 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 5f42f02c82..5c455222f1 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 @@ -15,16 +15,26 @@ 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.response.RpcErrorType.UNSUPPORTED_FORK; import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import org.hyperledger.besu.consensus.merge.PayloadWrapper; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; +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.JsonRpcSuccessResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.EngineGetPayloadResultV2; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.Quantity; +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.BlockWithReceipts; +import java.util.Collections; import java.util.Optional; import org.apache.tuweni.bytes.Bytes32; @@ -106,6 +116,29 @@ public class EngineGetPayloadV2Test extends AbstractEngineGetPayloadTest { verify(engineCallListener, times(1)).executionEngineCalled(); } + @Test + public void shouldReturnUnsupportedForkIfBlockTimestampIsAfterCancunMilestone() { + // Cancun starts at timestamp 30 + final BlockHeader mockHeader = new BlockHeaderTestFixture().timestamp(31L).buildHeader(); + final Block mockBlock = + new Block(mockHeader, new BlockBody(Collections.emptyList(), Collections.emptyList())); + final BlockWithReceipts mockBlockWithReceipts = + new BlockWithReceipts(mockBlock, Collections.emptyList()); + final PayloadWrapper mockPayload = new PayloadWrapper(mockPid, mockBlockWithReceipts); + + when(mergeContext.retrievePayloadById(mockPid)).thenReturn(Optional.of(mockPayload)); + + final var resp = resp(RpcMethod.ENGINE_GET_PAYLOAD_V2.getMethodName(), mockPid); + + final JsonRpcError jsonRpcError = + Optional.of(resp) + .map(JsonRpcErrorResponse.class::cast) + .map(JsonRpcErrorResponse::getError) + .get(); + assertThat(jsonRpcError.getCode()).isEqualTo(UNSUPPORTED_FORK.getCode()); + verify(engineCallListener, times(1)).executionEngineCalled(); + } + @Override protected String getMethodName() { return RpcMethod.ENGINE_GET_PAYLOAD_V2.getMethodName(); 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 afee556eda..4d53d83cf8 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 @@ -19,6 +19,7 @@ import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.Executi import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.WithdrawalParameterTestFixture.WITHDRAWAL_PARAM_1; import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType.INVALID_BLOB_GAS_USED_PARAMS; import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType.INVALID_PARAMS; +import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType.UNSUPPORTED_FORK; import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; @@ -193,6 +194,24 @@ public class EngineNewPayloadV2Test extends AbstractEngineNewPayloadTest { verify(engineCallListener, times(1)).executionEngineCalled(); } + @Test + public void shouldReturnUnsupportedForkIfBlockTimestampIsAfterCancunMilestone() { + // Cancun starte at timestamp 30 + final long blockTimestamp = 31L; + BlockHeader blockHeader = + createBlockHeaderFixture( + Optional.of(Collections.emptyList()), Optional.empty(), Optional.empty()) + .timestamp(blockTimestamp) + .buildHeader(); + + var resp = + resp(mockEnginePayload(blockHeader, Collections.emptyList(), List.of(), null, null, null)); + + final JsonRpcError jsonRpcError = fromErrorResp(resp); + assertThat(jsonRpcError.getCode()).isEqualTo(UNSUPPORTED_FORK.getCode()); + verify(engineCallListener, times(1)).executionEngineCalled(); + } + @Override protected ExecutionEngineJsonRpcMethod.EngineStatus getExpectedInvalidBlockHashStatus() { return INVALID; 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 8202588817..72f0108a69 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 @@ -66,6 +66,7 @@ import com.google.common.base.Suppliers; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.junit.jupiter.MockitoExtension; @@ -261,6 +262,12 @@ public class EngineNewPayloadV3Test extends EngineNewPayloadV2Test { .createTransaction(senderKeys); } + @Override + @Disabled + public void shouldReturnUnsupportedForkIfBlockTimestampIsAfterCancunMilestone() { + // only relevant for v2 + } + @Override protected JsonRpcResponse resp(final EnginePayloadParameter payload) { Object[] params = diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DefaultProtocolSchedule.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DefaultProtocolSchedule.java index e868abf2ae..d6d3cc0a55 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DefaultProtocolSchedule.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DefaultProtocolSchedule.java @@ -25,6 +25,8 @@ import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; import java.math.BigInteger; import java.util.Comparator; +import java.util.HashMap; +import java.util.Map; import java.util.NavigableSet; import java.util.Optional; import java.util.TreeSet; @@ -39,6 +41,8 @@ public class DefaultProtocolSchedule implements ProtocolSchedule { protected NavigableSet protocolSpecs = new TreeSet<>(Comparator.comparing(ScheduledProtocolSpec::fork).reversed()); + private final Map milestones = new HashMap<>(); + private final Optional chainId; public DefaultProtocolSchedule(final Optional chainId) { @@ -97,6 +101,12 @@ public class DefaultProtocolSchedule implements ProtocolSchedule { putMilestone(TimestampProtocolSpec.create(timestamp, protocolSpec)); } + @Override + public void setMilestones(final Map milestones) { + this.milestones.clear(); + this.milestones.putAll(milestones); + } + private void putMilestone(final ScheduledProtocolSpec scheduledProtocolSpec) { // Ensure this replaces any existing spec at the same block number. protocolSpecs.remove(scheduledProtocolSpec); @@ -117,6 +127,11 @@ public class DefaultProtocolSchedule implements ProtocolSchedule { .map(ScheduledProtocolSpec::fork); } + @Override + public Optional milestoneFor(final HardforkId hardforkId) { + return Optional.ofNullable(milestones.get(hardforkId)); + } + @Override public void setPermissionTransactionFilter( final PermissionTransactionFilter permissionTransactionFilter) { diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/HardforkId.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/HardforkId.java new file mode 100644 index 0000000000..6c764a4209 --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/HardforkId.java @@ -0,0 +1,61 @@ +/* + * 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; + +public interface HardforkId { + + String name(); + + enum MainnetHardforkId implements HardforkId { + FRONTIER, + HOMESTEAD, + DAO_FORK, + TANGERINE_WHISTLE, + SPURIOUS_DRAGON, + BYZANTIUM, + CONSTANTINOPLE, + PETERSBURG, + ISTANBUL, + MUIR_GLACIER, + BERLIN, + LONDON, + ARROW_GLACIER, + GRAY_GLACIER, + PARIS, + SHANGHAI, + CANCUN, + CANCUN_EOF, + PRAGUE, + PRAGUE_EOF, + FUTURE_EIPS, + EXPERIMENTAL_EIPS + } + + enum ClassicHardforkId implements HardforkId { + FRONTIER, + HOMESTEAD, + CLASSIC_TANGERINE_WHISTLE, + DIE_HARD, + GOTHAM, + DEFUSE_DIFFICULTY_BOMB, + ATLANTIS, + AGHARTA, + PHOENIX, + THANOS, + MAGNETO, + MYSTIQUE, + SPIRAL + } +} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolSchedule.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolSchedule.java index e07b2835e9..88448a8b54 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolSchedule.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolSchedule.java @@ -19,6 +19,7 @@ import org.hyperledger.besu.ethereum.core.BlockHeaderBuilder; import org.hyperledger.besu.ethereum.core.ProcessableBlockHeader; import java.math.BigInteger; +import java.util.Map; import java.util.Optional; import java.util.function.Predicate; @@ -46,11 +47,19 @@ public interface ProtocolSchedule extends PrivacySupportingProtocolSchedule { void putTimestampMilestone(final long timestamp, final ProtocolSpec protocolSpec); + default void setMilestones(final Map milestoneList) { + throw new UnsupportedOperationException("Not implemented"); + } + default Optional hardforkFor( final Predicate predicate) { throw new UnsupportedOperationException("Not implemented"); } + default Optional milestoneFor(final HardforkId hardforkId) { + throw new UnsupportedOperationException("Not implemented"); + } + boolean isOnMilestoneBoundary(final BlockHeader blockHeader); boolean anyMatch(Predicate predicate); 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 1cb3a5cb3c..fb8abbe1b6 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 @@ -23,6 +23,8 @@ import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.plugin.services.MetricsSystem; import java.math.BigInteger; +import java.util.List; +import java.util.Map; import java.util.NavigableMap; import java.util.Optional; import java.util.OptionalInt; @@ -142,7 +144,11 @@ public class ProtocolScheduleBuilder { validateForkOrdering(); - final NavigableMap builders = buildMilestoneMap(specFactory); + final List mileStones = createMilestones(specFactory); + final Map completeMileStoneList = buildFullMilestoneMap(mileStones); + protocolSchedule.setMilestones(completeMileStoneList); + + final NavigableMap builders = buildFlattenedMilestoneMap(mileStones); // At this stage, all milestones are flagged with the correct modifier, but ProtocolSpecs must // be @@ -159,7 +165,11 @@ public class ProtocolScheduleBuilder { builders.put( modifierBlock, new BuilderMapEntry( - parent.milestoneType, modifierBlock, parent.builder(), entry.getValue())); + parent.hardforkId, + parent.milestoneType, + modifierBlock, + parent.builder(), + entry.getValue())); }); } @@ -306,10 +316,9 @@ public class ProtocolScheduleBuilder { return referenceForkBlock; } - private NavigableMap buildMilestoneMap( - final MainnetProtocolSpecFactory specFactory) { - return createMilestones(specFactory) - .flatMap(Optional::stream) + private NavigableMap buildFlattenedMilestoneMap( + final List mileStones) { + return mileStones.stream() .collect( Collectors.toMap( BuilderMapEntry::blockIdentifier, @@ -318,68 +327,170 @@ public class ProtocolScheduleBuilder { TreeMap::new)); } - private Stream> createMilestones( - final MainnetProtocolSpecFactory specFactory) { + private Map buildFullMilestoneMap(final List mileStones) { + return mileStones.stream() + .collect( + Collectors.toMap( + b -> b.hardforkId, + BuilderMapEntry::blockIdentifier, + (existing, replacement) -> existing)); + } + + private List createMilestones(final MainnetProtocolSpecFactory specFactory) { return Stream.of( - blockNumberMilestone(OptionalLong.of(0), specFactory.frontierDefinition()), - blockNumberMilestone(config.getHomesteadBlockNumber(), specFactory.homesteadDefinition()), - blockNumberMilestone( - config.getTangerineWhistleBlockNumber(), specFactory.tangerineWhistleDefinition()), - blockNumberMilestone( - config.getSpuriousDragonBlockNumber(), specFactory.spuriousDragonDefinition()), - blockNumberMilestone(config.getByzantiumBlockNumber(), specFactory.byzantiumDefinition()), - blockNumberMilestone( - config.getConstantinopleBlockNumber(), specFactory.constantinopleDefinition()), - blockNumberMilestone(config.getPetersburgBlockNumber(), specFactory.petersburgDefinition()), - blockNumberMilestone(config.getIstanbulBlockNumber(), specFactory.istanbulDefinition()), - blockNumberMilestone( - config.getMuirGlacierBlockNumber(), specFactory.muirGlacierDefinition()), - blockNumberMilestone(config.getBerlinBlockNumber(), specFactory.berlinDefinition()), - blockNumberMilestone(config.getLondonBlockNumber(), specFactory.londonDefinition(config)), - blockNumberMilestone( - config.getArrowGlacierBlockNumber(), specFactory.arrowGlacierDefinition(config)), - blockNumberMilestone( - config.getGrayGlacierBlockNumber(), specFactory.grayGlacierDefinition(config)), - blockNumberMilestone( - config.getMergeNetSplitBlockNumber(), specFactory.parisDefinition(config)), - // Timestamp Forks - timestampMilestone(config.getShanghaiTime(), specFactory.shanghaiDefinition(config)), - timestampMilestone(config.getCancunTime(), specFactory.cancunDefinition(config)), - timestampMilestone(config.getCancunEOFTime(), specFactory.cancunEOFDefinition(config)), - timestampMilestone(config.getPragueTime(), specFactory.pragueDefinition(config)), - timestampMilestone(config.getPragueEOFTime(), specFactory.pragueEOFDefinition(config)), - timestampMilestone(config.getFutureEipsTime(), specFactory.futureEipsDefinition(config)), - timestampMilestone( - config.getExperimentalEipsTime(), specFactory.experimentalEipsDefinition(config)), - - // Classic Milestones - blockNumberMilestone( - config.getEcip1015BlockNumber(), specFactory.tangerineWhistleDefinition()), - blockNumberMilestone(config.getDieHardBlockNumber(), specFactory.dieHardDefinition()), - blockNumberMilestone(config.getGothamBlockNumber(), specFactory.gothamDefinition()), - blockNumberMilestone( - config.getDefuseDifficultyBombBlockNumber(), - specFactory.defuseDifficultyBombDefinition()), - blockNumberMilestone(config.getAtlantisBlockNumber(), specFactory.atlantisDefinition()), - blockNumberMilestone(config.getAghartaBlockNumber(), specFactory.aghartaDefinition()), - blockNumberMilestone(config.getPhoenixBlockNumber(), specFactory.phoenixDefinition()), - blockNumberMilestone(config.getThanosBlockNumber(), specFactory.thanosDefinition()), - blockNumberMilestone(config.getMagnetoBlockNumber(), specFactory.magnetoDefinition()), - blockNumberMilestone(config.getMystiqueBlockNumber(), specFactory.mystiqueDefinition()), - blockNumberMilestone(config.getSpiralBlockNumber(), specFactory.spiralDefinition())); + blockNumberMilestone( + HardforkId.MainnetHardforkId.FRONTIER, + OptionalLong.of(0), + specFactory.frontierDefinition()), + blockNumberMilestone( + HardforkId.MainnetHardforkId.HOMESTEAD, + config.getHomesteadBlockNumber(), + specFactory.homesteadDefinition()), + blockNumberMilestone( + HardforkId.MainnetHardforkId.TANGERINE_WHISTLE, + config.getTangerineWhistleBlockNumber(), + specFactory.tangerineWhistleDefinition()), + blockNumberMilestone( + HardforkId.MainnetHardforkId.SPURIOUS_DRAGON, + config.getSpuriousDragonBlockNumber(), + specFactory.spuriousDragonDefinition()), + blockNumberMilestone( + HardforkId.MainnetHardforkId.BYZANTIUM, + config.getByzantiumBlockNumber(), + specFactory.byzantiumDefinition()), + blockNumberMilestone( + HardforkId.MainnetHardforkId.CONSTANTINOPLE, + config.getConstantinopleBlockNumber(), + specFactory.constantinopleDefinition()), + blockNumberMilestone( + HardforkId.MainnetHardforkId.PETERSBURG, + config.getPetersburgBlockNumber(), + specFactory.petersburgDefinition()), + blockNumberMilestone( + HardforkId.MainnetHardforkId.ISTANBUL, + config.getIstanbulBlockNumber(), + specFactory.istanbulDefinition()), + blockNumberMilestone( + HardforkId.MainnetHardforkId.MUIR_GLACIER, + config.getMuirGlacierBlockNumber(), + specFactory.muirGlacierDefinition()), + blockNumberMilestone( + HardforkId.MainnetHardforkId.BERLIN, + config.getBerlinBlockNumber(), + specFactory.berlinDefinition()), + blockNumberMilestone( + HardforkId.MainnetHardforkId.LONDON, + config.getLondonBlockNumber(), + specFactory.londonDefinition(config)), + blockNumberMilestone( + HardforkId.MainnetHardforkId.ARROW_GLACIER, + config.getArrowGlacierBlockNumber(), + specFactory.arrowGlacierDefinition(config)), + blockNumberMilestone( + HardforkId.MainnetHardforkId.GRAY_GLACIER, + config.getGrayGlacierBlockNumber(), + specFactory.grayGlacierDefinition(config)), + blockNumberMilestone( + HardforkId.MainnetHardforkId.PARIS, + config.getMergeNetSplitBlockNumber(), + specFactory.parisDefinition(config)), + // Timestamp Forks + timestampMilestone( + HardforkId.MainnetHardforkId.SHANGHAI, + config.getShanghaiTime(), + specFactory.shanghaiDefinition(config)), + timestampMilestone( + HardforkId.MainnetHardforkId.CANCUN, + config.getCancunTime(), + specFactory.cancunDefinition(config)), + timestampMilestone( + HardforkId.MainnetHardforkId.CANCUN_EOF, + config.getCancunEOFTime(), + specFactory.cancunEOFDefinition(config)), + timestampMilestone( + HardforkId.MainnetHardforkId.PRAGUE, + config.getPragueTime(), + specFactory.pragueDefinition(config)), + timestampMilestone( + HardforkId.MainnetHardforkId.PRAGUE_EOF, + config.getPragueEOFTime(), + specFactory.pragueEOFDefinition(config)), + timestampMilestone( + HardforkId.MainnetHardforkId.FUTURE_EIPS, + config.getFutureEipsTime(), + specFactory.futureEipsDefinition(config)), + timestampMilestone( + HardforkId.MainnetHardforkId.EXPERIMENTAL_EIPS, + config.getExperimentalEipsTime(), + specFactory.experimentalEipsDefinition(config)), + + // Classic Milestones + blockNumberMilestone( + HardforkId.ClassicHardforkId.CLASSIC_TANGERINE_WHISTLE, + config.getEcip1015BlockNumber(), + specFactory.tangerineWhistleDefinition()), + blockNumberMilestone( + HardforkId.ClassicHardforkId.DIE_HARD, + config.getDieHardBlockNumber(), + specFactory.dieHardDefinition()), + blockNumberMilestone( + HardforkId.ClassicHardforkId.GOTHAM, + config.getGothamBlockNumber(), + specFactory.gothamDefinition()), + blockNumberMilestone( + HardforkId.ClassicHardforkId.DEFUSE_DIFFICULTY_BOMB, + config.getDefuseDifficultyBombBlockNumber(), + specFactory.defuseDifficultyBombDefinition()), + blockNumberMilestone( + HardforkId.ClassicHardforkId.ATLANTIS, + config.getAtlantisBlockNumber(), + specFactory.atlantisDefinition()), + blockNumberMilestone( + HardforkId.ClassicHardforkId.AGHARTA, + config.getAghartaBlockNumber(), + specFactory.aghartaDefinition()), + blockNumberMilestone( + HardforkId.ClassicHardforkId.PHOENIX, + config.getPhoenixBlockNumber(), + specFactory.phoenixDefinition()), + blockNumberMilestone( + HardforkId.ClassicHardforkId.THANOS, + config.getThanosBlockNumber(), + specFactory.thanosDefinition()), + blockNumberMilestone( + HardforkId.ClassicHardforkId.MAGNETO, + config.getMagnetoBlockNumber(), + specFactory.magnetoDefinition()), + blockNumberMilestone( + HardforkId.ClassicHardforkId.MYSTIQUE, + config.getMystiqueBlockNumber(), + specFactory.mystiqueDefinition()), + blockNumberMilestone( + HardforkId.ClassicHardforkId.SPIRAL, + config.getSpiralBlockNumber(), + specFactory.spiralDefinition())) + .flatMap(Optional::stream) + .toList(); } private Optional timestampMilestone( - final OptionalLong blockIdentifier, final ProtocolSpecBuilder builder) { - return createMilestone(blockIdentifier, builder, BuilderMapEntry.MilestoneType.TIMESTAMP); + final HardforkId hardforkId, + final OptionalLong blockIdentifier, + final ProtocolSpecBuilder builder) { + return createMilestone( + hardforkId, blockIdentifier, builder, BuilderMapEntry.MilestoneType.TIMESTAMP); } private Optional blockNumberMilestone( - final OptionalLong blockIdentifier, final ProtocolSpecBuilder builder) { - return createMilestone(blockIdentifier, builder, BuilderMapEntry.MilestoneType.BLOCK_NUMBER); + final HardforkId hardforkId, + final OptionalLong blockIdentifier, + final ProtocolSpecBuilder builder) { + return createMilestone( + hardforkId, blockIdentifier, builder, BuilderMapEntry.MilestoneType.BLOCK_NUMBER); } private Optional createMilestone( + final HardforkId hardforkId, final OptionalLong blockIdentifier, final ProtocolSpecBuilder builder, final BuilderMapEntry.MilestoneType milestoneType) { @@ -389,7 +500,11 @@ public class ProtocolScheduleBuilder { final long blockVal = blockIdentifier.getAsLong(); return Optional.of( new BuilderMapEntry( - milestoneType, blockVal, builder, protocolSpecAdapters.getModifierForBlock(blockVal))); + hardforkId, + milestoneType, + blockVal, + builder, + protocolSpecAdapters.getModifierForBlock(blockVal))); } private ProtocolSpec getProtocolSpec( @@ -429,6 +544,7 @@ public class ProtocolScheduleBuilder { } private record BuilderMapEntry( + HardforkId hardforkId, ProtocolScheduleBuilder.BuilderMapEntry.MilestoneType milestoneType, long blockIdentifier, ProtocolSpecBuilder builder, diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/ProtocolScheduleBuilderTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/ProtocolScheduleBuilderTest.java index 0e1011de76..a1f3d64797 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/ProtocolScheduleBuilderTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/ProtocolScheduleBuilderTest.java @@ -16,6 +16,11 @@ package org.hyperledger.besu.ethereum.mainnet; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.hyperledger.besu.ethereum.mainnet.HardforkId.MainnetHardforkId.BERLIN; +import static org.hyperledger.besu.ethereum.mainnet.HardforkId.MainnetHardforkId.CANCUN; +import static org.hyperledger.besu.ethereum.mainnet.HardforkId.MainnetHardforkId.LONDON; +import static org.hyperledger.besu.ethereum.mainnet.HardforkId.MainnetHardforkId.PRAGUE; +import static org.hyperledger.besu.ethereum.mainnet.HardforkId.MainnetHardforkId.SHANGHAI; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -32,6 +37,7 @@ import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import java.math.BigInteger; +import java.util.Optional; import java.util.OptionalLong; import java.util.function.Function; import java.util.stream.Collectors; @@ -122,6 +128,44 @@ class ProtocolScheduleBuilderTest { .isEqualTo("Prague"); } + @Test + void milestoneForShouldQueryAllAvailableHardforks() { + final long PRAGUE_TIME = 1722333828L; + + when(configOptions.getHomesteadBlockNumber()).thenReturn(OptionalLong.of(0)); + when(configOptions.getByzantiumBlockNumber()).thenReturn(OptionalLong.of(0)); + when(configOptions.getConstantinopleBlockNumber()).thenReturn(OptionalLong.of(0)); + when(configOptions.getPetersburgBlockNumber()).thenReturn(OptionalLong.of(0)); + when(configOptions.getIstanbulBlockNumber()).thenReturn(OptionalLong.of(0)); + when(configOptions.getBerlinBlockNumber()).thenReturn(OptionalLong.of(0)); + when(configOptions.getLondonBlockNumber()).thenReturn(OptionalLong.of(0)); + when(configOptions.getShanghaiTime()).thenReturn(OptionalLong.of(0)); + when(configOptions.getCancunTime()).thenReturn(OptionalLong.of(0)); + when(configOptions.getPragueTime()).thenReturn(OptionalLong.of(PRAGUE_TIME)); + + final ProtocolSchedule protocolSchedule = builder.createProtocolSchedule(); + + final Optional maybeBerlinMileStone = protocolSchedule.milestoneFor(BERLIN); + assertThat(maybeBerlinMileStone).isPresent(); + assertThat(maybeBerlinMileStone.get()).isEqualTo(0); + + final Optional maybeLondonMileStone = protocolSchedule.milestoneFor(LONDON); + assertThat(maybeLondonMileStone).isPresent(); + assertThat(maybeLondonMileStone.get()).isEqualTo(0); + + final Optional maybeShanghaiMileStone = protocolSchedule.milestoneFor(SHANGHAI); + assertThat(maybeShanghaiMileStone).isPresent(); + assertThat(maybeShanghaiMileStone.get()).isEqualTo(0); + + final Optional maybeCancunMileStone = protocolSchedule.milestoneFor(CANCUN); + assertThat(maybeCancunMileStone).isPresent(); + assertThat(maybeCancunMileStone.get()).isEqualTo(0); + + final Optional maybePragueMileStone = protocolSchedule.milestoneFor(PRAGUE); + assertThat(maybePragueMileStone).isPresent(); + assertThat(maybePragueMileStone.get()).isEqualTo(PRAGUE_TIME); + } + @Test void createProtocolScheduleOverlappingUsesLatestFork() { when(configOptions.getHomesteadBlockNumber()).thenReturn(OptionalLong.of(0L)); From 6623b2d693a06622c8dd2ec738ca0db8f206bb0d Mon Sep 17 00:00:00 2001 From: Luis Pinto Date: Mon, 12 Aug 2024 20:23:20 +0000 Subject: [PATCH 102/259] Move creator address warmup from targetContractAddress generation method to createe frame (#7415) Signed-off-by: Luis Pinto --- .../java/org/hyperledger/besu/evm/frame/MessageFrame.java | 1 + .../besu/evm/operation/AbstractCreateOperation.java | 4 ++-- .../hyperledger/besu/evm/operation/Create2Operation.java | 6 ++---- .../hyperledger/besu/evm/operation/CreateOperation.java | 7 ++----- .../hyperledger/besu/evm/operation/EOFCreateOperation.java | 6 ++---- .../besu/evm/operation/AbstractCreateOperationTest.java | 2 +- .../besu/evm/operation/Create2OperationTest.java | 2 +- 7 files changed, 11 insertions(+), 17 deletions(-) diff --git a/evm/src/main/java/org/hyperledger/besu/evm/frame/MessageFrame.java b/evm/src/main/java/org/hyperledger/besu/evm/frame/MessageFrame.java index cf77619229..fe44664d85 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/frame/MessageFrame.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/frame/MessageFrame.java @@ -1718,6 +1718,7 @@ public class MessageFrame { newTxValues = parentMessageFrame.txValues; updater = parentMessageFrame.getWorldUpdater().updater(); newStatic = isStatic || parentMessageFrame.isStatic; + parentMessageFrame.warmUpAddress(contract); } updater.setAuthorizedCodeService(authorizedCodeService); diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCreateOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCreateOperation.java index 16ea218f9c..901f7ff9de 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCreateOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCreateOperation.java @@ -153,7 +153,7 @@ public abstract class AbstractCreateOperation extends AbstractOperation { * @param initcode the initcode for the new contract. * @return the address */ - protected abstract Address targetContractAddress(MessageFrame frame, Code initcode); + protected abstract Address generateTargetContractAddress(MessageFrame frame, Code initcode); /** * Gets the initcode that will be run. @@ -175,7 +175,7 @@ public abstract class AbstractCreateOperation extends AbstractOperation { private void spawnChildMessage(final MessageFrame parent, final Code code, final EVM evm) { final Wei value = Wei.wrap(parent.getStackItem(0)); - final Address contractAddress = targetContractAddress(parent, code); + final Address contractAddress = generateTargetContractAddress(parent, code); final Bytes inputData = getInputData(parent); final long childGasStipend = diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/Create2Operation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/Create2Operation.java index a044cd138f..1fe3ef6469 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/Create2Operation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/Create2Operation.java @@ -58,13 +58,11 @@ public class Create2Operation extends AbstractCreateOperation { } @Override - public Address targetContractAddress(final MessageFrame frame, final Code initcode) { + public Address generateTargetContractAddress(final MessageFrame frame, final Code initcode) { final Address sender = frame.getRecipientAddress(); final Bytes32 salt = Bytes32.leftPad(frame.getStackItem(3)); final Bytes32 hash = keccak256(Bytes.concatenate(PREFIX, sender, salt, initcode.getCodeHash())); - final Address address = Address.extract(hash); - frame.warmUpAddress(address); - return address; + return Address.extract(hash); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/CreateOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/CreateOperation.java index fc26002453..a82288fff7 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/CreateOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/CreateOperation.java @@ -54,13 +54,10 @@ public class CreateOperation extends AbstractCreateOperation { } @Override - protected Address targetContractAddress(final MessageFrame frame, final Code initcode) { + protected Address generateTargetContractAddress(final MessageFrame frame, final Code initcode) { final Account sender = frame.getWorldUpdater().get(frame.getRecipientAddress()); // Decrement nonce by 1 to normalize the effect of transaction execution - final Address address = - Address.contractAddress(frame.getRecipientAddress(), sender.getNonce() - 1L); - frame.warmUpAddress(address); - return address; + return Address.contractAddress(frame.getRecipientAddress(), sender.getNonce() - 1L); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/EOFCreateOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/EOFCreateOperation.java index 0fb1e34a74..11d361e54c 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/EOFCreateOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/EOFCreateOperation.java @@ -59,13 +59,11 @@ public class EOFCreateOperation extends AbstractCreateOperation { } @Override - public Address targetContractAddress(final MessageFrame frame, final Code initcode) { + public Address generateTargetContractAddress(final MessageFrame frame, final Code initcode) { final Address sender = frame.getRecipientAddress(); final Bytes32 salt = Bytes32.leftPad(frame.getStackItem(1)); final Bytes32 hash = keccak256(Bytes.concatenate(PREFIX, sender, salt, initcode.getCodeHash())); - final Address address = Address.extract(hash); - frame.warmUpAddress(address); - return address; + return Address.extract(hash); } @Override diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operation/AbstractCreateOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operation/AbstractCreateOperationTest.java index 3c99bd71ff..d066b4e9ab 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operation/AbstractCreateOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operation/AbstractCreateOperationTest.java @@ -118,7 +118,7 @@ class AbstractCreateOperationTest { } @Override - protected Address targetContractAddress(final MessageFrame frame, final Code initcode) { + protected Address generateTargetContractAddress(final MessageFrame frame, final Code initcode) { final Account sender = frame.getWorldUpdater().get(frame.getRecipientAddress()); // Decrement nonce by 1 to normalize the effect of transaction execution final Address address = 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 51e2863a69..a08fd2916f 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 @@ -185,7 +185,7 @@ public class Create2OperationTest { final int ignoredExpectedGas) { setUp(sender, salt, code); final Address targetContractAddress = - operation.targetContractAddress( + operation.generateTargetContractAddress( messageFrame, evm.getCodeUncached(Bytes.fromHexString(code))); assertThat(targetContractAddress).isEqualTo(Address.fromHexString(expectedAddress)); } From b53db47dab5f509d775a681dc8aff4d477049441 Mon Sep 17 00:00:00 2001 From: daniellehrner Date: Mon, 12 Aug 2024 23:28:06 +0200 Subject: [PATCH 103/259] Wrapped WorldUpdater into `EVMWorldupdater` (#7434) * wrapped WorldUpdater into `EVMWorldupdater` to remove the authority code injection from the implementation of the actual world updaters Signed-off-by: Daniel Lehrner * add CHANGELOG entry Signed-off-by: Daniel Lehrner --------- Signed-off-by: Daniel Lehrner Co-authored-by: Justin Florentine Co-authored-by: Sally MacFarlane --- CHANGELOG.md | 1 + .../ethereum/mainnet/AuthorityProcessor.java | 20 +-- .../mainnet/MainnetTransactionProcessor.java | 34 ++--- .../PrivateMutableWorldStateUpdater.java | 20 +-- .../DiffBasedWorldStateUpdateAccumulator.java | 6 +- .../besu/evm/fluent/SimpleWorld.java | 23 +--- .../besu/evm/frame/MessageFrame.java | 36 +---- .../evm/operation/AbstractCallOperation.java | 1 - .../operation/AbstractCreateOperation.java | 1 - .../operation/AbstractExtCallOperation.java | 1 - .../evm/worldstate/AbstractWorldUpdater.java | 22 +-- .../besu/evm/worldstate/EVMWorldUpdater.java | 127 ++++++++++++++++++ .../besu/evm/worldstate/JournaledUpdater.java | 22 +-- .../besu/evm/worldstate/WorldUpdater.java | 8 -- .../hyperledger/besu/evm/toy/ToyWorld.java | 22 +-- 15 files changed, 188 insertions(+), 156 deletions(-) create mode 100644 evm/src/main/java/org/hyperledger/besu/evm/worldstate/EVMWorldUpdater.java diff --git a/CHANGELOG.md b/CHANGELOG.md index e7921fac5f..616ac3d1dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ ### Additions and Improvements - Expose set finalized/safe block in plugin api BlockchainService. These method can be used by plugins to set finalized/safe block for a PoA network (such as QBFT, IBFT and Clique).[#7382](https://github.com/hyperledger/besu/pull/7382) - In process RPC service [#7395](https://github.com/hyperledger/besu/pull/7395) +- Wrap WorldUpdater into EVMWorldupdater [#7434](https://github.com/hyperledger/besu/pull/7434) ### Bug fixes - Correct entrypoint in Docker evmtool [#7430](https://github.com/hyperledger/besu/pull/7430) diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/AuthorityProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/AuthorityProcessor.java index c40eca0f74..1d25d2d34f 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/AuthorityProcessor.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/AuthorityProcessor.java @@ -18,8 +18,7 @@ import org.hyperledger.besu.ethereum.core.Transaction; import org.hyperledger.besu.evm.account.Account; import org.hyperledger.besu.evm.account.AccountState; import org.hyperledger.besu.evm.account.MutableAccount; -import org.hyperledger.besu.evm.worldstate.AuthorizedCodeService; -import org.hyperledger.besu.evm.worldstate.WorldUpdater; +import org.hyperledger.besu.evm.worldstate.EVMWorldUpdater; import java.math.BigInteger; import java.util.Optional; @@ -38,10 +37,7 @@ public class AuthorityProcessor { } public void addContractToAuthority( - final WorldUpdater worldState, - final AuthorizedCodeService authorizedCodeService, - final Transaction transaction) { - + final EVMWorldUpdater evmWorldUpdater, final Transaction transaction) { transaction .getAuthorizationList() .get() @@ -60,7 +56,7 @@ public class AuthorityProcessor { } final Optional maybeAccount = - Optional.ofNullable(worldState.getAccount(authorityAddress)); + Optional.ofNullable(evmWorldUpdater.getAccount(authorityAddress)); final long accountNonce = maybeAccount.map(AccountState::getNonce).orElse(0L); @@ -69,12 +65,14 @@ public class AuthorityProcessor { return; } - if (authorizedCodeService.hasAuthorizedCode(authorityAddress)) { + if (evmWorldUpdater + .authorizedCodeService() + .hasAuthorizedCode(authorityAddress)) { return; } Optional codeAccount = - Optional.ofNullable(worldState.get(payload.address())); + Optional.ofNullable(evmWorldUpdater.get(payload.address())); final Bytes code; if (codeAccount.isPresent()) { code = codeAccount.get().getCode(); @@ -82,7 +80,9 @@ public class AuthorityProcessor { code = Bytes.EMPTY; } - authorizedCodeService.addAuthorizedCode(authorityAddress, code); + evmWorldUpdater + .authorizedCodeService() + .addAuthorizedCode(authorityAddress, code); })); } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java index cb9cd24e23..b008a8d5f6 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java @@ -42,7 +42,7 @@ import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.gascalculator.GasCalculator; import org.hyperledger.besu.evm.processor.AbstractMessageProcessor; import org.hyperledger.besu.evm.tracing.OperationTracer; -import org.hyperledger.besu.evm.worldstate.AuthorizedCodeService; +import org.hyperledger.besu.evm.worldstate.EVMWorldUpdater; import org.hyperledger.besu.evm.worldstate.WorldUpdater; import java.util.Deque; @@ -286,9 +286,8 @@ public class MainnetTransactionProcessor { final TransactionValidationParams transactionValidationParams, final PrivateMetadataUpdater privateMetadataUpdater, final Wei blobGasPrice) { + final EVMWorldUpdater evmWorldUpdater = new EVMWorldUpdater(worldState); try { - final AuthorizedCodeService authorizedCodeService = new AuthorizedCodeService(); - worldState.setAuthorizedCodeService(authorizedCodeService); final var transactionValidator = transactionValidatorFactory.get(); LOG.trace("Starting execution of {}", transaction); ValidationResult validationResult = @@ -306,7 +305,7 @@ public class MainnetTransactionProcessor { } final Address senderAddress = transaction.getSender(); - final MutableAccount sender = worldState.getOrCreateSenderAccount(senderAddress); + final MutableAccount sender = evmWorldUpdater.getOrCreateSenderAccount(senderAddress); validationResult = transactionValidator.validateForSender(transaction, sender, transactionValidationParams); @@ -315,7 +314,7 @@ public class MainnetTransactionProcessor { return TransactionProcessingResult.invalid(validationResult); } - operationTracer.tracePrepareTransaction(worldState, transaction); + operationTracer.tracePrepareTransaction(evmWorldUpdater, transaction); final Set
addressList = new BytesTrieSet<>(Address.SIZE); @@ -324,10 +323,8 @@ public class MainnetTransactionProcessor { throw new RuntimeException("Authority processor is required for 7702 transactions"); } - maybeAuthorityProcessor - .get() - .addContractToAuthority(worldState, authorizedCodeService, transaction); - addressList.addAll(authorizedCodeService.getAuthorities()); + maybeAuthorityProcessor.get().addContractToAuthority(evmWorldUpdater, transaction); + addressList.addAll(evmWorldUpdater.authorizedCodeService().getAuthorities()); } final long previousNonce = sender.incrementNonce(); @@ -384,8 +381,7 @@ public class MainnetTransactionProcessor { accessListGas, setCodeGas); - final WorldUpdater worldUpdater = worldState.updater(); - worldUpdater.setAuthorizedCodeService(authorizedCodeService); + final WorldUpdater worldUpdater = evmWorldUpdater.updater(); final ImmutableMap.Builder contextVariablesBuilder = ImmutableMap.builder() .put(KEY_IS_PERSISTING_PRIVATE_STATE, isPersistingPrivateState) @@ -437,12 +433,11 @@ public class MainnetTransactionProcessor { .contract(contractAddress) .inputData(initCodeBytes.slice(code.getSize())) .code(code) - .authorizedCodeService(authorizedCodeService) .build(); } else { @SuppressWarnings("OptionalGetWithoutIsPresent") // isContractCall tests isPresent final Address to = transaction.getTo().get(); - final Optional maybeContract = Optional.ofNullable(worldState.get(to)); + final Optional maybeContract = Optional.ofNullable(evmWorldUpdater.get(to)); initialFrame = commonMessageFrameBuilder .type(MessageFrame.Type.MESSAGE_CALL) @@ -453,7 +448,6 @@ public class MainnetTransactionProcessor { maybeContract .map(c -> messageCallProcessor.getCodeFromEVM(c.getCodeHash(), c.getCode())) .orElse(CodeV0.EMPTY_CODE)) - .authorizedCodeService(authorizedCodeService) .build(); } Deque messageFrameStack = initialFrame.getMessageFrameStack(); @@ -532,9 +526,9 @@ public class MainnetTransactionProcessor { operationTracer.traceBeforeRewardTransaction(worldUpdater, transaction, coinbaseWeiDelta); - final var coinbase = worldState.getOrCreate(miningBeneficiary); + final var coinbase = evmWorldUpdater.getOrCreate(miningBeneficiary); coinbase.incrementBalance(coinbaseWeiDelta); - authorizedCodeService.resetAuthorities(); + evmWorldUpdater.authorizedCodeService().resetAuthorities(); operationTracer.traceEndTransaction( worldUpdater, @@ -546,10 +540,10 @@ public class MainnetTransactionProcessor { initialFrame.getSelfDestructs(), 0L); - initialFrame.getSelfDestructs().forEach(worldState::deleteAccount); + initialFrame.getSelfDestructs().forEach(evmWorldUpdater::deleteAccount); if (clearEmptyAccounts) { - worldState.clearAccountsThatAreEmpty(); + evmWorldUpdater.clearAccountsThatAreEmpty(); } if (initialFrame.getState() == MessageFrame.State.COMPLETED_SUCCESS) { @@ -577,7 +571,7 @@ public class MainnetTransactionProcessor { } } catch (final MerkleTrieException re) { operationTracer.traceEndTransaction( - worldState.updater(), + evmWorldUpdater.updater(), transaction, false, Bytes.EMPTY, @@ -590,7 +584,7 @@ public class MainnetTransactionProcessor { throw re; } catch (final RuntimeException re) { operationTracer.traceEndTransaction( - worldState.updater(), + evmWorldUpdater.updater(), transaction, false, Bytes.EMPTY, diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateMutableWorldStateUpdater.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateMutableWorldStateUpdater.java index b4e8e28561..fc20db7f81 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateMutableWorldStateUpdater.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateMutableWorldStateUpdater.java @@ -18,7 +18,6 @@ import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.evm.account.Account; import org.hyperledger.besu.evm.account.MutableAccount; -import org.hyperledger.besu.evm.worldstate.AuthorizedCodeService; import org.hyperledger.besu.evm.worldstate.WorldUpdater; import java.util.Collection; @@ -31,39 +30,35 @@ public class PrivateMutableWorldStateUpdater implements WorldUpdater { protected final WorldUpdater publicWorldUpdater; protected final WorldUpdater privateWorldUpdater; - private AuthorizedCodeService authorizedCodeService; public PrivateMutableWorldStateUpdater( final WorldUpdater publicWorldUpdater, final WorldUpdater privateWorldUpdater) { this.publicWorldUpdater = publicWorldUpdater; this.privateWorldUpdater = privateWorldUpdater; - this.authorizedCodeService = new AuthorizedCodeService(); } @Override public MutableAccount createAccount(final Address address, final long nonce, final Wei balance) { - return authorizedCodeService.processMutableAccount( - this, privateWorldUpdater.createAccount(address, nonce, balance), address); + return privateWorldUpdater.createAccount(address, nonce, balance); } @Override public MutableAccount createAccount(final Address address) { - return authorizedCodeService.processMutableAccount( - this, privateWorldUpdater.createAccount(address), address); + return privateWorldUpdater.createAccount(address); } @Override public MutableAccount getAccount(final Address address) { final MutableAccount privateAccount = privateWorldUpdater.getAccount(address); if (privateAccount != null && !privateAccount.isEmpty()) { - return authorizedCodeService.processMutableAccount(this, privateAccount, address); + return privateAccount; } final MutableAccount publicAccount = publicWorldUpdater.getAccount(address); if (publicAccount != null && !publicAccount.isEmpty()) { publicAccount.becomeImmutable(); - return authorizedCodeService.processMutableAccount(this, publicAccount, address); + return publicAccount; } - return authorizedCodeService.processMutableAccount(this, privateAccount, address); + return privateAccount; } @Override @@ -109,9 +104,4 @@ public class PrivateMutableWorldStateUpdater implements WorldUpdater { public Optional parentUpdater() { return privateWorldUpdater.parentUpdater(); } - - @Override - public void setAuthorizedCodeService(final AuthorizedCodeService authorizedCodeService) { - this.authorizedCodeService = authorizedCodeService; - } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/worldview/accumulator/DiffBasedWorldStateUpdateAccumulator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/worldview/accumulator/DiffBasedWorldStateUpdateAccumulator.java index 0799ed3db2..c28bb731b5 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/worldview/accumulator/DiffBasedWorldStateUpdateAccumulator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/worldview/accumulator/DiffBasedWorldStateUpdateAccumulator.java @@ -250,8 +250,7 @@ public abstract class DiffBasedWorldStateUpdateAccumulator(diffBasedValue.getUpdated())), address); + return track(new UpdateTrackingAccount<>(diffBasedValue.getUpdated())); } else { throw new IllegalStateException("Cannot create an account when one already exists"); } @@ -268,8 +267,7 @@ public abstract class DiffBasedWorldStateUpdateAccumulator(newAccount)), address); + return track(new UpdateTrackingAccount<>(newAccount)); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/fluent/SimpleWorld.java b/evm/src/main/java/org/hyperledger/besu/evm/fluent/SimpleWorld.java index c64ca3744f..f52e788bab 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/fluent/SimpleWorld.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/fluent/SimpleWorld.java @@ -18,7 +18,6 @@ import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.evm.account.Account; import org.hyperledger.besu.evm.account.MutableAccount; -import org.hyperledger.besu.evm.worldstate.AuthorizedCodeService; import org.hyperledger.besu.evm.worldstate.WorldUpdater; import java.util.Collection; @@ -35,8 +34,6 @@ public class SimpleWorld implements WorldUpdater { /** The Accounts. */ Map accounts = new HashMap<>(); - private AuthorizedCodeService authorizedCodeService; - /** Instantiates a new Simple world. */ public SimpleWorld() { this(null); @@ -49,7 +46,6 @@ public class SimpleWorld implements WorldUpdater { */ public SimpleWorld(final SimpleWorld parent) { this.parent = parent; - this.authorizedCodeService = new AuthorizedCodeService(); } @Override @@ -60,11 +56,11 @@ public class SimpleWorld implements WorldUpdater { @Override public Account get(final Address address) { if (accounts.containsKey(address)) { - return authorizedCodeService.processAccount(this, accounts.get(address), address); + return accounts.get(address); } else if (parent != null) { - return authorizedCodeService.processAccount(this, parent.get(address), address); + return parent.get(address); } else { - return authorizedCodeService.processAccount(this, null, address); + return null; } } @@ -75,14 +71,14 @@ public class SimpleWorld implements WorldUpdater { } SimpleAccount account = new SimpleAccount(address, nonce, balance); accounts.put(address, account); - return authorizedCodeService.processMutableAccount(this, account, address); + return account; } @Override public MutableAccount getAccount(final Address address) { SimpleAccount account = accounts.get(address); if (account != null) { - return authorizedCodeService.processMutableAccount(this, account, address); + return account; } Account parentAccount = parent == null ? null : parent.getAccount(address); if (parentAccount != null) { @@ -94,9 +90,9 @@ public class SimpleWorld implements WorldUpdater { parentAccount.getBalance(), parentAccount.getCode()); accounts.put(address, account); - return authorizedCodeService.processMutableAccount(this, account, address); + return account; } - return authorizedCodeService.processMutableAccount(this, null, address); + return null; } @Override @@ -136,9 +132,4 @@ public class SimpleWorld implements WorldUpdater { public Optional parentUpdater() { return Optional.ofNullable(parent); } - - @Override - public void setAuthorizedCodeService(final AuthorizedCodeService authorizedCodeService) { - this.authorizedCodeService = authorizedCodeService; - } } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/frame/MessageFrame.java b/evm/src/main/java/org/hyperledger/besu/evm/frame/MessageFrame.java index fe44664d85..16551876d2 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/frame/MessageFrame.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/frame/MessageFrame.java @@ -33,7 +33,6 @@ import org.hyperledger.besu.evm.internal.UnderflowException; import org.hyperledger.besu.evm.log.Log; import org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup; import org.hyperledger.besu.evm.operation.Operation; -import org.hyperledger.besu.evm.worldstate.AuthorizedCodeService; import org.hyperledger.besu.evm.worldstate.WorldUpdater; import java.util.ArrayDeque; @@ -202,7 +201,6 @@ public class MessageFrame { // Global data fields. private final WorldUpdater worldUpdater; - private final AuthorizedCodeService authorizedCodeService; // Metadata fields. private final Type type; @@ -272,8 +270,7 @@ public class MessageFrame { final Consumer completer, final Map contextVariables, final Optional revertReason, - final TxValues txValues, - final AuthorizedCodeService authorizedCodeService) { + final TxValues txValues) { this.txValues = txValues; this.type = type; @@ -293,7 +290,6 @@ public class MessageFrame { this.completer = completer; this.contextVariables = contextVariables; this.revertReason = revertReason; - this.authorizedCodeService = authorizedCodeService; this.undoMark = txValues.transientStorage().mark(); } @@ -427,15 +423,6 @@ public class MessageFrame { return returnData; } - /** - * Return the authorized account service. - * - * @return the authorized account service - */ - public AuthorizedCodeService getAuthorizedCodeService() { - return authorizedCodeService; - } - /** * Set the return data. * @@ -1360,7 +1347,6 @@ public class MessageFrame { private Optional reason = Optional.empty(); private Set
accessListWarmAddresses = emptySet(); private Multimap accessListWarmStorage = HashMultimap.create(); - private AuthorizedCodeService authorizedCodeService; private Optional> versionedHashes = Optional.empty(); @@ -1645,17 +1631,6 @@ public class MessageFrame { return this; } - /** - * Sets authorized account service. - * - * @param authorizedCodeService the authorized account service - * @return the builder - */ - public Builder authorizedCodeService(final AuthorizedCodeService authorizedCodeService) { - this.authorizedCodeService = authorizedCodeService; - return this; - } - private void validate() { if (parentMessageFrame == null) { checkState(worldUpdater != null, "Missing message frame world updater"); @@ -1690,10 +1665,6 @@ public class MessageFrame { boolean newStatic; TxValues newTxValues; - if (authorizedCodeService == null) { - authorizedCodeService = new AuthorizedCodeService(); - } - if (parentMessageFrame == null) { newTxValues = new TxValues( @@ -1721,8 +1692,6 @@ public class MessageFrame { parentMessageFrame.warmUpAddress(contract); } - updater.setAuthorizedCodeService(authorizedCodeService); - MessageFrame messageFrame = new MessageFrame( type, @@ -1739,8 +1708,7 @@ public class MessageFrame { completer, contextVariables == null ? Map.of() : contextVariables, reason, - newTxValues, - authorizedCodeService); + newTxValues); newTxValues.messageFrameStack().addFirst(messageFrame); messageFrame.warmUpAddress(sender); messageFrame.warmUpAddress(contract); diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCallOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCallOperation.java index 68ded6793e..12cb06eaa6 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCallOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCallOperation.java @@ -230,7 +230,6 @@ public abstract class AbstractCallOperation extends AbstractOperation { .code(code) .isStatic(isStatic(frame)) .completer(child -> complete(frame, child)) - .authorizedCodeService(frame.getAuthorizedCodeService()) .build(); // see note in stack depth check about incrementing cost frame.incrementRemainingGas(cost); diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCreateOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCreateOperation.java index 901f7ff9de..3bc712341b 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCreateOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCreateOperation.java @@ -195,7 +195,6 @@ public abstract class AbstractCreateOperation extends AbstractOperation { .apparentValue(value) .code(code) .completer(child -> complete(parent, child, evm)) - .authorizedCodeService(parent.getAuthorizedCodeService()) .build(); parent.setState(MessageFrame.State.CODE_SUSPENDED); 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 e19b6cd8a2..43d7e343ff 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 @@ -180,7 +180,6 @@ public abstract class AbstractExtCallOperation extends AbstractCallOperation { .code(code) .isStatic(isStatic(frame)) .completer(child -> complete(frame, child)) - .authorizedCodeService(frame.getAuthorizedCodeService()) .build(); frame.setState(MessageFrame.State.CODE_SUSPENDED); diff --git a/evm/src/main/java/org/hyperledger/besu/evm/worldstate/AbstractWorldUpdater.java b/evm/src/main/java/org/hyperledger/besu/evm/worldstate/AbstractWorldUpdater.java index 00cd67ddb8..9623eaf89e 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/worldstate/AbstractWorldUpdater.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/worldstate/AbstractWorldUpdater.java @@ -43,9 +43,6 @@ public abstract class AbstractWorldUpdater> updatedAccounts = new ConcurrentHashMap<>(); @@ -62,7 +59,6 @@ public abstract class AbstractWorldUpdater account = new UpdateTrackingAccount<>(address); account.setNonce(nonce); account.setBalance(balance); - return authorizedCodeService.processMutableAccount(this, track(account), address); + return track(account); } @Override @@ -99,12 +95,12 @@ public abstract class AbstractWorldUpdater(origin)), address); + return track(new UpdateTrackingAccount<>(origin)); } } @@ -170,11 +165,6 @@ public abstract class AbstractWorldUpdater getTouchedAccounts() { + return rootWorldUpdater.getTouchedAccounts(); + } + + @Override + public Collection
getDeletedAccountAddresses() { + return rootWorldUpdater.getDeletedAccountAddresses(); + } + + @Override + public void revert() { + rootWorldUpdater.revert(); + } + + @Override + public void commit() { + rootWorldUpdater.commit(); + } + + @Override + public Optional parentUpdater() { + return rootWorldUpdater.parentUpdater(); + } + + @Override + public WorldUpdater updater() { + return new EVMWorldUpdater(rootWorldUpdater.updater(), authorizedCodeService); + } + + @Override + public Account get(final Address address) { + return authorizedCodeService.processAccount(this, rootWorldUpdater.get(address), address); + } +} diff --git a/evm/src/main/java/org/hyperledger/besu/evm/worldstate/JournaledUpdater.java b/evm/src/main/java/org/hyperledger/besu/evm/worldstate/JournaledUpdater.java index 2497ed348d..9987a5be75 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/worldstate/JournaledUpdater.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/worldstate/JournaledUpdater.java @@ -41,7 +41,6 @@ public class JournaledUpdater implements WorldUpdater { final UndoMap accounts; final UndoSet
deleted; final long undoMark; - private AuthorizedCodeService authorizedCodeService; /** * Instantiates a new Stacked updater. @@ -67,7 +66,6 @@ public class JournaledUpdater implements WorldUpdater { "WorldUpdater must be a JournaledWorldUpdater or an AbstractWorldUpdater"); } undoMark = accounts.mark(); - this.authorizedCodeService = new AuthorizedCodeService(); } /** @@ -128,18 +126,12 @@ public class JournaledUpdater implements WorldUpdater { accounts.values().forEach(JournaledAccount::markTransactionBoundary); } - @Override - public void setAuthorizedCodeService(final AuthorizedCodeService authorizedCodeService) { - this.authorizedCodeService = authorizedCodeService; - } - @Override public MutableAccount createAccount(final Address address, final long nonce, final Wei balance) { JournaledAccount journaledAccount = new JournaledAccount(rootWorld.createAccount(address, nonce, balance)); accounts.put(address, journaledAccount); - return authorizedCodeService.processMutableAccount( - this, new JournaledAccount(journaledAccount), address); + return new JournaledAccount(journaledAccount); } @Override @@ -147,7 +139,7 @@ public class JournaledUpdater implements WorldUpdater { // We may have updated it already, so check that first. final JournaledAccount existing = accounts.get(address); if (existing != null) { - return authorizedCodeService.processMutableAccount(this, existing, address); + return existing; } if (deleted.contains(address)) { return null; @@ -156,11 +148,11 @@ public class JournaledUpdater implements WorldUpdater { // Otherwise, get it from our wrapped view and create a new update tracker. final MutableAccount origin = rootWorld.getAccount(address); if (origin == null) { - return authorizedCodeService.processMutableAccount(this, null, address); + return null; } else { var newAccount = new JournaledAccount(origin); accounts.put(address, newAccount); - return authorizedCodeService.processMutableAccount(this, newAccount, address); + return newAccount; } } @@ -177,12 +169,12 @@ public class JournaledUpdater implements WorldUpdater { public Account get(final Address address) { final MutableAccount existing = accounts.get(address); if (existing != null) { - return authorizedCodeService.processAccount(this, existing, address); + return existing; } if (deleted.contains(address)) { - return authorizedCodeService.processAccount(this, null, address); + return null; } - return authorizedCodeService.processAccount(this, rootWorld.get(address), address); + return rootWorld.get(address); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/worldstate/WorldUpdater.java b/evm/src/main/java/org/hyperledger/besu/evm/worldstate/WorldUpdater.java index 5144176e79..4cbda73279 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/worldstate/WorldUpdater.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/worldstate/WorldUpdater.java @@ -179,12 +179,4 @@ public interface WorldUpdater extends MutableWorldView { default void markTransactionBoundary() { // default is to ignore } - - /** - * Sets the {@link AuthorizedCodeService} associated with this {@link WorldUpdater}. - * - * @param authorizedCodeService the {@link AuthorizedCodeService} to associate with this {@link - * WorldUpdater} - */ - void setAuthorizedCodeService(AuthorizedCodeService authorizedCodeService); } diff --git a/evm/src/test/java/org/hyperledger/besu/evm/toy/ToyWorld.java b/evm/src/test/java/org/hyperledger/besu/evm/toy/ToyWorld.java index 479376a8fe..e1e9c4c3ad 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/toy/ToyWorld.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/toy/ToyWorld.java @@ -18,7 +18,6 @@ import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.evm.account.Account; import org.hyperledger.besu.evm.account.MutableAccount; -import org.hyperledger.besu.evm.worldstate.AuthorizedCodeService; import org.hyperledger.besu.evm.worldstate.WorldUpdater; import java.util.Collection; @@ -33,7 +32,6 @@ public class ToyWorld implements WorldUpdater { ToyWorld parent; Map accounts = new HashMap<>(); - private AuthorizedCodeService authorizedCodeService; public ToyWorld() { this(null); @@ -41,7 +39,6 @@ public class ToyWorld implements WorldUpdater { public ToyWorld(final ToyWorld parent) { this.parent = parent; - this.authorizedCodeService = new AuthorizedCodeService(); } @Override @@ -52,11 +49,11 @@ public class ToyWorld implements WorldUpdater { @Override public Account get(final Address address) { if (accounts.containsKey(address)) { - return authorizedCodeService.processAccount(this, accounts.get(address), address); + return accounts.get(address); } else if (parent != null) { - return authorizedCodeService.processAccount(this, parent.get(address), address); + return parent.get(address); } else { - return authorizedCodeService.processAccount(this, null, address); + return null; } } @@ -73,17 +70,17 @@ public class ToyWorld implements WorldUpdater { final Bytes code) { ToyAccount account = new ToyAccount(parentAccount, address, nonce, balance, code); accounts.put(address, account); - return authorizedCodeService.processMutableAccount(this, account, address); + return account; } @Override public MutableAccount getAccount(final Address address) { if (accounts.containsKey(address)) { - return authorizedCodeService.processMutableAccount(this, accounts.get(address), address); + return accounts.get(address); } else if (parent != null) { Account parentAccount = parent.getAccount(address); if (parentAccount == null) { - return authorizedCodeService.processMutableAccount(this, null, address); + return null; } else { return createAccount( parentAccount, @@ -93,7 +90,7 @@ public class ToyWorld implements WorldUpdater { parentAccount.getCode()); } } else { - return authorizedCodeService.processMutableAccount(this, null, address); + return null; } } @@ -131,9 +128,4 @@ public class ToyWorld implements WorldUpdater { public Optional parentUpdater() { return Optional.empty(); } - - @Override - public void setAuthorizedCodeService(final AuthorizedCodeService authorizedCodeService) { - this.authorizedCodeService = authorizedCodeService; - } } From 290f21c227884555699de26b547ad2368fe92719 Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Tue, 13 Aug 2024 14:19:43 +1000 Subject: [PATCH 104/259] 5098: Disable txpoolForcePriceBumpToZeroWhenZeroBaseFeeMarket test and add comment explaining why (#7452) Signed-off-by: Matilda Clerke --- .../test/java/org/hyperledger/besu/cli/TxPoolOptionsTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/besu/src/test/java/org/hyperledger/besu/cli/TxPoolOptionsTest.java b/besu/src/test/java/org/hyperledger/besu/cli/TxPoolOptionsTest.java index a5ca07484a..8389ab5bae 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/TxPoolOptionsTest.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/TxPoolOptionsTest.java @@ -30,6 +30,7 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; public class TxPoolOptionsTest extends CommandTestAbstract { @@ -97,6 +98,7 @@ public class TxPoolOptionsTest extends CommandTestAbstract { } @Test + @Disabled // Failing in CI, but not locally public void txpoolForcePriceBumpToZeroWhenZeroBaseFeeMarket() throws IOException { final Path genesisFile = createFakeGenesisFile(GENESIS_WITH_ZERO_BASE_FEE_MARKET); parseCommand("--genesis-file", genesisFile.toString()); From 50f8add05222b0651cb38f3abfad85f1e0dd4499 Mon Sep 17 00:00:00 2001 From: Nischal Sharma Date: Tue, 13 Aug 2024 10:22:53 +0530 Subject: [PATCH 105/259] Tracing private transactions feature (#6161) * add private tx tracing feature Signed-off-by: Nischal Sharma Signed-off-by: Stefan Pingel <16143240+pinges@users.noreply.github.com> Co-authored-by: Stefan Pingel <16143240+pinges@users.noreply.github.com> Co-authored-by: Sally MacFarlane --- CHANGELOG.md | 2 + .../transaction/PrivacyTransactions.java | 7 + .../privacy/PrivTraceTransaction.java | 49 ++ .../privacy/PrivacyRequestFactory.java | 12 + .../PrivTraceTransactionAcceptanceTest.java | 174 +++++ .../besu/ethereum/api/jsonrpc/RpcMethod.java | 1 + .../priv/AbstractPrivateTraceByHash.java | 167 +++++ .../methods/priv/PrivTraceTransaction.java | 93 +++ .../privateProcessor/PrivateBlockReplay.java | 110 ++++ .../privateProcessor/PrivateBlockTrace.java | 30 + .../privateProcessor/PrivateBlockTracer.java | 87 +++ .../privateProcessor/PrivateTracer.java | 118 ++++ .../PrivateTransactionTrace.java | 91 +++ .../privateTracing/PrivateFlatTrace.java | 377 +++++++++++ .../privateTracing/PrivateTraceGenerator.java | 598 ++++++++++++++++++ .../internal/results/tracing/flat/Action.java | 2 +- .../tracing/flat/FlatTraceGenerator.java | 2 +- .../jsonrpc/methods/PrivJsonRpcMethods.java | 16 +- .../ethereum/api/query/PrivacyQueries.java | 6 + .../methods/PrivJsonRpcMethodsTest.java | 1 - .../ethereum/privacy/PrivateTransaction.java | 10 + .../privacy/PrivateWorldStateReader.java | 6 + plugin-api/build.gradle | 2 +- .../besu/plugin/data/PrivateTransaction.java | 10 + 24 files changed, 1966 insertions(+), 5 deletions(-) create mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivTraceTransaction.java create mode 100644 acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivTraceTransactionAcceptanceTest.java create mode 100644 ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/AbstractPrivateTraceByHash.java create mode 100644 ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivTraceTransaction.java create mode 100644 ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/processor/privateProcessor/PrivateBlockReplay.java create mode 100644 ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/processor/privateProcessor/PrivateBlockTrace.java create mode 100644 ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/processor/privateProcessor/PrivateBlockTracer.java create mode 100644 ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/processor/privateProcessor/PrivateTracer.java create mode 100644 ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/processor/privateProcessor/PrivateTransactionTrace.java create mode 100644 ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/privacy/privateTracing/PrivateFlatTrace.java create mode 100644 ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/privacy/privateTracing/PrivateTraceGenerator.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 616ac3d1dc..1629002cbd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,8 +15,10 @@ ### Additions and Improvements - Expose set finalized/safe block in plugin api BlockchainService. These method can be used by plugins to set finalized/safe block for a PoA network (such as QBFT, IBFT and Clique).[#7382](https://github.com/hyperledger/besu/pull/7382) - In process RPC service [#7395](https://github.com/hyperledger/besu/pull/7395) +- Added support for tracing private transactions using `priv_traceTransaction` API. [#6161](https://github.com/hyperledger/besu/pull/6161) - Wrap WorldUpdater into EVMWorldupdater [#7434](https://github.com/hyperledger/besu/pull/7434) + ### Bug fixes - Correct entrypoint in Docker evmtool [#7430](https://github.com/hyperledger/besu/pull/7430) - Fix protocol schedule check for devnets [#7429](https://github.com/hyperledger/besu/pull/7429) diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/PrivacyTransactions.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/PrivacyTransactions.java index 3763e40bb7..d168108c97 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/PrivacyTransactions.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/PrivacyTransactions.java @@ -15,6 +15,7 @@ package org.hyperledger.besu.tests.acceptance.dsl.privacy.transaction; import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.privacy.PrivacyGroupUtil; import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode; import org.hyperledger.besu.tests.acceptance.dsl.privacy.condition.PrivGetTransactionReceiptTransaction; @@ -25,6 +26,7 @@ import org.hyperledger.besu.tests.acceptance.dsl.transaction.privacy.PrivDebugGe import org.hyperledger.besu.tests.acceptance.dsl.transaction.privacy.PrivGetCodeTransaction; import org.hyperledger.besu.tests.acceptance.dsl.transaction.privacy.PrivGetLogsTransaction; import org.hyperledger.besu.tests.acceptance.dsl.transaction.privacy.PrivGetTransaction; +import org.hyperledger.besu.tests.acceptance.dsl.transaction.privacy.PrivTraceTransaction; import org.hyperledger.besu.tests.acceptance.dsl.transaction.privacy.filter.PrivGetFilterChangesTransaction; import org.hyperledger.besu.tests.acceptance.dsl.transaction.privacy.filter.PrivGetFilterLogsTransaction; import org.hyperledger.besu.tests.acceptance.dsl.transaction.privacy.filter.PrivNewFilterTransaction; @@ -115,6 +117,11 @@ public class PrivacyTransactions { return new PrivGetLogsTransaction(privacyGroupId, filterParameter); } + public PrivTraceTransaction privTraceTransaction( + final String privacyGroupId, final Hash transactionHash) { + return new PrivTraceTransaction(privacyGroupId, transactionHash); + } + public RemoveFromFlexiblePrivacyGroupTransaction removeFromPrivacyGroup( final String privacyGroupId, final String remover, diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivTraceTransaction.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivTraceTransaction.java new file mode 100644 index 0000000000..b971c4afde --- /dev/null +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivTraceTransaction.java @@ -0,0 +1,49 @@ +/* + * 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.transaction.privacy; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.hyperledger.besu.datatypes.Hash; +import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; +import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; + +import java.io.IOException; + +public class PrivTraceTransaction implements Transaction { + + private final String privacyGroupId; + private final Hash transactionHash; + + public PrivTraceTransaction(final String privacyGroupId, final Hash transactionHash) { + this.privacyGroupId = privacyGroupId; + this.transactionHash = transactionHash; + } + + @Override + public String execute(final NodeRequests node) { + try { + final PrivacyRequestFactory.PrivTraceTransaction response = + node.privacy().privTraceTransaction(privacyGroupId, transactionHash).send(); + + assertThat(response).as("check response is not null").isNotNull(); + assertThat(response.getResult()).as("check result in response is not null").isNotNull(); + + return response.getResult(); + } catch (final IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivacyRequestFactory.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivacyRequestFactory.java index 056598a9d5..7c01c02c48 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivacyRequestFactory.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivacyRequestFactory.java @@ -109,6 +109,8 @@ public class PrivacyRequestFactory { public static class GetPrivateTransactionResponse extends Response {} + public static class PrivTraceTransaction extends Response {} + public static class CreatePrivacyGroupResponse extends Response {} public static class DeletePrivacyGroupResponse extends Response {} @@ -455,6 +457,16 @@ public class PrivacyRequestFactory { "priv_getLogs", Arrays.asList(privacyGroupId, filterParameter), web3jService, EthLog.class); } + public Request privTraceTransaction( + final String privacyGroupId, final Hash transactionHash) { + + return new Request<>( + "priv_traceTransaction", + Arrays.asList(privacyGroupId, transactionHash), + web3jService, + PrivTraceTransaction.class); + } + public Request privNewFilter( final String privacyGroupId, final LogFilterJsonParameter filterParameter) { return new Request<>( diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivTraceTransactionAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivTraceTransactionAcceptanceTest.java new file mode 100644 index 0000000000..9cac6d8bf5 --- /dev/null +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivTraceTransactionAcceptanceTest.java @@ -0,0 +1,174 @@ +/* + * 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.privacy; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.web3j.utils.Restriction.UNRESTRICTED; + +import org.hyperledger.besu.datatypes.Hash; +import org.hyperledger.besu.tests.acceptance.dsl.privacy.ParameterizedEnclaveTestBase; +import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode; +import org.hyperledger.besu.tests.acceptance.dsl.privacy.account.PrivacyAccountResolver; +import org.hyperledger.besu.tests.web3j.generated.SimpleStorage; +import org.hyperledger.enclave.testutil.EnclaveEncryptorType; +import org.hyperledger.enclave.testutil.EnclaveType; + +import java.io.IOException; +import java.math.BigInteger; +import java.util.Optional; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.Test; +import org.web3j.utils.Restriction; + +public class PrivTraceTransactionAcceptanceTest extends ParameterizedEnclaveTestBase { + + private final PrivacyNode node; + + private final PrivacyNode wrongNode; + + public PrivTraceTransactionAcceptanceTest( + final Restriction restriction, + final EnclaveType enclaveType, + final EnclaveEncryptorType enclaveEncryptorType) + throws IOException { + + super(restriction, enclaveType, enclaveEncryptorType); + + node = + privacyBesu.createPrivateTransactionEnabledMinerNode( + restriction + "-node", + PrivacyAccountResolver.ALICE.resolve(enclaveEncryptorType), + enclaveType, + Optional.empty(), + false, + false, + restriction == UNRESTRICTED); + + wrongNode = + privacyBesu.createPrivateTransactionEnabledMinerNode( + restriction + "-node", + PrivacyAccountResolver.BOB.resolve(enclaveEncryptorType), + enclaveType, + Optional.empty(), + false, + false, + restriction == UNRESTRICTED); + + privacyCluster.start(node); + privacyCluster.start(wrongNode); + } + + @Test + public void getTransactionTrace() throws JsonProcessingException { + final String privacyGroupId = createPrivacyGroup(); + final SimpleStorage simpleStorageContract = deploySimpleStorageContract(privacyGroupId); + + Hash transactionHash = + Hash.fromHexString(doTransaction(privacyGroupId, simpleStorageContract, 0)); + + final String result = + node.execute(privacyTransactions.privTraceTransaction(privacyGroupId, transactionHash)); + + assertThat(result).isNotNull(); + ObjectMapper mapper = new ObjectMapper(); + + JsonNode rootNode = mapper.readTree(result); + JsonNode resultNode = rootNode.get("result"); + + assertThat(resultNode).isNotNull(); + assertThat(resultNode.isArray()).isTrue(); + assertThat(resultNode.size()).isGreaterThan(0); + + JsonNode trace = resultNode.get(0); + assertThat(trace.get("action").get("callType").asText()).isEqualTo("call"); + assertThat(trace.get("action").get("from").asText()).isEqualTo(node.getAddress().toString()); + assertThat(trace.get("action").get("input").asText()).startsWith("0x60fe47b1"); + assertThat(trace.get("action").get("to").asText()) + .isEqualTo(simpleStorageContract.getContractAddress()); + assertThat(trace.get("action").get("value").asText()).isEqualTo("0x0"); + assertThat(trace.get("blockHash").asText()).isNotEmpty(); + assertThat(trace.get("blockNumber").asInt()).isGreaterThan(0); + assertThat(trace.get("transactionHash").asText()).isEqualTo(transactionHash.toString()); + assertThat(trace.get("type").asText()).isEqualTo("call"); + + final String wrongPrivacyGroupId = createWrongPrivacyGroup(); + + final String resultEmpty = + wrongNode.execute( + privacyTransactions.privTraceTransaction(wrongPrivacyGroupId, transactionHash)); + + ObjectMapper mapperEmpty = new ObjectMapper(); + + JsonNode rootNodeEmpty = mapperEmpty.readTree(resultEmpty); + JsonNode resultNodeEmpty = rootNodeEmpty.get("result"); + + assertThat(resultNodeEmpty).isNotNull(); + assertThat(resultNodeEmpty.isArray()).isTrue(); + assertThat(resultNodeEmpty.isEmpty()).isTrue(); + + final String resultWrongHash = + wrongNode.execute(privacyTransactions.privTraceTransaction(privacyGroupId, Hash.EMPTY)); + + ObjectMapper mapperWrongHash = new ObjectMapper(); + + JsonNode rootNodeWrongHash = mapperWrongHash.readTree(resultWrongHash); + JsonNode resultNodeWrongHash = rootNodeWrongHash.get("result"); + + assertThat(resultNodeWrongHash).isNotNull(); + assertThat(resultNodeWrongHash.isArray()).isTrue(); + assertThat(resultNodeWrongHash.isEmpty()).isTrue(); + } + + private String createPrivacyGroup() { + return node.execute(createPrivacyGroup("myGroupName", "my group description", node)); + } + + private String createWrongPrivacyGroup() { + return wrongNode.execute(createPrivacyGroup("myGroupName", "my group description", wrongNode)); + } + + private SimpleStorage deploySimpleStorageContract(final String privacyGroupId) { + final SimpleStorage simpleStorage = + node.execute( + privateContractTransactions.createSmartContractWithPrivacyGroupId( + SimpleStorage.class, + node.getTransactionSigningKey(), + restriction, + node.getEnclaveKey(), + privacyGroupId)); + + privateContractVerifier + .validPrivateContractDeployed( + simpleStorage.getContractAddress(), node.getAddress().toString()) + .verify(simpleStorage); + + return simpleStorage; + } + + private String doTransaction( + final String privacyGroupId, final SimpleStorage simpleStorageContract, final int value) { + return node.execute( + privateContractTransactions.callSmartContractWithPrivacyGroupId( + simpleStorageContract.getContractAddress(), + simpleStorageContract.set(BigInteger.valueOf(value)).encodeFunctionCall(), + node.getTransactionSigningKey(), + restriction, + node.getEnclaveKey(), + privacyGroupId)); + } +} diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcMethod.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcMethod.java index 4174fdf831..2c883337d3 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcMethod.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcMethod.java @@ -86,6 +86,7 @@ public enum RpcMethod { PRIV_GET_FILTER_LOGS("priv_getFilterLogs"), PRIV_SUBSCRIBE("priv_subscribe"), PRIV_UNSUBSCRIBE("priv_unsubscribe"), + PRIV_TRACE_TRANSACTION("priv_traceTransaction"), PRIVX_FIND_PRIVACY_GROUP_OLD("privx_findOnchainPrivacyGroup"), PRIVX_FIND_PRIVACY_GROUP("privx_findFlexiblePrivacyGroup"), EEA_SEND_RAW_TRANSACTION("eea_sendRawTransaction"), diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/AbstractPrivateTraceByHash.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/AbstractPrivateTraceByHash.java new file mode 100644 index 0000000000..0139886862 --- /dev/null +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/AbstractPrivateTraceByHash.java @@ -0,0 +1,167 @@ +/* + * 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.privacy.methods.priv; + +import org.hyperledger.besu.datatypes.Hash; +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.privacy.methods.PrivacyIdProvider; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.privateProcessor.PrivateBlockTrace; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.privateProcessor.PrivateBlockTracer; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.privateProcessor.PrivateTracer; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.privateProcessor.PrivateTransactionTrace; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.privacy.privateTracing.PrivateFlatTrace; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.privacy.privateTracing.PrivateTraceGenerator; +import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; +import org.hyperledger.besu.ethereum.api.query.PrivacyQueries; +import org.hyperledger.besu.ethereum.core.Block; +import org.hyperledger.besu.ethereum.core.PrivacyParameters; +import org.hyperledger.besu.ethereum.debug.TraceOptions; +import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; +import org.hyperledger.besu.ethereum.privacy.ExecutedPrivateTransaction; +import org.hyperledger.besu.ethereum.privacy.MultiTenancyPrivacyController; +import org.hyperledger.besu.ethereum.privacy.PrivacyController; +import org.hyperledger.besu.ethereum.privacy.storage.PrivateBlockMetadata; +import org.hyperledger.besu.ethereum.vm.DebugOperationTracer; + +import java.util.Collections; +import java.util.Optional; +import java.util.function.Supplier; +import java.util.stream.Stream; + +public abstract class AbstractPrivateTraceByHash implements JsonRpcMethod { + + protected final Supplier blockTracerSupplier; + protected final BlockchainQueries blockchainQueries; + protected final PrivacyQueries privacyQueries; + protected final ProtocolSchedule protocolSchedule; + protected final PrivacyController privacyController; + protected final PrivacyParameters privacyParameters; + protected final PrivacyIdProvider privacyIdProvider; + + protected AbstractPrivateTraceByHash( + final Supplier blockTracerSupplier, + final BlockchainQueries blockchainQueries, + final PrivacyQueries privacyQueries, + final ProtocolSchedule protocolSchedule, + final PrivacyController privacyController, + final PrivacyParameters privacyParameters, + final PrivacyIdProvider privacyIdProvider) { + this.blockTracerSupplier = blockTracerSupplier; + this.blockchainQueries = blockchainQueries; + this.privacyQueries = privacyQueries; + this.protocolSchedule = protocolSchedule; + this.privacyController = privacyController; + this.privacyParameters = privacyParameters; + this.privacyIdProvider = privacyIdProvider; + } + + public Stream resultByTransactionHash( + final String privacyGroupId, + final Hash transactionHash, + final JsonRpcRequestContext requestContext) { + + final String enclaveKey = privacyIdProvider.getPrivacyUserId(requestContext.getUser()); + if (privacyController instanceof MultiTenancyPrivacyController) { + verifyPrivacyGroupMatchesAuthenticatedEnclaveKey( + requestContext, privacyGroupId, Optional.empty()); + } + + return privacyController + .findPrivateTransactionByPmtHash(transactionHash, enclaveKey) + .map(ExecutedPrivateTransaction::getBlockNumber) + .flatMap(blockNumber -> blockchainQueries.getBlockchain().getBlockHashByNumber(blockNumber)) + .map(blockHash -> getTraceBlock(blockHash, transactionHash, enclaveKey, privacyGroupId)) + .orElse(Stream.empty()); + } + + private Stream getTraceBlock( + final Hash blockHash, + final Hash transactionHash, + final String enclaveKey, + final String privacyGroupId) { + final Block block = blockchainQueries.getBlockchain().getBlockByHash(blockHash).orElse(null); + final PrivateBlockMetadata privateBlockMetadata = + privacyQueries.getPrivateBlockMetaData(privacyGroupId, blockHash).orElse(null); + + if (privateBlockMetadata == null || block == null) { + return Stream.empty(); + } + return PrivateTracer.processTracing( + blockchainQueries, + Optional.of(block.getHeader()), + privacyGroupId, + enclaveKey, + privacyParameters, + privacyController, + mutableWorldState -> { + final PrivateTransactionTrace privateTransactionTrace = + getTransactionTrace( + block, transactionHash, enclaveKey, privateBlockMetadata, privacyGroupId); + return Optional.ofNullable(getTraceStream(privateTransactionTrace, block)); + }) + .orElse(Stream.empty()); + } + + private PrivateTransactionTrace getTransactionTrace( + final Block block, + final Hash transactionHash, + final String enclaveKey, + final PrivateBlockMetadata privateBlockMetadata, + final String privacyGroupId) { + return PrivateTracer.processTracing( + blockchainQueries, + Optional.of(block.getHeader()), + privacyGroupId, + enclaveKey, + privacyParameters, + privacyController, + mutableWorldState -> + blockTracerSupplier + .get() + .trace( + mutableWorldState, + block, + new DebugOperationTracer(new TraceOptions(false, false, true), false), + enclaveKey, + privacyGroupId, + privateBlockMetadata) + .map(PrivateBlockTrace::getTransactionTraces) + .orElse(Collections.emptyList()) + .stream() + .filter( + trxTrace -> + trxTrace.getPrivateTransaction().getPmtHash().equals(transactionHash)) + .findFirst()) + .orElseThrow(); + } + + private Stream getTraceStream( + final PrivateTransactionTrace transactionTrace, final Block block) { + + return PrivateTraceGenerator.generateFromTransactionTraceAndBlock( + this.protocolSchedule, transactionTrace, block) + .map(PrivateFlatTrace.class::cast); + } + + private void verifyPrivacyGroupMatchesAuthenticatedEnclaveKey( + final JsonRpcRequestContext request, + final String privacyGroupId, + final Optional toBlock) { + final String privacyUserId = privacyIdProvider.getPrivacyUserId(request.getUser()); + privacyController.verifyPrivacyGroupContainsPrivacyUserId( + privacyGroupId, privacyUserId, toBlock); + } +} diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivTraceTransaction.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivTraceTransaction.java new file mode 100644 index 0000000000..b1802b07eb --- /dev/null +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivTraceTransaction.java @@ -0,0 +1,93 @@ +/* + * 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.privacy.methods.priv; + +import org.hyperledger.besu.datatypes.Hash; +import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.TraceTransaction; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.PrivacyIdProvider; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.privateProcessor.PrivateBlockTracer; +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.api.jsonrpc.internal.response.RpcErrorType; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.privacy.privateTracing.PrivateFlatTrace; +import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; +import org.hyperledger.besu.ethereum.api.query.PrivacyQueries; +import org.hyperledger.besu.ethereum.core.PrivacyParameters; +import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; +import org.hyperledger.besu.ethereum.privacy.PrivacyController; + +import java.util.function.Supplier; +import java.util.stream.Stream; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class PrivTraceTransaction extends AbstractPrivateTraceByHash implements JsonRpcMethod { + private static final Logger LOG = LoggerFactory.getLogger(TraceTransaction.class); + + public PrivTraceTransaction( + final Supplier blockTracerSupplier, + final BlockchainQueries blockchainQueries, + final ProtocolSchedule protocolSchedule, + final PrivacyQueries privacyQueries, + final PrivacyController privacyController, + final PrivacyParameters privacyParameters, + final PrivacyIdProvider privacyIdProvider) { + super( + blockTracerSupplier, + blockchainQueries, + privacyQueries, + protocolSchedule, + privacyController, + privacyParameters, + privacyIdProvider); + } + + @Override + public String getName() { + return RpcMethod.PRIV_TRACE_TRANSACTION.getMethodName(); + } + + @Override + public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { + final String privacyGroupId = requestContext.getRequiredParameter(0, String.class); + final Hash transactionHash = requestContext.getRequiredParameter(1, Hash.class); + LOG.trace("Received RPC rpcName={} txHash={}", getName(), transactionHash); + + if (privacyGroupId.isEmpty() || transactionHash.isEmpty()) { + return new JsonRpcErrorResponse( + requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + } + + return new JsonRpcSuccessResponse( + requestContext.getRequest().getId(), + arrayNodeFromTraceStream( + resultByTransactionHash(privacyGroupId, transactionHash, requestContext))); + } + + protected JsonNode arrayNodeFromTraceStream(final Stream traceStream) { + final ObjectMapper mapper = new ObjectMapper(); + final ArrayNode resultArrayNode = mapper.createArrayNode(); + traceStream.forEachOrdered(resultArrayNode::addPOJO); + return resultArrayNode; + } +} diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/processor/privateProcessor/PrivateBlockReplay.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/processor/privateProcessor/PrivateBlockReplay.java new file mode 100644 index 0000000000..de5c11940b --- /dev/null +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/processor/privateProcessor/PrivateBlockReplay.java @@ -0,0 +1,110 @@ +/* + * 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.processor.privateProcessor; + +import org.hyperledger.besu.ethereum.chain.Blockchain; +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.mainnet.ProtocolSchedule; +import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; +import org.hyperledger.besu.ethereum.privacy.ExecutedPrivateTransaction; +import org.hyperledger.besu.ethereum.privacy.PrivacyController; +import org.hyperledger.besu.ethereum.privacy.PrivateTransactionProcessor; +import org.hyperledger.besu.ethereum.privacy.storage.PrivateBlockMetadata; + +import java.util.List; +import java.util.Optional; + +public class PrivateBlockReplay { + + private final ProtocolSchedule protocolSchedule; + private final Blockchain blockchain; + private final PrivacyController privacyController; + + public PrivateBlockReplay( + final ProtocolSchedule protocolSchedule, + final Blockchain blockchain, + final PrivacyController privacyController) { + this.protocolSchedule = protocolSchedule; + this.blockchain = blockchain; + this.privacyController = privacyController; + } + + public Optional block( + final Block block, + final PrivateBlockMetadata privateBlockMetadata, + final String enclaveKey, + final TransactionAction action) { + return performActionWithBlock( + block.getHeader(), + block.getBody(), + (body, header, blockchain, transactionProcessor, protocolSpec) -> { + final List transactionTraces = + privateBlockMetadata.getPrivateTransactionMetadataList().stream() + .map( + privateTransactionMetadata -> + privacyController + .findPrivateTransactionByPmtHash( + privateTransactionMetadata.getPrivateMarkerTransactionHash(), + enclaveKey) + .map( + executedPrivateTransaction -> + action.performAction( + executedPrivateTransaction, + header, + blockchain, + transactionProcessor)) + .orElse(null)) + .toList(); + + return Optional.of(new PrivateBlockTrace(transactionTraces)); + }); + } + + private Optional performActionWithBlock( + final BlockHeader header, final BlockBody body, final BlockAction action) { + if (header == null) { + return Optional.empty(); + } + if (body == null) { + return Optional.empty(); + } + final ProtocolSpec protocolSpec = protocolSchedule.getByBlockHeader(header); + final PrivateTransactionProcessor transactionProcessor = + protocolSpec.getPrivateTransactionProcessor(); + + return action.perform(body, header, blockchain, transactionProcessor, protocolSpec); + } + + @FunctionalInterface + public interface BlockAction { + Optional perform( + BlockBody body, + BlockHeader blockHeader, + Blockchain blockchain, + PrivateTransactionProcessor transactionProcessor, + ProtocolSpec protocolSpec); + } + + @FunctionalInterface + public interface TransactionAction { + T performAction( + ExecutedPrivateTransaction transaction, + BlockHeader blockHeader, + Blockchain blockchain, + PrivateTransactionProcessor transactionProcessor); + } +} diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/processor/privateProcessor/PrivateBlockTrace.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/processor/privateProcessor/PrivateBlockTrace.java new file mode 100644 index 0000000000..4deebed261 --- /dev/null +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/processor/privateProcessor/PrivateBlockTrace.java @@ -0,0 +1,30 @@ +/* + * 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.processor.privateProcessor; + +import java.util.List; + +public class PrivateBlockTrace { + + private final List transactionTraces; + + public PrivateBlockTrace(final List transactionTraces) { + this.transactionTraces = transactionTraces; + } + + public List getTransactionTraces() { + return transactionTraces; + } +} diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/processor/privateProcessor/PrivateBlockTracer.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/processor/privateProcessor/PrivateBlockTracer.java new file mode 100644 index 0000000000..c58af8fc3f --- /dev/null +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/processor/privateProcessor/PrivateBlockTracer.java @@ -0,0 +1,87 @@ +/* + * 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.processor.privateProcessor; + +import org.hyperledger.besu.ethereum.core.Block; +import org.hyperledger.besu.ethereum.debug.TraceFrame; +import org.hyperledger.besu.ethereum.privacy.storage.PrivateBlockMetadata; +import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult; +import org.hyperledger.besu.ethereum.vm.CachingBlockHashLookup; +import org.hyperledger.besu.ethereum.vm.DebugOperationTracer; +import org.hyperledger.besu.evm.worldstate.StackedUpdater; +import org.hyperledger.besu.evm.worldstate.WorldUpdater; + +import java.util.List; +import java.util.Optional; + +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; + +public class PrivateBlockTracer { + private final PrivateBlockReplay blockReplay; + // Either the initial block state or the state of the prior TX, including miner rewards. + private WorldUpdater chainedUpdater; + + public PrivateBlockTracer(final PrivateBlockReplay blockReplay) { + this.blockReplay = blockReplay; + } + + public Optional trace( + final PrivateTracer.TraceableState mutableWorldState, + final Block block, + final DebugOperationTracer tracer, + final String enclaveKey, + final String privacyGroupId, + final PrivateBlockMetadata privateBlockMetadata) { + return blockReplay.block( + block, + privateBlockMetadata, + enclaveKey, + prepareReplayAction(mutableWorldState, tracer, privacyGroupId)); + } + + private PrivateBlockReplay.TransactionAction prepareReplayAction( + final PrivateTracer.TraceableState mutableWorldState, + final DebugOperationTracer tracer, + final String privacyGroupId) { + return (transaction, header, blockchain, transactionProcessor) -> { + // if we have no prior updater, it must be the first TX, so use the block's initial state + if (chainedUpdater == null) { + chainedUpdater = mutableWorldState.updater(); + + } else if (chainedUpdater instanceof StackedUpdater stackedUpdater) { + stackedUpdater.markTransactionBoundary(); + } + // create an updater for just this tx + chainedUpdater = chainedUpdater.updater(); + WorldUpdater privateChainedUpdater = mutableWorldState.privateUpdater(); + final TransactionProcessingResult result = + transactionProcessor.processTransaction( + chainedUpdater, + privateChainedUpdater, + header, + transaction.getPmtHash(), + transaction, + header.getCoinbase(), + tracer, + new CachingBlockHashLookup(header, blockchain), + Bytes32.wrap(Bytes.fromBase64String(privacyGroupId))); + + final List traceFrames = tracer.copyTraceFrames(); + tracer.reset(); + return new PrivateTransactionTrace(transaction, result, traceFrames); + }; + } +} diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/processor/privateProcessor/PrivateTracer.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/processor/privateProcessor/PrivateTracer.java new file mode 100644 index 0000000000..c79feead16 --- /dev/null +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/processor/privateProcessor/PrivateTracer.java @@ -0,0 +1,118 @@ +/* + * 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.processor.privateProcessor; + +import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.datatypes.Hash; +import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; +import org.hyperledger.besu.ethereum.core.BlockHeader; +import org.hyperledger.besu.ethereum.core.MutableWorldState; +import org.hyperledger.besu.ethereum.core.PrivacyParameters; +import org.hyperledger.besu.ethereum.privacy.PrivacyController; +import org.hyperledger.besu.evm.account.Account; +import org.hyperledger.besu.evm.worldstate.WorldUpdater; + +import java.util.Optional; +import java.util.function.Function; +import java.util.stream.Stream; + +import org.apache.tuweni.bytes.Bytes32; + +public class PrivateTracer { + + public static Optional processTracing( + final BlockchainQueries blockchainQueries, + final Optional blockHeader, + final String privacyGroupId, + final String enclaveKey, + final PrivacyParameters privacyParameters, + final PrivacyController privacyController, + final Function> mapper) { + + return blockHeader.flatMap( + header -> { + final long blockNumber = header.getNumber(); + final Hash parentHash = header.getParentHash(); + + final MutableWorldState disposablePrivateState = + privacyParameters + .getPrivateWorldStateArchive() + .getMutable( + privacyController + .getStateRootByBlockNumber(privacyGroupId, enclaveKey, blockNumber) + .get(), + parentHash) + .get(); + + return blockchainQueries.getAndMapWorldState( + parentHash, + mutableWorldState -> + mapper.apply( + new PrivateTracer.TraceableState(mutableWorldState, disposablePrivateState))); + }); + } + + /** + * This class force the use of the processTracing method to do tracing. processTracing allows you + * to cleanly manage the worldstate, to close it etc + */ + public static class TraceableState implements MutableWorldState { + private final MutableWorldState mutableWorldState; + private final MutableWorldState disposableWorldState; + + private TraceableState( + final MutableWorldState mutableWorldState, final MutableWorldState disposableWorldState) { + this.mutableWorldState = mutableWorldState; + this.disposableWorldState = disposableWorldState; + } + + @Override + public WorldUpdater updater() { + return mutableWorldState.updater(); + } + + public WorldUpdater privateUpdater() { + return disposableWorldState.updater(); + } + + @Override + public Hash rootHash() { + return mutableWorldState.rootHash(); + } + + @Override + public Hash frontierRootHash() { + return mutableWorldState.rootHash(); + } + + @Override + public Stream streamAccounts(final Bytes32 startKeyHash, final int limit) { + return mutableWorldState.streamAccounts(startKeyHash, limit); + } + + @Override + public Account get(final Address address) { + return mutableWorldState.get(address); + } + + @Override + public void close() throws Exception { + mutableWorldState.close(); + } + + @Override + public void persist(final BlockHeader blockHeader) {} + } +} diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/processor/privateProcessor/PrivateTransactionTrace.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/processor/privateProcessor/PrivateTransactionTrace.java new file mode 100644 index 0000000000..45e41d068b --- /dev/null +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/processor/privateProcessor/PrivateTransactionTrace.java @@ -0,0 +1,91 @@ +/* + * 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.processor.privateProcessor; + +import org.hyperledger.besu.ethereum.core.Block; +import org.hyperledger.besu.ethereum.debug.TraceFrame; +import org.hyperledger.besu.ethereum.privacy.ExecutedPrivateTransaction; +import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult; + +import java.util.List; +import java.util.Optional; + +public class PrivateTransactionTrace { + + private final ExecutedPrivateTransaction privateTransaction; + private final TransactionProcessingResult result; + private final List traceFrames; + private final Optional block; + + public PrivateTransactionTrace(final Optional block) { + this.privateTransaction = null; + this.result = null; + this.traceFrames = null; + this.block = block; + } + + public PrivateTransactionTrace( + final ExecutedPrivateTransaction privateTransaction, + final TransactionProcessingResult result, + final List traceFrames) { + this.privateTransaction = privateTransaction; + this.result = result; + this.traceFrames = traceFrames; + this.block = Optional.empty(); + } + + public PrivateTransactionTrace( + final ExecutedPrivateTransaction privateTransaction, + final TransactionProcessingResult result, + final List traceFrames, + final Optional block) { + this.privateTransaction = privateTransaction; + this.result = result; + this.traceFrames = traceFrames; + this.block = block; + } + + public PrivateTransactionTrace( + final ExecutedPrivateTransaction privateTransaction, final Optional block) { + this.privateTransaction = privateTransaction; + this.result = null; + this.traceFrames = null; + this.block = block; + } + + public ExecutedPrivateTransaction getPrivateTransaction() { + return privateTransaction; + } + + public long getGas() { + return privateTransaction.getGasLimit() - result.getGasRemaining(); + } + + public long getGasLimit() { + return privateTransaction.getGasLimit(); + } + + public TransactionProcessingResult getResult() { + return result; + } + + public List getTraceFrames() { + return traceFrames; + } + + public Optional getBlock() { + return block; + } +} diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/privacy/privateTracing/PrivateFlatTrace.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/privacy/privateTracing/PrivateFlatTrace.java new file mode 100644 index 0000000000..805e1c5ca3 --- /dev/null +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/privacy/privateTracing/PrivateFlatTrace.java @@ -0,0 +1,377 @@ +/* + * 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.results.privacy.privateTracing; + +import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL; + +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.privateProcessor.PrivateTransactionTrace; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.Quantity; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.tracing.Trace; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.tracing.flat.Action; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.tracing.flat.Result; +import org.hyperledger.besu.ethereum.debug.TraceFrame; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.atomic.AtomicReference; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +@JsonPropertyOrder({ + "action", + "blockHash", + "blockNumber", + "result", + "error", + "revertReason", + "subtraces", + "traceAddress", + "transactionHash", + "transactionPosition", + "type" +}) +public class PrivateFlatTrace implements Trace { + + private final Action action; + private final Result result; + private final Long blockNumber; + private final String blockHash; + private final Integer transactionPosition; + private final String transactionHash; + private final Optional error; + private final String revertReason; + private final int subtraces; + private final List traceAddress; + private final String type; + + protected PrivateFlatTrace( + final Action.Builder actionBuilder, + final Result.Builder resultBuilder, + final int subtraces, + final List traceAddress, + final String type, + final Long blockNumber, + final String blockHash, + final Integer transactionPosition, + final String transactionHash, + final Optional error) { + this( + actionBuilder != null ? actionBuilder.build() : null, + resultBuilder != null ? resultBuilder.build() : null, + subtraces, + traceAddress, + type, + blockNumber, + blockHash, + transactionPosition, + transactionHash, + error, + null); + } + + protected PrivateFlatTrace( + final Action.Builder actionBuilder, + final Result.Builder resultBuilder, + final int subtraces, + final List traceAddress, + final String type, + final Long blockNumber, + final String blockHash, + final Integer transactionPosition, + final String transactionHash, + final Optional error, + final String revertReason) { + this( + actionBuilder != null ? actionBuilder.build() : null, + resultBuilder != null ? resultBuilder.build() : null, + subtraces, + traceAddress, + type, + blockNumber, + blockHash, + transactionPosition, + transactionHash, + error, + revertReason); + } + + protected PrivateFlatTrace( + final Action action, + final Result result, + final int subtraces, + final List traceAddress, + final String type, + final Long blockNumber, + final String blockHash, + final Integer transactionPosition, + final String transactionHash, + final Optional error, + final String revertReason) { + this.action = action; + this.result = result; + this.subtraces = subtraces; + this.traceAddress = traceAddress; + this.type = type; + this.blockNumber = blockNumber; + this.blockHash = blockHash; + this.transactionPosition = transactionPosition; + this.transactionHash = transactionHash; + this.error = error; + this.revertReason = revertReason; + } + + static PrivateFlatTrace.Builder freshBuilder(final PrivateTransactionTrace transactionTrace) { + return PrivateFlatTrace.builder() + .resultBuilder(Result.builder()) + .actionBuilder(from(transactionTrace)); + } + + public static Action.Builder from(final PrivateTransactionTrace trace) { + final Action.Builder builder = + Action.builder() + .from(trace.getPrivateTransaction().getSender().toHexString()) + .value(Quantity.create(trace.getPrivateTransaction().getValue())); + if (!trace.getTraceFrames().isEmpty()) { + final TraceFrame traceFrame = trace.getTraceFrames().get(0); + builder.gas( + "0x" + + Long.toHexString( + traceFrame.getGasRemaining() + (traceFrame.getPrecompiledGasCost().orElse(0L)))); + } + return builder; + } + + public Action getAction() { + return action; + } + + @JsonInclude(NON_NULL) + public Long getBlockNumber() { + return blockNumber; + } + + @JsonInclude(NON_NULL) + public String getBlockHash() { + return blockHash; + } + + @JsonInclude(NON_NULL) + public String getTransactionHash() { + return transactionHash; + } + + @JsonInclude(NON_NULL) + public Integer getTransactionPosition() { + return transactionPosition; + } + + @JsonInclude(NON_NULL) + public String getError() { + return error.orElse(null); + } + + @JsonInclude(NON_NULL) + public String getRevertReason() { + return revertReason; + } + + @JsonInclude(NON_NULL) + public AtomicReference getResult() { + return (error.isPresent()) ? null : new AtomicReference<>(result); + } + + public int getSubtraces() { + return subtraces; + } + + public List getTraceAddress() { + return traceAddress; + } + + public String getType() { + return type; + } + + public static PrivateFlatTrace.Builder builder() { + return new PrivateFlatTrace.Builder(); + } + + public static class Context { + + private final PrivateFlatTrace.Builder builder; + private long gasUsed = 0; + private boolean createOp; + + Context(final PrivateFlatTrace.Builder builder) { + this.builder = builder; + } + + public PrivateFlatTrace.Builder getBuilder() { + return builder; + } + + void incGasUsed(final long gas) { + setGasUsed(gasUsed + gas); + } + + void decGasUsed(final long gas) { + setGasUsed(gasUsed - gas); + } + + public long getGasUsed() { + return gasUsed; + } + + public void setGasUsed(final long gasUsed) { + this.gasUsed = gasUsed; + builder.getResultBuilder().gasUsed("0x" + Long.toHexString(gasUsed)); + } + + boolean isCreateOp() { + return createOp; + } + + void setCreateOp(final boolean createOp) { + this.createOp = createOp; + } + } + + public static class Builder { + + private Action.Builder actionBuilder; + private Result.Builder resultBuilder; + private int subtraces; + private List traceAddress = new ArrayList<>(); + private String type = "call"; + private Long blockNumber; + private String blockHash; + private String transactionHash; + private Integer transactionPosition; + private Optional error = Optional.empty(); + private String revertReason; + + protected Builder() {} + + PrivateFlatTrace.Builder resultBuilder(final Result.Builder resultBuilder) { + this.resultBuilder = resultBuilder; + return this; + } + + PrivateFlatTrace.Builder actionBuilder(final Action.Builder actionBuilder) { + this.actionBuilder = actionBuilder; + return this; + } + + public PrivateFlatTrace.Builder traceAddress(final List traceAddress) { + this.traceAddress = traceAddress; + return this; + } + + public PrivateFlatTrace.Builder type(final String type) { + this.type = type; + return this; + } + + public PrivateFlatTrace.Builder blockNumber(final Long blockNumber) { + this.blockNumber = blockNumber; + return this; + } + + public PrivateFlatTrace.Builder blockHash(final String blockHash) { + this.blockHash = blockHash; + return this; + } + + public PrivateFlatTrace.Builder transactionHash(final String transactionHash) { + this.transactionHash = transactionHash; + return this; + } + + public PrivateFlatTrace.Builder error(final Optional error) { + this.error = error; + return this; + } + + public PrivateFlatTrace.Builder revertReason(final String revertReason) { + this.revertReason = revertReason; + return this; + } + + public String getType() { + return type; + } + + public int getSubtraces() { + return subtraces; + } + + public List getTraceAddress() { + return traceAddress; + } + + public Long getBlockNumber() { + return blockNumber; + } + + public String getBlockHash() { + return blockHash; + } + + public String getTransactionHash() { + return transactionHash; + } + + public Integer getTransactionPosition() { + return transactionPosition; + } + + public Optional getError() { + return error; + } + + public String getRevertReason() { + return revertReason; + } + + void incSubTraces() { + this.subtraces++; + } + + public PrivateFlatTrace build() { + return new PrivateFlatTrace( + actionBuilder, + resultBuilder, + subtraces, + traceAddress, + type, + blockNumber, + blockHash, + transactionPosition, + transactionHash, + error, + revertReason); + } + + public Result.Builder getResultBuilder() { + return resultBuilder; + } + + public Action.Builder getActionBuilder() { + return actionBuilder; + } + } +} diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/privacy/privateTracing/PrivateTraceGenerator.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/privacy/privateTracing/PrivateTraceGenerator.java new file mode 100644 index 0000000000..3f78ffe592 --- /dev/null +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/privacy/privateTracing/PrivateTraceGenerator.java @@ -0,0 +1,598 @@ +/* + * 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.results.privacy.privateTracing; + +import static org.hyperledger.besu.evm.internal.Words.toAddress; + +import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.datatypes.Wei; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.privateProcessor.PrivateTransactionTrace; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.Quantity; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.tracing.Trace; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.tracing.TracingUtils; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.tracing.flat.Action; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.tracing.flat.Result; +import org.hyperledger.besu.ethereum.core.Block; +import org.hyperledger.besu.ethereum.debug.TraceFrame; +import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; +import org.hyperledger.besu.ethereum.privacy.ExecutedPrivateTransaction; +import org.hyperledger.besu.evm.Code; +import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; + +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Deque; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Optional; +import java.util.OptionalLong; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Consumer; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import com.google.common.collect.Streams; +import com.google.common.util.concurrent.Atomics; +import org.apache.tuweni.bytes.Bytes; + +public class PrivateTraceGenerator { + + private static final String ZERO_ADDRESS_STRING = Address.ZERO.toHexString(); + private static final int EIP_150_DIVISOR = 64; + + public static Stream generateFromTransactionTrace( + final ProtocolSchedule protocolSchedule, + final PrivateTransactionTrace transactionTrace, + final Block block, + final AtomicInteger traceCounter, + final Consumer consumer) { + + final PrivateFlatTrace.Builder firstFlatTraceBuilder = + PrivateFlatTrace.freshBuilder(transactionTrace); + + final ExecutedPrivateTransaction tx = transactionTrace.getPrivateTransaction(); + + final Optional smartContractCode = + tx.getInit().map(__ -> transactionTrace.getResult().getOutput().toString()); + final Optional smartContractAddress = + smartContractCode.map( + __ -> Address.contractAddress(tx.getSender(), tx.getNonce()).toHexString()); + final Optional revertReason = transactionTrace.getResult().getRevertReason(); + + // set code field in result node + smartContractCode.ifPresent(firstFlatTraceBuilder.getResultBuilder()::code); + revertReason.ifPresent(r -> firstFlatTraceBuilder.revertReason(r.toHexString())); + + // set init field if transaction is a smart contract deployment + tx.getInit().map(Bytes::toHexString).ifPresent(firstFlatTraceBuilder.getActionBuilder()::init); + + // set to, input and callType fields if not a smart contract + if (tx.getTo().isPresent()) { + final Bytes payload = tx.getPayload(); + firstFlatTraceBuilder + .getActionBuilder() + .to(tx.getTo().map(Bytes::toHexString).orElse(null)) + .callType("call") + .input(payload == null ? "0x" : payload.toHexString()); + + if (!transactionTrace.getTraceFrames().isEmpty() + && hasRevertInSubCall(transactionTrace, transactionTrace.getTraceFrames().get(0))) { + firstFlatTraceBuilder.error(Optional.of("Reverted")); + } + + } else { + firstFlatTraceBuilder + .type("create") + .getResultBuilder() + .address(smartContractAddress.orElse(null)); + } + + if (!transactionTrace.getTraceFrames().isEmpty()) { + final OptionalLong precompiledGasCost = + transactionTrace.getTraceFrames().get(0).getPrecompiledGasCost(); + if (precompiledGasCost.isPresent()) { + firstFlatTraceBuilder + .getResultBuilder() + .gasUsed("0x" + Long.toHexString(precompiledGasCost.getAsLong())); + } + } + + final List flatTraces = new ArrayList<>(); + + // stack of previous contexts + final Deque tracesContexts = new ArrayDeque<>(); + + // add the first transactionTrace context to the queue of transactionTrace contexts + PrivateFlatTrace.Context currentContext = new PrivateFlatTrace.Context(firstFlatTraceBuilder); + tracesContexts.addLast(currentContext); + flatTraces.add(currentContext.getBuilder()); + // declare the first transactionTrace context as the previous transactionTrace context + long cumulativeGasCost = 0; + + final Iterator iter = transactionTrace.getTraceFrames().iterator(); + Optional nextTraceFrame = + iter.hasNext() ? Optional.of(iter.next()) : Optional.empty(); + while (nextTraceFrame.isPresent()) { + final TraceFrame traceFrame = nextTraceFrame.get(); + nextTraceFrame = iter.hasNext() ? Optional.of(iter.next()) : Optional.empty(); + cumulativeGasCost += + traceFrame.getGasCost().orElse(0L) + traceFrame.getPrecompiledGasCost().orElse(0L); + + final String opcodeString = traceFrame.getOpcode(); + if ("CALL".equals(opcodeString) + || "CALLCODE".equals(opcodeString) + || "DELEGATECALL".equals(opcodeString) + || "STATICCALL".equals(opcodeString)) { + + currentContext = + handleCall( + transactionTrace, + traceFrame, + nextTraceFrame, + flatTraces, + cumulativeGasCost, + tracesContexts, + opcodeString.toLowerCase(Locale.US)); + + } else if ("CALLDATALOAD".equals(opcodeString)) { + currentContext = handleCallDataLoad(currentContext, traceFrame); + } else if ("RETURN".equals(opcodeString) || "STOP".equals(opcodeString)) { + currentContext = + handleReturn( + protocolSchedule, + transactionTrace, + block, + traceFrame, + tracesContexts, + currentContext); + } else if ("SELFDESTRUCT".equals(opcodeString)) { + if (traceFrame.getExceptionalHaltReason().isPresent()) { + currentContext = + handleCall( + transactionTrace, + traceFrame, + nextTraceFrame, + flatTraces, + cumulativeGasCost, + tracesContexts, + opcodeString.toLowerCase(Locale.US)); + } else { + currentContext = + handleSelfDestruct(traceFrame, tracesContexts, currentContext, flatTraces); + } + } else if (("CREATE".equals(opcodeString) || "CREATE2".equals(opcodeString)) + && (traceFrame.getExceptionalHaltReason().isEmpty() || traceFrame.getDepth() == 0)) { + currentContext = + handleCreateOperation( + traceFrame, + nextTraceFrame, + flatTraces, + cumulativeGasCost, + tracesContexts, + smartContractAddress); + } else if ("REVERT".equals(opcodeString)) { + currentContext = handleRevert(tracesContexts, currentContext); + } + + if (traceFrame.getExceptionalHaltReason().isPresent()) { + currentContext = handleHalt(flatTraces, tracesContexts, currentContext, traceFrame); + } + + if (currentContext == null) { + break; + } + } + + return flatTraces.stream().peek(consumer).map(PrivateFlatTrace.Builder::build); + } + + public static Stream generateFromTransactionTraceAndBlock( + final ProtocolSchedule protocolSchedule, + final PrivateTransactionTrace transactionTrace, + final Block block) { + return generateFromTransactionTrace( + protocolSchedule, + transactionTrace, + block, + new AtomicInteger(), + builder -> + addAdditionalTransactionInformationToFlatTrace(builder, transactionTrace, block)); + } + + private static long computeGasUsed( + final Deque tracesContexts, + final PrivateFlatTrace.Context currentContext, + final PrivateTransactionTrace transactionTrace, + final TraceFrame traceFrame) { + + final long gasRemainingBeforeProcessed; + final long gasRemainingAfterProcessed; + long gasRefund = 0; + if (tracesContexts.size() == 1) { + gasRemainingBeforeProcessed = transactionTrace.getTraceFrames().get(0).getGasRemaining(); + gasRemainingAfterProcessed = transactionTrace.getResult().getGasRemaining(); + if (gasRemainingAfterProcessed > traceFrame.getGasRemaining()) { + gasRefund = gasRemainingAfterProcessed - traceFrame.getGasRemaining(); + } else { + gasRefund = traceFrame.getGasRefund(); + } + } else { + final Action.Builder actionBuilder = currentContext.getBuilder().getActionBuilder(); + gasRemainingBeforeProcessed = Long.decode(actionBuilder.getGas()); + gasRemainingAfterProcessed = traceFrame.getGasRemaining(); + } + return gasRemainingBeforeProcessed - gasRemainingAfterProcessed + gasRefund; + } + + private static long computeGas( + final TraceFrame traceFrame, final Optional nextTraceFrame) { + if (traceFrame.getGasCost().isPresent()) { + final long gasNeeded = traceFrame.getGasCost().getAsLong(); + final long currentGas = traceFrame.getGasRemaining(); + if (currentGas >= gasNeeded) { + final long gasRemaining = currentGas - gasNeeded; + return gasRemaining - Math.floorDiv(gasRemaining, EIP_150_DIVISOR); + } + } + return nextTraceFrame.map(TraceFrame::getGasRemaining).orElse(0L); + } + + private static String calculateCallingAddress(final PrivateFlatTrace.Context lastContext) { + final PrivateFlatTrace.Builder lastContextBuilder = lastContext.getBuilder(); + final Action.Builder lastActionBuilder = lastContextBuilder.getActionBuilder(); + if (lastActionBuilder.getCallType() == null) { + if ("create".equals(lastContextBuilder.getType())) { + return lastContextBuilder.getResultBuilder().getAddress(); + } else { + return ZERO_ADDRESS_STRING; + } + } + + switch (lastActionBuilder.getCallType()) { + case "call": + case "staticcall": + return lastActionBuilder.getTo(); + case "delegatecall": + case "callcode": + return lastActionBuilder.getFrom(); + case "create": + case "create2": + return lastContextBuilder.getResultBuilder().getAddress(); + default: + return ZERO_ADDRESS_STRING; + } + } + + private static List calculateTraceAddress( + final Deque contexts) { + return contexts.stream() + .map(context -> context.getBuilder().getSubtraces()) + .collect(Collectors.toList()); + } + + private static List calculateSelfDescructAddress( + final Deque contexts) { + return Streams.concat( + contexts.stream() + .map(context -> context.getBuilder().getSubtraces())) // , Stream.of(0)) + .collect(Collectors.toList()); + } + + private static String getActionAddress( + final Action.Builder callingAction, final String recipient) { + if (callingAction.getCallType() != null) { + return callingAction.getCallType().equals("call") + ? callingAction.getTo() + : callingAction.getFrom(); + } + return firstNonNull("", recipient, callingAction.getFrom(), callingAction.getTo()); + } + + private static String firstNonNull(final String defaultValue, final String... values) { + for (final String value : values) { + if (value != null) { + return value; + } + } + return defaultValue; + } + + private static PrivateFlatTrace.Context handleCreateOperation( + final TraceFrame traceFrame, + final Optional nextTraceFrame, + final List flatTraces, + final long cumulativeGasCost, + final Deque tracesContexts, + final Optional smartContractAddress) { + final PrivateFlatTrace.Context lastContext = tracesContexts.peekLast(); + + final String callingAddress = calculateCallingAddress(lastContext); + + final PrivateFlatTrace.Builder subTraceBuilder = + PrivateFlatTrace.builder() + .type("create") + .traceAddress(calculateTraceAddress(tracesContexts)) + .resultBuilder(Result.builder()); + + final Action.Builder subTraceActionBuilder = + Action.builder() + .from(smartContractAddress.orElse(callingAddress)) + .gas("0x" + Long.toHexString(computeGas(traceFrame, nextTraceFrame))) + .value(Quantity.create(nextTraceFrame.map(TraceFrame::getValue).orElse(Wei.ZERO))); + + traceFrame + .getMaybeCode() + .map(Code::getBytes) + .map(Bytes::toHexString) + .ifPresent(subTraceActionBuilder::init); + + final PrivateFlatTrace.Context currentContext = + new PrivateFlatTrace.Context(subTraceBuilder.actionBuilder(subTraceActionBuilder)); + + currentContext + .getBuilder() + .getResultBuilder() + .address(nextTraceFrame.map(TraceFrame::getRecipient).orElse(Address.ZERO).toHexString()); + currentContext.setCreateOp(true); + currentContext.decGasUsed(cumulativeGasCost); + tracesContexts.addLast(currentContext); + flatTraces.add(currentContext.getBuilder()); + return currentContext; + } + + private static PrivateFlatTrace.Context handleHalt( + final List flatTraces, + final Deque tracesContexts, + final PrivateFlatTrace.Context currentContext, + final TraceFrame traceFrame) { + final PrivateFlatTrace.Builder traceFrameBuilder; + if (currentContext == null) { + traceFrameBuilder = flatTraces.get(flatTraces.size() - 1); + } else { + traceFrameBuilder = currentContext.getBuilder(); + } + traceFrameBuilder.error( + traceFrame.getExceptionalHaltReason().map(ExceptionalHaltReason::getDescription)); + if (currentContext != null) { + final Action.Builder actionBuilder = traceFrameBuilder.getActionBuilder(); + actionBuilder.value(Quantity.create(traceFrame.getValue())); + tracesContexts.removeLast(); + final PrivateFlatTrace.Context nextContext = tracesContexts.peekLast(); + if (nextContext != null) { + nextContext.getBuilder().incSubTraces(); + } + return nextContext; + } + return currentContext; + } + + private static PrivateFlatTrace.Context handleRevert( + final Deque tracesContexts, + final PrivateFlatTrace.Context currentContext) { + currentContext.getBuilder().error(Optional.of("Reverted")); + tracesContexts.removeLast(); + final PrivateFlatTrace.Context nextContext = tracesContexts.peekLast(); + if (nextContext != null) { + nextContext.getBuilder().incSubTraces(); + } + return nextContext; + } + + private static PrivateFlatTrace.Context handleSelfDestruct( + final TraceFrame traceFrame, + final Deque tracesContexts, + final PrivateFlatTrace.Context currentContext, + final List flatTraces) { + + final Action.Builder actionBuilder = currentContext.getBuilder().getActionBuilder(); + final long gasUsed = + Long.decode(actionBuilder.getGas()) + - traceFrame.getGasRemaining() + + (traceFrame.getGasCost().orElse(0L)); + + currentContext.setGasUsed(gasUsed); + + final Bytes[] stack = traceFrame.getStack().orElseThrow(); + final Address refundAddress = toAddress(stack[stack.length - 1]); + final PrivateFlatTrace.Builder subTraceBuilder = + PrivateFlatTrace.builder() + .type("suicide") + .traceAddress(calculateSelfDescructAddress(tracesContexts)); + + final AtomicReference weiBalance = Atomics.newReference(Wei.ZERO); + traceFrame + .getMaybeRefunds() + .ifPresent(refunds -> weiBalance.set(refunds.getOrDefault(refundAddress, Wei.ZERO))); + + final Action.Builder callingAction = tracesContexts.peekLast().getBuilder().getActionBuilder(); + final String actionAddress = + getActionAddress(callingAction, traceFrame.getRecipient().toHexString()); + final Action.Builder subTraceActionBuilder = + Action.builder() + .address(actionAddress) + .refundAddress(refundAddress.toString()) + .balance(TracingUtils.weiAsHex(weiBalance.get())); + + flatTraces.add( + new PrivateFlatTrace.Context(subTraceBuilder.actionBuilder(subTraceActionBuilder)) + .getBuilder()); + final PrivateFlatTrace.Context lastContext = tracesContexts.removeLast(); + lastContext.getBuilder().incSubTraces(); + final PrivateFlatTrace.Context nextContext = tracesContexts.peekLast(); + if (nextContext != null) { + nextContext.getBuilder().incSubTraces(); + } + return nextContext; + } + + private static PrivateFlatTrace.Context handleReturn( + final ProtocolSchedule protocolSchedule, + final PrivateTransactionTrace transactionTrace, + final Block block, + final TraceFrame traceFrame, + final Deque tracesContexts, + final PrivateFlatTrace.Context currentContext) { + + final PrivateFlatTrace.Builder traceFrameBuilder = currentContext.getBuilder(); + final Result.Builder resultBuilder = traceFrameBuilder.getResultBuilder(); + final Action.Builder actionBuilder = traceFrameBuilder.getActionBuilder(); + actionBuilder.value(Quantity.create(traceFrame.getValue())); + + currentContext.setGasUsed( + computeGasUsed(tracesContexts, currentContext, transactionTrace, traceFrame)); + + if ("STOP".equals(traceFrame.getOpcode()) && resultBuilder.isGasUsedEmpty()) { + final long callStipend = + protocolSchedule + .getByBlockHeader(block.getHeader()) + .getGasCalculator() + .getAdditionalCallStipend(); + tracesContexts.stream() + .filter( + context -> + !tracesContexts.getFirst().equals(context) + && !tracesContexts.getLast().equals(context)) + .forEach(context -> context.decGasUsed(callStipend)); + } + + final Bytes outputData = traceFrame.getOutputData(); + if (resultBuilder.getCode() == null) { + resultBuilder.output(outputData.toHexString()); + } + + // set value for contract creation TXes, CREATE, and CREATE2 + if (actionBuilder.getCallType() == null && traceFrame.getMaybeCode().isPresent()) { + actionBuilder.init(traceFrame.getMaybeCode().get().getBytes().toHexString()); + resultBuilder.code(outputData.toHexString()); + if (currentContext.isCreateOp()) { + // this is from a CREATE/CREATE2, so add code deposit cost. + currentContext.incGasUsed(outputData.size() * 200L); + } + } + + tracesContexts.removeLast(); + final PrivateFlatTrace.Context nextContext = tracesContexts.peekLast(); + if (nextContext != null) { + nextContext.getBuilder().incSubTraces(); + } + return nextContext; + } + + private static PrivateFlatTrace.Context handleCallDataLoad( + final PrivateFlatTrace.Context currentContext, final TraceFrame traceFrame) { + if (!traceFrame.getValue().isZero()) { + currentContext + .getBuilder() + .getActionBuilder() + .value(traceFrame.getValue().toShortHexString()); + } else { + currentContext.getBuilder().getActionBuilder().value("0x0"); + } + return currentContext; + } + + private static PrivateFlatTrace.Context handleCall( + final PrivateTransactionTrace transactionTrace, + final TraceFrame traceFrame, + final Optional nextTraceFrame, + final List flatTraces, + final long cumulativeGasCost, + final Deque tracesContexts, + final String opcodeString) { + final Bytes[] stack = traceFrame.getStack().orElseThrow(); + final PrivateFlatTrace.Context lastContext = tracesContexts.peekLast(); + + final String callingAddress = calculateCallingAddress(lastContext); + + if (traceFrame.getDepth() >= nextTraceFrame.map(TraceFrame::getDepth).orElse(0)) { + // don't log calls to calls that don't execute, such as insufficient value and precompiles + return tracesContexts.peekLast(); + } + + final PrivateFlatTrace.Builder subTraceBuilder = + PrivateFlatTrace.builder() + .traceAddress(calculateTraceAddress(tracesContexts)) + .resultBuilder(Result.builder()); + final Action.Builder subTraceActionBuilder = + Action.builder() + .from(callingAddress) + .input( + nextTraceFrame.map(TraceFrame::getInputData).map(Bytes::toHexString).orElse(null)) + .gas( + "0x" + Long.toHexString(nextTraceFrame.map(TraceFrame::getGasRemaining).orElse(0L))) + .callType(opcodeString.toLowerCase(Locale.US)) + .value(Quantity.create(traceFrame.getValue())); + + if (stack.length > 1) { + subTraceActionBuilder.to(toAddress(stack[stack.length - 2]).toString()); + } + + nextTraceFrame.ifPresent( + nextFrame -> { + if (hasRevertInSubCall(transactionTrace, nextFrame)) { + subTraceBuilder.error(Optional.of("Reverted")); + } + }); + + final PrivateFlatTrace.Context currentContext = + new PrivateFlatTrace.Context(subTraceBuilder.actionBuilder(subTraceActionBuilder)); + currentContext.decGasUsed(cumulativeGasCost); + + tracesContexts.addLast(currentContext); + flatTraces.add(currentContext.getBuilder()); + return currentContext; + } + + private static boolean hasRevertInSubCall( + final PrivateTransactionTrace transactionTrace, final TraceFrame callFrame) { + return transactionTrace.getTraceFrames().stream() + .filter(traceFrame -> !traceFrame.equals(callFrame)) + .takeWhile(traceFrame -> !traceFrame.getOpcode().equals("RETURN")) + .filter(traceFrame -> traceFrame.getOpcode().equals("REVERT")) + .anyMatch(traceFrame -> traceFrame.getDepth() == callFrame.getDepth()); + } + + private static void addAdditionalTransactionInformationToFlatTrace( + final PrivateFlatTrace.Builder builder, + final PrivateTransactionTrace transactionTrace, + final Block block) { + // add block information (hash and number) + builder.blockHash(block.getHash().toHexString()).blockNumber(block.getHeader().getNumber()); + // add transaction information (position and hash) + builder.transactionHash(transactionTrace.getPrivateTransaction().getPmtHash().toHexString()); + + addContractCreationMethodToTrace(transactionTrace, builder); + } + + private static void addContractCreationMethodToTrace( + final PrivateTransactionTrace transactionTrace, final PrivateFlatTrace.Builder builder) { + // add creationMethod for create action + Optional.ofNullable(builder.getType()) + .filter(type -> type.equals("create")) + .ifPresent( + __ -> + builder + .getActionBuilder() + .creationMethod( + transactionTrace.getTraceFrames().stream() + .filter(frame -> "CREATE2".equals(frame.getOpcode())) + .findFirst() + .map(TraceFrame::getOpcode) + .orElse("CREATE") + .toLowerCase(Locale.US))); + } +} diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/tracing/flat/Action.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/tracing/flat/Action.java index 03bafbe859..de7ae2c6f0 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/tracing/flat/Action.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/tracing/flat/Action.java @@ -263,7 +263,7 @@ public class Action { return this; } - Builder refundAddress(final String refundAddress) { + public Builder refundAddress(final String refundAddress) { this.refundAddress = refundAddress; return this; } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/tracing/flat/FlatTraceGenerator.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/tracing/flat/FlatTraceGenerator.java index ad39330fa5..a253c6e323 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/tracing/flat/FlatTraceGenerator.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/tracing/flat/FlatTraceGenerator.java @@ -624,7 +624,7 @@ public class FlatTraceGenerator { .collect(Collectors.toList()); } - private static void addAdditionalTransactionInformationToFlatTrace( + protected static void addAdditionalTransactionInformationToFlatTrace( final FlatTrace.Builder builder, final TransactionTrace transactionTrace, final Block block) { // add block information (hash and number) builder.blockHash(block.getHash().toHexString()).blockNumber(block.getHeader().getNumber()); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/PrivJsonRpcMethods.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/PrivJsonRpcMethods.java index 0f6df40d14..8ae62741b9 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/PrivJsonRpcMethods.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/PrivJsonRpcMethods.java @@ -34,6 +34,9 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv.P import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv.PrivGetTransactionCount; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv.PrivGetTransactionReceipt; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv.PrivNewFilter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv.PrivTraceTransaction; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.privateProcessor.PrivateBlockReplay; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.privateProcessor.PrivateBlockTracer; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; import org.hyperledger.besu.ethereum.core.PrivacyParameters; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool; @@ -68,6 +71,9 @@ public class PrivJsonRpcMethods extends PrivacyApiGroupJsonRpcMethods { final PrivacyIdProvider privacyIdProvider, final PrivateMarkerTransactionFactory privateMarkerTransactionFactory) { + final PrivateBlockReplay blockReplay = + new PrivateBlockReplay( + getProtocolSchedule(), getBlockchainQueries().getBlockchain(), privacyController); final Map RPC_METHODS = mapOf( new PrivCall(getBlockchainQueries(), privacyController, privacyIdProvider), @@ -89,7 +95,15 @@ public class PrivJsonRpcMethods extends PrivacyApiGroupJsonRpcMethods { new PrivGetFilterLogs(filterManager, privacyController, privacyIdProvider), new PrivGetFilterChanges(filterManager, privacyController, privacyIdProvider), new PrivNewFilter(filterManager, privacyController, privacyIdProvider), - new PrivUninstallFilter(filterManager, privacyController, privacyIdProvider)); + new PrivUninstallFilter(filterManager, privacyController, privacyIdProvider), + new PrivTraceTransaction( + () -> new PrivateBlockTracer(blockReplay), + getBlockchainQueries(), + getProtocolSchedule(), + getPrivacyQueries(), + privacyController, + getPrivacyParameters(), + privacyIdProvider)); if (!getPrivacyParameters().isFlexiblePrivacyGroupsEnabled()) { final Map OFFCHAIN_METHODS = diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/query/PrivacyQueries.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/query/PrivacyQueries.java index 604bad0c9b..9768ead9dc 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/query/PrivacyQueries.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/query/PrivacyQueries.java @@ -20,6 +20,7 @@ import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.LogWithMetadata; import org.hyperledger.besu.ethereum.privacy.PrivateTransactionReceipt; import org.hyperledger.besu.ethereum.privacy.PrivateWorldStateReader; +import org.hyperledger.besu.ethereum.privacy.storage.PrivateBlockMetadata; import org.hyperledger.besu.ethereum.privacy.storage.PrivateTransactionMetadata; import java.util.Collection; @@ -43,6 +44,11 @@ public class PrivacyQueries { this.privateWorldStateReader = privateWorldStateReader; } + public Optional getPrivateBlockMetaData( + final String privacyGroupId, final Hash blockHash) { + return privateWorldStateReader.getPrivateBlockMetadata(privacyGroupId, blockHash); + } + public List matchingLogs( final String privacyGroupId, final long fromBlockNumber, diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/PrivJsonRpcMethodsTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/PrivJsonRpcMethodsTest.java index 249b2e7077..b9024db998 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/PrivJsonRpcMethodsTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/PrivJsonRpcMethodsTest.java @@ -44,7 +44,6 @@ public class PrivJsonRpcMethodsTest { @Mock private TransactionPool transactionPool; @Mock private PrivacyParameters privacyParameters; @Mock private FilterManager filterManager; - private PrivJsonRpcMethods privJsonRpcMethods; @BeforeEach diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateTransaction.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateTransaction.java index c108d27626..42672ddbf0 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateTransaction.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateTransaction.java @@ -355,6 +355,16 @@ public class PrivateTransaction implements org.hyperledger.besu.plugin.data.Priv return payload; } + /** + * Returns the payload if this is a contract creation transaction. + * + * @return if present the init code + */ + @Override + public Optional getInit() { + return getTo().isPresent() ? Optional.empty() : Optional.of(payload); + } + /** * Return the transaction chain id (if it exists) * diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateWorldStateReader.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateWorldStateReader.java index af32e76513..255f80b587 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateWorldStateReader.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateWorldStateReader.java @@ -66,6 +66,12 @@ public class PrivateWorldStateReader { .orElse(Collections.emptyList()); } + public Optional getPrivateBlockMetadata( + final String privacyGroupId, final Hash blockHash) { + final Bytes32 privacyGroupIdBytes = Bytes32.wrap(Bytes.fromBase64String(privacyGroupId)); + return privateStateStorage.getPrivateBlockMetadata(blockHash, privacyGroupIdBytes); + } + public Optional getPrivateTransactionReceipt( final Hash blockHash, final Hash transactionHash) { return privateStateStorage.getTransactionReceipt(blockHash, transactionHash); diff --git a/plugin-api/build.gradle b/plugin-api/build.gradle index e49297ab7b..fe7308993b 100644 --- a/plugin-api/build.gradle +++ b/plugin-api/build.gradle @@ -70,7 +70,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 = 'I851CCOs00yYpW10qIGIak1bKbYhKFQkV2wyCYELHKY=' + knownHash = 'W1gv5UjqU+RJZJN6xPNjVfjuz7nKIcBgmh1j2XON4EU=' } check.dependsOn('checkAPIChanges') diff --git a/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/PrivateTransaction.java b/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/PrivateTransaction.java index 4ab171ecae..fe918bf8f1 100644 --- a/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/PrivateTransaction.java +++ b/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/PrivateTransaction.java @@ -94,6 +94,16 @@ public interface PrivateTransaction { */ Address getSender(); + /** + * An unlimited size byte array specifying the EVM-code for the account initialization procedure. + * + *

Only present if this is a contract creation transaction, which is only true if {@link + * #getTo} is empty. + * + * @return if present, the contract init code. + */ + Optional getInit(); + /** * The chainId, computed from the 'V' portion of the signature. Used for replay protection. If * replay protection is not enabled this value will not be present. From c61cf0b5af900c05a082eadafbb1b4704bb9fa4e Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Tue, 13 Aug 2024 15:38:20 +1000 Subject: [PATCH 106/259] 5098 branch 12 update invalid block index and number (#7440) * 5098: Add RpcErrorTypes Signed-off-by: Matilda Clerke * 5098: Modify InvalidJsonRpcParameters and InvalidJsonRpcRequestException, apply spotless Signed-off-by: Matilda Clerke * 5098: Modify InvalidJsonRpcParameters and InvalidJsonRpcRequestException, apply spotless Signed-off-by: Matilda Clerke * 5098: Add JsonRpcParameterException for later use Signed-off-by: Matilda Clerke * 5098: Update locations for RpcErrorType.INVALID_ACCOUNTS_PARAMS Signed-off-by: Matilda Clerke * 5098: Address review comments, apply spotless Signed-off-by: Matilda Clerke * 5098: Update with changes from branch 1 Signed-off-by: Matilda Clerke * 5098: Update code to use RpcErrorType.INVALID_ADDRESS_HASH_PARAMS Signed-off-by: Matilda Clerke * 5098: apply spotless Signed-off-by: Matilda Clerke * 5098: apply spotless Signed-off-by: Matilda Clerke * 5098: Update plugin-api gradle hash Signed-off-by: Matilda Clerke * 5098: Add comment on INVALID_PARAMS_ERROR_CODE Signed-off-by: Matilda Clerke * 5098: Apply spotless on latest changes Signed-off-by: Matilda Clerke * 5098: Update code to use RpcErrorType.INVALID_ADDRESS_PARAMS Signed-off-by: Matilda Clerke * 5098: Fix broken unit test Signed-off-by: Matilda Clerke * 5098: Fix broken unit test Signed-off-by: Matilda Clerke * 5098: Update with usage of RpcErrorType.INVALID_AUTH_PARAMS Signed-off-by: Matilda Clerke * 5098: Update with usage of RpcErrorType.INVALID_BLOB_COUNT Signed-off-by: Matilda Clerke * 5098: Update with usage of RpcErrorType.INVALID_BLOB_GAS_USED_PARAMS Signed-off-by: Matilda Clerke * 5098: Update with usage of RpcErrorType.INVALID_BLOCK_PARAMS Signed-off-by: Matilda Clerke * 5098: Update with usage of RpcErrorType.INVALID_BLOCK_PARAMS Signed-off-by: Matilda Clerke * 5098: Update with usage of RpcErrorType.INVALID_BLOCK_PARAMS Signed-off-by: Matilda Clerke * 5098: Update with usage of RpcErrorType.INVALID_BLOCK_COUNT_PARAMS Signed-off-by: Matilda Clerke * 5098: Fix broken integration test Signed-off-by: Matilda Clerke * 5098: Add index to exception messages Signed-off-by: Matilda Clerke * 5098: apoply spotless Signed-off-by: Matilda Clerke * 5098: Update BaseJsonRpcProcessor to utilise RpcErrorType from InvalidJsonRpcParameters Signed-off-by: Matilda Clerke * 5098: Include parameter index in INVALID_AUTH_PARAMS Signed-off-by: Matilda Clerke * 5098: Include parameter index in INVALID_BLOCK_PARAMS Signed-off-by: Matilda Clerke * 5098: Include parameter index in INVALID_BLOCK_COUNT_PARAMS Signed-off-by: Matilda Clerke * 5098: Fix broken integration test Signed-off-by: Matilda Clerke * 5098: Rename INVALID_AUTH_PARAMS to INVALID_PROPOSAL_PARAMS Signed-off-by: Matilda Clerke * 5098: apply spotless Signed-off-by: Matilda Clerke * 5098: Update INVALID_BLOCK_HASH_PARAMS locations Signed-off-by: Matilda Clerke * 5098: Fix broken unit test Signed-off-by: Matilda Clerke * 5098: apply spotless Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_BLOCK_INDEX Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_BLOCK_NUMBER Signed-off-by: Matilda Clerke * 5098: apply spotless Signed-off-by: Matilda Clerke * 5098: Fix broken tests Signed-off-by: Matilda Clerke * 5098: Fix broken test Signed-off-by: Matilda Clerke * 5098: Apply spotless Signed-off-by: Matilda Clerke * 5098: Fix broken tests Signed-off-by: Matilda Clerke * 5098: Fix broken tests Signed-off-by: Matilda Clerke * 5098: Fix broken tests Signed-off-by: Matilda Clerke * 5098: Fix broken tests Signed-off-by: Matilda Clerke * 5098: Remove TODO by wrapping unexpected exception and rethrowing Signed-off-by: Matilda Clerke --------- Signed-off-by: Matilda Clerke Signed-off-by: Matilda-Clerke Co-authored-by: Sally MacFarlane --- .../methods/CliqueGetSignerMetricsTest.java | 4 ++-- .../AbstractGetSignerMetricsMethod.java | 21 ++++++++++++---- .../methods/IbftGetSignerMetricsTest.java | 4 ++-- .../methods/QbftGetSignerMetricsTest.java | 4 ++-- ...stractBlockParameterOrBlockHashMethod.java | 2 +- .../methods/AdminLogsRemoveCache.java | 21 ++++++++++++---- .../methods/AdminLogsRepairCache.java | 10 +++++++- .../internal/methods/EthFeeHistory.java | 2 +- .../jsonrpc/internal/methods/EthGetLogs.java | 24 ++++++++++++------- .../EthGetUncleByBlockHashAndIndex.java | 8 ++++++- .../EthGetUncleByBlockNumberAndIndex.java | 8 ++++++- .../EngineGetPayloadBodiesByRangeV1.java | 13 +++++++--- .../methods/AdminLogsRemoveCacheTest.java | 3 ++- .../internal/methods/EthFeeHistoryTest.java | 2 +- .../EthGetUncleByBlockHashAndIndexTest.java | 4 ++-- .../EthGetUncleByBlockNumberAndIndexTest.java | 2 +- .../eth_getBalance_illegalRangeLessThan.json | 2 +- .../eth/eth_getCode_illegalRangeLessThan.json | 2 +- .../eth_getProof_illegalRangeLessThan.json | 2 +- ...eth_getStorageAt_illegalRangeLessThan.json | 2 +- .../retesteth/methods/TestRewindToBlock.java | 10 +++++++- 21 files changed, 108 insertions(+), 42 deletions(-) diff --git a/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/CliqueGetSignerMetricsTest.java b/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/CliqueGetSignerMetricsTest.java index 89c48fb978..310b3b1017 100644 --- a/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/CliqueGetSignerMetricsTest.java +++ b/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/CliqueGetSignerMetricsTest.java @@ -75,14 +75,14 @@ public class CliqueGetSignerMetricsTest { public void exceptionWhenInvalidStartBlockSupplied() { assertThatThrownBy(() -> method.response(requestWithParams("INVALID"))) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Invalid json rpc parameter at index 0"); + .hasMessageContaining("Invalid start block parameter (index 0)"); } @Test public void exceptionWhenInvalidEndBlockSupplied() { assertThatThrownBy(() -> method.response(requestWithParams("1", "INVALID"))) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Invalid json rpc parameter at index 1"); + .hasMessageContaining("Invalid end block parameter (index 1)"); } @Test diff --git a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/jsonrpc/AbstractGetSignerMetricsMethod.java b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/jsonrpc/AbstractGetSignerMetricsMethod.java index 3566684ab1..7ef368fb76 100644 --- a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/jsonrpc/AbstractGetSignerMetricsMethod.java +++ b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/jsonrpc/AbstractGetSignerMetricsMethod.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.consensus.common.BlockInterface; import org.hyperledger.besu.consensus.common.validator.ValidatorProvider; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; @@ -66,17 +67,27 @@ public abstract class AbstractGetSignerMetricsMethod { */ public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { - final Optional startBlockParameter = - requestContext.getOptionalParameter(0, BlockParameter.class); - final Optional endBlockParameter = - requestContext.getOptionalParameter(1, BlockParameter.class); + final Optional startBlockParameter; + try { + startBlockParameter = requestContext.getOptionalParameter(0, BlockParameter.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid start block parameter (index 0)", RpcErrorType.INVALID_BLOCK_NUMBER_PARAMS, e); + } + final Optional endBlockParameter; + try { + endBlockParameter = requestContext.getOptionalParameter(1, BlockParameter.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid end block parameter (index 1)", RpcErrorType.INVALID_BLOCK_NUMBER_PARAMS, e); + } final long fromBlockNumber = getFromBlockNumber(startBlockParameter); final long toBlockNumber = getEndBlockNumber(endBlockParameter); if (!isValidParameters(fromBlockNumber, toBlockNumber)) { return new JsonRpcErrorResponse( - requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + requestContext.getRequest().getId(), RpcErrorType.INVALID_BLOCK_NUMBER_PARAMS); } final Map proposersMap = new HashMap<>(); diff --git a/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftGetSignerMetricsTest.java b/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftGetSignerMetricsTest.java index bb6d44aca6..4eb8fbe12b 100644 --- a/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftGetSignerMetricsTest.java +++ b/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftGetSignerMetricsTest.java @@ -75,14 +75,14 @@ public class IbftGetSignerMetricsTest { public void exceptionWhenInvalidStartBlockSupplied() { assertThatThrownBy(() -> method.response(requestWithParams("INVALID"))) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Invalid json rpc parameter at index 0"); + .hasMessageContaining("Invalid start block parameter (index 0)"); } @Test public void exceptionWhenInvalidEndBlockSupplied() { assertThatThrownBy(() -> method.response(requestWithParams("1", "INVALID"))) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Invalid json rpc parameter at index 1"); + .hasMessageContaining("Invalid end block parameter (index 1)"); } @Test diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftGetSignerMetricsTest.java b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftGetSignerMetricsTest.java index d070ba47cc..153a4ef55b 100644 --- a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftGetSignerMetricsTest.java +++ b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftGetSignerMetricsTest.java @@ -75,14 +75,14 @@ public class QbftGetSignerMetricsTest { public void exceptionWhenInvalidStartBlockSupplied() { assertThatThrownBy(() -> method.response(requestWithParams("INVALID"))) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Invalid json rpc parameter at index 0"); + .hasMessageContaining("Invalid start block parameter (index 0)"); } @Test public void exceptionWhenInvalidEndBlockSupplied() { assertThatThrownBy(() -> method.response(requestWithParams("1", "INVALID"))) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Invalid json rpc parameter at index 1"); + .hasMessageContaining("Invalid end block parameter (index 1)"); } @Test diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AbstractBlockParameterOrBlockHashMethod.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AbstractBlockParameterOrBlockHashMethod.java index be6ecfa82e..ba3bcd69c6 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AbstractBlockParameterOrBlockHashMethod.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AbstractBlockParameterOrBlockHashMethod.java @@ -106,7 +106,7 @@ public abstract class AbstractBlockParameterOrBlockHashMethod implements JsonRpc final OptionalLong blockNumber = blockParameterOrBlockHash.getNumber(); if (blockNumber.isEmpty() || blockNumber.getAsLong() < 0) { return new JsonRpcErrorResponse( - requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + requestContext.getRequest().getId(), RpcErrorType.INVALID_BLOCK_NUMBER_PARAMS); } else if (blockNumber.getAsLong() > getBlockchainQueries().headBlockNumber()) { return new JsonRpcErrorResponse( requestContext.getRequest().getId(), RpcErrorType.BLOCK_NOT_FOUND); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminLogsRemoveCache.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminLogsRemoveCache.java index 01cfb02a1e..94430c526f 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminLogsRemoveCache.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminLogsRemoveCache.java @@ -16,6 +16,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; @@ -42,10 +43,20 @@ public class AdminLogsRemoveCache implements JsonRpcMethod { @Override public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { - final Optional startBlockParameter = - requestContext.getOptionalParameter(0, BlockParameter.class); - final Optional stopBlockParameter = - requestContext.getOptionalParameter(1, BlockParameter.class); + final Optional startBlockParameter; + try { + startBlockParameter = requestContext.getOptionalParameter(0, BlockParameter.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid start block parameter (index 0)", RpcErrorType.INVALID_BLOCK_NUMBER_PARAMS, e); + } + final Optional stopBlockParameter; + try { + stopBlockParameter = requestContext.getOptionalParameter(1, BlockParameter.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid stop block parameter (index 1)", RpcErrorType.INVALID_BLOCK_NUMBER_PARAMS, e); + } final long startBlock; if (startBlockParameter.isEmpty() || startBlockParameter.get().isEarliest()) { @@ -81,7 +92,7 @@ public class AdminLogsRemoveCache implements JsonRpcMethod { if (stopBlock < startBlock) { return new JsonRpcErrorResponse( - requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + requestContext.getRequest().getId(), RpcErrorType.INVALID_BLOCK_NUMBER_PARAMS); } final TransactionLogBloomCacher transactionLogBloomCacher = diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminLogsRepairCache.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminLogsRepairCache.java index 757ac2756b..7336faff0e 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminLogsRepairCache.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminLogsRepairCache.java @@ -16,8 +16,10 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; 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.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; import org.hyperledger.besu.ethereum.api.query.cache.TransactionLogBloomCacher; @@ -38,7 +40,13 @@ public class AdminLogsRepairCache implements JsonRpcMethod { @Override public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { - final Optional blockNumber = requestContext.getOptionalParameter(0, Long.class); + final Optional blockNumber; + try { + blockNumber = requestContext.getOptionalParameter(0, Long.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid block number parameter (index 0)", RpcErrorType.INVALID_BLOCK_NUMBER_PARAMS, e); + } if (blockNumber.isPresent() && blockchainQueries.getBlockchain().getBlockByNumber(blockNumber.get()).isEmpty()) { 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 92d42f2278..e2056ac94b 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 @@ -113,7 +113,7 @@ public class EthFeeHistory implements JsonRpcMethod { final long chainHeadBlockNumber = chainHeadHeader.getNumber(); final long highestBlockNumber = highestBlock.getNumber().orElse(chainHeadBlockNumber); if (highestBlockNumber > chainHeadBlockNumber) { - return new JsonRpcErrorResponse(requestId, RpcErrorType.INVALID_PARAMS); + return new JsonRpcErrorResponse(requestId, RpcErrorType.INVALID_BLOCK_NUMBER_PARAMS); } final long firstBlock = Math.max(0, highestBlockNumber - (blockCount - 1)); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetLogs.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetLogs.java index c4356ce1c2..60f38fb7ac 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetLogs.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetLogs.java @@ -16,6 +16,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.FilterParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; @@ -78,16 +79,22 @@ public class EthGetLogs implements JsonRpcMethod { .getBlockNumber(blockchain) .orElseThrow( () -> - new Exception("fromBlock not found: " + filter.getFromBlock())); + new InvalidJsonRpcParameters( + "fromBlock not found: " + filter.getFromBlock(), + RpcErrorType.INVALID_BLOCK_NUMBER_PARAMS)); toBlockNumber = filter .getToBlock() .getBlockNumber(blockchain) .orElseThrow( - () -> new Exception("toBlock not found: " + filter.getToBlock())); + () -> + new InvalidJsonRpcParameters( + "toBlock not found: " + filter.getToBlock(), + RpcErrorType.INVALID_BLOCK_NUMBER_PARAMS)); if (maxLogRange > 0 && (toBlockNumber - fromBlockNumber) > maxLogRange) { - throw new IllegalArgumentException( - "Requested range exceeds maximum range limit"); + throw new InvalidJsonRpcParameters( + "Requested range exceeds maximum range limit", + RpcErrorType.EXCEEDS_RPC_MAX_BLOCK_RANGE); } } catch (final Exception e) { ex.set(e); @@ -107,12 +114,13 @@ public class EthGetLogs implements JsonRpcMethod { .addArgument(requestContext.getRequest()) .setCause(ex.get()) .log(); - if (ex.get() instanceof IllegalArgumentException) { + if (ex.get() instanceof InvalidJsonRpcParameters) { return new JsonRpcErrorResponse( - requestContext.getRequest().getId(), RpcErrorType.EXCEEDS_RPC_MAX_BLOCK_RANGE); + requestContext.getRequest().getId(), + ((InvalidJsonRpcParameters) ex.get()).getRpcErrorType()); + } else { + throw new RuntimeException(ex.get()); } - return new JsonRpcErrorResponse( - requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAMS); } return new JsonRpcSuccessResponse( diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetUncleByBlockHashAndIndex.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetUncleByBlockHashAndIndex.java index 93ae857a69..9269bf965c 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetUncleByBlockHashAndIndex.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetUncleByBlockHashAndIndex.java @@ -53,7 +53,13 @@ public class EthGetUncleByBlockHashAndIndex implements JsonRpcMethod { throw new InvalidJsonRpcParameters( "Invalid block hash parameter (index 0)", RpcErrorType.INVALID_BLOCK_HASH_PARAMS, e); } - final int index = requestContext.getRequiredParameter(1, UnsignedIntParameter.class).getValue(); + final int index; + try { + index = requestContext.getRequiredParameter(1, UnsignedIntParameter.class).getValue(); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid block index parameter (index 1)", RpcErrorType.INVALID_BLOCK_INDEX_PARAMS, e); + } return blockchain.getOmmer(hash, index).map(UncleBlockResult::build).orElse(null); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetUncleByBlockNumberAndIndex.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetUncleByBlockNumberAndIndex.java index d2ac0b26af..a6c5e6d89d 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetUncleByBlockNumberAndIndex.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetUncleByBlockNumberAndIndex.java @@ -48,7 +48,13 @@ public class EthGetUncleByBlockNumberAndIndex extends AbstractBlockParameterMeth @Override protected BlockResult resultByBlockNumber( final JsonRpcRequestContext request, final long blockNumber) { - final int index = request.getRequiredParameter(1, UnsignedIntParameter.class).getValue(); + final int index; + try { + index = request.getRequiredParameter(1, UnsignedIntParameter.class).getValue(); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid block index (index 1)", RpcErrorType.INVALID_BLOCK_INDEX_PARAMS, e); + } return getBlockchainQueries() .getOmmer(blockNumber, index) .map(UncleBlockResult::build) diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadBodiesByRangeV1.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadBodiesByRangeV1.java index 88431dd89b..ec5d5bf604 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadBodiesByRangeV1.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadBodiesByRangeV1.java @@ -58,8 +58,15 @@ public class EngineGetPayloadBodiesByRangeV1 extends ExecutionEngineJsonRpcMetho public JsonRpcResponse syncResponse(final JsonRpcRequestContext request) { engineCallListener.executionEngineCalled(); - final long startBlockNumber = - request.getRequiredParameter(0, UnsignedLongParameter.class).getValue(); + final long startBlockNumber; + try { + startBlockNumber = request.getRequiredParameter(0, UnsignedLongParameter.class).getValue(); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid start block number parameter (index 0)", + RpcErrorType.INVALID_BLOCK_NUMBER_PARAMS, + e); + } final long count; try { count = request.getRequiredParameter(1, UnsignedLongParameter.class).getValue(); @@ -77,7 +84,7 @@ public class EngineGetPayloadBodiesByRangeV1 extends ExecutionEngineJsonRpcMetho .log(); if (startBlockNumber < 1 || count < 1) { - return new JsonRpcErrorResponse(reqId, RpcErrorType.INVALID_PARAMS); + return new JsonRpcErrorResponse(reqId, RpcErrorType.INVALID_BLOCK_NUMBER_PARAMS); } if (count > getMaxRequestBlocks()) { diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminLogsRemoveCacheTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminLogsRemoveCacheTest.java index fbe27b42fb..c58556114c 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminLogsRemoveCacheTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminLogsRemoveCacheTest.java @@ -152,7 +152,8 @@ public class AdminLogsRemoveCacheTest { new JsonRpcRequestContext( new JsonRpcRequest("2.0", "admin_logsRemoveCache", new String[] {"0x20", "0x1"})); final JsonRpcResponse expectedResponse = - new JsonRpcErrorResponse(request.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + new JsonRpcErrorResponse( + request.getRequest().getId(), RpcErrorType.INVALID_BLOCK_NUMBER_PARAMS); when(blockchainQueries.getBlockchain()).thenReturn(blockchain); when(blockchain.getBlockByNumber(anyLong())).thenReturn(Optional.of(block)); 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 0ed7e13382..a04cb06c67 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 @@ -233,7 +233,7 @@ public class EthFeeHistoryTest { assertThat( ((JsonRpcErrorResponse) feeHistoryRequest("0x2", "11", new double[] {100.0})) .getErrorType()) - .isEqualTo(RpcErrorType.INVALID_PARAMS); + .isEqualTo(RpcErrorType.INVALID_BLOCK_NUMBER_PARAMS); } @Test diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetUncleByBlockHashAndIndexTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetUncleByBlockHashAndIndexTest.java index fff08f81fb..6b968380c6 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetUncleByBlockHashAndIndexTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetUncleByBlockHashAndIndexTest.java @@ -90,7 +90,7 @@ public class EthGetUncleByBlockHashAndIndexTest { assertThat(thrown) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage("Missing required json rpc parameter at index 1"); + .hasMessage("Invalid block index parameter (index 1)"); } @Test @@ -113,7 +113,7 @@ public class EthGetUncleByBlockHashAndIndexTest { assertThat(thrown) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Invalid json rpc parameter at index 1"); + .hasMessageContaining("Invalid block index parameter (index 1)"); } @Test diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetUncleByBlockNumberAndIndexTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetUncleByBlockNumberAndIndexTest.java index 06c7408a84..746f63be75 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetUncleByBlockNumberAndIndexTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetUncleByBlockNumberAndIndexTest.java @@ -90,7 +90,7 @@ public class EthGetUncleByBlockNumberAndIndexTest { assertThat(thrown) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage("Missing required json rpc parameter at index 1"); + .hasMessage("Invalid block index (index 1)"); } @Test diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBalance_illegalRangeLessThan.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBalance_illegalRangeLessThan.json index 146756fc55..2a59465e88 100644 --- a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBalance_illegalRangeLessThan.json +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getBalance_illegalRangeLessThan.json @@ -13,7 +13,7 @@ "id": 28, "error": { "code": -32602, - "message": "Invalid params" + "message": "Invalid block number params" } }, "statusCode": 200 diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getCode_illegalRangeLessThan.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getCode_illegalRangeLessThan.json index 6a336a9666..e2011bb4d0 100644 --- a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getCode_illegalRangeLessThan.json +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getCode_illegalRangeLessThan.json @@ -13,7 +13,7 @@ "id": 13, "error": { "code": -32602, - "message": "Invalid params" + "message": "Invalid block number params" } }, "statusCode": 200 diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getProof_illegalRangeLessThan.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getProof_illegalRangeLessThan.json index de1c3ccb57..f0cf31f79d 100644 --- a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getProof_illegalRangeLessThan.json +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getProof_illegalRangeLessThan.json @@ -14,7 +14,7 @@ "id": 28, "error": { "code": -32602, - "message": "Invalid params" + "message": "Invalid block number params" } }, "statusCode": 200 diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getStorageAt_illegalRangeLessThan.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getStorageAt_illegalRangeLessThan.json index 67892401ce..1f46003c8f 100644 --- a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getStorageAt_illegalRangeLessThan.json +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getStorageAt_illegalRangeLessThan.json @@ -14,7 +14,7 @@ "id": 337, "error": { "code": -32602, - "message": "Invalid params" + "message": "Invalid block number params" } }, "statusCode": 200 diff --git a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestRewindToBlock.java b/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestRewindToBlock.java index a2bc59ecc2..d5adb36a24 100644 --- a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestRewindToBlock.java +++ b/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestRewindToBlock.java @@ -15,9 +15,11 @@ package org.hyperledger.besu.ethereum.retesteth.methods; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; 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.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.retesteth.RetestethContext; public class TestRewindToBlock implements JsonRpcMethod { @@ -36,7 +38,13 @@ public class TestRewindToBlock implements JsonRpcMethod { @Override public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { - final long blockNumber = requestContext.getRequiredParameter(0, Long.TYPE); + final long blockNumber; + try { + blockNumber = requestContext.getRequiredParameter(0, Long.TYPE); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid block number parameter (index 0)", RpcErrorType.INVALID_BLOCK_NUMBER_PARAMS, e); + } return new JsonRpcSuccessResponse( requestContext.getRequest().getId(), context.getBlockchain().rewindToBlock(blockNumber)); From b8c062cdcba7c6e36f4c639087b7d9da2cbfba88 Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Tue, 13 Aug 2024 16:51:48 +1000 Subject: [PATCH 107/259] 5098 branch 13 update invalid call consolidation and privacy group (#7441) * 5098: Add RpcErrorTypes Signed-off-by: Matilda Clerke --------- Signed-off-by: Matilda Clerke Signed-off-by: Matilda-Clerke Co-authored-by: Sally MacFarlane --- .../internal/methods/JsonCallParameterUtil.java | 9 ++++++++- .../methods/engine/AbstractEngineNewPayload.java | 3 +-- .../internal/privacy/methods/priv/PrivCall.java | 11 +++++++++-- .../methods/priv/PrivCreatePrivacyGroup.java | 13 +++++++++++-- .../methods/priv/PrivCreatePrivacyGroupTest.java | 4 ++-- .../eth/eth_call_blob_zero_versioned_hash.json | 2 +- ..._invalidWithDifferentInputAndDataAttributes.json | 2 +- 7 files changed, 33 insertions(+), 11 deletions(-) diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/JsonCallParameterUtil.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/JsonCallParameterUtil.java index b2df8c0676..891d837df3 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/JsonCallParameterUtil.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/JsonCallParameterUtil.java @@ -17,13 +17,20 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonCallParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; public class JsonCallParameterUtil { private JsonCallParameterUtil() {} public static JsonCallParameter validateAndGetCallParams(final JsonRpcRequestContext request) { - final JsonCallParameter callParams = request.getRequiredParameter(0, JsonCallParameter.class); + final JsonCallParameter callParams; + try { + callParams = request.getRequiredParameter(0, JsonCallParameter.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid call parameters (index 0)", RpcErrorType.INVALID_CALL_PARAMS); + } if (callParams.getGasPrice() != null && (callParams.getMaxFeePerGas().isPresent() 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 c548507710..8d7a12f254 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 @@ -197,8 +197,7 @@ public abstract class AbstractEngineNewPayload extends ExecutionEngineJsonRpcMet if (!getConsolidationRequestValidator( protocolSchedule.get(), blockParam.getTimestamp(), blockParam.getBlockNumber()) .validateParameter(maybeConsolidationRequests)) { - return new JsonRpcErrorResponse( - reqId, new JsonRpcError(INVALID_PARAMS, "Invalid consolidation request")); + return new JsonRpcErrorResponse(reqId, RpcErrorType.INVALID_CONSOLIDATION_REQUEST_PARAMS); } Optional> maybeRequests = diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCall.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCall.java index 8fe48474a8..0418fc2474 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCall.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCall.java @@ -104,9 +104,16 @@ public class PrivCall extends AbstractBlockParameterMethod { } private JsonCallParameter validateAndGetCallParams(final JsonRpcRequestContext request) { - final JsonCallParameter callParams = request.getRequiredParameter(1, JsonCallParameter.class); + final JsonCallParameter callParams; + try { + callParams = request.getRequiredParameter(1, JsonCallParameter.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid call parameters (index 1)", RpcErrorType.INVALID_CALL_PARAMS); + } if (callParams.getTo() == null) { - throw new InvalidJsonRpcParameters("Missing \"to\" field in call arguments"); + throw new InvalidJsonRpcParameters( + "Missing \"to\" field in call arguments", RpcErrorType.INVALID_CALL_PARAMS); } return callParams; } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCreatePrivacyGroup.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCreatePrivacyGroup.java index 3527c02ad5..ae35506298 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCreatePrivacyGroup.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCreatePrivacyGroup.java @@ -18,12 +18,14 @@ import org.hyperledger.besu.enclave.types.PrivacyGroup; import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcEnclaveErrorConverter; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.PrivacyIdProvider; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.parameters.CreatePrivacyGroupParameter; 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.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.privacy.PrivacyController; import org.slf4j.Logger; @@ -50,8 +52,15 @@ public class PrivCreatePrivacyGroup implements JsonRpcMethod { public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { LOG.trace("Executing {}", RpcMethod.PRIV_CREATE_PRIVACY_GROUP.getMethodName()); - final CreatePrivacyGroupParameter parameter = - requestContext.getRequiredParameter(0, CreatePrivacyGroupParameter.class); + final CreatePrivacyGroupParameter parameter; + try { + parameter = requestContext.getRequiredParameter(0, CreatePrivacyGroupParameter.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid create privacy group parameter (index 0)", + RpcErrorType.INVALID_CREATE_PRIVACY_GROUP_PARAMS, + e); + } LOG.trace( "Creating a privacy group with name {} and description {}", diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCreatePrivacyGroupTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCreatePrivacyGroupTest.java index 9be3122c1e..771c287ac3 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCreatePrivacyGroupTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCreatePrivacyGroupTest.java @@ -231,7 +231,7 @@ public class PrivCreatePrivacyGroupTest { catchThrowableOfType( () -> privCreatePrivacyGroup.response(request), InvalidJsonRpcParameters.class); - assertThat(response.getMessage()).contains("Invalid json rpc parameter at index 0"); + assertThat(response.getMessage()).contains("Invalid create privacy group parameter (index 0)"); } @Test @@ -249,7 +249,7 @@ public class PrivCreatePrivacyGroupTest { catchThrowableOfType( () -> privCreatePrivacyGroup.response(request), InvalidJsonRpcParameters.class); - assertThat(response.getMessage()).isEqualTo("Missing required json rpc parameter at index 0"); + assertThat(response.getMessage()).isEqualTo("Invalid create privacy group parameter (index 0)"); } @Test diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_call_blob_zero_versioned_hash.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_call_blob_zero_versioned_hash.json index bf4cb06350..80c21e6a1b 100644 --- a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_call_blob_zero_versioned_hash.json +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_call_blob_zero_versioned_hash.json @@ -17,7 +17,7 @@ "response": { "jsonrpc": "2.0", "id": 4, - "error":{"code":-32602,"message":"Invalid params"} + "error":{"code":-32602,"message":"Invalid call params"} }, "statusCode": 200 } diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_call_invalidWithDifferentInputAndDataAttributes.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_call_invalidWithDifferentInputAndDataAttributes.json index 309e96df24..e304f0cbbd 100644 --- a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_call_invalidWithDifferentInputAndDataAttributes.json +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_call_invalidWithDifferentInputAndDataAttributes.json @@ -18,7 +18,7 @@ "id": 3, "error" : { "code" : -32602, - "message" : "Invalid params" + "message" : "Invalid call params" } }, "statusCode": 200 From 1a9154586fb4e7e4cc383935d964444fdfc70d92 Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Tue, 13 Aug 2024 17:49:32 +1000 Subject: [PATCH 108/259] 5098 branch 14 update invalid data deposit and engine exchange (#7442) * 5098: Add RpcErrorTypes Signed-off-by: Matilda Clerke --------- Signed-off-by: Matilda Clerke Signed-off-by: Matilda-Clerke Co-authored-by: Sally MacFarlane --- .../api/jsonrpc/internal/methods/Web3Sha3.java | 13 ++++++++++--- .../methods/engine/AbstractEngineNewPayload.java | 3 +-- .../EngineExchangeTransitionConfiguration.java | 16 +++++++++++++--- .../jsonrpc/internal/methods/Web3Sha3Test.java | 8 ++++---- 4 files changed, 28 insertions(+), 12 deletions(-) diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/Web3Sha3.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/Web3Sha3.java index b1d137bb6b..b06cd57293 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/Web3Sha3.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/Web3Sha3.java @@ -17,6 +17,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import org.hyperledger.besu.crypto.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; 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; @@ -41,11 +42,17 @@ public class Web3Sha3 implements JsonRpcMethod { requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAMS); } - final String data = requestContext.getRequiredParameter(0, String.class); + final String data; + try { + data = requestContext.getRequiredParameter(0, String.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid data parameter (index 0)", RpcErrorType.INVALID_DATA_PARAMS, e); + } if (!data.isEmpty() && !data.startsWith("0x")) { return new JsonRpcErrorResponse( - requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + requestContext.getRequest().getId(), RpcErrorType.INVALID_DATA_PARAMS); } try { @@ -54,7 +61,7 @@ public class Web3Sha3 implements JsonRpcMethod { requestContext.getRequest().getId(), Hash.keccak256(byteData).toString()); } catch (final IllegalArgumentException err) { return new JsonRpcErrorResponse( - requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + requestContext.getRequest().getId(), RpcErrorType.INVALID_DATA_PARAMS); } } } 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 8d7a12f254..246a2777c8 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 @@ -169,8 +169,7 @@ public abstract class AbstractEngineNewPayload extends ExecutionEngineJsonRpcMet if (!getDepositRequestValidator( protocolSchedule.get(), blockParam.getTimestamp(), blockParam.getBlockNumber()) .validateParameter(maybeDepositRequests)) { - return new JsonRpcErrorResponse( - reqId, new JsonRpcError(INVALID_PARAMS, "Invalid deposit request")); + return new JsonRpcErrorResponse(reqId, RpcErrorType.INVALID_DEPOSIT_REQUEST_PARAMS); } final Optional> maybeWithdrawalRequests = diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineExchangeTransitionConfiguration.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineExchangeTransitionConfiguration.java index fdb94df9d6..67b8657533 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineExchangeTransitionConfiguration.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineExchangeTransitionConfiguration.java @@ -20,10 +20,12 @@ import org.hyperledger.besu.consensus.merge.MergeContext; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.EngineExchangeTransitionConfigurationParameter; 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.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.EngineExchangeTransitionConfigurationResult; import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.Difficulty; @@ -65,9 +67,17 @@ public class EngineExchangeTransitionConfiguration extends ExecutionEngineJsonRp public JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext) { engineCallListener.executionEngineCalled(); - final EngineExchangeTransitionConfigurationParameter remoteTransitionConfiguration = - requestContext.getRequiredParameter( - 0, EngineExchangeTransitionConfigurationParameter.class); + final EngineExchangeTransitionConfigurationParameter remoteTransitionConfiguration; + try { + remoteTransitionConfiguration = + requestContext.getRequiredParameter( + 0, EngineExchangeTransitionConfigurationParameter.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid engine exchange transition configuration parameters (index 0)", + RpcErrorType.INVALID_ENGINE_EXCHANGE_TRANSITION_CONFIGURATION_PARAMS, + e); + } final Object reqId = requestContext.getRequest().getId(); LOG.atTrace() diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/Web3Sha3Test.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/Web3Sha3Test.java index 83310ead02..a978e5c0c1 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/Web3Sha3Test.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/Web3Sha3Test.java @@ -70,7 +70,7 @@ public class Web3Sha3Test { new JsonRpcRequest("2", "web3_sha3", new Object[] {"0x68656c6c6f20776f726c6"})); final JsonRpcResponse expected = - new JsonRpcErrorResponse(request.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + new JsonRpcErrorResponse(request.getRequest().getId(), RpcErrorType.INVALID_DATA_PARAMS); final JsonRpcResponse actual = method.response(request); assertThat(actual).usingRecursiveComparison().isEqualTo(expected); @@ -83,7 +83,7 @@ public class Web3Sha3Test { new JsonRpcRequest("2", "web3_sha3", new Object[] {"0x68656c6c6fThisIsNotHex"})); final JsonRpcResponse expected = - new JsonRpcErrorResponse(request.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + new JsonRpcErrorResponse(request.getRequest().getId(), RpcErrorType.INVALID_DATA_PARAMS); final JsonRpcResponse actual = method.response(request); assertThat(actual).usingRecursiveComparison().isEqualTo(expected); @@ -96,7 +96,7 @@ public class Web3Sha3Test { new JsonRpcRequest("2", "web3_sha3", new Object[] {"68656c6c6f20776f726c64"})); final JsonRpcResponse expected = - new JsonRpcErrorResponse(request.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + new JsonRpcErrorResponse(request.getRequest().getId(), RpcErrorType.INVALID_DATA_PARAMS); final JsonRpcResponse actual = method.response(request); assertThat(actual).usingRecursiveComparison().isEqualTo(expected); @@ -109,7 +109,7 @@ public class Web3Sha3Test { new JsonRpcRequest("2", "web3_sha3", new Object[] {"68656c6c6fThisIsNotHex"})); final JsonRpcResponse expected = - new JsonRpcErrorResponse(request.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + new JsonRpcErrorResponse(request.getRequest().getId(), RpcErrorType.INVALID_DATA_PARAMS); final JsonRpcResponse actual = method.response(request); assertThat(actual).usingRecursiveComparison().isEqualTo(expected); From a55c331e21e63bd19ad5686aa6a1ce345bf96ca0 Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Tue, 13 Aug 2024 12:21:49 -0600 Subject: [PATCH 109/259] Add test coverage for java precompiles (#7446) For tests that have a native/java switch ensure that the java path gets the same tests native paths do. Co-authored-by: Sally MacFarlane Signed-off-by: Danno Ferrin --- .../org/hyperledger/besu/cli/BesuCommand.java | 4 +- .../besu/crypto/AbstractSECP256.java | 4 +- .../besu/crypto/Blake2bfMessageDigest.java | 27 ++++++++---- .../hyperledger/besu/crypto/SECP256K1.java | 1 + .../hyperledger/besu/crypto/SECP256R1.java | 16 +++++++ .../besu/crypto/SignatureAlgorithm.java | 7 +++ .../besu/crypto/SECP256R1Test.java | 44 +++++-------------- ...ltBN128PairingPrecompiledContractTest.java | 24 ++++++++-- .../BLAKE2BFPrecompileContractTest.java | 18 +++++++- .../ECRECPrecompiledContractTest.java | 12 ++++- .../MODEXPPrecompiledContractTest.java | 17 ++++++- 11 files changed, 123 insertions(+), 51 deletions(-) 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 9c2b014ec0..72fbb48ec9 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java @@ -1503,7 +1503,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { private void configureNativeLibs() { if (unstableNativeLibraryOptions.getNativeAltbn128() - && AbstractAltBnPrecompiledContract.isNative()) { + && AbstractAltBnPrecompiledContract.maybeEnableNative()) { logger.info("Using the native implementation of alt bn128"); } else { AbstractAltBnPrecompiledContract.disableNative(); @@ -1519,7 +1519,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { } if (unstableNativeLibraryOptions.getNativeSecp() - && SignatureAlgorithmFactory.getInstance().isNative()) { + && SignatureAlgorithmFactory.getInstance().maybeEnableNative()) { logger.info("Using the native implementation of the signature algorithm"); } else { SignatureAlgorithmFactory.getInstance().disableNative(); diff --git a/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/AbstractSECP256.java b/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/AbstractSECP256.java index 27495cd97c..b10e654626 100644 --- a/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/AbstractSECP256.java +++ b/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/AbstractSECP256.java @@ -397,7 +397,9 @@ public abstract class AbstractSECP256 implements SignatureAlgorithm { final Bytes32 dataHash, final SECPSignature signature) { final BigInteger publicKeyBI = recoverFromSignature(signature.getRecId(), signature.getR(), signature.getS(), dataHash); - return Optional.of(SECPPublicKey.create(publicKeyBI, ALGORITHM)); + return publicKeyBI == null + ? Optional.empty() + : Optional.of(SECPPublicKey.create(publicKeyBI, ALGORITHM)); } @Override diff --git a/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/Blake2bfMessageDigest.java b/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/Blake2bfMessageDigest.java index ad4fe7ddb1..d458a4c43d 100644 --- a/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/Blake2bfMessageDigest.java +++ b/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/Blake2bfMessageDigest.java @@ -44,9 +44,10 @@ public class Blake2bfMessageDigest extends BCMessageDigest implements Cloneable /** * Implementation of the `F` compression function of the Blake2b cryptographic hash function. * - *

RFC - https://tools.ietf.org/html/rfc7693 + *

RFC - ... * - *

Adapted from - https://github.com/keep-network/blake2b/blob/master/compression/f.go + *

Adapted from - ... * *

Optimized for 64-bit platforms */ @@ -93,12 +94,7 @@ public class Blake2bfMessageDigest extends BCMessageDigest implements Cloneable private static boolean useNative; static { - try { - useNative = LibBlake2bf.ENABLED; - } catch (UnsatisfiedLinkError ule) { - LOG.info("blake2bf native precompile not available: {}", ule.getMessage()); - useNative = false; - } + maybeEnableNative(); } /** Instantiates a new Blake2bf digest. */ @@ -130,6 +126,21 @@ public class Blake2bfMessageDigest extends BCMessageDigest implements Cloneable return cloned; } + /** + * Attempt to enable the native libreary + * + * @return true if the native library was successfully enabled. + */ + public static boolean maybeEnableNative() { + try { + useNative = LibBlake2bf.ENABLED; + } catch (UnsatisfiedLinkError | NoClassDefFoundError e) { + LOG.info("blake2bf native precompile not available: {}", e.getMessage()); + useNative = false; + } + return useNative; + } + /** Disable native. */ public static void disableNative() { useNative = false; diff --git a/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/SECP256K1.java b/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/SECP256K1.java index 8d7ba7924f..2ec0470e54 100644 --- a/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/SECP256K1.java +++ b/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/SECP256K1.java @@ -72,6 +72,7 @@ public class SECP256K1 extends AbstractSECP256 { * * @return true if the native library was enabled. */ + @Override public boolean maybeEnableNative() { try { useNative = LibSecp256k1.CONTEXT != null; diff --git a/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/SECP256R1.java b/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/SECP256R1.java index 384723a239..812d776219 100644 --- a/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/SECP256R1.java +++ b/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/SECP256R1.java @@ -61,6 +61,22 @@ public class SECP256R1 extends AbstractSECP256 { return useNative; } + /** + * Attempt to enable the native library for secp256r1 + * + * @return true if the native library was enabled. + */ + @Override + public boolean maybeEnableNative() { + try { + useNative = BesuNativeEC.INSTANCE != null; + } catch (UnsatisfiedLinkError | NoClassDefFoundError e) { + LOG.info("Native secp256r1 not available - {}", e.getMessage()); + useNative = false; + } + return useNative; + } + /** * SECP256R1 is using the non-deterministic implementation of K calculation (standard) * diff --git a/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/SignatureAlgorithm.java b/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/SignatureAlgorithm.java index 408b1d423a..db9565d18d 100644 --- a/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/SignatureAlgorithm.java +++ b/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/SignatureAlgorithm.java @@ -31,6 +31,13 @@ public interface SignatureAlgorithm { /** Disable native. */ void disableNative(); + /** + * Attempt to enable the native library. + * + * @return true if the native library was enabled + */ + boolean maybeEnableNative(); + /** * Is native enabled. * diff --git a/crypto/algorithms/src/test/java/org/hyperledger/besu/crypto/SECP256R1Test.java b/crypto/algorithms/src/test/java/org/hyperledger/besu/crypto/SECP256R1Test.java index 7112d36294..22bd5c7651 100644 --- a/crypto/algorithms/src/test/java/org/hyperledger/besu/crypto/SECP256R1Test.java +++ b/crypto/algorithms/src/test/java/org/hyperledger/besu/crypto/SECP256R1Test.java @@ -127,7 +127,7 @@ public class SECP256R1Test { } @Test - public void recoverPublicKeyFromSignature() { + void recoverPublicKeyFromSignature() { final SECPPrivateKey privateKey = secp256R1.createPrivateKey( new BigInteger("c85ef7d79691fe79573b1a7064c19c1a9819ebdbd1faaab1a8ec92344438aaf4", 16)); @@ -139,20 +139,20 @@ public class SECP256R1Test { final SECPPublicKey recoveredPublicKey = secp256R1.recoverPublicKeyFromSignature(dataHash, signature).get(); - assertThat(recoveredPublicKey.toString()).isEqualTo(keyPair.getPublicKey().toString()); + assertThat(recoveredPublicKey).hasToString(keyPair.getPublicKey().toString()); } @Test - public void signatureGenerationVerificationAndPubKeyRecovery() { + void signatureGenerationVerificationAndPubKeyRecovery() { signTestVectors.forEach( signTestVector -> { final SECPPrivateKey privateKey = - secp256R1.createPrivateKey(new BigInteger(signTestVector.getPrivateKey(), 16)); - final BigInteger publicKeyBigInt = new BigInteger(signTestVector.getPublicKey(), 16); + secp256R1.createPrivateKey(new BigInteger(signTestVector.privateKey(), 16)); + final BigInteger publicKeyBigInt = new BigInteger(signTestVector.publicKey(), 16); final SECPPublicKey publicKey = secp256R1.createPublicKey(publicKeyBigInt); final KeyPair keyPair = secp256R1.createKeyPair(privateKey); - final Bytes32 dataHash = keccak256(Bytes.wrap(signTestVector.getData().getBytes(UTF_8))); + final Bytes32 dataHash = keccak256(Bytes.wrap(signTestVector.data().getBytes(UTF_8))); final SECPSignature signature = secp256R1.sign(dataHash, keyPair); assertThat(secp256R1.verify(dataHash, signature, publicKey)).isTrue(); @@ -165,44 +165,22 @@ public class SECP256R1Test { } @Test - public void invalidFileThrowsInvalidKeyPairException() throws Exception { + void invalidFileThrowsInvalidKeyPairException() throws Exception { final File tempFile = Files.createTempFile(suiteName(), ".keypair").toFile(); tempFile.deleteOnExit(); - Files.write(tempFile.toPath(), "not valid".getBytes(UTF_8)); + Files.writeString(tempFile.toPath(), "not valid"); assertThatThrownBy(() -> KeyPairUtil.load(tempFile)) .isInstanceOf(IllegalArgumentException.class); } @Test - public void invalidMultiLineFileThrowsInvalidIdException() throws Exception { + void invalidMultiLineFileThrowsInvalidIdException() throws Exception { final File tempFile = Files.createTempFile(suiteName(), ".keypair").toFile(); tempFile.deleteOnExit(); - Files.write(tempFile.toPath(), "not\n\nvalid".getBytes(UTF_8)); + Files.writeString(tempFile.toPath(), "not\n\nvalid"); assertThatThrownBy(() -> KeyPairUtil.load(tempFile)) .isInstanceOf(IllegalArgumentException.class); } - private static class SignTestVector { - private final String privateKey; - private final String publicKey; - private final String data; - - public SignTestVector(final String privateKey, final String publicKey, final String data) { - this.privateKey = privateKey; - this.publicKey = publicKey; - this.data = data; - } - - public String getPrivateKey() { - return privateKey; - } - - public String getPublicKey() { - return publicKey; - } - - public String getData() { - return data; - } - } + private record SignTestVector(String privateKey, String publicKey, String data) {} } diff --git a/evm/src/test/java/org/hyperledger/besu/evm/precompile/AltBN128PairingPrecompiledContractTest.java b/evm/src/test/java/org/hyperledger/besu/evm/precompile/AltBN128PairingPrecompiledContractTest.java index af78f975b7..5b7b470a8a 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/precompile/AltBN128PairingPrecompiledContractTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/precompile/AltBN128PairingPrecompiledContractTest.java @@ -22,6 +22,8 @@ import org.hyperledger.besu.evm.gascalculator.GasCalculator; 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.ValueSource; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; @@ -36,8 +38,14 @@ class AltBN128PairingPrecompiledContractTest { private final AltBN128PairingPrecompiledContract istanbulContract = AltBN128PairingPrecompiledContract.istanbul(gasCalculator); - @Test - void compute_validPoints() { + @ParameterizedTest + @ValueSource(booleans = {true, false}) + void compute_validPoints(final boolean useNative) { + if (useNative) { + AbstractAltBnPrecompiledContract.maybeEnableNative(); + } else { + AbstractAltBnPrecompiledContract.disableNative(); + } final Bytes input = validPointBytes(); final Bytes result = byzantiumContract.computePrecompile(input, messageFrame).getOutput(); assertThat(result).isEqualTo(AltBN128PairingPrecompiledContract.TRUE); @@ -80,8 +88,14 @@ class AltBN128PairingPrecompiledContractTest { return Bytes.concatenate(g1Point0, g2Point0, g1Point1, g2Point1); } - @Test - void compute_invalidPointsOutsideSubgroupG2() { + @ParameterizedTest + @ValueSource(booleans = {true, false}) + void compute_invalidPointsOutsideSubgroupG2(final boolean useNative) { + if (useNative) { + AbstractAltBnPrecompiledContract.maybeEnableNative(); + } else { + AbstractAltBnPrecompiledContract.disableNative(); + } final Bytes g1Point0 = Bytes.concatenate( Bytes.fromHexString( @@ -122,11 +136,13 @@ class AltBN128PairingPrecompiledContractTest { @Test void gasPrice_byzantium() { + // gas calculation is java only assertThat(byzantiumContract.gasRequirement(validPointBytes())).isEqualTo(260_000L); } @Test void gasPrice_istanbul() { + // gas calculation is java only assertThat(istanbulContract.gasRequirement(validPointBytes())).isEqualTo(113_000L); } } diff --git a/evm/src/test/java/org/hyperledger/besu/evm/precompile/BLAKE2BFPrecompileContractTest.java b/evm/src/test/java/org/hyperledger/besu/evm/precompile/BLAKE2BFPrecompileContractTest.java index 381e64c015..742edc8548 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/precompile/BLAKE2BFPrecompileContractTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/precompile/BLAKE2BFPrecompileContractTest.java @@ -17,6 +17,7 @@ package org.hyperledger.besu.evm.precompile; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; +import org.hyperledger.besu.crypto.Blake2bfMessageDigest.Blake2bfDigest; import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.gascalculator.PetersburgGasCalculator; @@ -67,9 +68,24 @@ class BLAKE2BFPrecompileContractTest { @ParameterizedTest @MethodSource("parameters") - void shouldRunFCompression( + void shouldRunFCompressionNative( final String inputString, final String expectedResult, final long expectedGasUsed) { + Blake2bfDigest.maybeEnableNative(); + testFCompression(inputString, expectedResult, expectedGasUsed); + } + + @ParameterizedTest + @MethodSource("parameters") + void shouldRunFCompressionJava( + final String inputString, final String expectedResult, final long expectedGasUsed) { + Blake2bfDigest.disableNative(); + + testFCompression(inputString, expectedResult, expectedGasUsed); + } + + private void testFCompression( + final String inputString, final String expectedResult, final long expectedGasUsed) { final Bytes input = Bytes.fromHexString(inputString); final Bytes expectedComputation = expectedResult == null ? null : Bytes.fromHexString(expectedResult); diff --git a/evm/src/test/java/org/hyperledger/besu/evm/precompile/ECRECPrecompiledContractTest.java b/evm/src/test/java/org/hyperledger/besu/evm/precompile/ECRECPrecompiledContractTest.java index ac248b947b..7d2c52efca 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/precompile/ECRECPrecompiledContractTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/precompile/ECRECPrecompiledContractTest.java @@ -349,8 +349,18 @@ class ECRECPrecompiledContractTest { @ParameterizedTest @MethodSource("parameters") - void shouldRecoverAddress(final String inputString, final String expectedResult) { + void shouldRecoverAddressNative(final String inputString, final String expectedResult) { + contract.signatureAlgorithm.maybeEnableNative(); + final Bytes input = Bytes.fromHexString(inputString); + final Bytes expected = + expectedResult == null ? Bytes.EMPTY : Bytes32.fromHexString(expectedResult); + assertThat(contract.computePrecompile(input, messageFrame).getOutput()).isEqualTo(expected); + } + @ParameterizedTest + @MethodSource("parameters") + void shouldRecoverAddressJava(final String inputString, final String expectedResult) { + contract.signatureAlgorithm.disableNative(); final Bytes input = Bytes.fromHexString(inputString); final Bytes expected = expectedResult == null ? Bytes.EMPTY : Bytes32.fromHexString(expectedResult); diff --git a/evm/src/test/java/org/hyperledger/besu/evm/precompile/MODEXPPrecompiledContractTest.java b/evm/src/test/java/org/hyperledger/besu/evm/precompile/MODEXPPrecompiledContractTest.java index ac4fd9041a..61e0f63cfb 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/precompile/MODEXPPrecompiledContractTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/precompile/MODEXPPrecompiledContractTest.java @@ -155,12 +155,27 @@ class MODEXPPrecompiledContractTest { @ParameterizedTest @MethodSource("parameters") - void testPrecompiledContract( + void testPrecompiledContractNative( final String inputString, final String precompiledResult, final Long eip198Gas, final Long eip2565Gas) { + BigIntegerModularExponentiationPrecompiledContract.maybeEnableNative(); + testComputation(inputString, precompiledResult); + } + + @ParameterizedTest + @MethodSource("parameters") + void testPrecompiledContractJava( + final String inputString, + final String precompiledResult, + final Long eip198Gas, + final Long eip2565Gas) { + BigIntegerModularExponentiationPrecompiledContract.disableNative(); + testComputation(inputString, precompiledResult); + } + private void testComputation(final String inputString, final String precompiledResult) { assumeThat(precompiledResult).isNotNull(); final Bytes input = Bytes.fromHexString(inputString); final Bytes expected = Bytes.fromHexString(precompiledResult); From dc336f48e96d56d8597c3c33b6ad49f500e9300f Mon Sep 17 00:00:00 2001 From: Jason Frame Date: Wed, 14 Aug 2024 09:28:30 +1000 Subject: [PATCH 110/259] Snap sync server StorageRange message limit to apply limit hash as post check (#7399) Signed-off-by: Jason Frame --- .../DiffBasedWorldStateKeyValueStorage.java | 10 +-- .../common/storage/flat/FlatDbStrategy.java | 39 ++++++++- .../ethereum/eth/manager/snap/SnapServer.java | 80 +++++++++++++------ .../eth/manager/snap/SnapServerTest.java | 41 +++++++--- 4 files changed, 126 insertions(+), 44 deletions(-) diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/storage/DiffBasedWorldStateKeyValueStorage.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/storage/DiffBasedWorldStateKeyValueStorage.java index 84441ca05f..50adf7b34f 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/storage/DiffBasedWorldStateKeyValueStorage.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/storage/DiffBasedWorldStateKeyValueStorage.java @@ -129,11 +129,9 @@ public abstract class DiffBasedWorldStateKeyValueStorage } public NavigableMap streamFlatAccounts( - final Bytes startKeyHash, - final Bytes32 endKeyHash, - final Predicate> takeWhile) { + final Bytes startKeyHash, final Predicate> takeWhile) { return getFlatDbStrategy() - .streamAccountFlatDatabase(composedWorldStateStorage, startKeyHash, endKeyHash, takeWhile); + .streamAccountFlatDatabase(composedWorldStateStorage, startKeyHash, takeWhile); } public NavigableMap streamFlatStorages( @@ -146,11 +144,9 @@ public abstract class DiffBasedWorldStateKeyValueStorage public NavigableMap streamFlatStorages( final Hash accountHash, final Bytes startKeyHash, - final Bytes32 endKeyHash, final Predicate> takeWhile) { return getFlatDbStrategy() - .streamStorageFlatDatabase( - composedWorldStateStorage, accountHash, startKeyHash, endKeyHash, takeWhile); + .streamStorageFlatDatabase(composedWorldStateStorage, accountHash, startKeyHash, takeWhile); } public boolean isWorldStateAvailable(final Bytes32 rootHash, final Hash blockHash) { 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 299d441350..ad631b8da9 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 @@ -207,11 +207,9 @@ public abstract class FlatDbStrategy { public NavigableMap streamAccountFlatDatabase( final SegmentedKeyValueStorage storage, final Bytes startKeyHash, - final Bytes32 endKeyHash, final Predicate> takeWhile) { - return toNavigableMap( - accountsToPairStream(storage, startKeyHash, endKeyHash).takeWhile(takeWhile)); + return toNavigableMap(accountsToPairStream(storage, startKeyHash).takeWhile(takeWhile)); } /** streams RLP encoded storage values using a specified stream limit. */ @@ -240,6 +238,34 @@ public abstract class FlatDbStrategy { .takeWhile(takeWhile)); } + /** streams raw storage Bytes using a specified predicate filter and value mapper. */ + public NavigableMap streamStorageFlatDatabase( + final SegmentedKeyValueStorage storage, + final Hash accountHash, + final Bytes startKeyHash, + final Predicate> takeWhile) { + return toNavigableMap( + storageToPairStream(storage, accountHash, startKeyHash, RLP::encodeValue) + .takeWhile(takeWhile)); + } + + private static 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()))); + } + private static Stream> storageToPairStream( final SegmentedKeyValueStorage storage, final Hash accountHash, @@ -266,6 +292,13 @@ public abstract class FlatDbStrategy { .map(pair -> new Pair<>(Bytes32.wrap(pair.getKey()), Bytes.wrap(pair.getValue()))); } + 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()))); + } + private static NavigableMap toNavigableMap( final Stream> pairStream) { final TreeMap collected = 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 cb92941e5b..c1b855f2d6 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 @@ -234,8 +234,8 @@ class SnapServer implements BesuEvents.InitialSyncCompletionListener { .map( storage -> { LOGGER.trace("obtained worldstate in {}", stopWatch); - StatefulPredicate shouldContinuePredicate = - new StatefulPredicate( + ResponseSizePredicate responseSizePredicate = + new ResponseSizePredicate( "account", stopWatch, maxResponseBytes, @@ -248,9 +248,13 @@ class SnapServer implements BesuEvents.InitialSyncCompletionListener { return rlpOutput.encodedSize(); }); + final Bytes32 endKeyBytes = range.endKeyHash(); + var shouldContinuePredicate = + new ExceedingPredicate( + new EndKeyExceedsPredicate(endKeyBytes).and(responseSizePredicate)); + NavigableMap accounts = - storage.streamFlatAccounts( - range.startKeyHash(), range.endKeyHash(), shouldContinuePredicate); + storage.streamFlatAccounts(range.startKeyHash(), shouldContinuePredicate); if (accounts.isEmpty() && shouldContinuePredicate.shouldContinue.get()) { // fetch next account after range, if it exists @@ -331,8 +335,8 @@ class SnapServer implements BesuEvents.InitialSyncCompletionListener { storage -> { LOGGER.trace("obtained worldstate in {}", stopWatch); // reusable predicate to limit by rec count and bytes: - var statefulPredicate = - new StatefulPredicate( + var responsePredicate = + new ResponseSizePredicate( "storage", stopWatch, maxResponseBytes, @@ -364,9 +368,12 @@ class SnapServer implements BesuEvents.InitialSyncCompletionListener { new WorldStateProofProvider(new WorldStateStorageCoordinator(storage)); for (var forAccountHash : range.hashes()) { + var predicate = + new ExceedingPredicate( + new EndKeyExceedsPredicate(endKeyBytes).and(responsePredicate)); var accountStorages = storage.streamFlatStorages( - Hash.wrap(forAccountHash), startKeyBytes, endKeyBytes, statefulPredicate); + Hash.wrap(forAccountHash), startKeyBytes, predicate); //// address partial range queries that return empty if (accountStorages.isEmpty() && isPartialRange) { @@ -386,7 +393,7 @@ class SnapServer implements BesuEvents.InitialSyncCompletionListener { // if a partial storage range was requested, or we interrupted storage due to // request limits, send proofs: - if (isPartialRange || !statefulPredicate.shouldGetMore()) { + if (isPartialRange || !predicate.shouldGetMore()) { // send a proof for the left side range origin proofNodes.addAll( worldStateProof.getStorageProofRelatedNodes( @@ -403,7 +410,7 @@ class SnapServer implements BesuEvents.InitialSyncCompletionListener { } } - if (!statefulPredicate.shouldGetMore()) { + if (!predicate.shouldGetMore()) { break; } } @@ -462,7 +469,7 @@ class SnapServer implements BesuEvents.InitialSyncCompletionListener { if (optCode.isPresent()) { if (!codeBytes.isEmpty() && (sumListBytes(codeBytes) + optCode.get().size() > maxResponseBytes - || stopWatch.getTime() > StatefulPredicate.MAX_MILLIS_PER_REQUEST)) { + || stopWatch.getTime() > ResponseSizePredicate.MAX_MILLIS_PER_REQUEST)) { break; } codeBytes.add(optCode.get()); @@ -521,7 +528,8 @@ class SnapServer implements BesuEvents.InitialSyncCompletionListener { var trieNode = optStorage.orElse(Bytes.EMPTY); if (!trieNodes.isEmpty() && (sumListBytes(trieNodes) + trieNode.size() > maxResponseBytes - || stopWatch.getTime() > StatefulPredicate.MAX_MILLIS_PER_REQUEST)) { + || stopWatch.getTime() + > ResponseSizePredicate.MAX_MILLIS_PER_REQUEST)) { break; } trieNodes.add(trieNode); @@ -578,7 +586,39 @@ class SnapServer implements BesuEvents.InitialSyncCompletionListener { } } - static class StatefulPredicate implements Predicate> { + /** + * Predicate that doesn't immediately stop when the delegate predicate returns false, but instead + * sets a flag to stop after the current element is processed. + */ + static class ExceedingPredicate implements Predicate> { + private final Predicate> delegate; + final AtomicBoolean shouldContinue = new AtomicBoolean(true); + + public ExceedingPredicate(final Predicate> delegate) { + this.delegate = delegate; + } + + @Override + public boolean test(final Pair pair) { + final boolean result = delegate.test(pair); + return shouldContinue.getAndSet(result); + } + + public boolean shouldGetMore() { + return shouldContinue.get(); + } + } + + /** Predicate that stops when the end key is exceeded. */ + record EndKeyExceedsPredicate(Bytes endKey) implements Predicate> { + + @Override + public boolean test(final Pair pair) { + return endKey.compareTo(Bytes.wrap(pair.getFirst())) > 0; + } + } + + static class ResponseSizePredicate implements Predicate> { // default to a max of 4 seconds per request static final long MAX_MILLIS_PER_REQUEST = 4000; @@ -588,26 +628,19 @@ class SnapServer implements BesuEvents.InitialSyncCompletionListener { final Function, Integer> encodingSizeAccumulator; final StopWatch stopWatch; final int maxResponseBytes; - // TODO: remove this hack, 10% is a fudge factor to account for the proof node size - final int maxResponseBytesFudgeFactor; final String forWhat; - StatefulPredicate( + ResponseSizePredicate( final String forWhat, final StopWatch stopWatch, final int maxResponseBytes, final Function, Integer> encodingSizeAccumulator) { this.stopWatch = stopWatch; this.maxResponseBytes = maxResponseBytes; - this.maxResponseBytesFudgeFactor = maxResponseBytes * 9 / 10; this.forWhat = forWhat; this.encodingSizeAccumulator = encodingSizeAccumulator; } - public boolean shouldGetMore() { - return shouldContinue.get(); - } - @Override public boolean test(final Pair pair) { LOGGER @@ -628,14 +661,11 @@ class SnapServer implements BesuEvents.InitialSyncCompletionListener { return false; } - var hasNoRecords = recordLimit.get() == 0; var underRecordLimit = recordLimit.addAndGet(1) <= MAX_ENTRIES_PER_REQUEST; var underByteLimit = byteLimit.accumulateAndGet(0, (cur, __) -> cur + encodingSizeAccumulator.apply(pair)) - < maxResponseBytesFudgeFactor; - // Only enforce limits when we have at least 1 record as the snapsync spec - // requires at least 1 record must be returned - if (hasNoRecords || (underRecordLimit && underByteLimit)) { + < maxResponseBytes; + if (underRecordLimit && underByteLimit) { return true; } else { shouldContinue.set(false); 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 e252fe0335..a41da1ef6b 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 @@ -214,8 +214,7 @@ public class SnapServerTest { var rangeData = getAndVerifyAccountRangeData( (AccountRangeMessage) snapServer.constructGetAccountRangeResponse(tinyRangeLimit), - // TODO: after sorting out the request fudge factor, adjust this assertion to match - acctCount * 90 / 100 - 1); + acctCount); // assert proofs are valid for the requested range assertThat(assertIsValidAccountRangeProof(Hash.ZERO, rangeData)).isTrue(); @@ -315,6 +314,31 @@ public class SnapServerTest { .isTrue(); } + @Test + public void assertPartialStorageLimitHashBetweenSlots() { + Bytes accountShortHash = Bytes.fromHexStringLenient("0x40"); + Hash accountFullHash = Hash.wrap(Bytes32.leftPad(accountShortHash)); + SnapTestAccount testAccount = createTestContractAccount(accountFullHash, 2, inMemoryStorage); + + Hash startHash = Hash.wrap(Bytes32.rightPad(Bytes.fromHexString("12"))); // slot 2 + Hash endHash = Hash.wrap(Bytes32.rightPad(Bytes.fromHexString("13"))); // between slots 2 and 3 + var rangeData = requestStorageRange(List.of(testAccount.addressHash), startHash, endHash); + + assertThat(rangeData).isNotNull(); + var slotsData = rangeData.slotsData(false); + assertThat(slotsData).isNotNull(); + assertThat(slotsData.slots()).isNotNull(); + assertThat(slotsData.slots().size()).isEqualTo(1); + var firstAccountStorages = slotsData.slots().first(); + // expecting to see 2 slots + assertThat(firstAccountStorages.size()).isEqualTo(2); + // assert proofs are valid for the requested range + assertThat( + assertIsValidStorageProof( + testAccount, startHash, firstAccountStorages, slotsData.proofs())) + .isTrue(); + } + @Test public void assertLastEmptyPartialStorageForSingleAccount() { // When our final range request is empty, no next account is possible, @@ -343,7 +367,7 @@ public class SnapServerTest { @Test public void assertStorageLimitRangeResponse() { // assert we limit the range response according to bytessize - final int storageSlotSize = 70; + final int storageSlotSize = 69; final int storageSlotCount = 16; insertTestAccounts(acct1, acct2, acct3, acct4); @@ -374,8 +398,7 @@ public class SnapServerTest { assertThat(firstAccountStorages.size()).isEqualTo(10); var secondAccountStorages = slotsData.slots().last(); // expecting to see only 6 since request was limited to 16 slots - // TODO: after sorting out the request fudge factor, adjust this assertion to match - assertThat(secondAccountStorages.size()).isEqualTo(6 * 90 / 100 - 1); + assertThat(secondAccountStorages.size()).isEqualTo(6); // proofs required for interrupted storage range: assertThat(slotsData.proofs().size()).isNotEqualTo(0); @@ -556,7 +579,7 @@ public class SnapServerTest { public void assertStorageTrieShortAccountHashPathRequest() { Bytes accountShortHash = Bytes.fromHexStringLenient("0x40"); Hash accountFullHash = Hash.wrap(Bytes32.leftPad(accountShortHash)); - SnapTestAccount testAccount = createTestContractAccount(accountFullHash, inMemoryStorage); + SnapTestAccount testAccount = createTestContractAccount(accountFullHash, 1, inMemoryStorage); insertTestAccounts(testAccount); var pathToSlot11 = CompactEncoding.encode(Bytes.fromHexStringLenient("0x0101")); var pathToSlot12 = CompactEncoding.encode(Bytes.fromHexStringLenient("0x0102")); @@ -707,11 +730,11 @@ public class SnapServerTest { static SnapTestAccount createTestContractAccount( final String hexAddr, final BonsaiWorldStateKeyValueStorage storage) { final Hash acctHash = Hash.wrap(Bytes32.rightPad(Bytes.fromHexString(hexAddr))); - return createTestContractAccount(acctHash, storage); + return createTestContractAccount(acctHash, 1, storage); } static SnapTestAccount createTestContractAccount( - final Hash acctHash, final BonsaiWorldStateKeyValueStorage storage) { + final Hash acctHash, final int slotKeyGap, final BonsaiWorldStateKeyValueStorage storage) { MerkleTrie trie = new StoredMerklePatriciaTrie<>( (loc, hash) -> storage.getAccountStorageTrieNode(acctHash, loc, hash), @@ -724,7 +747,7 @@ public class SnapServerTest { var flatdb = storage.getFlatDbStrategy(); var updater = storage.updater(); updater.putCode(Hash.hash(mockCode), mockCode); - IntStream.range(10, 20) + IntStream.iterate(10, i -> i < 20, i -> i + slotKeyGap) .boxed() .forEach( i -> { From 94f7c7d24dccbab83bde1365bec8eb47e3de80f6 Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Tue, 13 Aug 2024 18:00:04 -0600 Subject: [PATCH 111/259] EIP-3155 Last Call Nitpicks (#7455) A lot of small nitpicks for standard tracing conformance * Change evmtool run defaults to mirror go-ethereum's choices * Add fields to run summary * Make EOF PC zero to section * Correct EXT*CALL min gas * fix section depth Signed-off-by: Danno Ferrin --- .../besu/evmtool/CodeValidateSubCommand.java | 26 ++++--- .../besu/evmtool/EvmToolCommand.java | 55 ++++++------- .../evmtool/EvmToolCommandOptionsModule.java | 4 +- .../besu/evmtool/GenesisFileModule.java | 14 ++++ .../evmtool/MainnetGenesisFileModule.java | 77 +++++++++++++++---- .../besu/evmtool/trace/badcode.json | 2 +- .../besu/evmtool/trace/charge-intrinsic.json | 2 +- .../besu/evmtool/trace/coinbase-cold.json | 6 +- .../besu/evmtool/trace/coinbase-warm.json | 4 +- .../besu/evmtool/trace/create-eof.json | 2 +- .../besu/evmtool/trace/eof-section.json | 23 ++++++ .../hyperledger/besu/evmtool/trace/eof.json | 4 +- .../besu/evmtool/trace/revert.json | 2 +- .../besu/evmtool/trace/warm-contract.json | 2 +- .../operation/AbstractExtCallOperation.java | 2 +- .../besu/evm/tracing/StandardJsonTracer.java | 8 +- 16 files changed, 164 insertions(+), 69 deletions(-) create mode 100644 ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/eof-section.json 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 962fc2804b..6c8b9d5ad3 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 @@ -35,9 +35,11 @@ import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; +import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.IntStream; +import com.google.common.base.Suppliers; import org.apache.tuweni.bytes.Bytes; import org.web3j.utils.Strings; import picocli.CommandLine; @@ -63,7 +65,7 @@ public class CodeValidateSubCommand implements Runnable { @ParentCommand EvmToolCommand parentCommand; - private final EVM evm; + private final Supplier evm; @CommandLine.Option( names = {"--file"}, @@ -83,12 +85,18 @@ public class CodeValidateSubCommand implements Runnable { CodeValidateSubCommand(final EvmToolCommand parentCommand) { this.parentCommand = parentCommand; - String fork = EvmSpecVersion.PRAGUE.getName(); - if (parentCommand != null && parentCommand.hasFork()) { - fork = parentCommand.getFork(); - } - ProtocolSpec protocolSpec = ReferenceTestProtocolSchedules.create().geSpecByName(fork); - evm = protocolSpec.getEvm(); + String fork = + parentCommand != null && parentCommand.hasFork() + ? parentCommand.getFork() + : EvmSpecVersion.PRAGUE.getName(); + + evm = + Suppliers.memoize( + () -> { + ProtocolSpec protocolSpec = + ReferenceTestProtocolSchedules.create().geSpecByName(fork); + return protocolSpec.getEvm(); + }); } @Override @@ -155,12 +163,12 @@ public class CodeValidateSubCommand implements Runnable { return ""; } - EOFLayout layout = evm.parseEOF(codeBytes); + EOFLayout layout = evm.get().parseEOF(codeBytes); if (!layout.isValid()) { return "err: layout - " + layout.invalidReason(); } - Code code = evm.getCodeUncached(codeBytes); + Code code = evm.get().getCodeUncached(codeBytes); if (code instanceof CodeInvalid codeInvalid) { return "err: " + codeInvalid.getInvalidReason(); } else if (EOFContainerMode.INITCODE.equals( 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 989c6e0b7f..06ee967620 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 @@ -51,7 +51,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; -import java.time.Instant; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; @@ -152,13 +151,13 @@ public class EvmToolCommand implements Runnable { names = {"--sender"}, paramLabel = "

", description = "Calling address for this invocation.") - private final Address sender = Address.ZERO; + private final Address sender = Address.fromHexString("0x73656e646572"); @Option( names = {"--receiver"}, paramLabel = "
", description = "Receiving address for this invocation.") - private final Address receiver = Address.ZERO; + private final Address receiver = Address.fromHexString("0x7265636569766572"); @Option( names = {"--create"}, @@ -169,7 +168,7 @@ public class EvmToolCommand implements Runnable { names = {"--contract"}, paramLabel = "
", description = "The address holding the contract code.") - private final Address contract = Address.ZERO; + private final Address contract = Address.fromHexString("0x7265636569766572"); @Option( names = {"--coinbase"}, @@ -379,7 +378,7 @@ public class EvmToolCommand implements Runnable { } else if (genesisFile != null) { genesisFileModule = GenesisFileModule.createGenesisModule(genesisFile); } else { - genesisFileModule = GenesisFileModule.createGenesisModule(NetworkName.DEV); + genesisFileModule = GenesisFileModule.createGenesisModule(); } final EvmToolComponent component = DaggerEvmToolComponent.builder() @@ -463,10 +462,12 @@ public class EvmToolCommand implements Runnable { BlockHeaderBuilder.create() .parentHash(Hash.EMPTY) .coinbase(coinbase) - .difficulty(Difficulty.ONE) - .number(1) - .gasLimit(5000) - .timestamp(Instant.now().toEpochMilli()) + .difficulty( + Difficulty.fromHexString( + genesisFileModule.providesGenesisConfigFile().getDifficulty())) + .number(0) + .gasLimit(genesisFileModule.providesGenesisConfigFile().getGasLimit()) + .timestamp(0) .ommersHash(Hash.EMPTY_LIST_HASH) .stateRoot(Hash.EMPTY_TRIE_HASH) .transactionsRoot(Hash.EMPTY) @@ -474,7 +475,7 @@ public class EvmToolCommand implements Runnable { .logsBloom(LogsBloomFilter.empty()) .gasUsed(0) .extraData(Bytes.EMPTY) - .mixHash(Hash.EMPTY) + .mixHash(Hash.ZERO) .nonce(0) .blockHeaderFunctions(new MainnetBlockHeaderFunctions()) .baseFee(component.getBlockchain().getChainHeadHeader().getBaseFee().orElse(null)) @@ -527,28 +528,30 @@ public class EvmToolCommand implements Runnable { } } } - - if (lastLoop && messageFrameStack.isEmpty()) { - final long evmGas = txGas - messageFrame.getRemainingGas(); - final JsonObject resultLine = new JsonObject(); - resultLine.put("gasUser", "0x" + Long.toHexString(evmGas)); - if (!noTime) { - resultLine.put("timens", lastTime).put("time", lastTime / 1000); - } - resultLine - .put("gasTotal", "0x" + Long.toHexString(evmGas)) - .put("output", messageFrame.getOutputData().toHexString()); - out.println(); - out.println(resultLine); - } } lastTime = stopwatch.elapsed().toNanos(); stopwatch.reset(); - if (showJsonAlloc && lastLoop) { + if (lastLoop) { initialMessageFrame.getSelfDestructs().forEach(updater::deleteAccount); + updater.clearAccountsThatAreEmpty(); updater.commit(); MutableWorldState worldState = component.getWorldState(); - dumpWorldState(worldState, out); + final long evmGas = txGas - initialMessageFrame.getRemainingGas(); + final JsonObject resultLine = new JsonObject(); + resultLine + .put("stateRoot", worldState.rootHash().toHexString()) + .put("output", initialMessageFrame.getOutputData().toHexString()) + .put("gasUsed", "0x" + Long.toHexString(evmGas)) + .put("pass", initialMessageFrame.getExceptionalHaltReason().isEmpty()) + .put("fork", protocolSpec.getName()); + if (!noTime) { + resultLine.put("timens", lastTime).put("time", lastTime / 1000); + } + out.println(resultLine); + + if (showJsonAlloc) { + dumpWorldState(worldState, out); + } } } while (remainingIters-- > 0); diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EvmToolCommandOptionsModule.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EvmToolCommandOptionsModule.java index 820b11442e..01238e2b28 100644 --- a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EvmToolCommandOptionsModule.java +++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EvmToolCommandOptionsModule.java @@ -145,5 +145,7 @@ public class EvmToolCommandOptionsModule { } /** Default constructor for the EvmToolCommandOptionsModule class. */ - public EvmToolCommandOptionsModule() {} + public EvmToolCommandOptionsModule() { + // This is only here because of JavaDoc linting + } } diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/GenesisFileModule.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/GenesisFileModule.java index 1283ec039f..6eae387a64 100644 --- a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/GenesisFileModule.java +++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/GenesisFileModule.java @@ -111,6 +111,20 @@ public class GenesisFileModule { return createGenesisModule(Files.readString(genesisFile.toPath(), Charset.defaultCharset())); } + static GenesisFileModule createGenesisModule() { + final JsonObject genesis = new JsonObject(); + final JsonObject config = new JsonObject(); + genesis.put("config", config); + config.put("chainId", 1337); + config.put("londonBlock", 0); + genesis.put("baseFeePerGas", "0x3b9aca00"); + genesis.put("gasLimit", "0x2540be400"); + genesis.put("difficulty", "0x0"); + genesis.put("mixHash", "0x0000000000000000000000000000000000000000000000000000000000000000"); + genesis.put("coinbase", "0x0000000000000000000000000000000000000000"); + return createGenesisModule(genesis.toString()); + } + private static GenesisFileModule createGenesisModule(final String genesisConfig) { final JsonObject genesis = new JsonObject(genesisConfig); final JsonObject config = genesis.getJsonObject("config"); 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 4f10650273..e36668f47c 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 @@ -71,7 +71,7 @@ class MainnetGenesisFileModule extends GenesisFileModule { } } - var schedules = createSchedules(); + var schedules = createSchedules(configOptions.getChainId().orElse(BigInteger.valueOf(1337))); var schedule = schedules.get( fork.orElse(EvmSpecVersion.defaultVersion().getName()) @@ -89,9 +89,9 @@ class MainnetGenesisFileModule extends GenesisFileModule { new NoOpMetricsSystem()); } - public static Map> createSchedules() { + public static Map> createSchedules(final BigInteger chainId) { return Map.ofEntries( - Map.entry("frontier", createSchedule(new StubGenesisConfigOptions())), + Map.entry("frontier", createSchedule(new StubGenesisConfigOptions().chainId(chainId))), Map.entry("homestead", createSchedule(new StubGenesisConfigOptions().homesteadBlock(0))), Map.entry("eip150", createSchedule(new StubGenesisConfigOptions().eip150Block(0))), Map.entry("eip158", createSchedule(new StubGenesisConfigOptions().eip158Block(0))), @@ -102,43 +102,86 @@ class MainnetGenesisFileModule extends GenesisFileModule { Map.entry( "constantinoplefix", createSchedule(new StubGenesisConfigOptions().petersburgBlock(0))), Map.entry("petersburg", createSchedule(new StubGenesisConfigOptions().petersburgBlock(0))), - Map.entry("istanbul", createSchedule(new StubGenesisConfigOptions().istanbulBlock(0))), Map.entry( - "muirglacier", createSchedule(new StubGenesisConfigOptions().muirGlacierBlock(0))), - Map.entry("berlin", createSchedule(new StubGenesisConfigOptions().berlinBlock(0))), + "istanbul", + createSchedule(new StubGenesisConfigOptions().istanbulBlock(0).chainId(chainId))), + Map.entry( + "muirglacier", + createSchedule(new StubGenesisConfigOptions().muirGlacierBlock(0).chainId(chainId))), + Map.entry( + "berlin", + createSchedule(new StubGenesisConfigOptions().berlinBlock(0).chainId(chainId))), Map.entry( "london", - createSchedule(new StubGenesisConfigOptions().londonBlock(0).baseFeePerGas(0x0a))), + createSchedule( + new StubGenesisConfigOptions() + .londonBlock(0) + .baseFeePerGas(0x0a) + .chainId(chainId))), Map.entry( - "arrowglacier", createSchedule(new StubGenesisConfigOptions().arrowGlacierBlock(0))), + "arrowglacier", + createSchedule( + new StubGenesisConfigOptions() + .arrowGlacierBlock(0) + .baseFeePerGas(0x0a) + .chainId(chainId))), Map.entry( - "grayglacier", createSchedule(new StubGenesisConfigOptions().grayGlacierBlock(0))), + "grayglacier", + createSchedule( + new StubGenesisConfigOptions() + .grayGlacierBlock(0) + .baseFeePerGas(0x0a) + .chainId(chainId))), Map.entry( "merge", createSchedule( - new StubGenesisConfigOptions().mergeNetSplitBlock(0).baseFeePerGas(0x0a))), + new StubGenesisConfigOptions() + .mergeNetSplitBlock(0) + .baseFeePerGas(0x0a) + .chainId(chainId))), Map.entry( "shanghai", - createSchedule(new StubGenesisConfigOptions().shanghaiTime(0).baseFeePerGas(0x0a))), + createSchedule( + new StubGenesisConfigOptions() + .shanghaiTime(0) + .baseFeePerGas(0x0a) + .chainId(chainId))), Map.entry( "cancun", - createSchedule(new StubGenesisConfigOptions().cancunTime(0).baseFeePerGas(0x0a))), + createSchedule( + new StubGenesisConfigOptions().cancunTime(0).baseFeePerGas(0x0a).chainId(chainId))), Map.entry( "cancuneof", - createSchedule(new StubGenesisConfigOptions().cancunEOFTime(0).baseFeePerGas(0x0a))), + createSchedule( + new StubGenesisConfigOptions() + .cancunEOFTime(0) + .baseFeePerGas(0x0a) + .chainId(chainId))), Map.entry( "prague", - createSchedule(new StubGenesisConfigOptions().pragueTime(0).baseFeePerGas(0x0a))), + createSchedule( + new StubGenesisConfigOptions().pragueTime(0).baseFeePerGas(0x0a).chainId(chainId))), Map.entry( "pragueeof", - createSchedule(new StubGenesisConfigOptions().pragueEOFTime(0).baseFeePerGas(0x0a))), + createSchedule( + new StubGenesisConfigOptions() + .pragueEOFTime(0) + .baseFeePerGas(0x0a) + .chainId(chainId))), Map.entry( "futureeips", - createSchedule(new StubGenesisConfigOptions().futureEipsTime(0).baseFeePerGas(0x0a))), + createSchedule( + new StubGenesisConfigOptions() + .futureEipsTime(0) + .baseFeePerGas(0x0a) + .chainId(chainId))), Map.entry( "experimentaleips", createSchedule( - new StubGenesisConfigOptions().experimentalEipsTime(0).baseFeePerGas(0x0a)))); + new StubGenesisConfigOptions() + .experimentalEipsTime(0) + .baseFeePerGas(0x0a) + .chainId(chainId)))); } private static Supplier createSchedule(final GenesisConfigOptions options) { diff --git a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/badcode.json b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/badcode.json index 7ffca7e466..78dc43c02e 100644 --- a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/badcode.json +++ b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/badcode.json @@ -9,6 +9,6 @@ "stdout": [ {"pc":0,"op":96,"gas":"0x2540be400","gasCost":"0x3","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"PUSH1"}, {"pc":2,"op":239,"gas":"0x2540be3fd","gasCost":"0x0","memSize":0,"stack":["0x0"],"depth":1,"refund":0,"opName":"INVALID","error":"Bad instruction"}, - {"gasUser":"0x2540be400","gasTotal":"0x2540be400","output":"0x"} + {"stateRoot":"0xfc9dc1be50c1b0a497afa545d770cc7064f0d71efbc4338f002dc2e086965d98","output":"0x","gasUsed":"0x2540be400","pass":false,"fork":"Cancun"} ] } \ No newline at end of file diff --git a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/charge-intrinsic.json b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/charge-intrinsic.json index 6ea64e18cf..9355c47283 100644 --- a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/charge-intrinsic.json +++ b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/charge-intrinsic.json @@ -70,6 +70,6 @@ {"pc":24,"op":243,"gas":"0x45","gasCost":"0x0","memSize":96,"stack":["0x1","0x40"],"depth":2,"refund":0,"opName":"RETURN"}, {"pc":22,"op":96,"gas":"0x71","gasCost":"0x3","memSize":96,"stack":["0x1"],"depth":1,"refund":0,"opName":"PUSH1"}, {"pc":24,"op":243,"gas":"0x6e","gasCost":"0x0","memSize":96,"stack":["0x1","0x40"],"depth":1,"refund":0,"opName":"RETURN"}, - {"gasUser":"0x619e","gasTotal":"0x619e","output":"0x40"} + {"stateRoot":"0xcb5e8e232189003640b6f131ea2c09b1791ffd2e8357f64610f638e9a11ab2d2","output":"0x40","gasUsed":"0x619e","pass":true,"fork":"Cancun"} ] } \ No newline at end of file diff --git a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/coinbase-cold.json b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/coinbase-cold.json index f23565c64b..127d60fc60 100644 --- a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/coinbase-cold.json +++ b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/coinbase-cold.json @@ -7,13 +7,13 @@ "--coinbase", "4444588443C3A91288C5002483449ABA1054192B", "--fork", - "paris" + "london" ], "stdin": "", "stdout": [ {"pc":0,"op":65,"gas":"0x2540be400","gasCost":"0x2","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"COINBASE"}, {"pc":1,"op":49,"gas":"0x2540be3fe","gasCost":"0xa28","memSize":0,"stack":["0x4444588443c3a91288c5002483449aba1054192b"],"depth":1,"refund":0,"opName":"BALANCE"}, - {"pc":2,"op":255,"gas":"0x2540bd9d6","gasCost":"0x1388","memSize":0,"stack":["0x0"],"depth":1,"refund":0,"opName":"SELFDESTRUCT"}, - {"gasUser":"0x1db2","gasTotal":"0x1db2","output":"0x"} + {"pc":2,"op":255,"gas":"0x2540bd9d6","gasCost":"0x1db0","memSize":0,"stack":["0x0"],"depth":1,"refund":0,"opName":"SELFDESTRUCT"}, + {"stateRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","output":"0x","gasUsed":"0x27da","pass":true,"fork":"London"} ] } \ No newline at end of file diff --git a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/coinbase-warm.json b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/coinbase-warm.json index 79ca8e5bf3..02f9395981 100644 --- a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/coinbase-warm.json +++ b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/coinbase-warm.json @@ -13,7 +13,7 @@ "stdout": [ {"pc":0,"op":65,"gas":"0x2540be400","gasCost":"0x2","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"COINBASE"}, {"pc":1,"op":49,"gas":"0x2540be3fe","gasCost":"0x64","memSize":0,"stack":["0x4444588443c3a91288c5002483449aba1054192b"],"depth":1,"refund":0,"opName":"BALANCE"}, - {"pc":2,"op":255,"gas":"0x2540be39a","gasCost":"0x1388","memSize":0,"stack":["0x0"],"depth":1,"refund":0,"opName":"SELFDESTRUCT"}, - {"gasUser":"0x13ee","gasTotal":"0x13ee","output":"0x"} + {"pc":2,"op":255,"gas":"0x2540be39a","gasCost":"0x1db0","memSize":0,"stack":["0x0"],"depth":1,"refund":0,"opName":"SELFDESTRUCT"}, + {"stateRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","output":"0x","gasUsed":"0x1e16","pass":true,"fork":"Shanghai"} ] } \ No newline at end of file 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 b0699f1b3c..1fa459916b 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 @@ -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"}, - {"gasUser":"0x129b","gasTotal":"0x129b","output":"0x"} + {"stateRoot":"0x9790b070a5749acec6a7252a867f795df3c2cb5b800fb509ea259a1c0b5d96c1","output":"0x","gasUsed":"0x129b","pass":true,"fork":"CancunEOF"} ] } \ 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 new file mode 100644 index 0000000000..061d8f0940 --- /dev/null +++ b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/eof-section.json @@ -0,0 +1,23 @@ +{ + "cli": [ + "--notime", + "--json", + "--code", + "0xef000101000c020003000a0001000304000000008000020000000000000000e3000261201560015500e4e50001", + "--coinbase", + "4444588443C3A91288C5002483449ABA1054192B", + "--fork", + "PragueEOF" + ], + "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,"fdepth":1,"refund":0,"opName":"JUMPF"}, + {"pc":0,"section":1,"op":228,"gas":"0x2540be3f6","gasCost":"0x3","memSize":0,"stack":[],"depth":1,"fdepth":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"} + ] +} \ 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 ff9bf415e6..c9553c9209 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", - "CancunEOF" + "PragueEOF" ], "stdin": "", "stdout": [ {"pc":0,"section":0,"op":0,"gas":"0x2540be400","gasCost":"0x0","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"STOP"}, - {"gasUser":"0x0","gasTotal":"0x0","output":"0x"} + {"stateRoot":"0xdae5f2c233bf9fbb7413d06ce744a3345dbf971b5bb5638736c0388f43a61a4b","output":"0x","gasUsed":"0x0","pass":true,"fork":"PragueEOF"} ] } \ No newline at end of file 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 875ceb81b1..4798d5da70 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 @@ -13,6 +13,6 @@ {"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"}, - {"gasUser":"0x12","gasTotal":"0x12","output":"0x4e6f7065"} + {"stateRoot":"0x405bbd98da2aca6dff77f79e0b270270c48d6a3e07b76db675b20e454b50bbcb","output":"0x4e6f7065","gasUsed":"0x12","pass":true,"fork":"Cancun"} ] } \ No newline at end of file diff --git a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/warm-contract.json b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/warm-contract.json index 8a7a550058..1c2a9c8064 100644 --- a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/warm-contract.json +++ b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/warm-contract.json @@ -67,6 +67,6 @@ {"pc":24,"op":243,"gas":"0x45","gasCost":"0x0","memSize":96,"stack":["0x1","0x40"],"depth":2,"refund":0,"opName":"RETURN"}, {"pc":22,"op":96,"gas":"0x71","gasCost":"0x3","memSize":96,"stack":["0x1"],"depth":1,"refund":0,"opName":"PUSH1"}, {"pc":24,"op":243,"gas":"0x6e","gasCost":"0x0","memSize":96,"stack":["0x1","0x40"],"depth":1,"refund":0,"opName":"RETURN"}, - {"gasUser":"0x619e","gasTotal":"0x619e","output":"0x40"} + {"stateRoot":"0xcb5e8e232189003640b6f131ea2c09b1791ffd2e8357f64610f638e9a11ab2d2","output":"0x40","gasUsed":"0x619e","pass":true,"fork":"Cancun"} ] } \ No newline at end of file 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 43d7e343ff..e44c0e7f9c 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 @@ -152,7 +152,7 @@ public abstract class AbstractExtCallOperation extends AbstractCallOperation { 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().getMinRetainedGas()) { + 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/tracing/StandardJsonTracer.java b/evm/src/main/java/org/hyperledger/besu/evm/tracing/StandardJsonTracer.java index 4ea5bc1b7f..2a71fb70cd 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 @@ -127,7 +127,9 @@ 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(0).getEntryPoint(); + pc = + messageFrame.getPC() + - messageFrame.getCode().getCodeSection(messageFrame.getSection()).getEntryPoint(); section = messageFrame.getSection(); gas = shortNumber(messageFrame.getRemainingGas()); memorySize = messageFrame.memoryWordSize() * 32; @@ -213,8 +215,8 @@ public class StandardJsonTracer implements OperationTracer { sb.append("\"returnData\":\"").append(returnData.toHexString()).append("\","); } sb.append("\"depth\":").append(depth).append(","); - if (subdepth > 1) { - sb.append("\"subdepth\":").append(subdepth).append(","); + if (subdepth >= 1) { + sb.append("\"fdepth\":").append(subdepth).append(","); } sb.append("\"refund\":").append(messageFrame.getGasRefund()).append(","); sb.append("\"opName\":\"").append(currentOp.getName()).append("\""); From ac9f8bbd91384b380e6d52a3e23bf40c59cc0ce4 Mon Sep 17 00:00:00 2001 From: garyschulte Date: Tue, 13 Aug 2024 17:22:40 -0700 Subject: [PATCH 112/259] Bump besu-native dependency (#7456) * bump besu-native ahead of next release Signed-off-by: garyschulte --- CHANGELOG.md | 1 + gradle/verification-metadata.xml | 70 ++++++++++++++++---------------- gradle/versions.gradle | 2 +- 3 files changed, 37 insertions(+), 36 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1629002cbd..0d30381a92 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ - In process RPC service [#7395](https://github.com/hyperledger/besu/pull/7395) - Added support for tracing private transactions using `priv_traceTransaction` API. [#6161](https://github.com/hyperledger/besu/pull/6161) - Wrap WorldUpdater into EVMWorldupdater [#7434](https://github.com/hyperledger/besu/pull/7434) +- Bump besu-native to 0.9.4 [#7456](https://github.com/hyperledger/besu/pull/7456) ### Bug fixes diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index c7f3039dff..46029c87c8 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -4648,12 +4648,12 @@ - - - + + + - - + + @@ -4664,52 +4664,52 @@ - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + diff --git a/gradle/versions.gradle b/gradle/versions.gradle index 9ad95a2074..57f2acae37 100644 --- a/gradle/versions.gradle +++ b/gradle/versions.gradle @@ -156,7 +156,7 @@ dependencyManagement { dependency 'org.openjdk.jol:jol-core:0.17' dependency 'tech.pegasys:jc-kzg-4844:1.0.0' - dependencySet(group: 'org.hyperledger.besu', version: '0.9.3') { + dependencySet(group: 'org.hyperledger.besu', version: '0.9.4') { entry 'arithmetic' entry 'ipa-multipoint' entry 'bls12-381' From a3b6fd54022334acb01f643fed3ba8d86a90e303 Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Wed, 14 Aug 2024 14:34:45 +1000 Subject: [PATCH 113/259] 5098 branch 15 update remaining invalid engine params (#7443) Signed-off-by: Matilda Clerke --- .../execution/TracedJsonRpcProcessor.java | 4 +-- .../AbstractEngineForkchoiceUpdated.java | 24 ++++++++++--- .../engine/AbstractEngineNewPayload.java | 12 +++++-- .../engine/EnginePreparePayloadDebug.java | 36 ++++++++++++------- .../internal/response/RpcErrorType.java | 4 +-- 5 files changed, 58 insertions(+), 22 deletions(-) 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 822c6ac895..f1a799cf63 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 @@ -74,8 +74,8 @@ public class TracedJsonRpcProcessor implements JsonRpcProcessor { case INVALID_DEPOSIT_REQUEST_PARAMS: case INVALID_ENGINE_EXCHANGE_TRANSITION_CONFIGURATION_PARAMS: case INVALID_ENGINE_FORKCHOICE_UPDATED_PARAMS: - case INVALID_ENGINE_PAYLOAD_ATTRIBUTES_PARAMS: - case INVALID_ENGINE_PAYLOAD_PARAMS: + case INVALID_ENGINE_FORKCHOICE_UPDATED_PAYLOAD_ATTRIBUTES: + case INVALID_ENGINE_NEW_PAYLOAD_PARAMS: case INVALID_ENGINE_PREPARE_PAYLOAD_PARAMS: case INVALID_ENODE_PARAMS: case INVALID_EXCESS_BLOB_GAS_PARAMS: diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineForkchoiceUpdated.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineForkchoiceUpdated.java index eec79e9a7c..f958b58444 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineForkchoiceUpdated.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineForkchoiceUpdated.java @@ -27,6 +27,7 @@ import org.hyperledger.besu.consensus.merge.blockcreation.PayloadIdentifier; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.EngineForkchoiceUpdatedParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.EnginePayloadAttributesParameter; @@ -80,10 +81,25 @@ public abstract class AbstractEngineForkchoiceUpdated extends ExecutionEngineJso final Object requestId = requestContext.getRequest().getId(); - final EngineForkchoiceUpdatedParameter forkChoice = - requestContext.getRequiredParameter(0, EngineForkchoiceUpdatedParameter.class); - final Optional maybePayloadAttributes = - requestContext.getOptionalParameter(1, EnginePayloadAttributesParameter.class); + final EngineForkchoiceUpdatedParameter forkChoice; + try { + forkChoice = requestContext.getRequiredParameter(0, EngineForkchoiceUpdatedParameter.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid engine forkchoice updated parameter (index 0)", + RpcErrorType.INVALID_ENGINE_FORKCHOICE_UPDATED_PARAMS, + e); + } + final Optional maybePayloadAttributes; + try { + maybePayloadAttributes = + requestContext.getOptionalParameter(1, EnginePayloadAttributesParameter.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid engine payload attributes parameter (index 1)", + RpcErrorType.INVALID_ENGINE_FORKCHOICE_UPDATED_PAYLOAD_ATTRIBUTES, + e); + } LOG.debug("Forkchoice parameters {}", forkChoice); mergeContext 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 246a2777c8..5d0d379d81 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 @@ -35,6 +35,7 @@ import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.BlockProcessingResult; 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; @@ -107,8 +108,15 @@ public abstract class AbstractEngineNewPayload extends ExecutionEngineJsonRpcMet public JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext) { engineCallListener.executionEngineCalled(); - final EnginePayloadParameter blockParam = - requestContext.getRequiredParameter(0, EnginePayloadParameter.class); + final EnginePayloadParameter blockParam; + try { + blockParam = requestContext.getRequiredParameter(0, EnginePayloadParameter.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcRequestException( + "Invalid engine payload parameter (index 0)", + RpcErrorType.INVALID_ENGINE_NEW_PAYLOAD_PARAMS, + e); + } final Optional> maybeVersionedHashParam = requestContext.getOptionalList(1, String.class); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EnginePreparePayloadDebug.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EnginePreparePayloadDebug.java index 26f8e99edd..e55cfb1506 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EnginePreparePayloadDebug.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EnginePreparePayloadDebug.java @@ -23,6 +23,7 @@ import org.hyperledger.besu.consensus.merge.blockcreation.PayloadIdentifier; import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.EnginePreparePayloadParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.WithdrawalParameter; @@ -58,17 +59,25 @@ public class EnginePreparePayloadDebug extends ExecutionEngineJsonRpcMethod { @Override public JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext) { - final EnginePreparePayloadParameter enginePreparePayloadParameter = - requestContext - .getOptionalParameter(0, EnginePreparePayloadParameter.class) - .orElse( - new EnginePreparePayloadParameter( - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.empty())); + final EnginePreparePayloadParameter enginePreparePayloadParameter; + try { + enginePreparePayloadParameter = + requestContext + .getOptionalParameter(0, EnginePreparePayloadParameter.class) + .orElse( + new EnginePreparePayloadParameter( + Optional.empty(), + Optional.empty(), + Optional.empty(), + Optional.empty(), + Optional.empty(), + Optional.empty())); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid engine prepare payload parameter (index 0)", + RpcErrorType.INVALID_ENGINE_PREPARE_PAYLOAD_PARAMS, + e); + } final var requestId = requestContext.getRequest().getId(); @@ -81,7 +90,10 @@ public class EnginePreparePayloadDebug extends ExecutionEngineJsonRpcMethod { payloadIdentifier -> new JsonRpcSuccessResponse( requestId, new EnginePreparePayloadResult(VALID, payloadIdentifier))) - .orElseGet(() -> new JsonRpcErrorResponse(requestId, RpcErrorType.INVALID_PARAMS)); + .orElseGet( + () -> + new JsonRpcErrorResponse( + requestId, RpcErrorType.INVALID_ENGINE_PREPARE_PAYLOAD_PARAMS)); } @VisibleForTesting 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 d46dc900c5..d16c258879 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 @@ -52,9 +52,9 @@ public enum RpcErrorType implements RpcMethodError { INVALID_PARAMS_ERROR_CODE, "Invalid engine exchange transition configuration params"), INVALID_ENGINE_FORKCHOICE_UPDATED_PARAMS( INVALID_PARAMS_ERROR_CODE, "Invalid engine forkchoice updated params"), - INVALID_ENGINE_PAYLOAD_ATTRIBUTES_PARAMS( + INVALID_ENGINE_FORKCHOICE_UPDATED_PAYLOAD_ATTRIBUTES( INVALID_PARAMS_ERROR_CODE, "Invalid engine payload attributes parameter"), - INVALID_ENGINE_PAYLOAD_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid engine payload parameter"), + INVALID_ENGINE_NEW_PAYLOAD_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid engine payload parameter"), INVALID_ENGINE_PREPARE_PAYLOAD_PARAMS( INVALID_PARAMS_ERROR_CODE, "Invalid engine prepare payload parameter"), INVALID_ENODE_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid enode params"), From adf19afb1ac7cbd4593d0c6f05ed355d63bd65e4 Mon Sep 17 00:00:00 2001 From: Suyash Nayan <89125422+7suyash7@users.noreply.github.com> Date: Wed, 14 Aug 2024 10:36:24 +0530 Subject: [PATCH 114/259] Correct default `--help` values (#7454) * Fix #7367: Correct default value display for --rpc-max-trace-filter-range along with a test * Fix #7369: Show default value for --genesis-state-hash-cache-enabled Signed-off-by: 7suyash7 --- .../java/org/hyperledger/besu/cli/BesuCommand.java | 3 ++- .../cli/options/stable/ApiConfigurationOptions.java | 2 +- .../org/hyperledger/besu/cli/BesuCommandTest.java | 12 ++++++++++++ 3 files changed, 15 insertions(+), 2 deletions(-) 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 72fbb48ec9..67a360a882 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java @@ -375,7 +375,8 @@ public class BesuCommand implements DefaultCommandValues, Runnable { @Option( names = {"--genesis-state-hash-cache-enabled"}, - description = "Use genesis state hash from data on startup if specified") + description = + "Use genesis state hash from data on startup if specified (default: ${DEFAULT-VALUE})") private final Boolean genesisStateHashCacheEnabled = false; @Option( 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 d988238276..fbed68de0c 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 @@ -85,7 +85,7 @@ public class ApiConfigurationOptions { @CommandLine.Option( names = {"--rpc-max-trace-filter-range"}, description = - "Specifies the maximum number of blocks for the trace_filter method. Must be >=0. 0 specifies no limit (default: $DEFAULT-VALUE)") + "Specifies the maximum number of blocks for the trace_filter method. Must be >=0. 0 specifies no limit (default: ${DEFAULT-VALUE})") private final Long maxTraceFilterRange = 1000L; /** 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 d0c42f6718..23ba593a38 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java @@ -2503,4 +2503,16 @@ public class BesuCommandTest extends CommandTestAbstract { assertThat(commandOutput.toString(UTF_8)).isEmpty(); assertThat(commandErrorOutput.toString(UTF_8)).isEmpty(); } + + @Test + void helpOutputShouldDisplayCorrectDefaultValues() { + parseCommand("--help"); + + final String commandOutputString = commandOutput.toString(UTF_8); + final String errorOutputString = commandErrorOutput.toString(UTF_8); + + assertThat(commandOutputString).doesNotContain("$DEFAULT-VALUE"); + + assertThat(errorOutputString).isEmpty(); + } } From b99cdf627378ad4da646c105b24025ba0006e9c4 Mon Sep 17 00:00:00 2001 From: Luis Pinto Date: Wed, 14 Aug 2024 16:54:13 +0000 Subject: [PATCH 115/259] Precompile calls were not traced when insuficient gas (#7462) * Precompile calls were not traced when insuficient gas Signed-off-by: Luis Pinto * fixup! Precompile calls were not traced when insuficient gas revert RuntimeException in StateDiffGenerator Signed-off-by: Luis Pinto --------- Signed-off-by: Luis Pinto --- CHANGELOG.md | 1 + .../evm/processor/MessageCallProcessor.java | 1 + .../processor/MessageCallProcessorTest.java | 66 +++++++++++++++++++ 3 files changed, 68 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d30381a92..8a16284015 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ - Correct entrypoint in Docker evmtool [#7430](https://github.com/hyperledger/besu/pull/7430) - Fix protocol schedule check for devnets [#7429](https://github.com/hyperledger/besu/pull/7429) - Fix behaviour when starting in a pre-merge network [#7431](https://github.com/hyperledger/besu/pull/7431) +- Fix tracing in precompiled contracts when halting for out of gas [#7318](https://github.com/hyperledger/besu/issues/7318) ## 24.7.1 diff --git a/evm/src/main/java/org/hyperledger/besu/evm/processor/MessageCallProcessor.java b/evm/src/main/java/org/hyperledger/besu/evm/processor/MessageCallProcessor.java index 1963bba8a5..e3ce69d74a 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/processor/MessageCallProcessor.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/processor/MessageCallProcessor.java @@ -153,6 +153,7 @@ public class MessageCallProcessor extends AbstractMessageProcessor { if (frame.getRemainingGas() < gasRequirement) { frame.setExceptionalHaltReason(Optional.of(ExceptionalHaltReason.INSUFFICIENT_GAS)); frame.setState(MessageFrame.State.EXCEPTIONAL_HALT); + operationTracer.tracePrecompileCall(frame, gasRequirement, null); } else { frame.decrementRemainingGas(gasRequirement); final PrecompiledContract.PrecompileContractResult result = diff --git a/evm/src/test/java/org/hyperledger/besu/evm/processor/MessageCallProcessorTest.java b/evm/src/test/java/org/hyperledger/besu/evm/processor/MessageCallProcessorTest.java index c3f04c07c5..d17744c858 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/processor/MessageCallProcessorTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/processor/MessageCallProcessorTest.java @@ -14,10 +14,23 @@ */ package org.hyperledger.besu.evm.processor; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.evm.EVM; +import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.precompile.PrecompileContractRegistry; +import org.hyperledger.besu.evm.precompile.PrecompiledContract; +import org.hyperledger.besu.evm.testutils.TestMessageFrameBuilder; +import org.hyperledger.besu.evm.toy.ToyWorld; import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; @@ -28,9 +41,62 @@ class MessageCallProcessorTest extends AbstractMessageProcessorTest Date: Wed, 14 Aug 2024 16:41:38 -0400 Subject: [PATCH 116/259] isolates MetricsOptionGroup for future reusability, minor renaming (#7464) * isolates MetricsOptionGroup for future reusability, minor renaming --------- Signed-off-by: Justin Florentine --- .../org/hyperledger/besu/cli/BesuCommand.java | 130 +++--------- .../options/stable/MetricsOptionGroup.java | 197 ++++++++++++++++++ 2 files changed, 224 insertions(+), 103 deletions(-) create mode 100644 besu/src/main/java/org/hyperledger/besu/cli/options/stable/MetricsOptionGroup.java 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 67a360a882..a0e99db69f 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java @@ -25,10 +25,6 @@ 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.metrics.BesuMetricCategory.DEFAULT_METRIC_CATEGORIES; -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 static org.hyperledger.besu.nat.kubernetes.KubernetesNatManager.DEFAULT_BESU_SERVICE_NAME_FILTER; import org.hyperledger.besu.BesuInfo; @@ -54,6 +50,7 @@ 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.NodePrivateKeyFileOption; import org.hyperledger.besu.cli.options.stable.P2PTLSConfigOptions; import org.hyperledger.besu.cli.options.stable.PermissionsOptions; @@ -314,7 +311,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { final MiningOptions miningOptions = MiningOptions.create(); private final RunnerBuilder runnerBuilder; - private final BesuController.Builder controllerBuilderFactory; + private final BesuController.Builder controllerBuilder; private final BesuPluginContextImpl besuPluginContext; private final StorageServiceImpl storageService; private final SecurityModuleServiceImpl securityModuleService; @@ -746,81 +743,6 @@ public class BesuCommand implements DefaultCommandValues, Runnable { @CommandLine.ArgGroup(validate = false, heading = "@|bold Metrics Options|@%n") MetricsOptionGroup metricsOptionGroup = new MetricsOptionGroup(); - static class MetricsOptionGroup { - @Option( - names = {"--metrics-enabled"}, - description = "Set to start the metrics exporter (default: ${DEFAULT-VALUE})") - private final Boolean isMetricsEnabled = false; - - @SuppressWarnings({"FieldCanBeFinal", "FieldMayBeFinal"}) // PicoCLI requires non-final Strings. - @Option( - names = {"--metrics-protocol"}, - description = - "Metrics protocol, one of PROMETHEUS, OPENTELEMETRY or NONE. (default: ${DEFAULT-VALUE})") - private MetricsProtocol metricsProtocol = PROMETHEUS; - - @SuppressWarnings({"FieldCanBeFinal", "FieldMayBeFinal"}) // PicoCLI requires non-final Strings. - @Option( - names = {"--metrics-host"}, - paramLabel = MANDATORY_HOST_FORMAT_HELP, - description = "Host for the metrics exporter to listen on (default: ${DEFAULT-VALUE})", - arity = "1") - private String metricsHost; - - @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; - - @Option( - names = {"--metrics-category", "--metrics-categories"}, - paramLabel = "", - split = ",", - arity = "1..*", - description = - "Comma separated list of categories to track metrics for (default: ${DEFAULT-VALUE})") - private final Set metricCategories = DEFAULT_METRIC_CATEGORIES; - - @Option( - names = {"--metrics-push-enabled"}, - description = "Enable the metrics push gateway integration (default: ${DEFAULT-VALUE})") - private final Boolean isMetricsPushEnabled = false; - - @SuppressWarnings({"FieldCanBeFinal", "FieldMayBeFinal"}) // PicoCLI requires non-final Strings. - @Option( - names = {"--metrics-push-host"}, - paramLabel = MANDATORY_HOST_FORMAT_HELP, - description = - "Host of the Prometheus Push Gateway for push mode (default: ${DEFAULT-VALUE})", - arity = "1") - private String metricsPushHost; - - @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; - - @Option( - names = {"--metrics-push-interval"}, - paramLabel = MANDATORY_INTEGER_FORMAT_HELP, - description = - "Interval in seconds to push metrics when in push mode (default: ${DEFAULT-VALUE})", - arity = "1") - private final Integer metricsPushInterval = 15; - - @SuppressWarnings({"FieldCanBeFinal", "FieldMayBeFinal"}) // PicoCLI requires non-final Strings. - @Option( - names = {"--metrics-push-prometheus-job"}, - description = "Job name to use when in push mode (default: ${DEFAULT-VALUE})", - arity = "1") - private String metricsPrometheusJob = "besu-client"; - } - @Option( names = {"--host-allowlist"}, paramLabel = "[,...]... or * or all", @@ -962,7 +884,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { * @param jsonBlockImporterFactory instance of {@code Function} * @param rlpBlockExporterFactory instance of {@code Function} * @param runnerBuilder instance of RunnerBuilder - * @param controllerBuilderFactory instance of BesuController.Builder + * @param controllerBuilder instance of BesuController.Builder * @param besuPluginContext instance of BesuPluginContextImpl * @param environment Environment variables map */ @@ -972,7 +894,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { final Function jsonBlockImporterFactory, final Function rlpBlockExporterFactory, final RunnerBuilder runnerBuilder, - final BesuController.Builder controllerBuilderFactory, + final BesuController.Builder controllerBuilder, final BesuPluginContextImpl besuPluginContext, final Map environment) { this( @@ -981,7 +903,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { jsonBlockImporterFactory, rlpBlockExporterFactory, runnerBuilder, - controllerBuilderFactory, + controllerBuilder, besuPluginContext, environment, new StorageServiceImpl(), @@ -1003,7 +925,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { * @param jsonBlockImporterFactory instance of {@code Function} * @param rlpBlockExporterFactory instance of {@code Function} * @param runnerBuilder instance of RunnerBuilder - * @param controllerBuilderFactory instance of BesuController.Builder + * @param controllerBuilder instance of BesuController.Builder * @param besuPluginContext instance of BesuPluginContextImpl * @param environment Environment variables map * @param storageService instance of StorageServiceImpl @@ -1023,7 +945,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { final Function jsonBlockImporterFactory, final Function rlpBlockExporterFactory, final RunnerBuilder runnerBuilder, - final BesuController.Builder controllerBuilderFactory, + final BesuController.Builder controllerBuilder, final BesuPluginContextImpl besuPluginContext, final Map environment, final StorageServiceImpl storageService, @@ -1041,7 +963,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { this.rlpBlockExporterFactory = rlpBlockExporterFactory; this.jsonBlockImporterFactory = jsonBlockImporterFactory; this.runnerBuilder = runnerBuilder; - this.controllerBuilderFactory = controllerBuilderFactory; + this.controllerBuilder = controllerBuilder; this.besuPluginContext = besuPluginContext; this.environment = environment; this.storageService = storageService; @@ -1911,7 +1833,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { .withMiningParameters(miningParametersSupplier.get()) .withJsonRpcHttpOptions(jsonRpcHttpOptions); final KeyValueStorageProvider storageProvider = keyValueStorageProvider(keyValueStorageName); - return controllerBuilderFactory + return controllerBuilder .fromEthNetworkConfig(updateNetworkConfig(network), getDefaultSyncModeIfNotSet()) .synchronizerConfiguration(buildSyncConfig()) .ethProtocolConfiguration(unstableEthProtocolOptions.toDomainObject()) @@ -1987,7 +1909,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { * @return instance of MetricsConfiguration. */ public MetricsConfiguration metricsConfiguration() { - if (metricsOptionGroup.isMetricsEnabled && metricsOptionGroup.isMetricsPushEnabled) { + if (metricsOptionGroup.getMetricsEnabled() && metricsOptionGroup.getMetricsPushEnabled()) { throw new ParameterException( this.commandLine, "--metrics-enabled option and --metrics-push-enabled option can't be used at the same " @@ -1998,14 +1920,14 @@ public class BesuCommand implements DefaultCommandValues, Runnable { logger, commandLine, "--metrics-enabled", - !metricsOptionGroup.isMetricsEnabled, + !metricsOptionGroup.getMetricsEnabled(), asList("--metrics-host", "--metrics-port")); CommandLineUtils.checkOptionDependencies( logger, commandLine, "--metrics-push-enabled", - !metricsOptionGroup.isMetricsPushEnabled, + !metricsOptionGroup.getMetricsPushEnabled(), asList( "--metrics-push-host", "--metrics-push-port", @@ -2014,23 +1936,23 @@ public class BesuCommand implements DefaultCommandValues, Runnable { return unstableMetricsCLIOptions .toDomainObject() - .enabled(metricsOptionGroup.isMetricsEnabled) + .enabled(metricsOptionGroup.getMetricsEnabled()) .host( - Strings.isNullOrEmpty(metricsOptionGroup.metricsHost) + Strings.isNullOrEmpty(metricsOptionGroup.getMetricsHost()) ? p2PDiscoveryOptionGroup.autoDiscoverDefaultIP().getHostAddress() - : metricsOptionGroup.metricsHost) - .port(metricsOptionGroup.metricsPort) - .protocol(metricsOptionGroup.metricsProtocol) - .metricCategories(metricsOptionGroup.metricCategories) - .pushEnabled(metricsOptionGroup.isMetricsPushEnabled) + : metricsOptionGroup.getMetricsHost()) + .port(metricsOptionGroup.getMetricsPort()) + .protocol(metricsOptionGroup.getMetricsProtocol()) + .metricCategories(metricsOptionGroup.getMetricCategories()) + .pushEnabled(metricsOptionGroup.getMetricsPushEnabled()) .pushHost( - Strings.isNullOrEmpty(metricsOptionGroup.metricsPushHost) + Strings.isNullOrEmpty(metricsOptionGroup.getMetricsPushHost()) ? p2PDiscoveryOptionGroup.autoDiscoverDefaultIP().getHostAddress() - : metricsOptionGroup.metricsPushHost) - .pushPort(metricsOptionGroup.metricsPushPort) - .pushInterval(metricsOptionGroup.metricsPushInterval) + : metricsOptionGroup.getMetricsPushHost()) + .pushPort(metricsOptionGroup.getMetricsPushPort()) + .pushInterval(metricsOptionGroup.getMetricsPushInterval()) .hostsAllowlist(hostsAllowlist) - .prometheusJob(metricsOptionGroup.metricsPrometheusJob) + .prometheusJob(metricsOptionGroup.getMetricsPrometheusJob()) .build(); } @@ -2662,7 +2584,9 @@ public class BesuCommand implements DefaultCommandValues, Runnable { effectivePorts, rpcWebsocketOptions.getRpcWsPort(), rpcWebsocketOptions.isRpcWsEnabled()); addPortIfEnabled(effectivePorts, engineRPCOptionGroup.engineRpcPort, isEngineApiEnabled()); addPortIfEnabled( - effectivePorts, metricsOptionGroup.metricsPort, metricsOptionGroup.isMetricsEnabled); + effectivePorts, + metricsOptionGroup.getMetricsPort(), + metricsOptionGroup.getMetricsEnabled()); addPortIfEnabled( effectivePorts, miningParametersSupplier.get().getStratumPort(), 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/MetricsOptionGroup.java new file mode 100644 index 0000000000..add2bf1655 --- /dev/null +++ b/besu/src/main/java/org/hyperledger/besu/cli/options/stable/MetricsOptionGroup.java @@ -0,0 +1,197 @@ +/* + * 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.cli.DefaultCommandValues.MANDATORY_HOST_FORMAT_HELP; +import static org.hyperledger.besu.cli.DefaultCommandValues.MANDATORY_INTEGER_FORMAT_HELP; +import static org.hyperledger.besu.cli.DefaultCommandValues.MANDATORY_PORT_FORMAT_HELP; +import static org.hyperledger.besu.metrics.BesuMetricCategory.DEFAULT_METRIC_CATEGORIES; +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.metrics.MetricsProtocol; +import org.hyperledger.besu.plugin.services.metrics.MetricCategory; + +import java.util.Set; + +import picocli.CommandLine; + +/** Command line options for configuring metrics. */ +public class MetricsOptionGroup { + @CommandLine.Option( + names = {"--metrics-enabled"}, + description = "Set to start the metrics exporter (default: ${DEFAULT-VALUE})") + private final Boolean isMetricsEnabled = false; + + @SuppressWarnings({"FieldCanBeFinal", "FieldMayBeFinal"}) // PicoCLI requires non-final Strings. + @CommandLine.Option( + names = {"--metrics-protocol"}, + description = + "Metrics protocol, one of PROMETHEUS, OPENTELEMETRY or NONE. (default: ${DEFAULT-VALUE})") + private MetricsProtocol metricsProtocol = PROMETHEUS; + + @SuppressWarnings({"FieldCanBeFinal", "FieldMayBeFinal"}) // PicoCLI requires non-final Strings. + @CommandLine.Option( + names = {"--metrics-host"}, + paramLabel = MANDATORY_HOST_FORMAT_HELP, + description = "Host for the metrics exporter to listen on (default: ${DEFAULT-VALUE})", + arity = "1") + private String metricsHost; + + @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; + + @CommandLine.Option( + names = {"--metrics-category", "--metrics-categories"}, + paramLabel = "", + split = ",", + arity = "1..*", + description = + "Comma separated list of categories to track metrics for (default: ${DEFAULT-VALUE})") + private final 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; + + @SuppressWarnings({"FieldCanBeFinal", "FieldMayBeFinal"}) // PicoCLI requires non-final Strings. + @CommandLine.Option( + names = {"--metrics-push-host"}, + paramLabel = MANDATORY_HOST_FORMAT_HELP, + description = "Host of the Prometheus Push Gateway for push mode (default: ${DEFAULT-VALUE})", + arity = "1") + private String metricsPushHost; + + @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; + + @CommandLine.Option( + names = {"--metrics-push-interval"}, + paramLabel = MANDATORY_INTEGER_FORMAT_HELP, + description = + "Interval in seconds to push metrics when in push mode (default: ${DEFAULT-VALUE})", + arity = "1") + private final Integer metricsPushInterval = 15; + + @SuppressWarnings({"FieldCanBeFinal", "FieldMayBeFinal"}) // PicoCLI requires non-final Strings. + @CommandLine.Option( + names = {"--metrics-push-prometheus-job"}, + description = "Job name to use when in push mode (default: ${DEFAULT-VALUE})", + arity = "1") + private String metricsPrometheusJob = "besu-client"; + + /** Returns a newly created {@link MetricsOptionGroup} with default values. */ + public MetricsOptionGroup() {} + + /** + * Returns whether metrics are enabled. + * + * @return true if metrics are enabled, otherwise false + */ + public Boolean getMetricsEnabled() { + return isMetricsEnabled; + } + + /** + * Returns the metrics protocol. + * + * @return the metrics protocol + */ + public MetricsProtocol getMetricsProtocol() { + return metricsProtocol; + } + + /** + * Returns the metrics host. + * + * @return the metrics host + */ + public String getMetricsHost() { + return metricsHost; + } + + /** + * Returns the metrics port. + * + * @return the metrics port + */ + public Integer getMetricsPort() { + return metricsPort; + } + + /** + * Returns the metric categories. + * + * @return the metric categories + */ + public Set getMetricCategories() { + return metricCategories; + } + + /** + * Returns whether metrics push is enabled. + * + * @return true if metrics push is enabled, otherwise false + */ + public Boolean getMetricsPushEnabled() { + return isMetricsPushEnabled; + } + + /** + * Returns the metrics push host. + * + * @return the metrics push host + */ + public String getMetricsPushHost() { + return metricsPushHost; + } + + /** + * Returns the metrics push port. + * + * @return the metrics push port + */ + public Integer getMetricsPushPort() { + return metricsPushPort; + } + + /** + * Returns the metrics push interval. + * + * @return the metrics push interval + */ + public Integer getMetricsPushInterval() { + return metricsPushInterval; + } + + /** + * Returns the metrics prometheus job. + * + * @return the metrics prometheus job + */ + public String getMetricsPrometheusJob() { + return metricsPrometheusJob; + } +} From b4869e7b864c83ca54a3c0e0ab5909948df06cd0 Mon Sep 17 00:00:00 2001 From: Sally MacFarlane Date: Thu, 15 Aug 2024 08:23:11 +1000 Subject: [PATCH 117/259] remove vestigial whitelist methods (#7449) * remove vestigial whitelist methods * rename param and method Signed-off-by: Sally MacFarlane --------- Signed-off-by: Sally MacFarlane --- .../besu/ethereum/api/jsonrpc/RpcMethod.java | 2 -- .../PermissioningConfigurationBuilder.java | 27 +++++-------------- ...PermissioningConfigurationBuilderTest.java | 22 --------------- .../permissioning_config_whitelists.toml | 6 ----- 4 files changed, 7 insertions(+), 50 deletions(-) delete mode 100644 ethereum/permissioning/src/test/resources/permissioning_config_whitelists.toml diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcMethod.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcMethod.java index 2c883337d3..63fa5b3ce5 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcMethod.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcMethod.java @@ -177,9 +177,7 @@ public enum RpcMethod { PERM_GET_NODES_WHITELIST("perm_getNodesWhitelist"), PERM_GET_NODES_ALLOWLIST("perm_getNodesAllowlist"), PERM_RELOAD_PERMISSIONS_FROM_FILE("perm_reloadPermissionsFromFile"), - PERM_REMOVE_ACCOUNTS_FROM_WHITELIST("perm_removeAccountsFromWhitelist"), PERM_REMOVE_ACCOUNTS_FROM_ALLOWLIST("perm_removeAccountsFromAllowlist"), - PERM_REMOVE_NODES_FROM_WHITELIST("perm_removeNodesFromWhitelist"), PERM_REMOVE_NODES_FROM_ALLOWLIST("perm_removeNodesFromAllowlist"), RPC_MODULES("rpc_modules"), TRACE_BLOCK("trace_block"), diff --git a/ethereum/permissioning/src/main/java/org/hyperledger/besu/ethereum/permissioning/PermissioningConfigurationBuilder.java b/ethereum/permissioning/src/main/java/org/hyperledger/besu/ethereum/permissioning/PermissioningConfigurationBuilder.java index d9c2ba0e80..b8ba439745 100644 --- a/ethereum/permissioning/src/main/java/org/hyperledger/besu/ethereum/permissioning/PermissioningConfigurationBuilder.java +++ b/ethereum/permissioning/src/main/java/org/hyperledger/besu/ethereum/permissioning/PermissioningConfigurationBuilder.java @@ -27,8 +27,6 @@ import org.apache.tuweni.toml.TomlParseResult; public class PermissioningConfigurationBuilder { - @Deprecated public static final String ACCOUNTS_WHITELIST_KEY = "accounts-whitelist"; - @Deprecated public static final String NODES_WHITELIST_KEY = "nodes-whitelist"; public static final String ACCOUNTS_ALLOWLIST_KEY = "accounts-allowlist"; public static final String NODES_ALLOWLIST_KEY = "nodes-allowlist"; @@ -69,8 +67,7 @@ public class PermissioningConfigurationBuilder { if (localConfigNodePermissioningEnabled) { final TomlParseResult nodePermissioningToml = readToml(nodePermissioningConfigFilepath); - final TomlArray nodeAllowlistTomlArray = - getAllowlistArray(nodePermissioningToml, NODES_ALLOWLIST_KEY, NODES_WHITELIST_KEY); + final TomlArray nodeAllowlistTomlArray = getArray(nodePermissioningToml, NODES_ALLOWLIST_KEY); permissioningConfiguration.setNodePermissioningConfigFilePath( nodePermissioningConfigFilepath); @@ -104,8 +101,7 @@ public class PermissioningConfigurationBuilder { if (localConfigAccountPermissioningEnabled) { final TomlParseResult accountPermissioningToml = readToml(accountPermissioningConfigFilepath); final TomlArray accountAllowlistTomlArray = - getAllowlistArray( - accountPermissioningToml, ACCOUNTS_ALLOWLIST_KEY, ACCOUNTS_WHITELIST_KEY); + getArray(accountPermissioningToml, ACCOUNTS_ALLOWLIST_KEY); permissioningConfiguration.setAccountPermissioningConfigFilePath( accountPermissioningConfigFilepath); @@ -137,23 +133,14 @@ public class PermissioningConfigurationBuilder { } /** - * This method allows support for both keys for now. Whitelist TOML keys will be removed in future - * (breaking change) + * This method retrieves an array from parsed toml, using the given key. * * @param tomlParseResult result of a prior toml parse - * @param primaryKey key to fetch - * @param alternateKey alternate key to fetch - * @return In order: the array of the primaryKey if it exists, or the array of the alternateKey if - * it exists, or null. + * @param key key to fetch + * @return The array matching the key if it exists, or null. */ - private static TomlArray getAllowlistArray( - final TomlParseResult tomlParseResult, final String primaryKey, final String alternateKey) { - final TomlArray array = tomlParseResult.getArray(primaryKey); - if (array == null) { - return tomlParseResult.getArray(alternateKey); - } else { - return array; - } + private static TomlArray getArray(final TomlParseResult tomlParseResult, final String key) { + return tomlParseResult.getArray(key); } private static TomlParseResult readToml(final String filepath) throws Exception { diff --git a/ethereum/permissioning/src/test/java/org/hyperledger/besu/ethereum/permissioning/LocalPermissioningConfigurationBuilderTest.java b/ethereum/permissioning/src/test/java/org/hyperledger/besu/ethereum/permissioning/LocalPermissioningConfigurationBuilderTest.java index c4e965513a..8f2059f935 100644 --- a/ethereum/permissioning/src/test/java/org/hyperledger/besu/ethereum/permissioning/LocalPermissioningConfigurationBuilderTest.java +++ b/ethereum/permissioning/src/test/java/org/hyperledger/besu/ethereum/permissioning/LocalPermissioningConfigurationBuilderTest.java @@ -36,10 +36,6 @@ public class LocalPermissioningConfigurationBuilderTest { private static final String PERMISSIONING_CONFIG_VALID = "/permissioning_config.toml"; - @Deprecated - private static final String PERMISSIONING_CONFIG_VALID_WHITELISTS = - "/permissioning_config_whitelists.toml"; - private static final String PERMISSIONING_CONFIG_ACCOUNT_ALLOWLIST_ONLY = "/permissioning_config_account_allowlist_only.toml"; private static final String PERMISSIONING_CONFIG_NODE_ALLOWLIST_ONLY = @@ -61,24 +57,6 @@ public class LocalPermissioningConfigurationBuilderTest { private final String VALID_NODE_ID = "6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0"; - @Test - public void permissioningConfig_usingDeprecatedKeysIsStillValid() throws Exception { - final String uri = "enode://" + VALID_NODE_ID + "@192.168.0.9:4567"; - final String uri2 = "enode://" + VALID_NODE_ID + "@192.169.0.9:4568"; - - final URL configFile = this.getClass().getResource(PERMISSIONING_CONFIG_VALID_WHITELISTS); - final Path toml = createTempFile("toml", Resources.toByteArray(configFile)); - - LocalPermissioningConfiguration permissioningConfiguration = permissioningConfig(toml); - - assertThat(permissioningConfiguration.isAccountAllowlistEnabled()).isTrue(); - assertThat(permissioningConfiguration.getAccountAllowlist()) - .containsExactly("0x0000000000000000000000000000000000000009"); - assertThat(permissioningConfiguration.isNodeAllowlistEnabled()).isTrue(); - assertThat(permissioningConfiguration.getNodeAllowlist()) - .containsExactly(EnodeURLImpl.fromString(uri), EnodeURLImpl.fromString(uri2)); - } - @Test public void permissioningConfig() throws Exception { final String uri = "enode://" + VALID_NODE_ID + "@192.168.0.9:4567"; diff --git a/ethereum/permissioning/src/test/resources/permissioning_config_whitelists.toml b/ethereum/permissioning/src/test/resources/permissioning_config_whitelists.toml deleted file mode 100644 index 9c1cfd9e47..0000000000 --- a/ethereum/permissioning/src/test/resources/permissioning_config_whitelists.toml +++ /dev/null @@ -1,6 +0,0 @@ -# Permissioning TOML file -# NOTE whitelist is being deprecated in favor of allowlist -# support for whitelist will be removed in future - -accounts-whitelist=["0x0000000000000000000000000000000000000009"] -nodes-whitelist=["enode://6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@192.168.0.9:4567","enode://6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@192.169.0.9:4568"] From 137515de44b64597ccd7f2462230f5d2e3e86360 Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Thu, 15 Aug 2024 15:39:30 +1000 Subject: [PATCH 118/259] 5098 branch 16 update invalid enode and excess blob gas params (#7457) * 5098: Add RpcErrorTypes Signed-off-by: Matilda Clerke * 5098: Modify InvalidJsonRpcParameters and InvalidJsonRpcRequestException, apply spotless Signed-off-by: Matilda Clerke * 5098: Modify InvalidJsonRpcParameters and InvalidJsonRpcRequestException, apply spotless Signed-off-by: Matilda Clerke * 5098: Add JsonRpcParameterException for later use Signed-off-by: Matilda Clerke * 5098: Update locations for RpcErrorType.INVALID_ACCOUNTS_PARAMS Signed-off-by: Matilda Clerke * 5098: Address review comments, apply spotless Signed-off-by: Matilda Clerke * 5098: Update with changes from branch 1 Signed-off-by: Matilda Clerke * 5098: Update code to use RpcErrorType.INVALID_ADDRESS_HASH_PARAMS Signed-off-by: Matilda Clerke * 5098: apply spotless Signed-off-by: Matilda Clerke * 5098: apply spotless Signed-off-by: Matilda Clerke * 5098: Update plugin-api gradle hash Signed-off-by: Matilda Clerke * 5098: Add comment on INVALID_PARAMS_ERROR_CODE Signed-off-by: Matilda Clerke * 5098: Apply spotless on latest changes Signed-off-by: Matilda Clerke * 5098: Update code to use RpcErrorType.INVALID_ADDRESS_PARAMS Signed-off-by: Matilda Clerke * 5098: Fix broken unit test Signed-off-by: Matilda Clerke * 5098: Fix broken unit test Signed-off-by: Matilda Clerke * 5098: Update with usage of RpcErrorType.INVALID_AUTH_PARAMS Signed-off-by: Matilda Clerke * 5098: Update with usage of RpcErrorType.INVALID_BLOB_COUNT Signed-off-by: Matilda Clerke * 5098: Update with usage of RpcErrorType.INVALID_BLOB_GAS_USED_PARAMS Signed-off-by: Matilda Clerke * 5098: Update with usage of RpcErrorType.INVALID_BLOCK_PARAMS Signed-off-by: Matilda Clerke * 5098: Update with usage of RpcErrorType.INVALID_BLOCK_PARAMS Signed-off-by: Matilda Clerke * 5098: Update with usage of RpcErrorType.INVALID_BLOCK_PARAMS Signed-off-by: Matilda Clerke * 5098: Update with usage of RpcErrorType.INVALID_BLOCK_COUNT_PARAMS Signed-off-by: Matilda Clerke * 5098: Fix broken integration test Signed-off-by: Matilda Clerke * 5098: Add index to exception messages Signed-off-by: Matilda Clerke * 5098: apoply spotless Signed-off-by: Matilda Clerke * 5098: Update BaseJsonRpcProcessor to utilise RpcErrorType from InvalidJsonRpcParameters Signed-off-by: Matilda Clerke * 5098: Include parameter index in INVALID_AUTH_PARAMS Signed-off-by: Matilda Clerke * 5098: Include parameter index in INVALID_BLOCK_PARAMS Signed-off-by: Matilda Clerke * 5098: Include parameter index in INVALID_BLOCK_COUNT_PARAMS Signed-off-by: Matilda Clerke * 5098: Fix broken integration test Signed-off-by: Matilda Clerke * 5098: Rename INVALID_AUTH_PARAMS to INVALID_PROPOSAL_PARAMS Signed-off-by: Matilda Clerke * 5098: apply spotless Signed-off-by: Matilda Clerke * 5098: Update INVALID_BLOCK_HASH_PARAMS locations Signed-off-by: Matilda Clerke * 5098: Fix broken unit test Signed-off-by: Matilda Clerke * 5098: apply spotless Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_BLOCK_INDEX Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_BLOCK_NUMBER Signed-off-by: Matilda Clerke * 5098: apply spotless Signed-off-by: Matilda Clerke * 5098: Fix broken tests Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_CALL_PARAMS Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_CONSOLIDATION_REQUEST_PARAMS Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_CREATE_PRIVACY_GROUP_PARAMS Signed-off-by: Matilda Clerke * 5098: Fix broken test Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_DATA_PARAMS Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_DEPOSIT_REQUEST_PARAMS Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_ENGINE_EXCHANGE_TRANSITION_CONFIGURATION_PARAMS Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_ENGINE_FORKCHOICE_UPDATED_PARAMS Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_ENGINE_PAYLOAD_ATTRIBUTES_PARAMS Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_ENGINE_PAYLOAD_PARAMS Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_ENGINE_PREPARE_PAYLOAD_PARAMS Signed-off-by: Matilda Clerke * 5098: Apply spotless Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_ENODE_PARAMS Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_EXCESS_BLOB_GAS_PARAMS Signed-off-by: Matilda Clerke * 5098: Apply spotless Signed-off-by: Matilda Clerke --------- Signed-off-by: Matilda Clerke Signed-off-by: Matilda-Clerke Co-authored-by: Sally MacFarlane --- .../api/jsonrpc/internal/methods/AdminModifyPeer.java | 7 +++---- .../methods/engine/AbstractEngineNewPayload.java | 2 +- .../internal/methods/engine/EngineNewPayloadV2.java | 2 +- .../internal/methods/engine/EngineNewPayloadV3.java | 3 ++- .../internal/methods/engine/EngineNewPayloadV4.java | 2 +- .../methods/permissioning/PermAddNodesToAllowlist.java | 10 ++++++++-- .../permissioning/PermRemoveNodesFromAllowlist.java | 10 ++++++++-- .../methods/engine/EngineNewPayloadV2Test.java | 2 +- .../methods/engine/EngineNewPayloadV3Test.java | 2 +- 9 files changed, 26 insertions(+), 14 deletions(-) diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminModifyPeer.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminModifyPeer.java index 7ad3c9286b..4f50ad180d 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminModifyPeer.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminModifyPeer.java @@ -15,7 +15,6 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; 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.RpcErrorType; @@ -45,9 +44,6 @@ public abstract class AdminModifyPeer implements JsonRpcMethod { try { final String enodeString = requestContext.getRequiredParameter(0, String.class); return performOperation(requestContext.getRequest().getId(), enodeString); - } catch (final InvalidJsonRpcParameters e) { - return new JsonRpcErrorResponse( - requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAMS); } catch (final IllegalArgumentException e) { if (e.getMessage() .endsWith( @@ -69,6 +65,9 @@ public abstract class AdminModifyPeer implements JsonRpcMethod { } catch (final P2PDisabledException e) { return new JsonRpcErrorResponse( requestContext.getRequest().getId(), RpcErrorType.P2P_DISABLED); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + return new JsonRpcErrorResponse( + requestContext.getRequest().getId(), RpcErrorType.INVALID_ENODE_PARAMS); } } 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 5d0d379d81..0588121516 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 @@ -494,7 +494,7 @@ public abstract class AbstractEngineNewPayload extends ExecutionEngineJsonRpcMet if (maybeParentHeader.isPresent()) { if (!validateExcessBlobGas(header, maybeParentHeader.get(), protocolSpec)) { return ValidationResult.invalid( - RpcErrorType.INVALID_PARAMS, + RpcErrorType.INVALID_EXCESS_BLOB_GAS_PARAMS, "Payload excessBlobGas does not match calculated excessBlobGas"); } } 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 ba7624a493..fa15891750 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 @@ -64,7 +64,7 @@ public class EngineNewPayloadV2 extends AbstractEngineNewPayload { } if (payloadParameter.getExcessBlobGas() != null) { return ValidationResult.invalid( - RpcErrorType.INVALID_PARAMS, "non-null ExcessBlobGas pre-cancun"); + RpcErrorType.INVALID_EXCESS_BLOB_GAS_PARAMS, "Missing excess blob gas field"); } return ValidationResult.valid(); } 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 c6bfb638c8..b946df40bd 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 @@ -60,7 +60,8 @@ public class EngineNewPayloadV3 extends AbstractEngineNewPayload { return ValidationResult.invalid( RpcErrorType.INVALID_BLOB_GAS_USED_PARAMS, "Missing blob gas used field"); } else if (payloadParameter.getExcessBlobGas() == null) { - return ValidationResult.invalid(RpcErrorType.INVALID_PARAMS, "Missing blob gas fields"); + return ValidationResult.invalid( + RpcErrorType.INVALID_EXCESS_BLOB_GAS_PARAMS, "Missing excess blob gas field"); } else if (maybeVersionedHashParam == null || maybeVersionedHashParam.isEmpty()) { return ValidationResult.invalid( RpcErrorType.INVALID_PARAMS, "Missing versioned hashes 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 09354fa1ba..b87eceed5d 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 @@ -61,7 +61,7 @@ public class EngineNewPayloadV4 extends AbstractEngineNewPayload { RpcErrorType.INVALID_BLOB_GAS_USED_PARAMS, "Missing blob gas used field"); } else if (payloadParameter.getExcessBlobGas() == null) { return ValidationResult.invalid( - RpcErrorType.INVALID_PARAMS, "non-null ExcessBlobGas pre-cancun"); + RpcErrorType.INVALID_EXCESS_BLOB_GAS_PARAMS, "Missing excess blob gas field"); } else if (maybeVersionedHashParam == null || maybeVersionedHashParam.isEmpty()) { return ValidationResult.invalid( RpcErrorType.INVALID_PARAMS, "Missing versioned hashes field"); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermAddNodesToAllowlist.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermAddNodesToAllowlist.java index 9659f5a776..2aec3b6f95 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermAddNodesToAllowlist.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermAddNodesToAllowlist.java @@ -16,6 +16,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.permissioning import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.StringListParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; @@ -46,8 +47,13 @@ public class PermAddNodesToAllowlist implements JsonRpcMethod { @Override public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { - final StringListParameter enodeListParam = - requestContext.getRequiredParameter(0, StringListParameter.class); + final StringListParameter enodeListParam; + try { + enodeListParam = requestContext.getRequiredParameter(0, StringListParameter.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid enode list parameter (index 0)", RpcErrorType.INVALID_ENODE_PARAMS, e); + } try { if (nodeAllowlistPermissioningController.isPresent()) { diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermRemoveNodesFromAllowlist.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermRemoveNodesFromAllowlist.java index 876376fab1..862b694f4f 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermRemoveNodesFromAllowlist.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermRemoveNodesFromAllowlist.java @@ -16,6 +16,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.permissioning import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.StringListParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; @@ -46,8 +47,13 @@ public class PermRemoveNodesFromAllowlist implements JsonRpcMethod { @Override public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { - final StringListParameter enodeListParam = - requestContext.getRequiredParameter(0, StringListParameter.class); + final StringListParameter enodeListParam; + try { + enodeListParam = requestContext.getRequiredParameter(0, StringListParameter.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid enode list parameter (index 0)", RpcErrorType.INVALID_ENODE_PARAMS, e); + } try { if (nodeAllowlistPermissioningController.isPresent()) { try { 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 4d53d83cf8..4e68cca76c 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 @@ -170,7 +170,7 @@ public class EngineNewPayloadV2Test extends AbstractEngineNewPayloadTest { final JsonRpcError jsonRpcError = fromErrorResp(resp); assertThat(jsonRpcError.getCode()).isEqualTo(INVALID_PARAMS.getCode()); - assertThat(jsonRpcError.getData()).isEqualTo("non-null ExcessBlobGas pre-cancun"); + assertThat(jsonRpcError.getData()).isEqualTo("Missing excess blob gas field"); verify(engineCallListener, times(1)).executionEngineCalled(); } 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 72f0108a69..d8cf86758f 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 @@ -219,7 +219,7 @@ public class EngineNewPayloadV3Test extends EngineNewPayloadV2Test { final JsonRpcError jsonRpcError = fromErrorResp(resp); assertThat(jsonRpcError.getCode()).isEqualTo(INVALID_PARAMS.getCode()); - assertThat(jsonRpcError.getData()).isEqualTo("Missing blob gas fields"); + assertThat(jsonRpcError.getData()).isEqualTo("Missing excess blob gas field"); verify(engineCallListener, times(1)).executionEngineCalled(); } From f5d6e7237cad4a1a0f5bc3b74a03fc961aaf6aed Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Thu, 15 Aug 2024 20:31:06 +1000 Subject: [PATCH 119/259] 5098 branch 17 update extra data and filter params (#7458) * 5098: Add RpcErrorTypes Signed-off-by: Matilda Clerke --------- Signed-off-by: Matilda Clerke Signed-off-by: Matilda-Clerke Co-authored-by: Sally MacFarlane --- .../internal/methods/EthGetFilterChanges.java | 9 ++++++++- .../internal/methods/EthGetFilterLogs.java | 9 ++++++++- .../jsonrpc/internal/methods/EthGetLogs.java | 10 ++++++++-- .../internal/methods/EthNewFilter.java | 11 ++++++++-- .../internal/methods/EthUninstallFilter.java | 10 +++++++++- .../jsonrpc/internal/methods/TraceFilter.java | 10 ++++++++-- .../methods/miner/MinerSetExtraData.java | 6 ++++-- .../parameters/PendingTransactionsParams.java | 17 +++++++++++----- .../privacy/methods/PrivGetFilterChanges.java | 9 ++++++++- .../privacy/methods/PrivGetFilterLogs.java | 9 ++++++++- .../privacy/methods/PrivUninstallFilter.java | 10 +++++++++- .../privacy/methods/priv/PrivGetLogs.java | 11 ++++++++-- .../privacy/methods/priv/PrivNewFilter.java | 12 +++++++++-- .../request/SubscriptionRequestMapper.java | 20 ++++++++++++++++--- .../methods/EthGetFilterChangesTest.java | 5 ++--- .../methods/EthGetFilterLogsTest.java | 4 ++-- .../internal/methods/EthGetLogsTest.java | 2 +- .../internal/methods/EthNewFilterTest.java | 2 +- .../methods/miner/MinerSetExtraDataTest.java | 4 ++-- .../priv/PrivGetFilterChangesTest.java | 2 +- .../methods/priv/PrivGetFilterLogsTest.java | 2 +- .../privacy/methods/priv/PrivGetLogsTest.java | 4 ++-- .../methods/priv/PrivNewFilterTest.java | 4 ++-- .../methods/priv/PrivUninstallFilterTest.java | 2 +- .../SubscriptionRequestMapperTest.java | 4 ++-- .../jsonrpc/eth/eth_getLogs_invalidInput.json | 2 +- .../eth/eth_getNewFilter_invalidFilter.json | 2 +- 27 files changed, 146 insertions(+), 46 deletions(-) diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetFilterChanges.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetFilterChanges.java index fa9031efe5..0773651b61 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetFilterChanges.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetFilterChanges.java @@ -17,6 +17,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.filter.FilterManager; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; @@ -43,7 +44,13 @@ public class EthGetFilterChanges implements JsonRpcMethod { @Override public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { - final String filterId = requestContext.getRequiredParameter(0, String.class); + final String filterId; + try { + filterId = requestContext.getRequiredParameter(0, String.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid filter ID parameter (index 0)", RpcErrorType.INVALID_FILTER_PARAMS, e); + } final List blockHashes = filterManager.blockChanges(filterId); if (blockHashes != null) { diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetFilterLogs.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetFilterLogs.java index 2e928c3b54..b66b7963e1 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetFilterLogs.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetFilterLogs.java @@ -16,6 +16,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.filter.FilterManager; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; @@ -41,7 +42,13 @@ public class EthGetFilterLogs implements JsonRpcMethod { @Override public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { - final String filterId = requestContext.getRequiredParameter(0, String.class); + final String filterId; + try { + filterId = requestContext.getRequiredParameter(0, String.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid filter ID parameter (index 0)", RpcErrorType.INVALID_FILTER_PARAMS, e); + } final List logs = filterManager.logs(filterId); if (logs != null) { diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetLogs.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetLogs.java index 60f38fb7ac..c9645d53e0 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetLogs.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetLogs.java @@ -52,12 +52,18 @@ public class EthGetLogs implements JsonRpcMethod { @Override public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { - final FilterParameter filter = requestContext.getRequiredParameter(0, FilterParameter.class); + final FilterParameter filter; + try { + filter = requestContext.getRequiredParameter(0, FilterParameter.class); + } catch (Exception e) { + throw new InvalidJsonRpcParameters( + "Invalid filter parameter (index 0)", RpcErrorType.INVALID_FILTER_PARAMS, e); + } LOG.atTrace().setMessage("eth_getLogs FilterParameter: {}").addArgument(filter).log(); if (!filter.isValid()) { return new JsonRpcErrorResponse( - requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + requestContext.getRequest().getId(), RpcErrorType.INVALID_FILTER_PARAMS); } final AtomicReference ex = new AtomicReference<>(); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthNewFilter.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthNewFilter.java index e2e4576d43..7578b43a2e 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthNewFilter.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthNewFilter.java @@ -16,6 +16,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.filter.FilterManager; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.FilterParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; @@ -38,11 +39,17 @@ public class EthNewFilter implements JsonRpcMethod { @Override public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { - final FilterParameter filter = requestContext.getRequiredParameter(0, FilterParameter.class); + final FilterParameter filter; + try { + filter = requestContext.getRequiredParameter(0, FilterParameter.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid filter paramters (index 0)", RpcErrorType.INVALID_FILTER_PARAMS, e); + } if (!filter.isValid()) { return new JsonRpcErrorResponse( - requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + requestContext.getRequest().getId(), RpcErrorType.INVALID_FILTER_PARAMS); } final String logFilterId = diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthUninstallFilter.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthUninstallFilter.java index ede4f105d0..b51dc1f4fd 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthUninstallFilter.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthUninstallFilter.java @@ -16,9 +16,11 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.filter.FilterManager; 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.api.jsonrpc.internal.response.RpcErrorType; public class EthUninstallFilter implements JsonRpcMethod { @@ -35,7 +37,13 @@ public class EthUninstallFilter implements JsonRpcMethod { @Override public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { - final String filterId = requestContext.getRequiredParameter(0, String.class); + final String filterId; + try { + filterId = requestContext.getRequiredParameter(0, String.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid filter ID parameter (index 0)", RpcErrorType.INVALID_FILTER_PARAMS, e); + } return new JsonRpcSuccessResponse( requestContext.getRequest().getId(), filterManager.uninstallFilter(filterId)); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceFilter.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceFilter.java index 1b04ee1d52..a3d6b2561f 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceFilter.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceFilter.java @@ -19,6 +19,7 @@ import static org.hyperledger.besu.services.pipeline.PipelineBuilder.createPipel import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.FilterParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.BlockTracer; @@ -86,8 +87,13 @@ public class TraceFilter extends TraceBlock { @Override public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { - final FilterParameter filterParameter = - requestContext.getRequiredParameter(0, FilterParameter.class); + final FilterParameter filterParameter; + try { + filterParameter = requestContext.getRequiredParameter(0, FilterParameter.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid filter parameter (index 0)", RpcErrorType.INVALID_FILTER_PARAMS, e); + } final long fromBlock = resolveBlockNumber(filterParameter.getFromBlock()); final long toBlock = resolveBlockNumber(filterParameter.getToBlock()); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetExtraData.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetExtraData.java index f82d30684a..5b9bc581db 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetExtraData.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetExtraData.java @@ -60,10 +60,12 @@ public class MinerSetExtraData implements JsonRpcMethod { .addArgument(() -> new String(extraData.toArray(), StandardCharsets.UTF_8)) .log(); return new JsonRpcSuccessResponse(requestContext.getRequest().getId(), true); - } catch (final IllegalArgumentException invalidJsonRpcParameters) { + } catch (Exception invalidJsonRpcParameters) { // TODO:replace with "IllegalArgumentException | + // JsonRpcParameter.JsonRpcParameterException" return new JsonRpcErrorResponse( requestContext.getRequest().getId(), - new JsonRpcError(RpcErrorType.INVALID_PARAMS, invalidJsonRpcParameters.getMessage())); + new JsonRpcError( + RpcErrorType.INVALID_EXTRA_DATA_PARAMS, invalidJsonRpcParameters.getMessage())); } } } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/PendingTransactionsParams.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/PendingTransactionsParams.java index 1bfe0e09ae..dd2684e827 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/PendingTransactionsParams.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/PendingTransactionsParams.java @@ -24,6 +24,7 @@ import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.transac import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.transaction.pool.Predicate.EQ; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.transaction.pool.PendingTransactionFilter.Filter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.transaction.pool.Predicate; @@ -79,7 +80,8 @@ public class PendingTransactionsParams { private Optional getFilter(final String key, final Map map) { if (map != null) { if (map.size() > 1) { - throw new InvalidJsonRpcParameters("Only one operator per filter type allowed"); + throw new InvalidJsonRpcParameters( + "Only one operator per filter type allowed", RpcErrorType.INVALID_FILTER_PARAMS); } else if (!map.isEmpty()) { final Map.Entry foundEntry = map.entrySet().stream().findFirst().get(); final Predicate predicate = @@ -87,17 +89,22 @@ public class PendingTransactionsParams { .orElseThrow( () -> new InvalidJsonRpcParameters( - "Unknown field expected one of `eq`, `gt`, `lt`, `action`")); + "Unknown field expected one of `eq`, `gt`, `lt`, `action`", + RpcErrorType.INVALID_FILTER_PARAMS)); final Filter filter = new Filter(key, foundEntry.getValue(), predicate); if (key.equals(FROM_FIELD) && !predicate.equals(EQ)) { - throw new InvalidJsonRpcParameters("The `from` filter only supports the `eq` operator"); + throw new InvalidJsonRpcParameters( + "The `from` filter only supports the `eq` operator", + RpcErrorType.INVALID_FILTER_PARAMS); } else if (key.equals(TO_FIELD) && !predicate.equals(EQ) && !predicate.equals(ACTION)) { throw new InvalidJsonRpcParameters( - "The `to` filter only supports the `eq` or `action` operator"); + "The `to` filter only supports the `eq` or `action` operator", + RpcErrorType.INVALID_FILTER_PARAMS); } else if (!key.equals(TO_FIELD) && predicate.equals(ACTION)) { throw new InvalidJsonRpcParameters( - "The operator `action` is only supported by the `to` filter"); + "The operator `action` is only supported by the `to` filter", + RpcErrorType.INVALID_FILTER_PARAMS); } return Optional.of(filter); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivGetFilterChanges.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivGetFilterChanges.java index 57b13cc423..7b9a8d1478 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivGetFilterChanges.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivGetFilterChanges.java @@ -16,6 +16,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.filter.FilterManager; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; @@ -52,7 +53,13 @@ public class PrivGetFilterChanges implements JsonRpcMethod { @Override public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { final String privacyGroupId = requestContext.getRequiredParameter(0, String.class); - final String filterId = requestContext.getRequiredParameter(1, String.class); + final String filterId; + try { + filterId = requestContext.getRequiredParameter(1, String.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid filter ID parameter (index 1)", RpcErrorType.INVALID_FILTER_PARAMS, e); + } if (privacyController instanceof MultiTenancyPrivacyController) { checkIfPrivacyGroupMatchesAuthenticatedPrivacyUserId(requestContext, privacyGroupId); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivGetFilterLogs.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivGetFilterLogs.java index c687d66a1a..0e564772c0 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivGetFilterLogs.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivGetFilterLogs.java @@ -16,6 +16,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.filter.FilterManager; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; @@ -52,7 +53,13 @@ public class PrivGetFilterLogs implements JsonRpcMethod { @Override public JsonRpcResponse response(final JsonRpcRequestContext request) { final String privacyGroupId = request.getRequiredParameter(0, String.class); - final String filterId = request.getRequiredParameter(1, String.class); + final String filterId; + try { + filterId = request.getRequiredParameter(1, String.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid filter ID parameter (index 1)", RpcErrorType.INVALID_FILTER_PARAMS, e); + } if (privacyController instanceof MultiTenancyPrivacyController) { checkIfPrivacyGroupMatchesAuthenticatedPrivacyUserId(request, privacyGroupId); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivUninstallFilter.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivUninstallFilter.java index 1683c9511c..738c0b19cf 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivUninstallFilter.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivUninstallFilter.java @@ -16,10 +16,12 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.filter.FilterManager; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; 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.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.privacy.MultiTenancyPrivacyController; import org.hyperledger.besu.ethereum.privacy.PrivacyController; @@ -46,7 +48,13 @@ public class PrivUninstallFilter implements JsonRpcMethod { @Override public JsonRpcResponse response(final JsonRpcRequestContext request) { final String privacyGroupId = request.getRequiredParameter(0, String.class); - final String filterId = request.getRequiredParameter(1, String.class); + final String filterId; + try { + filterId = request.getRequiredParameter(1, String.class); + } catch (Exception e) { + throw new InvalidJsonRpcParameters( + "Invalid filter ID paramter (index 1)", RpcErrorType.INVALID_FILTER_PARAMS, e); + } if (privacyController instanceof MultiTenancyPrivacyController) { checkIfPrivacyGroupMatchesAuthenticatedEnclaveKey(request, privacyGroupId); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetLogs.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetLogs.java index 5e89386cda..abb6411b00 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetLogs.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetLogs.java @@ -17,6 +17,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.FilterParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.PrivacyIdProvider; @@ -62,11 +63,17 @@ public class PrivGetLogs implements JsonRpcMethod { @Override public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { final String privacyGroupId = requestContext.getRequiredParameter(0, String.class); - final FilterParameter filter = requestContext.getRequiredParameter(1, FilterParameter.class); + final FilterParameter filter; + try { + filter = requestContext.getRequiredParameter(1, FilterParameter.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid filter parameter (index 1)", RpcErrorType.INVALID_FILTER_PARAMS, e); + } if (!filter.isValid()) { return new JsonRpcErrorResponse( - requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + requestContext.getRequest().getId(), RpcErrorType.INVALID_FILTER_PARAMS); } final List matchingLogs = diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivNewFilter.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivNewFilter.java index 830e7e7e93..f9a080c72f 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivNewFilter.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivNewFilter.java @@ -16,6 +16,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.filter.FilterManager; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.FilterParameter; @@ -50,7 +51,13 @@ public class PrivNewFilter implements JsonRpcMethod { @Override public JsonRpcResponse response(final JsonRpcRequestContext request) { final String privacyGroupId = request.getRequiredParameter(0, String.class); - final FilterParameter filter = request.getRequiredParameter(1, FilterParameter.class); + final FilterParameter filter; + try { + filter = request.getRequiredParameter(1, FilterParameter.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid filter parameter (index 1)", RpcErrorType.INVALID_FILTER_PARAMS, e); + } final String privacyUserId = privacyIdProvider.getPrivacyUserId(request.getUser()); if (privacyController instanceof MultiTenancyPrivacyController) { @@ -60,7 +67,8 @@ public class PrivNewFilter implements JsonRpcMethod { } if (!filter.isValid()) { - return new JsonRpcErrorResponse(request.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + return new JsonRpcErrorResponse( + request.getRequest().getId(), RpcErrorType.INVALID_FILTER_PARAMS); } final String logFilterId = diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/subscription/request/SubscriptionRequestMapper.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/subscription/request/SubscriptionRequestMapper.java index b3e76fead8..d9099e697d 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/subscription/request/SubscriptionRequestMapper.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/subscription/request/SubscriptionRequestMapper.java @@ -15,8 +15,10 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.websocket.subscription.request; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.FilterParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.UnsignedLongParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.websocket.methods.WebSocketRpcRequest; import java.util.Optional; @@ -70,7 +72,13 @@ public class SubscriptionRequestMapper { } private SubscribeRequest parseLogsRequest(final WebSocketRpcRequest request) { - final FilterParameter filterParameter = request.getRequiredParameter(1, FilterParameter.class); + final FilterParameter filterParameter; + try { + filterParameter = request.getRequiredParameter(1, FilterParameter.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid filter parameters (index 1)", RpcErrorType.INVALID_FILTER_PARAMS, e); + } return new SubscribeRequest( SubscriptionType.LOGS, filterParameter, null, request.getConnectionId()); } @@ -101,8 +109,14 @@ public class SubscriptionRequestMapper { switch (subscriptionType) { case LOGS: { - final FilterParameter filterParameter = - jsonRpcRequestContext.getRequiredParameter(2, FilterParameter.class); + final FilterParameter filterParameter; + try { + filterParameter = + jsonRpcRequestContext.getRequiredParameter(2, FilterParameter.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid filter parameter (index 2)", RpcErrorType.INVALID_FILTER_PARAMS, e); + } return new PrivateSubscribeRequest( SubscriptionType.LOGS, filterParameter, diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetFilterChangesTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetFilterChangesTest.java index 7bf8e1a9dd..584702d746 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetFilterChangesTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetFilterChangesTest.java @@ -69,9 +69,8 @@ public class EthGetFilterChangesTest { final Throwable thrown = catchThrowable(() -> method.response(request)); assertThat(thrown) - .hasNoCause() .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage("Missing required json rpc parameter at index 0"); + .hasMessage("Invalid filter ID parameter (index 0)"); verifyNoInteractions(filterManager); } @@ -83,7 +82,7 @@ public class EthGetFilterChangesTest { final Throwable thrown = catchThrowable(() -> method.response(request)); assertThat(thrown) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage("Missing required json rpc parameter at index 0"); + .hasMessage("Invalid filter ID parameter (index 0)"); verifyNoInteractions(filterManager); } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetFilterLogsTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetFilterLogsTest.java index ee9723c667..c7b4ae8507 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetFilterLogsTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetFilterLogsTest.java @@ -70,7 +70,7 @@ public class EthGetFilterLogsTest { final Throwable thrown = catchThrowable(() -> method.response(request)); assertThat(thrown) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage("Missing required json rpc parameter at index 0"); + .hasMessage("Invalid filter ID parameter (index 0)"); verifyNoInteractions(filterManager); } @@ -82,7 +82,7 @@ public class EthGetFilterLogsTest { final Throwable thrown = catchThrowable(() -> method.response(request)); assertThat(thrown) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage("Missing required json rpc parameter at index 0"); + .hasMessage("Invalid filter ID parameter (index 0)"); verifyNoInteractions(filterManager); } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetLogsTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetLogsTest.java index 5af104335d..93cb216011 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetLogsTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetLogsTest.java @@ -73,7 +73,7 @@ public class EthGetLogsTest { final Throwable thrown = catchThrowable(() -> method.response(request)); assertThat(thrown) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage("Missing required json rpc parameter at index 0"); + .hasMessage("Invalid filter parameter (index 0)"); verifyNoInteractions(blockchainQueries); } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthNewFilterTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthNewFilterTest.java index edaf60d765..c6ae2dc101 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthNewFilterTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthNewFilterTest.java @@ -182,7 +182,7 @@ public class EthNewFilterTest { final JsonRpcRequestContext request = ethNewFilter(invalidFilter); final JsonRpcResponse expectedResponse = - new JsonRpcErrorResponse(null, RpcErrorType.INVALID_PARAMS); + new JsonRpcErrorResponse(null, RpcErrorType.INVALID_FILTER_PARAMS); final JsonRpcResponse response = method.response(request); diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetExtraDataTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetExtraDataTest.java index ad44c69043..b3c7b45d07 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetExtraDataTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetExtraDataTest.java @@ -83,7 +83,7 @@ public class MinerSetExtraDataTest { new JsonRpcErrorResponse( request.getRequest().getId(), new JsonRpcError( - RpcErrorType.INVALID_PARAMS, + RpcErrorType.INVALID_EXTRA_DATA_PARAMS, "Illegal character 'n' found at index 0 in hex binary representation")); final JsonRpcResponse actual = method.response(request); @@ -100,7 +100,7 @@ public class MinerSetExtraDataTest { new JsonRpcErrorResponse( request.getRequest().getId(), new JsonRpcError( - RpcErrorType.INVALID_PARAMS, + RpcErrorType.INVALID_EXTRA_DATA_PARAMS, "Hex value is too large: expected at most 32 bytes but got 37")); final JsonRpcResponse actual = method.response(request); diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetFilterChangesTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetFilterChangesTest.java index 5d4d381c1e..cf89a4bbca 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetFilterChangesTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetFilterChangesTest.java @@ -107,7 +107,7 @@ public class PrivGetFilterChangesTest { assertThatThrownBy(() -> method.response(request)) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Missing required json rpc parameter at index 1"); + .hasMessageContaining("Invalid filter ID parameter (index 1)"); } @Test diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetFilterLogsTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetFilterLogsTest.java index 1bd983ffd7..1c5be87572 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetFilterLogsTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetFilterLogsTest.java @@ -84,7 +84,7 @@ public class PrivGetFilterLogsTest { assertThatThrownBy(() -> method.response(request)) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Missing required json rpc parameter at index 1"); + .hasMessageContaining("Invalid filter ID parameter (index 1)"); } @Test diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetLogsTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetLogsTest.java index 09eb8b0089..d06b47ee10 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetLogsTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetLogsTest.java @@ -96,7 +96,7 @@ public class PrivGetLogsTest { assertThatThrownBy(() -> method.response(request)) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Missing required json rpc parameter at index 1"); + .hasMessageContaining("Invalid filter parameter (index 1)"); } @Test @@ -116,7 +116,7 @@ public class PrivGetLogsTest { final JsonRpcRequestContext request = privGetLogRequest(PRIVACY_GROUP_ID, invalidFilter); final JsonRpcResponse expectedResponse = - new JsonRpcErrorResponse(null, RpcErrorType.INVALID_PARAMS); + new JsonRpcErrorResponse(null, RpcErrorType.INVALID_FILTER_PARAMS); final JsonRpcResponse response = method.response(request); diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivNewFilterTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivNewFilterTest.java index f9e9795f1c..696e3333ca 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivNewFilterTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivNewFilterTest.java @@ -87,7 +87,7 @@ public class PrivNewFilterTest { assertThatThrownBy(() -> method.response(request)) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Missing required json rpc parameter at index 1"); + .hasMessageContaining("Invalid filter parameter (index 1)"); } @Test @@ -107,7 +107,7 @@ public class PrivNewFilterTest { final JsonRpcRequestContext request = privNewFilterRequest(PRIVACY_GROUP_ID, invalidFilter); final JsonRpcResponse expectedResponse = - new JsonRpcErrorResponse(null, RpcErrorType.INVALID_PARAMS); + new JsonRpcErrorResponse(null, RpcErrorType.INVALID_FILTER_PARAMS); final JsonRpcResponse response = method.response(request); diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivUninstallFilterTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivUninstallFilterTest.java index a0e28aab16..9a60d60d72 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivUninstallFilterTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivUninstallFilterTest.java @@ -70,7 +70,7 @@ public class PrivUninstallFilterTest { assertThatThrownBy(() -> method.response(request)) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Missing required json rpc parameter at index 1"); + .hasMessageContaining("Invalid filter ID paramter (index 1)"); } @Test diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/subscription/request/SubscriptionRequestMapperTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/subscription/request/SubscriptionRequestMapperTest.java index d71b47421e..80bb9b05dc 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/subscription/request/SubscriptionRequestMapperTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/subscription/request/SubscriptionRequestMapperTest.java @@ -290,7 +290,7 @@ public class SubscriptionRequestMapperTest { .isInstanceOf(InvalidSubscriptionRequestException.class) .getCause() .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Invalid json rpc parameter at index 1"); + .hasMessageContaining("Invalid filter parameters (index 1)"); } @Test @@ -303,7 +303,7 @@ public class SubscriptionRequestMapperTest { .isInstanceOf(InvalidSubscriptionRequestException.class) .getCause() .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Invalid json rpc parameter at index 1"); + .hasMessageContaining("Invalid filter parameters (index 1)"); } @Test diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getLogs_invalidInput.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getLogs_invalidInput.json index 5a3dcb038a..c2c23fdfec 100644 --- a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getLogs_invalidInput.json +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getLogs_invalidInput.json @@ -16,7 +16,7 @@ "id" : 406, "error" : { "code": -32602, - "message": "Invalid params" + "message": "Invalid filter params" } }, "statusCode": 200 diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getNewFilter_invalidFilter.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getNewFilter_invalidFilter.json index be517fc357..52d5bd7966 100644 --- a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getNewFilter_invalidFilter.json +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getNewFilter_invalidFilter.json @@ -12,7 +12,7 @@ "id": 406, "error" : { "code" : -32602, - "message" : "Invalid params" + "message" : "Invalid filter params" } }, "statusCode": 200 From cca2f7554abe55c4c3d36a024d3594a6d69c9442 Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Fri, 16 Aug 2024 09:51:29 +1000 Subject: [PATCH 120/259] 5098 branch 18 update more invalid params (#7459) * 5098: Add RpcErrorTypes Signed-off-by: Matilda Clerke * 5098: Modify InvalidJsonRpcParameters and InvalidJsonRpcRequestException, apply spotless Signed-off-by: Matilda Clerke * 5098: Modify InvalidJsonRpcParameters and InvalidJsonRpcRequestException, apply spotless Signed-off-by: Matilda Clerke * 5098: Add JsonRpcParameterException for later use Signed-off-by: Matilda Clerke * 5098: Update locations for RpcErrorType.INVALID_ACCOUNTS_PARAMS Signed-off-by: Matilda Clerke * 5098: Address review comments, apply spotless Signed-off-by: Matilda Clerke * 5098: Update with changes from branch 1 Signed-off-by: Matilda Clerke * 5098: Update code to use RpcErrorType.INVALID_ADDRESS_HASH_PARAMS Signed-off-by: Matilda Clerke * 5098: apply spotless Signed-off-by: Matilda Clerke * 5098: apply spotless Signed-off-by: Matilda Clerke * 5098: Update plugin-api gradle hash Signed-off-by: Matilda Clerke * 5098: Add comment on INVALID_PARAMS_ERROR_CODE Signed-off-by: Matilda Clerke * 5098: Apply spotless on latest changes Signed-off-by: Matilda Clerke * 5098: Update code to use RpcErrorType.INVALID_ADDRESS_PARAMS Signed-off-by: Matilda Clerke * 5098: Fix broken unit test Signed-off-by: Matilda Clerke * 5098: Fix broken unit test Signed-off-by: Matilda Clerke * 5098: Update with usage of RpcErrorType.INVALID_AUTH_PARAMS Signed-off-by: Matilda Clerke * 5098: Update with usage of RpcErrorType.INVALID_BLOB_COUNT Signed-off-by: Matilda Clerke * 5098: Update with usage of RpcErrorType.INVALID_BLOB_GAS_USED_PARAMS Signed-off-by: Matilda Clerke * 5098: Update with usage of RpcErrorType.INVALID_BLOCK_PARAMS Signed-off-by: Matilda Clerke * 5098: Update with usage of RpcErrorType.INVALID_BLOCK_PARAMS Signed-off-by: Matilda Clerke * 5098: Update with usage of RpcErrorType.INVALID_BLOCK_PARAMS Signed-off-by: Matilda Clerke * 5098: Update with usage of RpcErrorType.INVALID_BLOCK_COUNT_PARAMS Signed-off-by: Matilda Clerke * 5098: Fix broken integration test Signed-off-by: Matilda Clerke * 5098: Add index to exception messages Signed-off-by: Matilda Clerke * 5098: apoply spotless Signed-off-by: Matilda Clerke * 5098: Update BaseJsonRpcProcessor to utilise RpcErrorType from InvalidJsonRpcParameters Signed-off-by: Matilda Clerke * 5098: Include parameter index in INVALID_AUTH_PARAMS Signed-off-by: Matilda Clerke * 5098: Include parameter index in INVALID_BLOCK_PARAMS Signed-off-by: Matilda Clerke * 5098: Include parameter index in INVALID_BLOCK_COUNT_PARAMS Signed-off-by: Matilda Clerke * 5098: Fix broken integration test Signed-off-by: Matilda Clerke * 5098: Rename INVALID_AUTH_PARAMS to INVALID_PROPOSAL_PARAMS Signed-off-by: Matilda Clerke * 5098: apply spotless Signed-off-by: Matilda Clerke * 5098: Update INVALID_BLOCK_HASH_PARAMS locations Signed-off-by: Matilda Clerke * 5098: Fix broken unit test Signed-off-by: Matilda Clerke * 5098: apply spotless Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_BLOCK_INDEX Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_BLOCK_NUMBER Signed-off-by: Matilda Clerke * 5098: apply spotless Signed-off-by: Matilda Clerke * 5098: Fix broken tests Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_CALL_PARAMS Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_CONSOLIDATION_REQUEST_PARAMS Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_CREATE_PRIVACY_GROUP_PARAMS Signed-off-by: Matilda Clerke * 5098: Fix broken test Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_DATA_PARAMS Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_DEPOSIT_REQUEST_PARAMS Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_ENGINE_EXCHANGE_TRANSITION_CONFIGURATION_PARAMS Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_ENGINE_FORKCHOICE_UPDATED_PARAMS Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_ENGINE_PAYLOAD_ATTRIBUTES_PARAMS Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_ENGINE_PAYLOAD_PARAMS Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_ENGINE_PREPARE_PAYLOAD_PARAMS Signed-off-by: Matilda Clerke * 5098: Apply spotless Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_ENODE_PARAMS Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_EXCESS_BLOB_GAS_PARAMS Signed-off-by: Matilda Clerke * 5098: Apply spotless Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_EXTRA_DATA_PARAMS Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_FILTER_PARAMS Signed-off-by: Matilda Clerke * 5098: Apply spotless Signed-off-by: Matilda Clerke * 5098: Fix broken tests Signed-off-by: Matilda Clerke * 5098: Update several RpcErrorTypes Signed-off-by: Matilda Clerke * 5098: Apply spotless Signed-off-by: Matilda Clerke * 5098: Hopefully fix broken integration test Signed-off-by: Matilda Clerke * 5098: Hopefully fix broken integration test Signed-off-by: Matilda Clerke --------- Signed-off-by: Matilda Clerke Signed-off-by: Matilda-Clerke Co-authored-by: Sally MacFarlane --- .../EthGetBlockByNumberIntegrationTest.java | 2 +- .../jsonrpc/internal/JsonRpcRequestId.java | 3 ++- .../internal/methods/AdminChangeLogLevel.java | 21 ++++++++++++++----- .../internal/methods/DebugStorageRangeAt.java | 9 ++++++-- .../internal/methods/EthGetBlockByHash.java | 9 +++++++- .../internal/methods/EthGetBlockByNumber.java | 9 +++++++- .../internal/methods/EthSubmitHashRate.java | 10 ++++++++- .../methods/JsonCallParameterUtil.java | 3 ++- .../internal/response/RpcErrorType.java | 1 + .../api/jsonrpc/JsonRpcHttpServiceTest.java | 4 ++-- .../methods/AdminChangeLogLevelTest.java | 9 +++++--- .../methods/EthGetBlockByHashTest.java | 5 ++--- .../methods/EthGetBlockByNumberTest.java | 5 ++--- .../ethereum/stratum/StratumProtocol.java | 10 ++++++++- 14 files changed, 75 insertions(+), 25 deletions(-) diff --git a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/frontier/EthGetBlockByNumberIntegrationTest.java b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/frontier/EthGetBlockByNumberIntegrationTest.java index 9f76609fd7..966cda1200 100644 --- a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/frontier/EthGetBlockByNumberIntegrationTest.java +++ b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/frontier/EthGetBlockByNumberIntegrationTest.java @@ -437,7 +437,7 @@ public class EthGetBlockByNumberIntegrationTest { assertThat(thrown) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage("Missing required json rpc parameter at index 1"); + .hasMessage("Invalid is transaction complete parameter (index 1)"); } /** diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/JsonRpcRequestId.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/JsonRpcRequestId.java index 678eae61b7..8944b0d84c 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/JsonRpcRequestId.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/JsonRpcRequestId.java @@ -15,6 +15,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcRequestException; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import java.math.BigInteger; import java.util.Objects; @@ -34,7 +35,7 @@ public class JsonRpcRequestId { @JsonCreator public JsonRpcRequestId(final Object id) { if (isRequestTypeInvalid(id)) { - throw new InvalidJsonRpcRequestException("Invalid id"); + throw new InvalidJsonRpcRequestException("Invalid id", RpcErrorType.INVALID_ID_PARAMS); } this.id = id; } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminChangeLogLevel.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminChangeLogLevel.java index 4538130331..3cfd524c14 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminChangeLogLevel.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminChangeLogLevel.java @@ -44,13 +44,24 @@ public class AdminChangeLogLevel implements JsonRpcMethod { @Override public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { try { - final String logLevel = requestContext.getRequiredParameter(0, String.class); + final String logLevel; + try { + logLevel = requestContext.getRequiredParameter(0, String.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid log level parameter (index 0)", RpcErrorType.INVALID_LOG_LEVEL_PARAMS, e); + } if (!VALID_PARAMS.contains(logLevel)) { return new JsonRpcErrorResponse( - requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + requestContext.getRequest().getId(), RpcErrorType.INVALID_LOG_LEVEL_PARAMS); + } + final Optional optionalLogFilters; + try { + optionalLogFilters = requestContext.getOptionalParameter(1, String[].class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid log filter parameters (index 1)", RpcErrorType.INVALID_LOG_FILTER_PARAMS, e); } - final Optional optionalLogFilters = - requestContext.getOptionalParameter(1, String[].class); optionalLogFilters.ifPresentOrElse( logFilters -> Arrays.stream(logFilters).forEach(logFilter -> setLogLevel(logFilter, logLevel)), @@ -58,7 +69,7 @@ public class AdminChangeLogLevel implements JsonRpcMethod { return new JsonRpcSuccessResponse(requestContext.getRequest().getId()); } catch (InvalidJsonRpcParameters invalidJsonRpcParameters) { return new JsonRpcErrorResponse( - requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + requestContext.getRequest().getId(), invalidJsonRpcParameters.getRpcErrorType()); } } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStorageRangeAt.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStorageRangeAt.java index 9f0f2f0b1e..f6f1601331 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStorageRangeAt.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStorageRangeAt.java @@ -85,8 +85,13 @@ public class DebugStorageRangeAt implements JsonRpcMethod { throw new InvalidJsonRpcParameters( "Invalid account address parameter (index 2)", RpcErrorType.INVALID_ADDRESS_PARAMS, e); } - final Hash startKey = - Hash.fromHexStringLenient(requestContext.getRequiredParameter(3, String.class)); + final Hash startKey; + try { + startKey = Hash.fromHexStringLenient(requestContext.getRequiredParameter(3, String.class)); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid data start hash parameter (index 3)", RpcErrorType.INVALID_DATA_HASH_PARAMS, e); + } final int limit = requestContext.getRequiredParameter(4, Integer.class); final Optional blockHashOptional = hashFromParameter(blockParameterOrBlockHash); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByHash.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByHash.java index d5f1bba01c..09b1c2f952 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByHash.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByHash.java @@ -93,6 +93,13 @@ public class EthGetBlockByHash implements JsonRpcMethod { } private boolean isCompleteTransactions(final JsonRpcRequestContext requestContext) { - return requestContext.getRequiredParameter(1, Boolean.class); + try { + return requestContext.getRequiredParameter(1, Boolean.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid is complete transaction parameter (index 1)", + RpcErrorType.INVALID_IS_TRANSACTION_COMPLETE_PARAMS, + e); + } } } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByNumber.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByNumber.java index 19ad9a51ad..5e0bc9c7ab 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByNumber.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByNumber.java @@ -124,6 +124,13 @@ public class EthGetBlockByNumber extends AbstractBlockParameterMethod { } private boolean isCompleteTransactions(final JsonRpcRequestContext request) { - return request.getRequiredParameter(1, Boolean.class); + try { + return request.getRequiredParameter(1, Boolean.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid is transaction complete parameter (index 1)", + RpcErrorType.INVALID_IS_TRANSACTION_COMPLETE_PARAMS, + e); + } } } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSubmitHashRate.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSubmitHashRate.java index c2e792b23f..9db7edcc80 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSubmitHashRate.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSubmitHashRate.java @@ -16,8 +16,10 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; 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.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.blockcreation.MiningCoordinator; import org.apache.tuweni.bytes.Bytes; @@ -37,7 +39,13 @@ public class EthSubmitHashRate implements JsonRpcMethod { @Override public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { - final String hashRate = requestContext.getRequiredParameter(0, String.class); + final String hashRate; + try { + hashRate = requestContext.getRequiredParameter(0, String.class); + } catch (Exception e) { + throw new InvalidJsonRpcParameters( + "Invalid hash rate parameter (index 0)", RpcErrorType.INVALID_HASH_RATE_PARAMS, e); + } final String id = requestContext.getRequiredParameter(1, String.class); return new JsonRpcSuccessResponse( requestContext.getRequest().getId(), diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/JsonCallParameterUtil.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/JsonCallParameterUtil.java index 891d837df3..7d7bd013be 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/JsonCallParameterUtil.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/JsonCallParameterUtil.java @@ -36,7 +36,8 @@ public class JsonCallParameterUtil { && (callParams.getMaxFeePerGas().isPresent() || callParams.getMaxPriorityFeePerGas().isPresent())) { throw new InvalidJsonRpcParameters( - "gasPrice cannot be used with maxFeePerGas or maxPriorityFeePerGas"); + "gasPrice cannot be used with maxFeePerGas or maxPriorityFeePerGas", + RpcErrorType.INVALID_GAS_PRICE_PARAMS); } return callParams; } 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 d16c258879..cb19d2e7a3 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 @@ -47,6 +47,7 @@ public enum RpcErrorType implements RpcMethodError { INVALID_CREATE_PRIVACY_GROUP_PARAMS( INVALID_PARAMS_ERROR_CODE, "Invalid create privacy group params"), INVALID_DATA_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid data params"), + INVALID_DATA_HASH_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid data hash params"), INVALID_DEPOSIT_REQUEST_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid deposit request"), INVALID_ENGINE_EXCHANGE_TRANSITION_CONFIGURATION_PARAMS( INVALID_PARAMS_ERROR_CODE, "Invalid engine exchange transition configuration params"), diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTest.java index 05284af6b8..7be6b7499e 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTest.java @@ -784,7 +784,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { assertThat(resp.code()).isEqualTo(200); // Check general format of result final JsonObject json = new JsonObject(resp.body().string()); - final RpcErrorType expectedError = RpcErrorType.INVALID_PARAMS; + final RpcErrorType expectedError = RpcErrorType.INVALID_IS_TRANSACTION_COMPLETE_PARAMS; testHelper.assertValidJsonRpcError( json, id, expectedError.getCode(), expectedError.getMessage()); } @@ -854,7 +854,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { assertThat(resp.code()).isEqualTo(200); // Check general format of result final JsonObject json = new JsonObject(resp.body().string()); - final RpcErrorType expectedError = RpcErrorType.INVALID_PARAMS; + final RpcErrorType expectedError = RpcErrorType.INVALID_IS_TRANSACTION_COMPLETE_PARAMS; testHelper.assertValidJsonRpcError( json, id, expectedError.getCode(), expectedError.getMessage()); } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminChangeLogLevelTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminChangeLogLevelTest.java index 120f380cd7..cf7e3337fd 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminChangeLogLevelTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminChangeLogLevelTest.java @@ -117,7 +117,8 @@ public class AdminChangeLogLevelTest { new JsonRpcRequestContext( new JsonRpcRequest("2.0", "admin_changeLogLevel", new Object[] {null})); final JsonRpcResponse expectedResponse = - new JsonRpcErrorResponse(request.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + new JsonRpcErrorResponse( + request.getRequest().getId(), RpcErrorType.INVALID_LOG_LEVEL_PARAMS); final JsonRpcResponse actualResponse = adminChangeLogLevel.response(request); assertThat(actualResponse).usingRecursiveComparison().isEqualTo(expectedResponse); @@ -129,7 +130,8 @@ public class AdminChangeLogLevelTest { new JsonRpcRequestContext( new JsonRpcRequest("2.0", "admin_changeLogLevel", new String[] {"INVALID"})); final JsonRpcResponse expectedResponse = - new JsonRpcErrorResponse(request.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + new JsonRpcErrorResponse( + request.getRequest().getId(), RpcErrorType.INVALID_LOG_LEVEL_PARAMS); final JsonRpcResponse actualResponse = adminChangeLogLevel.response(request); assertThat(actualResponse).usingRecursiveComparison().isEqualTo(expectedResponse); @@ -141,7 +143,8 @@ public class AdminChangeLogLevelTest { new JsonRpcRequestContext( new JsonRpcRequest("2.0", "admin_changeLogLevel", new Object[] {"DEBUG", "INVALID"})); final JsonRpcResponse expectedResponse = - new JsonRpcErrorResponse(request.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + new JsonRpcErrorResponse( + request.getRequest().getId(), RpcErrorType.INVALID_LOG_FILTER_PARAMS); final JsonRpcResponse actualResponse = adminChangeLogLevel.response(request); assertThat(actualResponse).usingRecursiveComparison().isEqualTo(expectedResponse); diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByHashTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByHashTest.java index 28043b2e09..0fc8969c93 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByHashTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByHashTest.java @@ -69,7 +69,7 @@ public class EthGetBlockByHashTest { public void exceptionWhenNoBoolSupplied() { assertThatThrownBy(() -> method.response(requestWithParams(ZERO_HASH))) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage("Missing required json rpc parameter at index 1"); + .hasMessage("Invalid is complete transaction parameter (index 1)"); verifyNoMoreInteractions(blockchainQueries); } @@ -85,8 +85,7 @@ public class EthGetBlockByHashTest { public void exceptionWhenBoolParamInvalid() { assertThatThrownBy(() -> method.response(requestWithParams(ZERO_HASH, "maybe"))) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage( - "Invalid json rpc parameter at index 1. Supplied value was: 'maybe' of type: 'java.lang.String' - expected type: 'java.lang.Boolean'"); + .hasMessage("Invalid is complete transaction parameter (index 1)"); verifyNoMoreInteractions(blockchainQueries); } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByNumberTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByNumberTest.java index e283759380..bc6ec997f3 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByNumberTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByNumberTest.java @@ -121,7 +121,7 @@ public class EthGetBlockByNumberTest { public void exceptionWhenNoBoolSupplied() { assertThatThrownBy(() -> method.response(requestWithParams("0"))) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage("Missing required json rpc parameter at index 1"); + .hasMessage("Invalid is transaction complete parameter (index 1)"); verifyNoMoreInteractions(blockchainQueries); } @@ -137,8 +137,7 @@ public class EthGetBlockByNumberTest { public void exceptionWhenBoolParamInvalid() { assertThatThrownBy(() -> method.response(requestWithParams("0", "maybe"))) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage( - "Invalid json rpc parameter at index 1. Supplied value was: 'maybe' of type: 'java.lang.String' - expected type: 'java.lang.Boolean'"); + .hasMessage("Invalid is transaction complete parameter (index 1)"); verifyNoMoreInteractions(blockchainQueries); } diff --git a/ethereum/stratum/src/main/java/org/hyperledger/besu/ethereum/stratum/StratumProtocol.java b/ethereum/stratum/src/main/java/org/hyperledger/besu/ethereum/stratum/StratumProtocol.java index 275724aa96..7f928fbdda 100644 --- a/ethereum/stratum/src/main/java/org/hyperledger/besu/ethereum/stratum/StratumProtocol.java +++ b/ethereum/stratum/src/main/java/org/hyperledger/besu/ethereum/stratum/StratumProtocol.java @@ -15,7 +15,9 @@ package org.hyperledger.besu.ethereum.stratum; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.blockcreation.MiningCoordinator; import org.hyperledger.besu.ethereum.mainnet.PoWSolution; import org.hyperledger.besu.ethereum.mainnet.PoWSolverInputs; @@ -78,7 +80,13 @@ public interface StratumProtocol { final StratumConnection conn, final JsonRpcRequest message, final Consumer sender) { - final String hashRate = message.getRequiredParameter(0, String.class); + final String hashRate; + try { + hashRate = message.getRequiredParameter(0, String.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid hash rate parameter (index 0)", RpcErrorType.INVALID_HASH_RATE_PARAMS, e); + } final String id = message.getRequiredParameter(1, String.class); String response; try { From b2b55a54fb663649f089eab773d36354132cec73 Mon Sep 17 00:00:00 2001 From: Suyash Nayan <89125422+7suyash7@users.noreply.github.com> Date: Fri, 16 Aug 2024 06:07:19 +0530 Subject: [PATCH 121/259] Add 'inbound' field to admin_peers JSON-RPC Call (#7461) * Add 'inbound' field to admin_peers JSON-RPC Call Signed-off-by: 7suyash7 * added changelog entry Signed-off-by: Sally MacFarlane --------- Signed-off-by: 7suyash7 Signed-off-by: Sally MacFarlane Co-authored-by: Sally MacFarlane --- CHANGELOG.md | 1 + .../jsonrpc/internal/results/NetworkResult.java | 10 +++++++++- .../api/jsonrpc/internal/results/PeerResult.java | 6 +++++- .../internal/results/NetworkResultTest.java | 15 ++++++++++++++- 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a16284015..183ca24e55 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ - Added support for tracing private transactions using `priv_traceTransaction` API. [#6161](https://github.com/hyperledger/besu/pull/6161) - Wrap WorldUpdater into EVMWorldupdater [#7434](https://github.com/hyperledger/besu/pull/7434) - Bump besu-native to 0.9.4 [#7456](https://github.com/hyperledger/besu/pull/7456) +- Add 'inbound' field to admin_peers JSON-RPC Call [#7461](https://github.com/hyperledger/besu/pull/7461) ### Bug fixes diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/NetworkResult.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/NetworkResult.java index e5176c55b2..2a48201dcc 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/NetworkResult.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/NetworkResult.java @@ -24,10 +24,13 @@ public class NetworkResult { private final String localAddress; private final String remoteAddress; + private final boolean inbound; - public NetworkResult(final SocketAddress localAddress, final SocketAddress remoteAddress) { + public NetworkResult( + final SocketAddress localAddress, final SocketAddress remoteAddress, final boolean inbound) { this.localAddress = removeTrailingSlash(localAddress.toString()); this.remoteAddress = removeTrailingSlash(remoteAddress.toString()); + this.inbound = inbound; } @JsonGetter(value = "localAddress") @@ -40,6 +43,11 @@ public class NetworkResult { return remoteAddress; } + @JsonGetter(value = "inbound") + public boolean isInbound() { + return inbound; + } + private String removeTrailingSlash(final String address) { if (address != null && address.startsWith("/")) { return address.substring(1); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/PeerResult.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/PeerResult.java index c420990d65..1bc2283acc 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/PeerResult.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/PeerResult.java @@ -45,7 +45,11 @@ public interface PeerResult { .map(Capability::toString) .map(TextNode::new) .collect(Collectors.toList())) - .network(new NetworkResult(connection.getLocalAddress(), connection.getRemoteAddress())) + .network( + new NetworkResult( + connection.getLocalAddress(), + connection.getRemoteAddress(), + connection.inboundInitiated())) .port(Quantity.create(peerInfo.getPort())) .id(peerInfo.getNodeId().toString()) .protocols(Map.of(peer.getProtocolName(), ProtocolsResult.fromEthPeer(peer))) diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/NetworkResultTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/NetworkResultTest.java index 876e795468..63f71c435f 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/NetworkResultTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/NetworkResultTest.java @@ -26,9 +26,22 @@ public class NetworkResultTest { @Test public void localAndRemoteAddressShouldNotStartWithForwardSlash() { final SocketAddress socketAddress = new InetSocketAddress("1.2.3.4", 7890); - final NetworkResult networkResult = new NetworkResult(socketAddress, socketAddress); + final NetworkResult networkResult = new NetworkResult(socketAddress, socketAddress, true); assertThat(networkResult.getLocalAddress()).isEqualTo("1.2.3.4:7890"); assertThat(networkResult.getRemoteAddress()).isEqualTo("1.2.3.4:7890"); + assertThat(networkResult.isInbound()).isTrue(); + } + + @Test + public void inboundFieldShouldReflectConnectionDirection() { + final SocketAddress localAddress = new InetSocketAddress("192.168.0.1", 30303); + final SocketAddress remoteAddress = new InetSocketAddress("10.0.0.1", 30303); + + final NetworkResult inboundConnection = new NetworkResult(localAddress, remoteAddress, true); + assertThat(inboundConnection.isInbound()).isTrue(); + + final NetworkResult outboundConnection = new NetworkResult(localAddress, remoteAddress, false); + assertThat(outboundConnection.isInbound()).isFalse(); } } From cafe82d2d56085da31ab9d3a46c0a5320f85f615 Mon Sep 17 00:00:00 2001 From: Sally MacFarlane Date: Fri, 16 Aug 2024 11:37:10 +1000 Subject: [PATCH 122/259] clarification for release steps (#7400) * clarification for release steps Signed-off-by: Sally MacFarlane * PR feedback Signed-off-by: Sally MacFarlane * burn-in signoff Signed-off-by: Sally MacFarlane * added items Signed-off-by: Sally MacFarlane --------- Signed-off-by: Sally MacFarlane Co-authored-by: Simon Dudley --- .github/ISSUE_TEMPLATE/release-checklist.md | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/release-checklist.md b/.github/ISSUE_TEMPLATE/release-checklist.md index 9840a3fa49..721c26edbd 100644 --- a/.github/ISSUE_TEMPLATE/release-checklist.md +++ b/.github/ISSUE_TEMPLATE/release-checklist.md @@ -11,11 +11,16 @@ assignees: '' - [ ] Update changelog if necessary, and merge a PR for it to main - [ ] Notify maintainers about updating changelog for in-flight PRs - [ ] Optional: for hotfixes, create a release branch and cherry-pick, e.g. `release--hotfix` -- [ ] Optional: create a PR into main from the hotfix branch to see the CI checks pass + - [ ] 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` -- [ ] Sign-off with team; confirm tag is correct in #besu-release in Discord -- [ ] Consensys staff start burn-in using the proposed release tag -- [ ] Sign off burn-in; convey burn-in results in #besu-release in Discord + - [ ] git tag 24.4.0-RC2 + - [ ] git push upstream 24.4.0-RC2 +- [ ] 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 +- [ ] 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: - this is now public and notifies subscribed users @@ -24,8 +29,9 @@ assignees: '' - publishes the docker `latest` tag variants - [ ] Check binary SHAs are correct on the release page - [ ] Check "Container Verify" GitHub workflow has run successfully -- [ ] Create homebrew release - run https://github.com/hyperledger/homebrew-besu/actions/workflows/update-version.yml - [ ] Create besu-docs release - https://github.com/hyperledger/besu-docs/releases/new - - Copy release notes from besu - - If publishing the release in github doesn't automatically trigger this workflow, then manually run https://github.com/hyperledger/besu-docs/actions/workflows/update-version.yml + - Copy release notes from besu + - If publishing the release in github doesn't automatically trigger this workflow, then manually run https://github.com/hyperledger/besu-docs/actions/workflows/update-version.yml +- [ ] Create homebrew release - run GHA workflow directly https://github.com/hyperledger/homebrew-besu/actions/workflows/update-version.yml +- [ ] Delete the burn-in nodes (unless required for further analysis eg performance) - [ ] Social announcements From 68d7bd0bd1d9681a3334e2bdc41c6e11f8381697 Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Fri, 16 Aug 2024 11:59:57 +1000 Subject: [PATCH 123/259] 5098 branch 19 update more invalid params (#7460) * 5098: Add RpcErrorTypes Signed-off-by: Matilda Clerke --------- Signed-off-by: Matilda Clerke Signed-off-by: Matilda-Clerke Co-authored-by: Sally MacFarlane --- .../api/jsonrpc/internal/JsonRpcRequest.java | 4 +++- .../internal/methods/DebugAccountRange.java | 8 ++++++- .../internal/methods/EthSubmitWork.java | 24 ++++++++++++++----- .../engine/AbstractEngineNewPayload.java | 11 +++++++-- .../methods/engine/EngineNewPayloadV3.java | 3 ++- .../methods/engine/EngineNewPayloadV4.java | 3 ++- .../methods/miner/MinerSetMinGasPrice.java | 9 ++++++- .../methods/miner/MinerSetMinPriorityFee.java | 3 ++- .../miner/MinerSetMinGasPriceTest.java | 2 +- .../miner/MinerSetMinPriorityFeeTest.java | 5 ++-- .../ethereum/stratum/Stratum1Protocol.java | 24 ++++++++++++++----- 11 files changed, 73 insertions(+), 23 deletions(-) diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/JsonRpcRequest.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/JsonRpcRequest.java index db7fe13105..06b495624e 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/JsonRpcRequest.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/JsonRpcRequest.java @@ -16,6 +16,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcRequestException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import java.util.Arrays; import java.util.List; @@ -51,7 +52,8 @@ public class JsonRpcRequest { this.method = method; this.params = params; if (method == null) { - throw new InvalidJsonRpcRequestException("Field 'method' is required"); + throw new InvalidJsonRpcRequestException( + "Field 'method' is required", RpcErrorType.INVALID_METHOD_PARAMS); } } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugAccountRange.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugAccountRange.java index c891bde56a..fc787031da 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugAccountRange.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugAccountRange.java @@ -75,7 +75,13 @@ public class DebugAccountRange implements JsonRpcMethod { throw new InvalidJsonRpcParameters( "Invalid address hash parameter (index 2)", RpcErrorType.INVALID_ADDRESS_HASH_PARAMS, e); } - final int maxResults = requestContext.getRequiredParameter(3, Integer.TYPE); + final int maxResults; + try { + maxResults = requestContext.getRequiredParameter(3, Integer.TYPE); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid max results parameter (index 3)", RpcErrorType.INVALID_MAX_RESULTS_PARAMS, e); + } final Optional blockHashOptional = hashFromParameter(blockParameterOrBlockHash); if (blockHashOptional.isEmpty()) { diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSubmitWork.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSubmitWork.java index 370643f203..cebb2e7a00 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSubmitWork.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSubmitWork.java @@ -17,6 +17,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; 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; @@ -49,12 +50,23 @@ public class EthSubmitWork implements JsonRpcMethod { public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { final Optional solver = miner.getWorkDefinition(); if (solver.isPresent()) { - final PoWSolution solution = - new PoWSolution( - Bytes.fromHexString(requestContext.getRequiredParameter(0, String.class)).getLong(0), - requestContext.getRequiredParameter(2, Hash.class), - null, - Bytes.fromHexString(requestContext.getRequiredParameter(1, String.class))); + long nonce; + try { + nonce = + Bytes.fromHexString(requestContext.getRequiredParameter(0, String.class)).getLong(0); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid nonce parameter (index 0)", RpcErrorType.INVALID_NONCE_PARAMS, e); + } + Hash mixHash; + try { + mixHash = requestContext.getRequiredParameter(2, Hash.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid mix hash parameter (index 2)", RpcErrorType.INVALID_MIX_HASH_PARAMS, e); + } + Bytes powHash = Bytes.fromHexString(requestContext.getRequiredParameter(1, String.class)); + final PoWSolution solution = new PoWSolution(nonce, mixHash, null, powHash); final boolean result = miner.submitWork(solution); return new JsonRpcSuccessResponse(requestContext.getRequest().getId(), result); } else { 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 0588121516..369d7a387a 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 @@ -123,8 +123,15 @@ public abstract class AbstractEngineNewPayload extends ExecutionEngineJsonRpcMet final Object reqId = requestContext.getRequest().getId(); - Optional maybeParentBeaconBlockRootParam = - requestContext.getOptionalParameter(2, String.class); + Optional maybeParentBeaconBlockRootParam; + try { + maybeParentBeaconBlockRootParam = requestContext.getOptionalParameter(2, String.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcRequestException( + "Invalid parent beacon block root parameters (index 2)", + RpcErrorType.INVALID_PARENT_BEACON_BLOCK_ROOT_PARAMS, + e); + } final Optional maybeParentBeaconBlockRoot = maybeParentBeaconBlockRootParam.map(Bytes32::fromHexString); 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 b946df40bd..0277d6990e 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 @@ -67,7 +67,8 @@ public class EngineNewPayloadV3 extends AbstractEngineNewPayload { RpcErrorType.INVALID_PARAMS, "Missing versioned hashes field"); } else if (maybeBeaconBlockRootParam.isEmpty()) { return ValidationResult.invalid( - RpcErrorType.INVALID_PARAMS, "Missing parent beacon block root field"); + RpcErrorType.INVALID_PARENT_BEACON_BLOCK_ROOT_PARAMS, + "Missing parent beacon block root field"); } else { return ValidationResult.valid(); } 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 b87eceed5d..a767c72345 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 @@ -67,7 +67,8 @@ public class EngineNewPayloadV4 extends AbstractEngineNewPayload { RpcErrorType.INVALID_PARAMS, "Missing versioned hashes field"); } else if (maybeBeaconBlockRootParam.isEmpty()) { return ValidationResult.invalid( - RpcErrorType.INVALID_PARAMS, "Missing parent beacon block root field"); + 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 { diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetMinGasPrice.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetMinGasPrice.java index c72e5c95c7..59c18b80db 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetMinGasPrice.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetMinGasPrice.java @@ -17,6 +17,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.miner; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; @@ -53,7 +54,13 @@ public class MinerSetMinGasPrice implements JsonRpcMethod { } catch (final IllegalArgumentException invalidJsonRpcParameters) { return new JsonRpcErrorResponse( requestContext.getRequest().getId(), - new JsonRpcError(RpcErrorType.INVALID_PARAMS, invalidJsonRpcParameters.getMessage())); + new JsonRpcError( + RpcErrorType.INVALID_MIN_GAS_PRICE_PARAMS, invalidJsonRpcParameters.getMessage())); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid min gas price parameter (index 0)", + RpcErrorType.INVALID_MIN_GAS_PRICE_PARAMS, + e); } } } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetMinPriorityFee.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetMinPriorityFee.java index f3dd52f906..9c217b0c23 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetMinPriorityFee.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetMinPriorityFee.java @@ -54,7 +54,8 @@ public class MinerSetMinPriorityFee implements JsonRpcMethod { } catch (final IllegalArgumentException invalidJsonRpcParameters) { return new JsonRpcErrorResponse( requestContext.getRequest().getId(), - new JsonRpcError(RpcErrorType.INVALID_PARAMS, invalidJsonRpcParameters.getMessage())); + new JsonRpcError( + RpcErrorType.INVALID_MIN_PRIORITY_FEE_PARAMS, invalidJsonRpcParameters.getMessage())); } } } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetMinGasPriceTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetMinGasPriceTest.java index a5cb18a2df..fb56b57307 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetMinGasPriceTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetMinGasPriceTest.java @@ -48,7 +48,7 @@ public class MinerSetMinGasPriceTest { new JsonRpcErrorResponse( request.getRequest().getId(), new JsonRpcError( - RpcErrorType.INVALID_PARAMS, + RpcErrorType.INVALID_MIN_GAS_PRICE_PARAMS, "Illegal character '-' found at index 0 in hex binary representation")); final JsonRpcResponse actual = method.response(request); diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetMinPriorityFeeTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetMinPriorityFeeTest.java index cc69c1e7c4..7e564ac425 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetMinPriorityFeeTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetMinPriorityFeeTest.java @@ -49,7 +49,7 @@ public class MinerSetMinPriorityFeeTest { new JsonRpcErrorResponse( request.getRequest().getId(), new JsonRpcError( - RpcErrorType.INVALID_PARAMS, + RpcErrorType.INVALID_MIN_PRIORITY_FEE_PARAMS, "Hex value is too large: expected at most 32 bytes but got 33")); final JsonRpcResponse actual = method.response(request); @@ -65,7 +65,8 @@ public class MinerSetMinPriorityFeeTest { new JsonRpcErrorResponse( request.getRequest().getId(), new JsonRpcError( - RpcErrorType.INVALID_PARAMS, "Missing required json rpc parameter at index 0")); + RpcErrorType.INVALID_MIN_PRIORITY_FEE_PARAMS, + "Missing required json rpc parameter at index 0")); final JsonRpcResponse actual = method.response(request); assertThat(actual).usingRecursiveComparison().isEqualTo(expected); } diff --git a/ethereum/stratum/src/main/java/org/hyperledger/besu/ethereum/stratum/Stratum1Protocol.java b/ethereum/stratum/src/main/java/org/hyperledger/besu/ethereum/stratum/Stratum1Protocol.java index d3408dc4c9..308d15f6f1 100644 --- a/ethereum/stratum/src/main/java/org/hyperledger/besu/ethereum/stratum/Stratum1Protocol.java +++ b/ethereum/stratum/src/main/java/org/hyperledger/besu/ethereum/stratum/Stratum1Protocol.java @@ -17,7 +17,9 @@ package org.hyperledger.besu.ethereum.stratum; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.blockcreation.MiningCoordinator; import org.hyperledger.besu.ethereum.blockcreation.PoWMiningCoordinator; import org.hyperledger.besu.ethereum.mainnet.DirectAcyclicGraphSeed; @@ -170,13 +172,23 @@ public class Stratum1Protocol implements StratumProtocol { private void handleMiningSubmit(final JsonRpcRequest message, final Consumer sender) { LOG.debug("Miner submitted solution {}", message); + long nonce; + try { + nonce = Bytes.fromHexString(message.getRequiredParameter(2, String.class)).getLong(0); + } catch (Exception e) { + throw new InvalidJsonRpcParameters( + "Invalid nonce parameter (index 2)", RpcErrorType.INVALID_NONCE_PARAMS, e); + } + Hash mixHash = null; + try { + mixHash = Hash.fromHexString(message.getRequiredParameter(4, String.class)); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid mix hash parameter (index 4)", RpcErrorType.INVALID_MIX_HASH_PARAMS, e); + } + Bytes powHash = Bytes.fromHexString(message.getRequiredParameter(3, String.class)); boolean result = false; - final PoWSolution solution = - new PoWSolution( - Bytes.fromHexString(message.getRequiredParameter(2, String.class)).getLong(0), - Hash.fromHexString(message.getRequiredParameter(4, String.class)), - null, - Bytes.fromHexString(message.getRequiredParameter(3, String.class))); + final PoWSolution solution = new PoWSolution(nonce, mixHash, null, powHash); if (currentInput.getPrePowHash().equals(solution.getPowHash())) { result = submitCallback.apply(solution); } From 35faf06b92ded5e3b1ed22b80c90da9599326c1c Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Fri, 16 Aug 2024 12:59:03 +1000 Subject: [PATCH 124/259] 5098 branch 20 update invalid param count (#7466) * 5098: Add RpcErrorTypes Signed-off-by: Matilda Clerke --------- Signed-off-by: Matilda Clerke Signed-off-by: Matilda-Clerke Co-authored-by: Sally MacFarlane --- .../internal/methods/AdminModifyPeer.java | 2 +- .../methods/EthGetTransactionByHash.java | 2 +- .../methods/EthSendRawTransaction.java | 2 +- .../methods/PluginsReloadConfiguration.java | 5 ++--- .../internal/methods/TraceCallMany.java | 2 +- .../jsonrpc/internal/methods/TraceGet.java | 2 +- .../internal/methods/TraceRawTransaction.java | 2 +- .../TxPoolBesuPendingTransactions.java | 20 ++++++++++++++----- .../jsonrpc/internal/methods/Web3Sha3.java | 2 +- .../engine/AbstractEngineGetPayload.java | 9 ++++++++- .../priv/PrivGetEeaTransactionCount.java | 2 +- .../methods/priv/PrivGetTransactionCount.java | 2 +- .../api/jsonrpc/PluginJsonRpcMethodTest.java | 5 +++-- .../internal/methods/AdminAddPeerTest.java | 8 ++++---- .../internal/methods/AdminRemovePeerTest.java | 8 ++++---- .../methods/EthGetTransactionByHashTest.java | 2 +- .../methods/EthSendRawTransactionTest.java | 6 +++--- .../TxPoolBesuPendingTransactionsTest.java | 8 ++++---- .../internal/methods/Web3Sha3Test.java | 4 ++-- ...TransactionByHash_invalidHashAndIndex.json | 2 +- ...th_getTransactionByHash_invalidParams.json | 2 +- 21 files changed, 57 insertions(+), 40 deletions(-) diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminModifyPeer.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminModifyPeer.java index 4f50ad180d..f1c134ed91 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminModifyPeer.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminModifyPeer.java @@ -39,7 +39,7 @@ public abstract class AdminModifyPeer implements JsonRpcMethod { public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { if (requestContext.getRequest().getParamLength() != 1) { return new JsonRpcErrorResponse( - requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAM_COUNT); } try { final String enodeString = requestContext.getRequiredParameter(0, String.class); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionByHash.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionByHash.java index 2c854239e7..8221de1f3f 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionByHash.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionByHash.java @@ -48,7 +48,7 @@ public class EthGetTransactionByHash implements JsonRpcMethod { public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { if (requestContext.getRequest().getParamLength() != 1) { return new JsonRpcErrorResponse( - requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAM_COUNT); } final Hash hash = requestContext.getRequiredParameter(0, Hash.class); final JsonRpcSuccessResponse jsonRpcSuccessResponse = diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSendRawTransaction.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSendRawTransaction.java index e79c0b60b7..70b232faab 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSendRawTransaction.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSendRawTransaction.java @@ -66,7 +66,7 @@ public class EthSendRawTransaction implements JsonRpcMethod { public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { if (requestContext.getRequest().getParamLength() != 1) { return new JsonRpcErrorResponse( - requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAM_COUNT); } final String rawTransaction = requestContext.getRequiredParameter(0, String.class); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/PluginsReloadConfiguration.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/PluginsReloadConfiguration.java index 34e9276c82..f895008e23 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/PluginsReloadConfiguration.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/PluginsReloadConfiguration.java @@ -16,7 +16,6 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; 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; @@ -56,9 +55,9 @@ public class PluginsReloadConfiguration implements JsonRpcMethod { } reloadPluginConfig(namedPlugins.get(pluginName)); return new JsonRpcSuccessResponse(requestContext.getRequest().getId()); - } catch (InvalidJsonRpcParameters invalidJsonRpcParameters) { + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException return new JsonRpcErrorResponse( - requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + requestContext.getRequest().getId(), RpcErrorType.INVAlID_PLUGIN_NAME_PARAMS); } } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceCallMany.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceCallMany.java index 8dabd29a3e..5b14019b07 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceCallMany.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceCallMany.java @@ -81,7 +81,7 @@ public class TraceCallMany extends TraceCall implements JsonRpcMethod { if (requestContext.getRequest().getParamLength() != 2) { return new JsonRpcErrorResponse( - requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAM_COUNT); } final TraceCallManyParameter[] transactionsAndTraceTypeParameters; diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceGet.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceGet.java index f6289e2ce2..2837e93e13 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceGet.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceGet.java @@ -51,7 +51,7 @@ public class TraceGet extends AbstractTraceByHash implements JsonRpcMethod { public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { if (requestContext.getRequest().getParamLength() != 2) { return new JsonRpcErrorResponse( - requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAM_COUNT); } final Hash transactionHash = requestContext.getRequiredParameter(0, Hash.class); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceRawTransaction.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceRawTransaction.java index ad34d92b49..a69414900f 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceRawTransaction.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceRawTransaction.java @@ -67,7 +67,7 @@ public class TraceRawTransaction extends AbstractTraceByBlock implements JsonRpc public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { if (requestContext.getRequest().getParamLength() != 2) { return new JsonRpcErrorResponse( - requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAM_COUNT); } final var rawTransaction = requestContext.getRequiredParameter(0, String.class); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TxPoolBesuPendingTransactions.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TxPoolBesuPendingTransactions.java index c1d224e1f1..67e90d55b5 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TxPoolBesuPendingTransactions.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TxPoolBesuPendingTransactions.java @@ -16,9 +16,11 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.PendingTransactionsParams; 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.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.TransactionPendingResult; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.transaction.pool.PendingTransactionFilter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.transaction.pool.PendingTransactionFilter.Filter; @@ -54,11 +56,19 @@ public class TxPoolBesuPendingTransactions implements JsonRpcMethod { transactionPool.getPendingTransactions(); final Integer limit = requestContext.getOptionalParameter(0, Integer.class).orElse(pendingTransactions.size()); - final List filters = - requestContext - .getOptionalParameter(1, PendingTransactionsParams.class) - .map(PendingTransactionsParams::filters) - .orElse(Collections.emptyList()); + final List filters; + try { + filters = + requestContext + .getOptionalParameter(1, PendingTransactionsParams.class) + .map(PendingTransactionsParams::filters) + .orElse(Collections.emptyList()); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid pending transactions parameter (index 1)", + RpcErrorType.INVALID_PENDING_TRANSACTIONS_PARAMS, + e); + } final Collection pendingTransactionsFiltered = pendingTransactionFilter.reduce(pendingTransactions, filters, limit); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/Web3Sha3.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/Web3Sha3.java index b06cd57293..b70ad76051 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/Web3Sha3.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/Web3Sha3.java @@ -39,7 +39,7 @@ public class Web3Sha3 implements JsonRpcMethod { if (requestContext.getRequest().getParamLength() != 1) { // Do we want custom messages for each different type of invalid params? return new JsonRpcErrorResponse( - requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAM_COUNT); } final String data; diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineGetPayload.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineGetPayload.java index 901eda782c..a6f94ac00e 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineGetPayload.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineGetPayload.java @@ -19,6 +19,7 @@ import org.hyperledger.besu.consensus.merge.blockcreation.MergeMiningCoordinator import org.hyperledger.besu.consensus.merge.blockcreation.PayloadIdentifier; import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; @@ -68,7 +69,13 @@ public abstract class AbstractEngineGetPayload extends ExecutionEngineJsonRpcMet public JsonRpcResponse syncResponse(final JsonRpcRequestContext request) { engineCallListener.executionEngineCalled(); - final PayloadIdentifier payloadId = request.getRequiredParameter(0, PayloadIdentifier.class); + final PayloadIdentifier payloadId; + try { + payloadId = request.getRequiredParameter(0, PayloadIdentifier.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid payload ID parameter (index 0)", RpcErrorType.INVALID_PAYLOAD_ID_PARAMS, e); + } mergeMiningCoordinator.finalizeProposalById(payloadId); final Optional maybePayload = mergeContext.get().retrievePayloadById(payloadId); if (maybePayload.isPresent()) { diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetEeaTransactionCount.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetEeaTransactionCount.java index cd107b2e71..8fa43b79e3 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetEeaTransactionCount.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetEeaTransactionCount.java @@ -63,7 +63,7 @@ public class PrivGetEeaTransactionCount implements JsonRpcMethod { public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { if (requestContext.getRequest().getParamLength() != 3) { return new JsonRpcErrorResponse( - requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAM_COUNT); } final Address address; diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetTransactionCount.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetTransactionCount.java index c796d35d5f..b51f0fc36f 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetTransactionCount.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetTransactionCount.java @@ -54,7 +54,7 @@ public class PrivGetTransactionCount implements JsonRpcMethod { public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { if (requestContext.getRequest().getParamLength() != 2) { return new JsonRpcErrorResponse( - requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAM_COUNT); } final Address address; diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/PluginJsonRpcMethodTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/PluginJsonRpcMethodTest.java index 897029afcd..5c92a43e57 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/PluginJsonRpcMethodTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/PluginJsonRpcMethodTest.java @@ -104,7 +104,7 @@ public class PluginJsonRpcMethodTest extends JsonRpcHttpServiceTestBase { try (final Response resp = client.newCall(buildPostRequest(body)).execute()) { assertThat(resp.code()).isEqualTo(200); final JsonObject json = new JsonObject(resp.body().string()); - final JsonRpcError expectedError = new JsonRpcError(RpcErrorType.INVALID_PARAMS); + final JsonRpcError expectedError = new JsonRpcError(RpcErrorType.INVALID_PARAM_COUNT); testHelper.assertValidJsonRpcError( json, 1, expectedError.getCode(), expectedError.getMessage()); } @@ -173,7 +173,8 @@ public class PluginJsonRpcMethodTest extends JsonRpcHttpServiceTestBase { private static Object echoPluginRpcMethod(final PluginRpcRequest request) { final var params = request.getParams(); if (params.length == 0) { - throw new InvalidJsonRpcParameters("parameter is mandatory"); + throw new InvalidJsonRpcParameters( + "parameter is mandatory", RpcErrorType.INVALID_PARAM_COUNT); } final var input = params[0]; if (input.toString().isBlank()) { diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminAddPeerTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminAddPeerTest.java index 25a0899c8c..f3dcb1c8f5 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminAddPeerTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminAddPeerTest.java @@ -102,7 +102,7 @@ public class AdminAddPeerTest { final JsonRpcRequestContext request = new JsonRpcRequestContext(new JsonRpcRequest("2.0", "admin_addPeer", new String[] {})); final JsonRpcResponse expectedResponse = - new JsonRpcErrorResponse(request.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + new JsonRpcErrorResponse(request.getRequest().getId(), RpcErrorType.INVALID_PARAM_COUNT); final JsonRpcResponse actualResponse = method.response(request); @@ -114,7 +114,7 @@ public class AdminAddPeerTest { final JsonRpcRequestContext request = new JsonRpcRequestContext(new JsonRpcRequest("2.0", "admin_addPeer", null)); final JsonRpcResponse expectedResponse = - new JsonRpcErrorResponse(request.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + new JsonRpcErrorResponse(request.getRequest().getId(), RpcErrorType.INVALID_PARAM_COUNT); final JsonRpcResponse actualResponse = method.response(request); @@ -126,7 +126,7 @@ public class AdminAddPeerTest { final JsonRpcRequestContext request = new JsonRpcRequestContext(new JsonRpcRequest("2.0", "admin_addPeer", new String[] {null})); final JsonRpcResponse expectedResponse = - new JsonRpcErrorResponse(request.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + new JsonRpcErrorResponse(request.getRequest().getId(), RpcErrorType.INVALID_PARAM_COUNT); final JsonRpcResponse actualResponse = method.response(request); @@ -221,7 +221,7 @@ public class AdminAddPeerTest { new JsonRpcRequest("2.0", "admin_addPeer", new String[] {validEnode, validEnode})); final JsonRpcResponse expectedResponse = - new JsonRpcErrorResponse(request.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + new JsonRpcErrorResponse(request.getRequest().getId(), RpcErrorType.INVALID_PARAM_COUNT); final JsonRpcResponse actualResponse = method.response(request); diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminRemovePeerTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminRemovePeerTest.java index 3bbe50684b..2ba7c33523 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminRemovePeerTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminRemovePeerTest.java @@ -102,7 +102,7 @@ public class AdminRemovePeerTest { final JsonRpcRequestContext request = new JsonRpcRequestContext(new JsonRpcRequest("2.0", "admin_removePeer", new String[] {})); final JsonRpcResponse expectedResponse = - new JsonRpcErrorResponse(request.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + new JsonRpcErrorResponse(request.getRequest().getId(), RpcErrorType.INVALID_PARAM_COUNT); final JsonRpcResponse actualResponse = method.response(request); @@ -114,7 +114,7 @@ public class AdminRemovePeerTest { final JsonRpcRequestContext request = new JsonRpcRequestContext(new JsonRpcRequest("2.0", "admin_removePeer", null)); final JsonRpcResponse expectedResponse = - new JsonRpcErrorResponse(request.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + new JsonRpcErrorResponse(request.getRequest().getId(), RpcErrorType.INVALID_PARAM_COUNT); final JsonRpcResponse actualResponse = method.response(request); @@ -127,7 +127,7 @@ public class AdminRemovePeerTest { new JsonRpcRequestContext( new JsonRpcRequest("2.0", "admin_removePeer", new String[] {null})); final JsonRpcResponse expectedResponse = - new JsonRpcErrorResponse(request.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + new JsonRpcErrorResponse(request.getRequest().getId(), RpcErrorType.INVALID_PARAM_COUNT); final JsonRpcResponse actualResponse = method.response(request); @@ -222,7 +222,7 @@ public class AdminRemovePeerTest { new JsonRpcRequest("2.0", "admin_removePeer", new String[] {validEnode, validEnode})); final JsonRpcResponse expectedResponse = - new JsonRpcErrorResponse(request.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + new JsonRpcErrorResponse(request.getRequest().getId(), RpcErrorType.INVALID_PARAM_COUNT); final JsonRpcResponse actualResponse = method.response(request); diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionByHashTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionByHashTest.java index b376ef1ef8..48350ff9d0 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionByHashTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionByHashTest.java @@ -77,7 +77,7 @@ class EthGetTransactionByHashTest { final JsonRpcRequestContext context = new JsonRpcRequestContext(request); final JsonRpcErrorResponse expectedResponse = - new JsonRpcErrorResponse(request.getId(), RpcErrorType.INVALID_PARAMS); + new JsonRpcErrorResponse(request.getId(), RpcErrorType.INVALID_PARAM_COUNT); final JsonRpcResponse actualResponse = method.response(context); diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSendRawTransactionTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSendRawTransactionTest.java index 16cbbe3649..35abfa66ce 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSendRawTransactionTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSendRawTransactionTest.java @@ -57,7 +57,7 @@ public class EthSendRawTransactionTest { new JsonRpcRequest("2.0", "eth_sendRawTransaction", new String[] {})); final JsonRpcResponse expectedResponse = - new JsonRpcErrorResponse(request.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + new JsonRpcErrorResponse(request.getRequest().getId(), RpcErrorType.INVALID_PARAM_COUNT); final JsonRpcResponse actualResponse = method.response(request); @@ -70,7 +70,7 @@ public class EthSendRawTransactionTest { new JsonRpcRequestContext(new JsonRpcRequest("2.0", "eth_sendRawTransaction", null)); final JsonRpcResponse expectedResponse = - new JsonRpcErrorResponse(request.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + new JsonRpcErrorResponse(request.getRequest().getId(), RpcErrorType.INVALID_PARAM_COUNT); final JsonRpcResponse actualResponse = method.response(request); @@ -84,7 +84,7 @@ public class EthSendRawTransactionTest { new JsonRpcRequest("2.0", "eth_sendRawTransaction", new String[] {null})); final JsonRpcResponse expectedResponse = - new JsonRpcErrorResponse(request.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + new JsonRpcErrorResponse(request.getRequest().getId(), RpcErrorType.INVALID_PARAM_COUNT); final JsonRpcResponse actualResponse = method.response(request); diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TxPoolBesuPendingTransactionsTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TxPoolBesuPendingTransactionsTest.java index 1eef04fb93..9cc6947b26 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TxPoolBesuPendingTransactionsTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TxPoolBesuPendingTransactionsTest.java @@ -201,7 +201,7 @@ public class TxPoolBesuPendingTransactionsTest { assertThatThrownBy(() -> method.response(request)) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Unknown field expected one of `eq`, `gt`, `lt`, `action`"); + .hasMessageContaining("Invalid pending transactions parameter (index 1)"); } @Test @@ -229,7 +229,7 @@ public class TxPoolBesuPendingTransactionsTest { assertThatThrownBy(() -> method.response(request)) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Only one operator per filter type allowed"); + .hasMessageContaining("Invalid pending transactions parameter (index 1)"); } @Test @@ -256,7 +256,7 @@ public class TxPoolBesuPendingTransactionsTest { assertThatThrownBy(() -> method.response(request)) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("The `from` filter only supports the `eq` operator"); + .hasMessageContaining("Invalid pending transactions parameter (index 1)"); } @Test @@ -283,7 +283,7 @@ public class TxPoolBesuPendingTransactionsTest { assertThatThrownBy(() -> method.response(request)) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("The `to` filter only supports the `eq` or `action` operator"); + .hasMessageContaining("Invalid pending transactions parameter (index 1)"); } private Set getTransactionPool() { diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/Web3Sha3Test.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/Web3Sha3Test.java index a978e5c0c1..d690a1a614 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/Web3Sha3Test.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/Web3Sha3Test.java @@ -123,7 +123,7 @@ public class Web3Sha3Test { "2", "web3_sha3", new Object[] {"0x68656c6c6f20776f726c64", "{encode:'hex'}"})); final JsonRpcResponse expected = - new JsonRpcErrorResponse(request.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + new JsonRpcErrorResponse(request.getRequest().getId(), RpcErrorType.INVALID_PARAM_COUNT); final JsonRpcResponse actual = method.response(request); assertThat(actual).usingRecursiveComparison().isEqualTo(expected); @@ -135,7 +135,7 @@ public class Web3Sha3Test { new JsonRpcRequestContext(new JsonRpcRequest("2", "web3_sha3", new Object[] {})); final JsonRpcResponse expected = - new JsonRpcErrorResponse(request.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + new JsonRpcErrorResponse(request.getRequest().getId(), RpcErrorType.INVALID_PARAM_COUNT); final JsonRpcResponse actual = method.response(request); assertThat(actual).usingRecursiveComparison().isEqualTo(expected); diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByHash_invalidHashAndIndex.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByHash_invalidHashAndIndex.json index 03756bd7bb..424c31ebf0 100644 --- a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByHash_invalidHashAndIndex.json +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByHash_invalidHashAndIndex.json @@ -13,7 +13,7 @@ "id" : 406, "error" : { "code" : -32602, - "message" : "Invalid params" + "message" : "Invalid number of params" } }, "statusCode": 200 diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByHash_invalidParams.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByHash_invalidParams.json index 7791942380..a0a7fea74b 100644 --- a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByHash_invalidParams.json +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByHash_invalidParams.json @@ -10,7 +10,7 @@ "id" : 412, "error" : { "code" : -32602, - "message" : "Invalid params" + "message" : "Invalid number of params" } }, "statusCode": 200 From 51335954c251a4d096bd075af5dfce9c4813605a Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Thu, 15 Aug 2024 22:02:26 -0600 Subject: [PATCH 125/259] Reuse HardforkId in EvmSpecVersion (#7448) * Reuse HardforkId in EvmSpecVersion Move the HardforkId into datatypes and re-use the data in EvmSpecVersion, keeping evm specific details in the evm and merging the rest into datatypes. Signed-off-by: Danno Ferrin * Update evm/src/main/java/org/hyperledger/besu/evm/EvmSpecVersion.java Co-authored-by: Sally MacFarlane Signed-off-by: Danno Ferrin --------- Signed-off-by: Danno Ferrin Signed-off-by: Danno Ferrin Co-authored-by: Sally MacFarlane --- .../merge/TransitionProtocolSchedule.java | 2 +- .../besu/datatypes/HardforkId.java | 164 ++++++++++++++++++ .../AbstractEngineForkchoiceUpdated.java | 2 +- .../engine/EngineForkchoiceUpdatedV3.java | 2 +- .../methods/engine/EngineGetPayloadV2.java | 2 +- .../methods/engine/EngineGetPayloadV3.java | 2 +- .../methods/engine/EngineGetPayloadV4.java | 2 +- .../methods/engine/EngineNewPayloadV2.java | 2 +- .../methods/engine/EngineNewPayloadV3.java | 2 +- .../methods/engine/EngineNewPayloadV4.java | 2 +- .../methods/engine/ForkSupportHelper.java | 2 +- .../AbstractEngineForkchoiceUpdatedTest.java | 2 +- .../engine/AbstractScheduledApiTest.java | 12 +- .../mainnet/DefaultProtocolSchedule.java | 1 + .../besu/ethereum/mainnet/HardforkId.java | 61 ------- .../ethereum/mainnet/ProtocolSchedule.java | 1 + .../mainnet/ProtocolScheduleBuilder.java | 1 + .../mainnet/ProtocolScheduleBuilderTest.java | 10 +- .../ReferenceTestProtocolSchedules.java | 106 ++++++----- .../hyperledger/besu/evm/EvmSpecVersion.java | 92 ++++------ 20 files changed, 285 insertions(+), 185 deletions(-) create mode 100644 datatypes/src/main/java/org/hyperledger/besu/datatypes/HardforkId.java delete mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/HardforkId.java diff --git a/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/TransitionProtocolSchedule.java b/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/TransitionProtocolSchedule.java index f24e11bd8b..e733cc800e 100644 --- a/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/TransitionProtocolSchedule.java +++ b/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/TransitionProtocolSchedule.java @@ -15,6 +15,7 @@ package org.hyperledger.besu.consensus.merge; import org.hyperledger.besu.config.GenesisConfigOptions; +import org.hyperledger.besu.datatypes.HardforkId; import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.chain.BadBlockManager; import org.hyperledger.besu.ethereum.core.BlockHeader; @@ -22,7 +23,6 @@ import org.hyperledger.besu.ethereum.core.Difficulty; import org.hyperledger.besu.ethereum.core.MiningParameters; import org.hyperledger.besu.ethereum.core.PermissionTransactionFilter; import org.hyperledger.besu.ethereum.core.ProcessableBlockHeader; -import org.hyperledger.besu.ethereum.mainnet.HardforkId; import org.hyperledger.besu.ethereum.mainnet.MainnetProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; diff --git a/datatypes/src/main/java/org/hyperledger/besu/datatypes/HardforkId.java b/datatypes/src/main/java/org/hyperledger/besu/datatypes/HardforkId.java new file mode 100644 index 0000000000..73eaddb7ca --- /dev/null +++ b/datatypes/src/main/java/org/hyperledger/besu/datatypes/HardforkId.java @@ -0,0 +1,164 @@ +/* + * 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.datatypes; + +/** Description and metadata for a hard fork */ +public interface HardforkId { + + /** + * The name of the hard fork. + * + * @return the name for the fork + */ + String name(); + + /** + * Has the fork been finalized? i.e., could the definition change in future versions of Besu? + * + * @return true if the specification is finalized. + */ + boolean finalized(); + + /** + * A brief description of the hard fork, suitable for human consumption + * + * @return the description of the fork. + */ + String description(); + + /** List of all Ethereum Mainnet hardforks, including future and developmental forks. */ + enum MainnetHardforkId implements HardforkId { + /** Frontier fork. */ + FRONTIER(true, "Frontier"), + /** Homestead fork. */ + HOMESTEAD(true, "Homestead"), + /** DAO Fork fork. */ + DAO_FORK(true, "DAO Fork"), + /** Tangerine Whistle fork. */ + TANGERINE_WHISTLE(true, "Tangerine Whistle"), + /** Spurious Dragon fork. */ + SPURIOUS_DRAGON(true, "Spurious Dragon"), + /** Byzantium fork. */ + BYZANTIUM(true, "Byzantium"), + /** Constantinople fork. */ + CONSTANTINOPLE(true, "Constantinople"), + /** Petersburg fork. */ + PETERSBURG(true, "Petersburg"), + /** Istanbul fork. */ + ISTANBUL(true, "Istanbul"), + /** Muir Glacier fork. */ + MUIR_GLACIER(true, "Muir Glacier"), + /** Berlin fork. */ + BERLIN(true, "Berlin"), + /** London fork. */ + LONDON(true, "London"), + /** Arrow Glacier fork. */ + ARROW_GLACIER(true, "Arrow Glacier"), + /** Gray Glacier fork. */ + GRAY_GLACIER(true, "Gray Glacier"), + /** Paris fork. */ + PARIS(true, "Paris"), + /** Shanghai fork. */ + SHANGHAI(true, "Shanghai"), + /** Cancun fork. */ + CANCUN(true, "Cancun"), + /** Cancun + EOF fork. */ + 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. */ + AMSTERDAM(false, "Amsterdam"), + /** Bogota fork. */ + BOGOTA(false, "Bogota"), + /** Polis fork. (from the greek form of an earlier incarnation of the city of Istanbul. */ + POLIS(false, "Polis"), + /** Bangkok fork. */ + BANGKOK(false, "Bangkok"), + /** Development fork, for accepted and unscheduled EIPs. */ + FUTURE_EIPS(false, "Development, for accepted and unscheduled EIPs"), + /** Developmental fork, for experimental EIPs. */ + EXPERIMENTAL_EIPS(false, "Developmental, for experimental EIPs"); + + final boolean finalized; + final String description; + + MainnetHardforkId(final boolean finalized, final String description) { + this.finalized = finalized; + this.description = description; + } + + @Override + public boolean finalized() { + return finalized; + } + + @Override + public String description() { + return description; + } + } + + /** List of all Ethereum Classic hard forks. */ + enum ClassicHardforkId implements HardforkId { + /** Frontier fork. */ + FRONTIER(true, "Frontier"), + /** Homestead fork. */ + HOMESTEAD(true, "Homestead"), + /** Classic Tangerine Whistle fork. */ + CLASSIC_TANGERINE_WHISTLE(true, "Classic Tangerine Whistle"), + /** Die Hard fork. */ + DIE_HARD(true, "Die Hard"), + /** Gotham fork. */ + GOTHAM(true, "Gotham"), + /** Defuse Difficulty Bomb fork. */ + DEFUSE_DIFFICULTY_BOMB(true, "Defuse Difficulty Bomb"), + /** Atlantis fork. */ + ATLANTIS(true, "Atlantis"), + /** Agharta fork. */ + AGHARTA(true, "Agharta"), + /** Phoenix fork. */ + PHOENIX(true, "Phoenix"), + /** Thanos fork. */ + THANOS(true, "Thanos"), + /** Magneto fork. */ + MAGNETO(true, "Magneto"), + /** Mystique fork. */ + MYSTIQUE(true, "Mystique"), + /** Spiral fork. */ + SPIRAL(true, "Spiral"); + + final boolean finalized; + final String description; + + ClassicHardforkId(final boolean finalized, final String description) { + this.finalized = finalized; + this.description = description; + } + + @Override + public boolean finalized() { + return finalized; + } + + @Override + public String description() { + return description; + } + } +} diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineForkchoiceUpdated.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineForkchoiceUpdated.java index f958b58444..df169560f5 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineForkchoiceUpdated.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineForkchoiceUpdated.java @@ -15,11 +15,11 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine; import static java.util.stream.Collectors.toList; +import static org.hyperledger.besu.datatypes.HardforkId.MainnetHardforkId.CANCUN; import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod.EngineStatus.INVALID; 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.WithdrawalsValidatorProvider.getWithdrawalsValidator; -import static org.hyperledger.besu.ethereum.mainnet.HardforkId.MainnetHardforkId.CANCUN; import org.hyperledger.besu.consensus.merge.blockcreation.MergeMiningCoordinator; import org.hyperledger.besu.consensus.merge.blockcreation.MergeMiningCoordinator.ForkchoiceResult; diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineForkchoiceUpdatedV3.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineForkchoiceUpdatedV3.java index 414d4625b2..c06b119328 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineForkchoiceUpdatedV3.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineForkchoiceUpdatedV3.java @@ -14,7 +14,7 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine; -import static org.hyperledger.besu.ethereum.mainnet.HardforkId.MainnetHardforkId.CANCUN; +import static org.hyperledger.besu.datatypes.HardforkId.MainnetHardforkId.CANCUN; import org.hyperledger.besu.consensus.merge.blockcreation.MergeMiningCoordinator; import org.hyperledger.besu.ethereum.ProtocolContext; diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV2.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV2.java index 1732585f16..ce9cdcbbb3 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV2.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV2.java @@ -14,7 +14,7 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine; -import static org.hyperledger.besu.ethereum.mainnet.HardforkId.MainnetHardforkId.CANCUN; +import static org.hyperledger.besu.datatypes.HardforkId.MainnetHardforkId.CANCUN; import org.hyperledger.besu.consensus.merge.PayloadWrapper; import org.hyperledger.besu.consensus.merge.blockcreation.MergeMiningCoordinator; diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV3.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV3.java index 555afb50b9..f0b026ef45 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV3.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV3.java @@ -14,7 +14,7 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine; -import static org.hyperledger.besu.ethereum.mainnet.HardforkId.MainnetHardforkId.CANCUN; +import static org.hyperledger.besu.datatypes.HardforkId.MainnetHardforkId.CANCUN; import org.hyperledger.besu.consensus.merge.PayloadWrapper; import org.hyperledger.besu.consensus.merge.blockcreation.MergeMiningCoordinator; diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV4.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV4.java index f67a2743ea..ba42aec2ed 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV4.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV4.java @@ -14,7 +14,7 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine; -import static org.hyperledger.besu.ethereum.mainnet.HardforkId.MainnetHardforkId.PRAGUE; +import static org.hyperledger.besu.datatypes.HardforkId.MainnetHardforkId.PRAGUE; import org.hyperledger.besu.consensus.merge.PayloadWrapper; import org.hyperledger.besu.consensus.merge.blockcreation.MergeMiningCoordinator; 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 fa15891750..acb177c3e0 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 @@ -14,7 +14,7 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine; -import static org.hyperledger.besu.ethereum.mainnet.HardforkId.MainnetHardforkId.CANCUN; +import static org.hyperledger.besu.datatypes.HardforkId.MainnetHardforkId.CANCUN; import org.hyperledger.besu.consensus.merge.blockcreation.MergeMiningCoordinator; import org.hyperledger.besu.datatypes.VersionedHash; 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 0277d6990e..393687743e 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 @@ -14,7 +14,7 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine; -import static org.hyperledger.besu.ethereum.mainnet.HardforkId.MainnetHardforkId.CANCUN; +import static org.hyperledger.besu.datatypes.HardforkId.MainnetHardforkId.CANCUN; import org.hyperledger.besu.consensus.merge.blockcreation.MergeMiningCoordinator; import org.hyperledger.besu.ethereum.ProtocolContext; 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 a767c72345..2465cdd813 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 @@ -14,7 +14,7 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine; -import static org.hyperledger.besu.ethereum.mainnet.HardforkId.MainnetHardforkId.PRAGUE; +import static org.hyperledger.besu.datatypes.HardforkId.MainnetHardforkId.PRAGUE; import org.hyperledger.besu.consensus.merge.blockcreation.MergeMiningCoordinator; import org.hyperledger.besu.ethereum.ProtocolContext; diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/ForkSupportHelper.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/ForkSupportHelper.java index 0059f3d61b..57b8f549c9 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/ForkSupportHelper.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/ForkSupportHelper.java @@ -14,8 +14,8 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine; +import org.hyperledger.besu.datatypes.HardforkId; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; -import org.hyperledger.besu.ethereum.mainnet.HardforkId; import org.hyperledger.besu.ethereum.mainnet.ValidationResult; import java.util.Optional; diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineForkchoiceUpdatedTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineForkchoiceUpdatedTest.java index d2fb3c3741..5496224e25 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineForkchoiceUpdatedTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineForkchoiceUpdatedTest.java @@ -16,10 +16,10 @@ 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.hyperledger.besu.datatypes.HardforkId.MainnetHardforkId.CANCUN; import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod.EngineStatus.INVALID; 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.mainnet.HardforkId.MainnetHardforkId.CANCUN; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.mock; diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractScheduledApiTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractScheduledApiTest.java index bfe23e07e7..46fe7d3b6c 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractScheduledApiTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractScheduledApiTest.java @@ -14,12 +14,12 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine; -import static org.hyperledger.besu.ethereum.mainnet.HardforkId.MainnetHardforkId.CANCUN; -import static org.hyperledger.besu.ethereum.mainnet.HardforkId.MainnetHardforkId.EXPERIMENTAL_EIPS; -import static org.hyperledger.besu.ethereum.mainnet.HardforkId.MainnetHardforkId.LONDON; -import static org.hyperledger.besu.ethereum.mainnet.HardforkId.MainnetHardforkId.PARIS; -import static org.hyperledger.besu.ethereum.mainnet.HardforkId.MainnetHardforkId.PRAGUE; -import static org.hyperledger.besu.ethereum.mainnet.HardforkId.MainnetHardforkId.SHANGHAI; +import static org.hyperledger.besu.datatypes.HardforkId.MainnetHardforkId.CANCUN; +import static org.hyperledger.besu.datatypes.HardforkId.MainnetHardforkId.EXPERIMENTAL_EIPS; +import static org.hyperledger.besu.datatypes.HardforkId.MainnetHardforkId.LONDON; +import static org.hyperledger.besu.datatypes.HardforkId.MainnetHardforkId.PARIS; +import static org.hyperledger.besu.datatypes.HardforkId.MainnetHardforkId.PRAGUE; +import static org.hyperledger.besu.datatypes.HardforkId.MainnetHardforkId.SHANGHAI; import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.mock; diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DefaultProtocolSchedule.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DefaultProtocolSchedule.java index d6d3cc0a55..4c67466b9b 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DefaultProtocolSchedule.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DefaultProtocolSchedule.java @@ -16,6 +16,7 @@ package org.hyperledger.besu.ethereum.mainnet; import static com.google.common.base.Preconditions.checkArgument; +import org.hyperledger.besu.datatypes.HardforkId; import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.PermissionTransactionFilter; import org.hyperledger.besu.ethereum.core.ProcessableBlockHeader; diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/HardforkId.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/HardforkId.java deleted file mode 100644 index 6c764a4209..0000000000 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/HardforkId.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.mainnet; - -public interface HardforkId { - - String name(); - - enum MainnetHardforkId implements HardforkId { - FRONTIER, - HOMESTEAD, - DAO_FORK, - TANGERINE_WHISTLE, - SPURIOUS_DRAGON, - BYZANTIUM, - CONSTANTINOPLE, - PETERSBURG, - ISTANBUL, - MUIR_GLACIER, - BERLIN, - LONDON, - ARROW_GLACIER, - GRAY_GLACIER, - PARIS, - SHANGHAI, - CANCUN, - CANCUN_EOF, - PRAGUE, - PRAGUE_EOF, - FUTURE_EIPS, - EXPERIMENTAL_EIPS - } - - enum ClassicHardforkId implements HardforkId { - FRONTIER, - HOMESTEAD, - CLASSIC_TANGERINE_WHISTLE, - DIE_HARD, - GOTHAM, - DEFUSE_DIFFICULTY_BOMB, - ATLANTIS, - AGHARTA, - PHOENIX, - THANOS, - MAGNETO, - MYSTIQUE, - SPIRAL - } -} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolSchedule.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolSchedule.java index 88448a8b54..f97d8f27ea 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolSchedule.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolSchedule.java @@ -14,6 +14,7 @@ */ package org.hyperledger.besu.ethereum.mainnet; +import org.hyperledger.besu.datatypes.HardforkId; import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.BlockHeaderBuilder; import org.hyperledger.besu.ethereum.core.ProcessableBlockHeader; 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 fb8abbe1b6..beac906be5 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 @@ -15,6 +15,7 @@ package org.hyperledger.besu.ethereum.mainnet; import org.hyperledger.besu.config.GenesisConfigOptions; +import org.hyperledger.besu.datatypes.HardforkId; import org.hyperledger.besu.ethereum.chain.BadBlockManager; import org.hyperledger.besu.ethereum.core.MiningParameters; import org.hyperledger.besu.ethereum.core.PrivacyParameters; diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/ProtocolScheduleBuilderTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/ProtocolScheduleBuilderTest.java index a1f3d64797..ad261abf47 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/ProtocolScheduleBuilderTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/ProtocolScheduleBuilderTest.java @@ -16,11 +16,11 @@ package org.hyperledger.besu.ethereum.mainnet; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.hyperledger.besu.ethereum.mainnet.HardforkId.MainnetHardforkId.BERLIN; -import static org.hyperledger.besu.ethereum.mainnet.HardforkId.MainnetHardforkId.CANCUN; -import static org.hyperledger.besu.ethereum.mainnet.HardforkId.MainnetHardforkId.LONDON; -import static org.hyperledger.besu.ethereum.mainnet.HardforkId.MainnetHardforkId.PRAGUE; -import static org.hyperledger.besu.ethereum.mainnet.HardforkId.MainnetHardforkId.SHANGHAI; +import static org.hyperledger.besu.datatypes.HardforkId.MainnetHardforkId.BERLIN; +import static org.hyperledger.besu.datatypes.HardforkId.MainnetHardforkId.CANCUN; +import static org.hyperledger.besu.datatypes.HardforkId.MainnetHardforkId.LONDON; +import static org.hyperledger.besu.datatypes.HardforkId.MainnetHardforkId.PRAGUE; +import static org.hyperledger.besu.datatypes.HardforkId.MainnetHardforkId.SHANGHAI; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; 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 5dfb12f1d6..d6c5afdc4a 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 @@ -32,10 +32,10 @@ import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import java.math.BigInteger; import java.util.Arrays; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.function.Function; - -import com.google.common.collect.ImmutableMap; +import java.util.stream.Collectors; public class ReferenceTestProtocolSchedules { @@ -49,57 +49,67 @@ public class ReferenceTestProtocolSchedules { } public static ReferenceTestProtocolSchedules create(final StubGenesisConfigOptions genesisStub) { - final ImmutableMap.Builder builder = ImmutableMap.builder(); - builder.put("Frontier", createSchedule(genesisStub.clone())); - builder.put("FrontierToHomesteadAt5", createSchedule(genesisStub.clone().homesteadBlock(5))); - builder.put("Homestead", createSchedule(genesisStub.clone().homesteadBlock(0))); - builder.put( - "HomesteadToEIP150At5", - createSchedule(genesisStub.clone().homesteadBlock(0).eip150Block(5))); - builder.put( - "HomesteadToDaoAt5", createSchedule(genesisStub.clone().homesteadBlock(0).daoForkBlock(5))); - builder.put("EIP150", createSchedule(genesisStub.clone().eip150Block(0))); - builder.put("EIP158", createSchedule(genesisStub.clone().eip158Block(0))); - builder.put( - "EIP158ToByzantiumAt5", - createSchedule(genesisStub.clone().eip158Block(0).byzantiumBlock(5))); - builder.put("Byzantium", createSchedule(genesisStub.clone().byzantiumBlock(0))); - builder.put("Constantinople", createSchedule(genesisStub.clone().constantinopleBlock(0))); - builder.put("ConstantinopleFix", createSchedule(genesisStub.clone().petersburgBlock(0))); - builder.put("Petersburg", createSchedule(genesisStub.clone().petersburgBlock(0))); - builder.put("Istanbul", createSchedule(genesisStub.clone().istanbulBlock(0))); - builder.put("MuirGlacier", createSchedule(genesisStub.clone().muirGlacierBlock(0))); - builder.put("Berlin", createSchedule(genesisStub.clone().berlinBlock(0))); - // the following schedules activate EIP-1559, but may have non-default if (genesisStub.getBaseFeePerGas().isEmpty()) { genesisStub.baseFeePerGas(0x0a); } - builder.put("London", createSchedule(genesisStub.clone().londonBlock(0))); - builder.put("ArrowGlacier", createSchedule(genesisStub.clone().arrowGlacierBlock(0))); - builder.put("GrayGlacier", createSchedule(genesisStub.clone().grayGlacierBlock(0))); - builder.put("Merge", createSchedule(genesisStub.clone().mergeNetSplitBlock(0))); - builder.put("Paris", createSchedule(genesisStub.clone().mergeNetSplitBlock(0))); - builder.put("Shanghai", createSchedule(genesisStub.clone().shanghaiTime(0))); - builder.put( - "ShanghaiToCancunAtTime15k", - createSchedule(genesisStub.clone().shanghaiTime(0).cancunTime(15000))); - builder.put("Cancun", createSchedule(genesisStub.clone().cancunTime(0))); - builder.put("CancunEOF", createSchedule(genesisStub.clone().cancunEOFTime(0))); // also load KZG file for mainnet KZGPointEvalPrecompiledContract.init(); - builder.put( - "CancunToPragueAtTime15k", - createSchedule(genesisStub.clone().cancunTime(0).pragueTime(15000))); - builder.put("Prague", createSchedule(genesisStub.clone().pragueEOFTime(0))); - builder.put("Osaka", createSchedule(genesisStub.clone().futureEipsTime(0))); - builder.put("Amsterdam", createSchedule(genesisStub.clone().futureEipsTime(0))); - builder.put("Bogota", createSchedule(genesisStub.clone().futureEipsTime(0))); - builder.put("Polis", createSchedule(genesisStub.clone().futureEipsTime(0))); - builder.put("Bangkok", createSchedule(genesisStub.clone().futureEipsTime(0))); - builder.put("Future_EIPs", createSchedule(genesisStub.clone().futureEipsTime(0))); - builder.put("Experimental_EIPs", createSchedule(genesisStub.clone().experimentalEipsTime(0))); - return new ReferenceTestProtocolSchedules(builder.build()); + return new ReferenceTestProtocolSchedules( + Map.ofEntries( + Map.entry("Frontier", createSchedule(genesisStub.clone())), + Map.entry( + "FrontierToHomesteadAt5", + createSchedule(genesisStub.clone().homesteadBlock(5))), + Map.entry("Homestead", createSchedule(genesisStub.clone().homesteadBlock(0))), + Map.entry( + "HomesteadToEIP150At5", + createSchedule(genesisStub.clone().homesteadBlock(0).eip150Block(5))), + Map.entry( + "HomesteadToDaoAt5", + createSchedule(genesisStub.clone().homesteadBlock(0).daoForkBlock(5))), + Map.entry("EIP150", createSchedule(genesisStub.clone().eip150Block(0))), + Map.entry("EIP158", createSchedule(genesisStub.clone().eip158Block(0))), + Map.entry( + "EIP158ToByzantiumAt5", + createSchedule(genesisStub.clone().eip158Block(0).byzantiumBlock(5))), + Map.entry("Byzantium", createSchedule(genesisStub.clone().byzantiumBlock(0))), + Map.entry( + "Constantinople", createSchedule(genesisStub.clone().constantinopleBlock(0))), + Map.entry( + "ConstantinopleFix", createSchedule(genesisStub.clone().petersburgBlock(0))), + Map.entry("Petersburg", createSchedule(genesisStub.clone().petersburgBlock(0))), + Map.entry("Istanbul", createSchedule(genesisStub.clone().istanbulBlock(0))), + Map.entry("MuirGlacier", createSchedule(genesisStub.clone().muirGlacierBlock(0))), + Map.entry("Berlin", createSchedule(genesisStub.clone().berlinBlock(0))), + Map.entry("London", createSchedule(genesisStub.clone().londonBlock(0))), + Map.entry("ArrowGlacier", createSchedule(genesisStub.clone().arrowGlacierBlock(0))), + Map.entry("GrayGlacier", createSchedule(genesisStub.clone().grayGlacierBlock(0))), + Map.entry("Merge", createSchedule(genesisStub.clone().mergeNetSplitBlock(0))), + Map.entry("Paris", createSchedule(genesisStub.clone().mergeNetSplitBlock(0))), + Map.entry("Shanghai", createSchedule(genesisStub.clone().shanghaiTime(0))), + Map.entry( + "ShanghaiToCancunAtTime15k", + createSchedule(genesisStub.clone().shanghaiTime(0).cancunTime(15000))), + Map.entry("Cancun", createSchedule(genesisStub.clone().cancunTime(0))), + Map.entry("CancunEOF", createSchedule(genesisStub.clone().cancunEOFTime(0))), + 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("Amsterdam", createSchedule(genesisStub.clone().futureEipsTime(0))), + Map.entry("Bogota", createSchedule(genesisStub.clone().futureEipsTime(0))), + Map.entry("Polis", createSchedule(genesisStub.clone().futureEipsTime(0))), + Map.entry("Bangkok", createSchedule(genesisStub.clone().futureEipsTime(0))), + Map.entry("Future_EIPs", createSchedule(genesisStub.clone().futureEipsTime(0))), + Map.entry( + "Experimental_EIPs", + createSchedule(genesisStub.clone().experimentalEipsTime(0)))) + .entrySet() + .stream() + .map(e -> Map.entry(e.getKey().toLowerCase(Locale.ROOT), e.getValue())) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))); } private final Map schedules; @@ -109,7 +119,7 @@ public class ReferenceTestProtocolSchedules { } public ProtocolSchedule getByName(final String name) { - return schedules.get(name); + return schedules.get(name.toLowerCase(Locale.ROOT)); } public ProtocolSpec geSpecByName(final String name) { 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 5368a7fd74..7d4344c6bc 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/EvmSpecVersion.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/EvmSpecVersion.java @@ -14,6 +14,9 @@ */ package org.hyperledger.besu.evm; +import org.hyperledger.besu.datatypes.HardforkId; +import org.hyperledger.besu.datatypes.HardforkId.MainnetHardforkId; + import java.util.Comparator; import java.util.stream.Stream; @@ -23,65 +26,56 @@ import org.slf4j.LoggerFactory; /** The enum Evm spec version. */ public enum EvmSpecVersion { /** Frontier evm spec version. */ - FRONTIER(Integer.MAX_VALUE, Integer.MAX_VALUE, 0, true, "Frontier", "Finalized"), + FRONTIER(MainnetHardforkId.FRONTIER, Integer.MAX_VALUE, Integer.MAX_VALUE, 0), /** Homestead evm spec version. */ - HOMESTEAD(Integer.MAX_VALUE, Integer.MAX_VALUE, 0, true, "Homestead", "Finalized"), + HOMESTEAD(MainnetHardforkId.HOMESTEAD, Integer.MAX_VALUE, Integer.MAX_VALUE, 0), /** Tangerine Whistle evm spec version. */ - TANGERINE_WHISTLE( - Integer.MAX_VALUE, Integer.MAX_VALUE, 0, true, "Tangerine Whistle", "Finalized"), + TANGERINE_WHISTLE(MainnetHardforkId.TANGERINE_WHISTLE, Integer.MAX_VALUE, Integer.MAX_VALUE, 0), /** Spurious Dragon evm spec version. */ - SPURIOUS_DRAGON(0x6000, Integer.MAX_VALUE, 0, true, "Spuruous Dragon", "Finalized"), + SPURIOUS_DRAGON(MainnetHardforkId.SPURIOUS_DRAGON, 0x6000, Integer.MAX_VALUE, 0), /** Byzantium evm spec version. */ - BYZANTIUM(0x6000, Integer.MAX_VALUE, 0, true, "Byzantium", "Finalized"), + BYZANTIUM(MainnetHardforkId.BYZANTIUM, 0x6000, Integer.MAX_VALUE, 0), /** Constantinople evm spec version. */ - CONSTANTINOPLE(0x6000, Integer.MAX_VALUE, 0, true, "Constantinople", "Did not reach Mainnet"), + CONSTANTINOPLE(MainnetHardforkId.CONSTANTINOPLE, 0x6000, Integer.MAX_VALUE, 0), /** Petersburg / ConstantinopleFix evm spec version. */ - PETERSBURG( - 0x6000, - Integer.MAX_VALUE, - 0, - true, - "ConstantinopleFix", - "Finalized (also called Petersburg)"), + PETERSBURG(MainnetHardforkId.PETERSBURG, 0x6000, Integer.MAX_VALUE, 0), /** Istanbul evm spec version. */ - ISTANBUL(0x6000, Integer.MAX_VALUE, 0, true, "Istanbul", "Finalized"), + ISTANBUL(MainnetHardforkId.ISTANBUL, 0x6000, Integer.MAX_VALUE, 0), /** Berlin evm spec version */ - BERLIN(0x6000, Integer.MAX_VALUE, 0, true, "Berlin", "Finalized"), + BERLIN(MainnetHardforkId.BERLIN, 0x6000, Integer.MAX_VALUE, 0), /** London evm spec version. */ - LONDON(0x6000, Integer.MAX_VALUE, 0, true, "London", "Finalized"), + LONDON(MainnetHardforkId.LONDON, 0x6000, Integer.MAX_VALUE, 0), /** Paris evm spec version. */ - PARIS(0x6000, Integer.MAX_VALUE, 0, true, "Merge", "Finalized (also called Paris)"), + PARIS(MainnetHardforkId.PARIS, 0x6000, Integer.MAX_VALUE, 0), /** Shanghai evm spec version. */ - SHANGHAI(0x6000, 0xc000, 0, true, "Shanghai", "Finalized"), + SHANGHAI(MainnetHardforkId.SHANGHAI, 0x6000, 0xc000, 0), /** Cancun evm spec version. */ - CANCUN(0x6000, 0xc000, 0, true, "Cancun", "Finalized"), + CANCUN(MainnetHardforkId.CANCUN, 0x6000, 0xc000, 0), /** Cancun evm spec version. */ - CANCUN_EOF(0x6000, 0xc000, 1, false, "CancunEOF", "For Testing"), + CANCUN_EOF(MainnetHardforkId.CANCUN_EOF, 0x6000, 0xc000, 1), /** Prague evm spec version. */ - PRAGUE(0x6000, 0xc000, 0, false, "Prague", "In Development"), + PRAGUE(MainnetHardforkId.PRAGUE, 0x6000, 0xc000, 0), /** PragueEOF evm spec version. */ - PRAGUE_EOF(0x6000, 0xc000, 1, false, "PragueEOF", "Prague + EOF. In Development"), + PRAGUE_EOF(MainnetHardforkId.PRAGUE_EOF, 0x6000, 0xc000, 1), /** Osaka evm spec version. */ - OSAKA(0x6000, 0xc000, 1, false, "Osaka", "Placeholder"), + OSAKA(MainnetHardforkId.OSAKA, 0x6000, 0xc000, 1), /** Amsterdam evm spec version. */ - AMSTERDAM(0x6000, 0xc000, 1, false, "Amsterdam", "Placeholder"), + AMSTERDAM(MainnetHardforkId.AMSTERDAM, 0x6000, 0xc000, 1), /** Bogota evm spec version. */ - BOGOTA(0x6000, 0xc000, 1, false, "Bogota", "Placeholder"), + BOGOTA(MainnetHardforkId.BOGOTA, 0x6000, 0xc000, 1), /** Polis evm spec version. */ - POLIS(0x6000, 0xc000, 1, false, "Polis", "Placeholder"), - /** Bogota evm spec version. */ - BANGKOK(0x6000, 0xc000, 1, false, "Bangkok", "Placeholder"), + POLIS(MainnetHardforkId.POLIS, 0x6000, 0xc000, 1), + /** Bangkok evm spec version. */ + BANGKOK(MainnetHardforkId.BANGKOK, 0x6000, 0xc000, 1), /** Development fork for unscheduled EIPs */ - FUTURE_EIPS( - 0x6000, 0xc000, 1, false, "Future_EIPs", "Development, for accepted and unscheduled EIPs"), - /** Development fork for EIPs not accepted to Mainnet */ - EXPERIMENTAL_EIPS( - 0x6000, 0xc000, 1, false, "Experimental_EIPs", "Development, for experimental EIPs"); + FUTURE_EIPS(MainnetHardforkId.FUTURE_EIPS, 0x6000, 0xc000, 1), + /** Development fork for EIPs that are not yet accepted to Mainnet */ + EXPERIMENTAL_EIPS(MainnetHardforkId.EXPERIMENTAL_EIPS, 0x6000, 0xc000, 1); private static final Logger LOGGER = LoggerFactory.getLogger(EvmSpecVersion.class); - /** The Spec finalized. */ - final boolean specFinalized; + /** What hardfork did this VM version first show up in? */ + final HardforkId initialHardfork; /** The Max eof version. */ final int maxEofVersion; @@ -92,28 +86,18 @@ public enum EvmSpecVersion { /** Maximum size of initcode */ final int maxInitcodeSize; - /** Public name matching execution-spec-tests name */ - final String name; - - /** A brief description of the state of the fork */ - final String description; - /** The Version warned. */ boolean versionWarned = false; EvmSpecVersion( + final HardforkId initialHarfork, final int maxCodeSize, final int maxInitcodeSize, - final int maxEofVersion, - final boolean specFinalized, - final String name, - final String description) { + final int maxEofVersion) { + this.initialHardfork = initialHarfork; this.maxEofVersion = maxEofVersion; this.maxCodeSize = maxCodeSize; this.maxInitcodeSize = maxInitcodeSize; - this.specFinalized = specFinalized; - this.name = name; - this.description = description; } /** @@ -125,7 +109,7 @@ public enum EvmSpecVersion { public static EvmSpecVersion defaultVersion() { EvmSpecVersion answer = null; for (EvmSpecVersion version : EvmSpecVersion.values()) { - if (version.specFinalized) { + if (version.initialHardfork.finalized()) { answer = version; } } @@ -165,7 +149,7 @@ public enum EvmSpecVersion { * @return name of the fork */ public String getName() { - return name; + return initialHardfork.name(); } /** @@ -174,7 +158,7 @@ public enum EvmSpecVersion { * @return description */ public String getDescription() { - return description; + return initialHardfork.description(); } /** Maybe warn version. */ @@ -184,7 +168,7 @@ public enum EvmSpecVersion { return; } - if (!specFinalized) { + if (!initialHardfork.finalized()) { LOGGER.error( "****** Not for Production Network Use ******\nExecuting code from EVM Spec Version {}, which has not been finalized.\n****** Not for Production Network Use ******", this.name()); @@ -223,7 +207,7 @@ public enum EvmSpecVersion { */ public static EvmSpecVersion mostRecent() { return Stream.of(EvmSpecVersion.values()) - .filter(v -> v.specFinalized) + .filter(v -> v.initialHardfork.finalized()) .max(Comparator.naturalOrder()) .orElseThrow(); } From d7041d4221dc1bc4fb9e7e529df4468931d64a11 Mon Sep 17 00:00:00 2001 From: Gabriel-Trintinalia Date: Fri, 16 Aug 2024 15:09:31 +1000 Subject: [PATCH 126/259] CLI option for disabling auto-registration of external plugins (#7470) Signed-off-by: Gabriel-Trintinalia --- .../dsl/node/ThreadBesuNodeRunner.java | 3 +- .../services/BesuPluginContextImplTest.java | 46 +++++-- .../org/hyperledger/besu/cli/BesuCommand.java | 9 +- .../besu/cli/DefaultCommandValues.java | 3 + .../stable/PluginsConfigurationOptions.java | 38 +++++- .../besu/services/BesuPluginContextImpl.java | 30 +++-- .../besu/cli/PluginsOptionsTest.java | 118 ++++++++++++++++++ .../src/test/resources/everything_config.toml | 4 + .../core/plugins/PluginConfiguration.java | 94 +++++++------- 9 files changed, 269 insertions(+), 76 deletions(-) create mode 100644 besu/src/test/java/org/hyperledger/besu/cli/PluginsOptionsTest.java 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 7e8d435c72..001406cb78 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 @@ -432,7 +432,8 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner { besuPluginContext.addService(PermissioningService.class, permissioningService); besuPluginContext.addService(PrivacyPluginService.class, new PrivacyPluginServiceImpl()); - besuPluginContext.registerPlugins(new PluginConfiguration(pluginsPath)); + besuPluginContext.registerPlugins( + new PluginConfiguration.Builder().pluginsDir(pluginsPath).build()); // register built-in plugins new RocksDBPlugin().register(besuPluginContext); diff --git a/acceptance-tests/test-plugins/src/test/java/org/hyperledger/besu/services/BesuPluginContextImplTest.java b/acceptance-tests/test-plugins/src/test/java/org/hyperledger/besu/services/BesuPluginContextImplTest.java index c266eaf66a..7e27704177 100644 --- a/acceptance-tests/test-plugins/src/test/java/org/hyperledger/besu/services/BesuPluginContextImplTest.java +++ b/acceptance-tests/test-plugins/src/test/java/org/hyperledger/besu/services/BesuPluginContextImplTest.java @@ -64,7 +64,8 @@ public class BesuPluginContextImplTest { @Test public void verifyEverythingGoesSmoothly() { assertThat(contextImpl.getRegisteredPlugins()).isEmpty(); - contextImpl.registerPlugins(new PluginConfiguration(DEFAULT_PLUGIN_DIRECTORY)); + contextImpl.registerPlugins( + PluginConfiguration.builder().pluginsDir(DEFAULT_PLUGIN_DIRECTORY).build()); assertThat(contextImpl.getRegisteredPlugins()).isNotEmpty(); final Optional testPluginOptional = @@ -86,7 +87,8 @@ public class BesuPluginContextImplTest { System.setProperty("testPicoCLIPlugin.testOption", "FAILREGISTER"); assertThat(contextImpl.getRegisteredPlugins()).isEmpty(); - contextImpl.registerPlugins(new PluginConfiguration(DEFAULT_PLUGIN_DIRECTORY)); + contextImpl.registerPlugins( + PluginConfiguration.builder().pluginsDir(DEFAULT_PLUGIN_DIRECTORY).build()); assertThat(contextImpl.getRegisteredPlugins()).isNotInstanceOfAny(TestPicoCLIPlugin.class); contextImpl.beforeExternalServices(); @@ -104,7 +106,8 @@ public class BesuPluginContextImplTest { System.setProperty("testPicoCLIPlugin.testOption", "FAILSTART"); assertThat(contextImpl.getRegisteredPlugins()).isEmpty(); - contextImpl.registerPlugins(new PluginConfiguration(DEFAULT_PLUGIN_DIRECTORY)); + contextImpl.registerPlugins( + PluginConfiguration.builder().pluginsDir(DEFAULT_PLUGIN_DIRECTORY).build()); assertThat(contextImpl.getRegisteredPlugins()) .extracting("class") .contains(TestPicoCLIPlugin.class); @@ -129,7 +132,8 @@ public class BesuPluginContextImplTest { System.setProperty("testPicoCLIPlugin.testOption", "FAILSTOP"); assertThat(contextImpl.getRegisteredPlugins()).isEmpty(); - contextImpl.registerPlugins(new PluginConfiguration(DEFAULT_PLUGIN_DIRECTORY)); + contextImpl.registerPlugins( + PluginConfiguration.builder().pluginsDir(DEFAULT_PLUGIN_DIRECTORY).build()); assertThat(contextImpl.getRegisteredPlugins()) .extracting("class") .contains(TestPicoCLIPlugin.class); @@ -151,7 +155,9 @@ public class BesuPluginContextImplTest { @Test public void lifecycleExceptions() throws Throwable { final ThrowableAssert.ThrowingCallable registerPlugins = - () -> contextImpl.registerPlugins(new PluginConfiguration(DEFAULT_PLUGIN_DIRECTORY)); + () -> + contextImpl.registerPlugins( + PluginConfiguration.builder().pluginsDir(DEFAULT_PLUGIN_DIRECTORY).build()); assertThatExceptionOfType(IllegalStateException.class).isThrownBy(contextImpl::startPlugins); assertThatExceptionOfType(IllegalStateException.class).isThrownBy(contextImpl::stopPlugins); @@ -173,7 +179,8 @@ public class BesuPluginContextImplTest { @Test public void shouldRegisterAllPluginsWhenNoPluginsOption() { - final PluginConfiguration config = createConfigurationForAllPlugins(); + final PluginConfiguration config = + PluginConfiguration.builder().pluginsDir(DEFAULT_PLUGIN_DIRECTORY).build(); assertThat(contextImpl.getRegisteredPlugins()).isEmpty(); contextImpl.registerPlugins(config); @@ -227,12 +234,33 @@ public class BesuPluginContextImplTest { assertThat(contextImpl.getRegisteredPlugins()).isEmpty(); } - private PluginConfiguration createConfigurationForAllPlugins() { - return new PluginConfiguration(null, DEFAULT_PLUGIN_DIRECTORY); + @Test + void shouldNotRegisterAnyPluginsIfExternalPluginsDisabled() { + PluginConfiguration config = + PluginConfiguration.builder() + .pluginsDir(DEFAULT_PLUGIN_DIRECTORY) + .externalPluginsEnabled(false) + .build(); + contextImpl.registerPlugins(config); + assertThat(contextImpl.getRegisteredPlugins().isEmpty()).isTrue(); + } + + @Test + void shouldRegisterPluginsIfExternalPluginsEnabled() { + PluginConfiguration config = + PluginConfiguration.builder() + .pluginsDir(DEFAULT_PLUGIN_DIRECTORY) + .externalPluginsEnabled(true) + .build(); + contextImpl.registerPlugins(config); + assertThat(contextImpl.getRegisteredPlugins().isEmpty()).isFalse(); } private PluginConfiguration createConfigurationForSpecificPlugin(final String pluginName) { - return new PluginConfiguration(List.of(new PluginInfo(pluginName)), DEFAULT_PLUGIN_DIRECTORY); + return PluginConfiguration.builder() + .requestedPlugins(List.of(new PluginInfo(pluginName))) + .pluginsDir(DEFAULT_PLUGIN_DIRECTORY) + .build(); } private Optional findTestPlugin( 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 a0e99db69f..ba61a869ff 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java @@ -1122,7 +1122,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { runner.startExternalServices(); startPlugins(runner); - validatePluginOptions(); + validatePrivacyPluginOptions(); setReleaseMetrics(); preSynchronization(); @@ -1347,7 +1347,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { besuPluginContext.startPlugins(); } - private void validatePluginOptions() { + private void validatePrivacyPluginOptions() { // plugins do not 'wire up' until start has been called // consequently you can only do some configuration checks // after start has been called on plugins @@ -1491,6 +1491,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { validateGraphQlOptions(); validateApiOptions(); validateConsensusSyncCompatibilityOptions(); + validatePluginOptions(); p2pTLSConfigOptions.checkP2PTLSOptionsDependencies(logger, commandLine); } @@ -1511,6 +1512,10 @@ public class BesuCommand implements DefaultCommandValues, Runnable { } } + private void validatePluginOptions() { + pluginsConfigurationOptions.validate(commandLine); + } + private void validateApiOptions() { apiConfigurationOptions.validate(commandLine, logger); } diff --git a/besu/src/main/java/org/hyperledger/besu/cli/DefaultCommandValues.java b/besu/src/main/java/org/hyperledger/besu/cli/DefaultCommandValues.java index 84055db663..ba05f45524 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/DefaultCommandValues.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/DefaultCommandValues.java @@ -128,6 +128,9 @@ public interface DefaultCommandValues { /** The constant DEFAULT_PLUGINS_OPTION_NAME. */ String DEFAULT_PLUGINS_OPTION_NAME = "--plugins"; + /** The constant DEFAULT_PLUGINS_EXTERNAL_ENABLED_OPTION_NAME. */ + String DEFAULT_PLUGINS_EXTERNAL_ENABLED_OPTION_NAME = "--Xplugins-external-enabled"; + /** * Gets default besu data path. * diff --git a/besu/src/main/java/org/hyperledger/besu/cli/options/stable/PluginsConfigurationOptions.java b/besu/src/main/java/org/hyperledger/besu/cli/options/stable/PluginsConfigurationOptions.java index 88f88c06d4..47df831c57 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/options/stable/PluginsConfigurationOptions.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/options/stable/PluginsConfigurationOptions.java @@ -14,6 +14,7 @@ */ package org.hyperledger.besu.cli.options.stable; +import static org.hyperledger.besu.cli.DefaultCommandValues.DEFAULT_PLUGINS_EXTERNAL_ENABLED_OPTION_NAME; import static org.hyperledger.besu.cli.DefaultCommandValues.DEFAULT_PLUGINS_OPTION_NAME; import org.hyperledger.besu.cli.converter.PluginInfoConverter; @@ -28,6 +29,15 @@ import picocli.CommandLine; /** The Plugins Options options. */ public class PluginsConfigurationOptions implements CLIOptions { + + @CommandLine.Option( + names = {DEFAULT_PLUGINS_EXTERNAL_ENABLED_OPTION_NAME}, + description = "Enables external plugins (default: ${DEFAULT-VALUE})", + hidden = true, + defaultValue = "true", + arity = "1") + private Boolean externalPluginsEnabled = true; + @CommandLine.Option( names = {DEFAULT_PLUGINS_OPTION_NAME}, description = "Comma-separated list of plugin names", @@ -42,7 +52,24 @@ public class PluginsConfigurationOptions implements CLIOptions registeringPlugins = - matchAndValidateRequestedPlugins(requestedPlugins, detectedPlugins); - - registerPlugins(registeringPlugins); + if (config.isExternalPluginsEnabled()) { + detectedPlugins = detectPlugins(config); + + if (config.getRequestedPlugins().isEmpty()) { + // If no plugins were specified, register all detected plugins + registerPlugins(detectedPlugins); + } else { + // Register only the plugins that were explicitly requested and validated + requestedPlugins = config.getRequestedPlugins(); + // Match and validate the requested plugins against the detected plugins + List registeringPlugins = + matchAndValidateRequestedPlugins(requestedPlugins, detectedPlugins); + + registerPlugins(registeringPlugins); + } } else { - // If no plugins were specified, register all detected plugins - registerPlugins(detectedPlugins); + LOG.debug("External plugins are disabled. Skipping plugins registration."); } + state = Lifecycle.REGISTERED; } private List matchAndValidateRequestedPlugins( @@ -182,7 +187,6 @@ public class BesuPluginContextImpl implements BesuContext, PluginVersionsProvide registeredPlugins.add(plugin); } } - state = Lifecycle.REGISTERED; } private boolean registerPlugin(final BesuPlugin plugin) { diff --git a/besu/src/test/java/org/hyperledger/besu/cli/PluginsOptionsTest.java b/besu/src/test/java/org/hyperledger/besu/cli/PluginsOptionsTest.java new file mode 100644 index 0000000000..1adfb585e9 --- /dev/null +++ b/besu/src/test/java/org/hyperledger/besu/cli/PluginsOptionsTest.java @@ -0,0 +1,118 @@ +/* + * 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; + +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.verify; + +import org.hyperledger.besu.ethereum.core.plugins.PluginConfiguration; + +import java.util.List; + +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; + +public class PluginsOptionsTest extends CommandTestAbstract { + + @Captor protected ArgumentCaptor pluginConfigurationArgumentCaptor; + + @Test + public void shouldParsePluginOptionForSinglePlugin() { + parseCommand("--plugins", "pluginA"); + verify(mockBesuPluginContext).registerPlugins(pluginConfigurationArgumentCaptor.capture()); + assertThat(pluginConfigurationArgumentCaptor.getValue().getRequestedPlugins()) + .isEqualTo(List.of("pluginA")); + assertThat(commandOutput.toString(UTF_8)).isEmpty(); + assertThat(commandErrorOutput.toString(UTF_8)).isEmpty(); + } + + @Test + public void shouldParsePluginOptionForMultiplePlugins() { + parseCommand("--plugins", "pluginA,pluginB"); + verify(mockBesuPluginContext).registerPlugins(pluginConfigurationArgumentCaptor.capture()); + assertThat(pluginConfigurationArgumentCaptor.getValue().getRequestedPlugins()) + .isEqualTo(List.of("pluginA", "pluginB")); + + assertThat(commandOutput.toString(UTF_8)).isEmpty(); + assertThat(commandErrorOutput.toString(UTF_8)).isEmpty(); + } + + @Test + public void shouldNotUsePluginOptionWhenNoPluginsSpecified() { + parseCommand(); + verify(mockBesuPluginContext).registerPlugins(pluginConfigurationArgumentCaptor.capture()); + assertThat(pluginConfigurationArgumentCaptor.getValue().getRequestedPlugins()) + .isEqualTo(List.of()); + assertThat(commandOutput.toString(UTF_8)).isEmpty(); + assertThat(commandErrorOutput.toString(UTF_8)).isEmpty(); + } + + @Test + public void shouldNotParseAnyPluginsWhenPluginOptionIsEmpty() { + parseCommand("--plugins", ""); + verify(mockBesuPluginContext).registerPlugins(pluginConfigurationArgumentCaptor.capture()); + assertThat(pluginConfigurationArgumentCaptor.getValue().getRequestedPlugins()) + .isEqualTo(List.of()); + assertThat(commandOutput.toString(UTF_8)).isEmpty(); + assertThat(commandErrorOutput.toString(UTF_8)).isEmpty(); + } + + @Test + public void shouldParsePluginsExternalEnabledOptionWhenFalse() { + parseCommand("--Xplugins-external-enabled=false"); + verify(mockBesuPluginContext).registerPlugins(pluginConfigurationArgumentCaptor.capture()); + + assertThat(pluginConfigurationArgumentCaptor.getValue().isExternalPluginsEnabled()) + .isEqualTo(false); + + assertThat(commandOutput.toString(UTF_8)).isEmpty(); + assertThat(commandErrorOutput.toString(UTF_8)).isEmpty(); + } + + @Test + public void shouldParsePluginsExternalEnabledOptionWhenTrue() { + parseCommand("--Xplugins-external-enabled=true"); + verify(mockBesuPluginContext).registerPlugins(pluginConfigurationArgumentCaptor.capture()); + + assertThat(pluginConfigurationArgumentCaptor.getValue().isExternalPluginsEnabled()) + .isEqualTo(true); + + assertThat(commandOutput.toString(UTF_8)).isEmpty(); + assertThat(commandErrorOutput.toString(UTF_8)).isEmpty(); + } + + @Test + public void shouldEnablePluginsExternalByDefault() { + parseCommand(); + verify(mockBesuPluginContext).registerPlugins(pluginConfigurationArgumentCaptor.capture()); + assertThat(pluginConfigurationArgumentCaptor.getValue().isExternalPluginsEnabled()) + .isEqualTo(true); + + assertThat(commandOutput.toString(UTF_8)).isEmpty(); + assertThat(commandErrorOutput.toString(UTF_8)).isEmpty(); + } + + @Test + public void shouldFailWhenPluginsIsDisabledAndPluginsExplicitlyRequested() { + parseCommand("--Xplugins-external-enabled=false", "--plugins", "pluginA"); + verify(mockBesuPluginContext).registerPlugins(pluginConfigurationArgumentCaptor.capture()); + + assertThat(commandOutput.toString(UTF_8)).isEmpty(); + assertThat(commandErrorOutput.toString(UTF_8)) + .contains("--plugins option can only be used when --Xplugins-external-enabled is true"); + } +} diff --git a/besu/src/test/resources/everything_config.toml b/besu/src/test/resources/everything_config.toml index 27ea5c1645..b489df9fa2 100644 --- a/besu/src/test/resources/everything_config.toml +++ b/besu/src/test/resources/everything_config.toml @@ -242,3 +242,7 @@ Xp2p-tls-clienthello-sni=false #contracts Xevm-jumpdest-cache-weight-kb=32000 + +# plugins +Xplugins-external-enabled=true +plugins=["none"] \ No newline at end of file diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/plugins/PluginConfiguration.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/plugins/PluginConfiguration.java index dbc742fb2f..ebc99f647a 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/plugins/PluginConfiguration.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/plugins/PluginConfiguration.java @@ -14,58 +14,25 @@ */ package org.hyperledger.besu.ethereum.core.plugins; -import static java.util.Objects.requireNonNull; - import java.nio.file.Path; import java.nio.file.Paths; import java.util.Collections; import java.util.List; -/** - * Configuration for managing plugins, including their information, detection type, and directory. - */ public class PluginConfiguration { private final List requestedPlugins; private final Path pluginsDir; + private final boolean externalPluginsEnabled; - /** - * Constructs a new PluginConfiguration with the specified plugin information and requestedPlugins - * directory. - * - * @param requestedPlugins List of {@link PluginInfo} objects representing the requestedPlugins. - * @param pluginsDir The directory where requestedPlugins are located. - */ - public PluginConfiguration(final List requestedPlugins, final Path pluginsDir) { + public PluginConfiguration( + final List requestedPlugins, + final Path pluginsDir, + final boolean externalPluginsEnabled) { this.requestedPlugins = requestedPlugins; this.pluginsDir = pluginsDir; + this.externalPluginsEnabled = externalPluginsEnabled; } - /** - * Constructs a PluginConfiguration with specified plugins using the default directory. - * - * @param requestedPlugins List of plugins for consideration or registration. discoverable plugins - * are. - */ - public PluginConfiguration(final List requestedPlugins) { - this.requestedPlugins = requestedPlugins; - this.pluginsDir = PluginConfiguration.defaultPluginsDir(); - } - - /** - * Constructs a PluginConfiguration with the specified plugins directory - * - * @param pluginsDir The directory where plugins are located. Cannot be null. - */ - public PluginConfiguration(final Path pluginsDir) { - this.requestedPlugins = null; - this.pluginsDir = requireNonNull(pluginsDir); - } - - /** - * Returns the names of requested plugins, or an empty list if none. - * - * @return List of requested plugin names, never {@code null}. - */ public List getRequestedPlugins() { return requestedPlugins == null ? Collections.emptyList() @@ -76,17 +43,46 @@ public class PluginConfiguration { return pluginsDir; } - /** - * Returns the default plugins directory based on system properties. - * - * @return The default {@link Path} to the plugin's directory. - */ + public boolean isExternalPluginsEnabled() { + return externalPluginsEnabled; + } + public static Path defaultPluginsDir() { - final String pluginsDirProperty = System.getProperty("besu.plugins.dir"); - if (pluginsDirProperty == null) { - return Paths.get(System.getProperty("besu.home", "."), "plugins"); - } else { - return Paths.get(pluginsDirProperty); + String pluginsDirProperty = System.getProperty("besu.plugins.dir"); + return pluginsDirProperty == null + ? Paths.get(System.getProperty("besu.home", "."), "plugins") + : Paths.get(pluginsDirProperty); + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + private List requestedPlugins; + private Path pluginsDir; + private boolean externalPluginsEnabled = true; + + public Builder requestedPlugins(final List requestedPlugins) { + this.requestedPlugins = requestedPlugins; + return this; + } + + public Builder pluginsDir(final Path pluginsDir) { + this.pluginsDir = pluginsDir; + return this; + } + + public Builder externalPluginsEnabled(final boolean externalPluginsEnabled) { + this.externalPluginsEnabled = externalPluginsEnabled; + return this; + } + + public PluginConfiguration build() { + if (pluginsDir == null) { + pluginsDir = PluginConfiguration.defaultPluginsDir(); + } + return new PluginConfiguration(requestedPlugins, pluginsDir, externalPluginsEnabled); } } } From 8523ed0e438b186638d97cca89c6f7b63ccbeadb Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Fri, 16 Aug 2024 15:46:56 +1000 Subject: [PATCH 127/259] 5098 branch 21 update more invalid params (#7467) * 5098: Add RpcErrorTypes Signed-off-by: Matilda Clerke * 5098: Modify InvalidJsonRpcParameters and InvalidJsonRpcRequestException, apply spotless Signed-off-by: Matilda Clerke * 5098: Modify InvalidJsonRpcParameters and InvalidJsonRpcRequestException, apply spotless Signed-off-by: Matilda Clerke * 5098: Add JsonRpcParameterException for later use Signed-off-by: Matilda Clerke * 5098: Update locations for RpcErrorType.INVALID_ACCOUNTS_PARAMS Signed-off-by: Matilda Clerke * 5098: Address review comments, apply spotless Signed-off-by: Matilda Clerke * 5098: Update with changes from branch 1 Signed-off-by: Matilda Clerke * 5098: Update code to use RpcErrorType.INVALID_ADDRESS_HASH_PARAMS Signed-off-by: Matilda Clerke * 5098: apply spotless Signed-off-by: Matilda Clerke * 5098: apply spotless Signed-off-by: Matilda Clerke * 5098: Update plugin-api gradle hash Signed-off-by: Matilda Clerke * 5098: Add comment on INVALID_PARAMS_ERROR_CODE Signed-off-by: Matilda Clerke * 5098: Apply spotless on latest changes Signed-off-by: Matilda Clerke * 5098: Update code to use RpcErrorType.INVALID_ADDRESS_PARAMS Signed-off-by: Matilda Clerke * 5098: Fix broken unit test Signed-off-by: Matilda Clerke * 5098: Fix broken unit test Signed-off-by: Matilda Clerke * 5098: Update with usage of RpcErrorType.INVALID_AUTH_PARAMS Signed-off-by: Matilda Clerke * 5098: Update with usage of RpcErrorType.INVALID_BLOB_COUNT Signed-off-by: Matilda Clerke * 5098: Update with usage of RpcErrorType.INVALID_BLOB_GAS_USED_PARAMS Signed-off-by: Matilda Clerke * 5098: Update with usage of RpcErrorType.INVALID_BLOCK_PARAMS Signed-off-by: Matilda Clerke * 5098: Update with usage of RpcErrorType.INVALID_BLOCK_PARAMS Signed-off-by: Matilda Clerke * 5098: Update with usage of RpcErrorType.INVALID_BLOCK_PARAMS Signed-off-by: Matilda Clerke * 5098: Update with usage of RpcErrorType.INVALID_BLOCK_COUNT_PARAMS Signed-off-by: Matilda Clerke * 5098: Fix broken integration test Signed-off-by: Matilda Clerke * 5098: Add index to exception messages Signed-off-by: Matilda Clerke * 5098: apoply spotless Signed-off-by: Matilda Clerke * 5098: Update BaseJsonRpcProcessor to utilise RpcErrorType from InvalidJsonRpcParameters Signed-off-by: Matilda Clerke * 5098: Include parameter index in INVALID_AUTH_PARAMS Signed-off-by: Matilda Clerke * 5098: Include parameter index in INVALID_BLOCK_PARAMS Signed-off-by: Matilda Clerke * 5098: Include parameter index in INVALID_BLOCK_COUNT_PARAMS Signed-off-by: Matilda Clerke * 5098: Fix broken integration test Signed-off-by: Matilda Clerke * 5098: Rename INVALID_AUTH_PARAMS to INVALID_PROPOSAL_PARAMS Signed-off-by: Matilda Clerke * 5098: apply spotless Signed-off-by: Matilda Clerke * 5098: Update INVALID_BLOCK_HASH_PARAMS locations Signed-off-by: Matilda Clerke * 5098: Fix broken unit test Signed-off-by: Matilda Clerke * 5098: apply spotless Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_BLOCK_INDEX Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_BLOCK_NUMBER Signed-off-by: Matilda Clerke * 5098: apply spotless Signed-off-by: Matilda Clerke * 5098: Fix broken tests Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_CALL_PARAMS Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_CONSOLIDATION_REQUEST_PARAMS Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_CREATE_PRIVACY_GROUP_PARAMS Signed-off-by: Matilda Clerke * 5098: Fix broken test Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_DATA_PARAMS Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_DEPOSIT_REQUEST_PARAMS Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_ENGINE_EXCHANGE_TRANSITION_CONFIGURATION_PARAMS Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_ENGINE_FORKCHOICE_UPDATED_PARAMS Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_ENGINE_PAYLOAD_ATTRIBUTES_PARAMS Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_ENGINE_PAYLOAD_PARAMS Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_ENGINE_PREPARE_PAYLOAD_PARAMS Signed-off-by: Matilda Clerke * 5098: Apply spotless Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_ENODE_PARAMS Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_EXCESS_BLOB_GAS_PARAMS Signed-off-by: Matilda Clerke * 5098: Apply spotless Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_EXTRA_DATA_PARAMS Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_FILTER_PARAMS Signed-off-by: Matilda Clerke * 5098: Apply spotless Signed-off-by: Matilda Clerke * 5098: Fix broken tests Signed-off-by: Matilda Clerke * 5098: Update several RpcErrorTypes Signed-off-by: Matilda Clerke * 5098: Apply spotless Signed-off-by: Matilda Clerke * 5098: Hopefully fix broken integration test Signed-off-by: Matilda Clerke * 5098: Hopefully fix broken integration test Signed-off-by: Matilda Clerke * 5098: Update several more RpcErrorTypes Signed-off-by: Matilda Clerke * 5098: Apply spotless Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_PARAM_COUNT Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_PAYLOAD_ID_PARAMS Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVALID_PENDING_TRANSACTIONS_PARAMS Signed-off-by: Matilda Clerke * 5098: Update RpcErrorType.INVAlID_PLUGIN_NAME_PARAMS Signed-off-by: Matilda Clerke * 5098: Apply spotless Signed-off-by: Matilda Clerke * 5098: Fix broken tests Signed-off-by: Matilda Clerke * 5098: Update RpcErrorTypes Signed-off-by: Matilda Clerke * 5098: Fix broken tests Signed-off-by: Matilda Clerke * 5098: Apply spotless Signed-off-by: Matilda Clerke * Update ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetEeaTransactionCount.java Co-authored-by: Sally MacFarlane Signed-off-by: Matilda-Clerke --------- Signed-off-by: Matilda Clerke Signed-off-by: Matilda-Clerke Co-authored-by: Sally MacFarlane --- .../internal/methods/EthFeeHistory.java | 11 ++- .../jsonrpc/internal/methods/EthGetProof.java | 11 ++- .../internal/methods/EthGetStorageAt.java | 8 +- .../internal/methods/EthSubmitHashRate.java | 10 ++- .../internal/methods/EthSubmitWork.java | 8 +- .../engine/EngineExchangeCapabilities.java | 15 +++- .../privacy/methods/PrivGetFilterChanges.java | 10 ++- .../privacy/methods/PrivGetFilterLogs.java | 10 ++- .../privacy/methods/PrivUninstallFilter.java | 12 ++- .../privacy/methods/priv/PrivCall.java | 10 ++- .../methods/priv/PrivDebugGetStateRoot.java | 12 ++- .../methods/priv/PrivDeletePrivacyGroup.java | 12 ++- .../privacy/methods/priv/PrivGetCode.java | 10 ++- .../priv/PrivGetEeaTransactionCount.java | 16 +++- .../privacy/methods/priv/PrivGetLogs.java | 10 ++- .../methods/priv/PrivGetTransactionCount.java | 10 ++- .../privacy/methods/priv/PrivNewFilter.java | 10 ++- .../request/SubscriptionRequestMapper.java | 75 ++++++++++++++++--- .../api/jsonrpc/JsonRpcHttpServiceTest.java | 2 +- .../internal/methods/EthGetProofTest.java | 2 +- .../privacy/methods/priv/PrivCallTest.java | 3 +- .../priv/PrivDebugGetStateRootTest.java | 3 +- .../priv/PrivGetFilterChangesTest.java | 2 +- .../methods/priv/PrivGetFilterLogsTest.java | 2 +- .../privacy/methods/priv/PrivGetLogsTest.java | 2 +- .../methods/priv/PrivNewFilterTest.java | 2 +- .../methods/priv/PrivUninstallFilterTest.java | 4 +- .../SubscriptionRequestMapperTest.java | 6 +- .../ethereum/stratum/StratumProtocol.java | 8 +- 29 files changed, 244 insertions(+), 52 deletions(-) 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 e2056ac94b..01a0802279 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 @@ -106,8 +106,15 @@ public class EthFeeHistory implements JsonRpcMethod { "Invalid highest block parameter (index 1)", RpcErrorType.INVALID_BLOCK_PARAMS, e); } - final Optional> maybeRewardPercentiles = - request.getOptionalParameter(2, Double[].class).map(Arrays::asList); + final Optional> maybeRewardPercentiles; + try { + maybeRewardPercentiles = request.getOptionalParameter(2, Double[].class).map(Arrays::asList); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid reward percentiles parameter (index 2)", + RpcErrorType.INVALID_REWARD_PERCENTILES_PARAMS, + e); + } final BlockHeader chainHeadHeader = blockchain.getChainHeadHeader(); final long chainHeadBlockNumber = chainHeadHeader.getNumber(); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetProof.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetProof.java index a20cd62f29..7c2f67b724 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetProof.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetProof.java @@ -106,8 +106,13 @@ public class EthGetProof extends AbstractBlockParameterOrBlockHashMethod { } private List getStorageKeys(final JsonRpcRequestContext request) { - return Arrays.stream(request.getRequiredParameter(1, String[].class)) - .map(UInt256::fromHexString) - .collect(Collectors.toList()); + try { + return Arrays.stream(request.getRequiredParameter(1, String[].class)) + .map(UInt256::fromHexString) + .collect(Collectors.toList()); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid storage keys parameters (index 1)", RpcErrorType.INVALID_STORAGE_KEYS_PARAMS, e); + } } } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetStorageAt.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetStorageAt.java index 7b84365b56..34ed62b632 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetStorageAt.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetStorageAt.java @@ -56,7 +56,13 @@ public class EthGetStorageAt extends AbstractBlockParameterOrBlockHashMethod { throw new InvalidJsonRpcParameters( "Invalid address parameter (index 0)", RpcErrorType.INVALID_ADDRESS_PARAMS, e); } - final UInt256 position = request.getRequiredParameter(1, UInt256Parameter.class).getValue(); + final UInt256 position; + try { + position = request.getRequiredParameter(1, UInt256Parameter.class).getValue(); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid position parameter (index 1)", RpcErrorType.INVALID_POSITION_PARAMS, e); + } return blockchainQueries .get() .storageAt(address, position, blockHash) diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSubmitHashRate.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSubmitHashRate.java index 9db7edcc80..c0763e77f6 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSubmitHashRate.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSubmitHashRate.java @@ -42,11 +42,17 @@ public class EthSubmitHashRate implements JsonRpcMethod { final String hashRate; try { hashRate = requestContext.getRequiredParameter(0, String.class); - } catch (Exception e) { + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException throw new InvalidJsonRpcParameters( "Invalid hash rate parameter (index 0)", RpcErrorType.INVALID_HASH_RATE_PARAMS, e); } - final String id = requestContext.getRequiredParameter(1, String.class); + final String id; + try { + id = requestContext.getRequiredParameter(1, String.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid sealer ID parameter (index 1)", RpcErrorType.INVALID_SEALER_ID_PARAMS, e); + } return new JsonRpcSuccessResponse( requestContext.getRequest().getId(), miningCoordinator.submitHashRate( diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSubmitWork.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSubmitWork.java index cebb2e7a00..9474fec7ba 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSubmitWork.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSubmitWork.java @@ -65,7 +65,13 @@ public class EthSubmitWork implements JsonRpcMethod { throw new InvalidJsonRpcParameters( "Invalid mix hash parameter (index 2)", RpcErrorType.INVALID_MIX_HASH_PARAMS, e); } - Bytes powHash = Bytes.fromHexString(requestContext.getRequiredParameter(1, String.class)); + Bytes powHash; + try { + powHash = Bytes.fromHexString(requestContext.getRequiredParameter(1, String.class)); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid PoW hash parameter (index 1)", RpcErrorType.INVALID_POW_HASH_PARAMS, e); + } final PoWSolution solution = new PoWSolution(nonce, mixHash, null, powHash); final boolean result = miner.submitWork(solution); return new JsonRpcSuccessResponse(requestContext.getRequest().getId(), result); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineExchangeCapabilities.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineExchangeCapabilities.java index 0431898c78..624d9bebdd 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineExchangeCapabilities.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineExchangeCapabilities.java @@ -20,9 +20,11 @@ import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod.ENGINE_PREPARE import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod; 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.api.jsonrpc.internal.response.RpcErrorType; import java.util.List; import java.util.stream.Collectors; @@ -55,7 +57,18 @@ public class EngineExchangeCapabilities extends ExecutionEngineJsonRpcMethod { LOG.atTrace() .setMessage("received remote capabilities: {}") - .addArgument(() -> requestContext.getRequiredParameter(0, String[].class)) + .addArgument( + () -> { + try { + return requestContext.getRequiredParameter(0, String[].class); + } catch ( + Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid remote capabilities parameters (index 0)", + RpcErrorType.INVALID_REMOTE_CAPABILITIES_PARAMS, + e); + } + }) .log(); final List localCapabilities = diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivGetFilterChanges.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivGetFilterChanges.java index 7b9a8d1478..bbd7189ffa 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivGetFilterChanges.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivGetFilterChanges.java @@ -52,7 +52,15 @@ public class PrivGetFilterChanges implements JsonRpcMethod { @Override public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { - final String privacyGroupId = requestContext.getRequiredParameter(0, String.class); + final String privacyGroupId; + try { + privacyGroupId = requestContext.getRequiredParameter(0, String.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid privacy group ID parameter (index 0)", + RpcErrorType.INVALID_PRIVACY_GROUP_PARAMS, + e); + } final String filterId; try { filterId = requestContext.getRequiredParameter(1, String.class); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivGetFilterLogs.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivGetFilterLogs.java index 0e564772c0..4436c33b50 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivGetFilterLogs.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivGetFilterLogs.java @@ -52,7 +52,15 @@ public class PrivGetFilterLogs implements JsonRpcMethod { @Override public JsonRpcResponse response(final JsonRpcRequestContext request) { - final String privacyGroupId = request.getRequiredParameter(0, String.class); + final String privacyGroupId; + try { + privacyGroupId = request.getRequiredParameter(0, String.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid privacy group ID parameter (index 0)", + RpcErrorType.INVALID_PRIVACY_GROUP_PARAMS, + e); + } final String filterId; try { filterId = request.getRequiredParameter(1, String.class); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivUninstallFilter.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivUninstallFilter.java index 738c0b19cf..c1e122578a 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivUninstallFilter.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivUninstallFilter.java @@ -47,13 +47,21 @@ public class PrivUninstallFilter implements JsonRpcMethod { @Override public JsonRpcResponse response(final JsonRpcRequestContext request) { - final String privacyGroupId = request.getRequiredParameter(0, String.class); + final String privacyGroupId; + try { + privacyGroupId = request.getRequiredParameter(0, String.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid privacy group ID parameter (index 0)", + RpcErrorType.INVALID_PRIVACY_GROUP_PARAMS, + e); + } final String filterId; try { filterId = request.getRequiredParameter(1, String.class); } catch (Exception e) { throw new InvalidJsonRpcParameters( - "Invalid filter ID paramter (index 1)", RpcErrorType.INVALID_FILTER_PARAMS, e); + "Invalid filter ID parameter (index 1)", RpcErrorType.INVALID_FILTER_PARAMS, e); } if (privacyController instanceof MultiTenancyPrivacyController) { diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCall.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCall.java index 0418fc2474..e09d5966cf 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCall.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCall.java @@ -65,7 +65,15 @@ public class PrivCall extends AbstractBlockParameterMethod { protected Object resultByBlockNumber( final JsonRpcRequestContext request, final long blockNumber) { final JsonCallParameter callParams = validateAndGetCallParams(request); - final String privacyGroupId = request.getRequiredParameter(0, String.class); + final String privacyGroupId; + try { + privacyGroupId = request.getRequiredParameter(0, String.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid privacy group ID parameter (index 0)", + RpcErrorType.INVALID_PRIVACY_GROUP_PARAMS, + e); + } final String privacyUserId = privacyIdProvider.getPrivacyUserId(request.getUser()); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDebugGetStateRoot.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDebugGetStateRoot.java index b6ea645dc3..9ee5d57b3b 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDebugGetStateRoot.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDebugGetStateRoot.java @@ -72,7 +72,15 @@ public class PrivDebugGetStateRoot extends AbstractBlockParameterMethod { @Override protected Object resultByBlockNumber( final JsonRpcRequestContext requestContext, final long blockNumber) { - final String privacyGroupId = requestContext.getRequiredParameter(0, String.class); + final String privacyGroupId; + try { + privacyGroupId = requestContext.getRequiredParameter(0, String.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid privacy group ID parameter (index 0)", + RpcErrorType.INVALID_PRIVACY_GROUP_PARAMS, + e); + } final String privacyUserId = privacyIdProvider.getPrivacyUserId(requestContext.getUser()); if (LOG.isTraceEnabled()) { LOG.trace("Executing {}", getName()); @@ -97,7 +105,7 @@ public class PrivDebugGetStateRoot extends AbstractBlockParameterMethod { } } catch (final Exception e) { return new JsonRpcErrorResponse( - requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + requestContext.getRequest().getId(), RpcErrorType.INVALID_PRIVACY_GROUP_PARAMS); } if (privacyGroup.isEmpty()) { diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDeletePrivacyGroup.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDeletePrivacyGroup.java index db0c11ea5a..5c6f929c5c 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDeletePrivacyGroup.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDeletePrivacyGroup.java @@ -18,11 +18,13 @@ import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErr import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.PrivacyIdProvider; 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.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.privacy.MultiTenancyValidationException; import org.hyperledger.besu.ethereum.privacy.PrivacyController; @@ -50,7 +52,15 @@ public class PrivDeletePrivacyGroup implements JsonRpcMethod { public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { LOG.trace("Executing {}", RpcMethod.PRIV_DELETE_PRIVACY_GROUP.getMethodName()); - final String privacyGroupId = requestContext.getRequiredParameter(0, String.class); + final String privacyGroupId; + try { + privacyGroupId = requestContext.getRequiredParameter(0, String.class); + } catch (Exception e) { + throw new InvalidJsonRpcParameters( + "Invalid privacy group ID parameter (index 0)", + RpcErrorType.INVALID_PRIVACY_GROUP_PARAMS, + e); + } final String response; try { diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetCode.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetCode.java index 0010b8e052..5d9498f3bd 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetCode.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetCode.java @@ -59,7 +59,15 @@ public class PrivGetCode extends AbstractBlockParameterMethod { @Override protected String resultByBlockNumber( final JsonRpcRequestContext request, final long blockNumber) { - final String privacyGroupId = request.getRequiredParameter(0, String.class); + final String privacyGroupId; + try { + privacyGroupId = request.getRequiredParameter(0, String.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid privacy group ID parameter (index 0)", + RpcErrorType.INVALID_PRIVACY_GROUP_PARAMS, + e); + } final Address address; try { address = request.getRequiredParameter(1, Address.class); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetEeaTransactionCount.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetEeaTransactionCount.java index 8fa43b79e3..7bdba8824a 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetEeaTransactionCount.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetEeaTransactionCount.java @@ -73,8 +73,20 @@ public class PrivGetEeaTransactionCount implements JsonRpcMethod { throw new InvalidJsonRpcParameters( "Invalid address parameter (index 0)", RpcErrorType.INVALID_ADDRESS_PARAMS, e); } - final String privateFrom = requestContext.getRequiredParameter(1, String.class); - final String[] privateFor = requestContext.getRequiredParameter(2, String[].class); + final String privateFrom; + try { + privateFrom = requestContext.getRequiredParameter(1, String.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid private from parameter (index 1)", RpcErrorType.INVALID_PRIVATE_FROM_PARAMS, e); + } + final String[] privateFor; + try { + privateFor = requestContext.getRequiredParameter(2, String[].class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid private for parameter (index 2)", RpcErrorType.INVALID_PRIVATE_FOR_PARAMS, e); + } final String privacyUserId = privacyIdProvider.getPrivacyUserId(requestContext.getUser()); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetLogs.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetLogs.java index abb6411b00..d0c75da33f 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetLogs.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetLogs.java @@ -62,7 +62,15 @@ public class PrivGetLogs implements JsonRpcMethod { @Override public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { - final String privacyGroupId = requestContext.getRequiredParameter(0, String.class); + final String privacyGroupId; + try { + privacyGroupId = requestContext.getRequiredParameter(0, String.class); + } catch (Exception e) { + throw new InvalidJsonRpcParameters( + "Invalid privacy group ID parameter (index 0)", + RpcErrorType.INVALID_PRIVACY_GROUP_PARAMS, + e); + } final FilterParameter filter; try { filter = requestContext.getRequiredParameter(1, FilterParameter.class); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetTransactionCount.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetTransactionCount.java index b51f0fc36f..2cbcc65535 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetTransactionCount.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetTransactionCount.java @@ -64,7 +64,15 @@ public class PrivGetTransactionCount implements JsonRpcMethod { throw new InvalidJsonRpcParameters( "Invalid address parameter (index 0)", RpcErrorType.INVALID_ADDRESS_PARAMS, e); } - final String privacyGroupId = requestContext.getRequiredParameter(1, String.class); + final String privacyGroupId; + try { + privacyGroupId = requestContext.getRequiredParameter(1, String.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid privacy group ID parameter (index 1)", + RpcErrorType.INVALID_PRIVACY_GROUP_PARAMS, + e); + } try { final long nonce = diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivNewFilter.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivNewFilter.java index f9a080c72f..e73b0c141c 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivNewFilter.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivNewFilter.java @@ -50,7 +50,15 @@ public class PrivNewFilter implements JsonRpcMethod { @Override public JsonRpcResponse response(final JsonRpcRequestContext request) { - final String privacyGroupId = request.getRequiredParameter(0, String.class); + final String privacyGroupId; + try { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + privacyGroupId = request.getRequiredParameter(0, String.class); + } catch (Exception e) { + throw new InvalidJsonRpcParameters( + "Invalid privacy group ID parameter (index 0)", + RpcErrorType.INVALID_PRIVACY_GROUP_PARAMS, + e); + } final FilterParameter filter; try { filter = request.getRequiredParameter(1, FilterParameter.class); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/subscription/request/SubscriptionRequestMapper.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/subscription/request/SubscriptionRequestMapper.java index d9099e697d..7235a81987 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/subscription/request/SubscriptionRequestMapper.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/subscription/request/SubscriptionRequestMapper.java @@ -32,8 +32,15 @@ public class SubscriptionRequestMapper { try { final WebSocketRpcRequest webSocketRpcRequestBody = validateRequest(jsonRpcRequestContext); - final SubscriptionType subscriptionType = - webSocketRpcRequestBody.getRequiredParameter(0, SubscriptionType.class); + final SubscriptionType subscriptionType; + try { + subscriptionType = webSocketRpcRequestBody.getRequiredParameter(0, SubscriptionType.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid subscription type parameter (index 0)", + RpcErrorType.INVALID_SUBSCRIPTION_PARAMS, + e); + } switch (subscriptionType) { case NEW_BLOCK_HEADERS: { @@ -60,8 +67,13 @@ public class SubscriptionRequestMapper { } private boolean includeTransactions(final WebSocketRpcRequest webSocketRpcRequestBody) { - final Optional params = - webSocketRpcRequestBody.getOptionalParameter(1, SubscriptionParam.class); + final Optional params; + try { + params = webSocketRpcRequestBody.getOptionalParameter(1, SubscriptionParam.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid subscription parameter (index 1)", RpcErrorType.INVALID_SUBSCRIPTION_PARAMS, e); + } return params.isPresent() && params.get().includeTransaction(); } @@ -88,8 +100,16 @@ public class SubscriptionRequestMapper { try { final WebSocketRpcRequest webSocketRpcRequestBody = validateRequest(jsonRpcRequestContext); - final long subscriptionId = - webSocketRpcRequestBody.getRequiredParameter(0, UnsignedLongParameter.class).getValue(); + final long subscriptionId; + try { + subscriptionId = + webSocketRpcRequestBody.getRequiredParameter(0, UnsignedLongParameter.class).getValue(); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid subscription ID parameter (index 0)", + RpcErrorType.INVALID_SUBSCRIPTION_PARAMS, + e); + } return new UnsubscribeRequest(subscriptionId, webSocketRpcRequestBody.getConnectionId()); } catch (final Exception e) { throw new InvalidSubscriptionRequestException("Error parsing unsubscribe request", e); @@ -102,9 +122,24 @@ public class SubscriptionRequestMapper { try { final WebSocketRpcRequest webSocketRpcRequestBody = validateRequest(jsonRpcRequestContext); - final String privacyGroupId = webSocketRpcRequestBody.getRequiredParameter(0, String.class); - final SubscriptionType subscriptionType = - webSocketRpcRequestBody.getRequiredParameter(1, SubscriptionType.class); + final String privacyGroupId; + try { + privacyGroupId = webSocketRpcRequestBody.getRequiredParameter(0, String.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid privacy group ID parameter (index 0)", + RpcErrorType.INVALID_PRIVACY_GROUP_PARAMS, + e); + } + final SubscriptionType subscriptionType; + try { + subscriptionType = webSocketRpcRequestBody.getRequiredParameter(1, SubscriptionType.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid subscription type parameter (index 1)", + RpcErrorType.INVALID_SUBSCRIPTION_PARAMS, + e); + } switch (subscriptionType) { case LOGS: @@ -142,9 +177,25 @@ public class SubscriptionRequestMapper { try { final WebSocketRpcRequest webSocketRpcRequestBody = validateRequest(jsonRpcRequestContext); - final String privacyGroupId = webSocketRpcRequestBody.getRequiredParameter(0, String.class); - final long subscriptionId = - webSocketRpcRequestBody.getRequiredParameter(1, UnsignedLongParameter.class).getValue(); + final String privacyGroupId; + try { + privacyGroupId = webSocketRpcRequestBody.getRequiredParameter(0, String.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid privacy group ID parameter (index 0)", + RpcErrorType.INVALID_PRIVACY_GROUP_PARAMS, + e); + } + final long subscriptionId; + try { + subscriptionId = + webSocketRpcRequestBody.getRequiredParameter(1, UnsignedLongParameter.class).getValue(); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid subscription ID parameter (index 1)", + RpcErrorType.INVALID_SUBSCRIPTION_PARAMS, + e); + } return new PrivateUnsubscribeRequest( subscriptionId, webSocketRpcRequestBody.getConnectionId(), privacyGroupId); } catch (final Exception e) { diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTest.java index 7be6b7499e..dcfd198d6e 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTest.java @@ -2033,7 +2033,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { assertThat(resp.code()).isEqualTo(200); // Check general format of result final JsonObject json = new JsonObject(resp.body().string()); - final RpcErrorType expectedError = RpcErrorType.INVALID_PARAMS; + final RpcErrorType expectedError = RpcErrorType.INVALID_POSITION_PARAMS; testHelper.assertValidJsonRpcError( json, id, expectedError.getCode(), expectedError.getMessage()); } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetProofTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetProofTest.java index 3cf24df3d4..06a4b9d0e7 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetProofTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetProofTest.java @@ -120,7 +120,7 @@ class EthGetProofTest { Assertions.assertThatThrownBy(() -> method.response(request)) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Missing required json rpc parameter at index 1"); + .hasMessageContaining("Invalid storage keys parameters (index 1)"); } @Test diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCallTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCallTest.java index 0919ea48e9..cc5169d75d 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCallTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCallTest.java @@ -173,8 +173,7 @@ public class PrivCallTest { assertThat(thrown) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasNoCause() - .hasMessage("Missing required json rpc parameter at index 0"); + .hasMessage("Invalid privacy group ID parameter (index 0)"); } private JsonCallParameter callParameter() { diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDebugGetStateRootTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDebugGetStateRootTest.java index a7a4f6f590..c730be1db8 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDebugGetStateRootTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDebugGetStateRootTest.java @@ -82,8 +82,7 @@ public class PrivDebugGetStateRootTest { assertThat(thrown) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasNoCause() - .hasMessage("Missing required json rpc parameter at index 0"); + .hasMessage("Invalid privacy group ID parameter (index 0)"); } @Test diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetFilterChangesTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetFilterChangesTest.java index cf89a4bbca..3b9f5c8131 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetFilterChangesTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetFilterChangesTest.java @@ -81,7 +81,7 @@ public class PrivGetFilterChangesTest { assertThatThrownBy(() -> method.response(request)) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Missing required json rpc parameter at index 0"); + .hasMessageContaining("Invalid privacy group ID parameter (index 0)"); } @Test diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetFilterLogsTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetFilterLogsTest.java index 1c5be87572..c055988271 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetFilterLogsTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetFilterLogsTest.java @@ -75,7 +75,7 @@ public class PrivGetFilterLogsTest { assertThatThrownBy(() -> method.response(request)) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Missing required json rpc parameter at index 0"); + .hasMessageContaining("Invalid privacy group ID parameter (index 0)"); } @Test diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetLogsTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetLogsTest.java index d06b47ee10..9426f21478 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetLogsTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetLogsTest.java @@ -87,7 +87,7 @@ public class PrivGetLogsTest { assertThatThrownBy(() -> method.response(request)) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Missing required json rpc parameter at index 0"); + .hasMessageContaining("Invalid privacy group ID parameter (index 0)"); } @Test diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivNewFilterTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivNewFilterTest.java index 696e3333ca..855da64b01 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivNewFilterTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivNewFilterTest.java @@ -78,7 +78,7 @@ public class PrivNewFilterTest { assertThatThrownBy(() -> method.response(request)) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Missing required json rpc parameter at index 0"); + .hasMessageContaining("Invalid privacy group ID parameter (index 0)"); } @Test diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivUninstallFilterTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivUninstallFilterTest.java index 9a60d60d72..74935692e8 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivUninstallFilterTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivUninstallFilterTest.java @@ -61,7 +61,7 @@ public class PrivUninstallFilterTest { assertThatThrownBy(() -> method.response(request)) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Missing required json rpc parameter at index 0"); + .hasMessageContaining("Invalid privacy group ID parameter (index 0)"); } @Test @@ -70,7 +70,7 @@ public class PrivUninstallFilterTest { assertThatThrownBy(() -> method.response(request)) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Invalid filter ID paramter (index 1)"); + .hasMessageContaining("Invalid filter ID parameter (index 1)"); } @Test diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/subscription/request/SubscriptionRequestMapperTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/subscription/request/SubscriptionRequestMapperTest.java index 80bb9b05dc..f560dfaa08 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/subscription/request/SubscriptionRequestMapperTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/subscription/request/SubscriptionRequestMapperTest.java @@ -83,7 +83,7 @@ public class SubscriptionRequestMapperTest { .isInstanceOf(InvalidSubscriptionRequestException.class) .getCause() .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage("Missing required json rpc parameter at index 0"); + .hasMessage("Invalid subscription type parameter (index 0)"); } @Test @@ -138,7 +138,7 @@ public class SubscriptionRequestMapperTest { .isInstanceOf(InvalidSubscriptionRequestException.class) .getCause() .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Invalid json rpc parameter at index 1"); + .hasMessageContaining("Invalid subscription parameter (index 1)"); } @Test @@ -372,7 +372,7 @@ public class SubscriptionRequestMapperTest { .isInstanceOf(InvalidSubscriptionRequestException.class) .getCause() .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Invalid json rpc parameter at index 0"); + .hasMessageContaining("Invalid subscription type parameter (index 0)"); } @Test diff --git a/ethereum/stratum/src/main/java/org/hyperledger/besu/ethereum/stratum/StratumProtocol.java b/ethereum/stratum/src/main/java/org/hyperledger/besu/ethereum/stratum/StratumProtocol.java index 7f928fbdda..3f13a56880 100644 --- a/ethereum/stratum/src/main/java/org/hyperledger/besu/ethereum/stratum/StratumProtocol.java +++ b/ethereum/stratum/src/main/java/org/hyperledger/besu/ethereum/stratum/StratumProtocol.java @@ -87,7 +87,13 @@ public interface StratumProtocol { throw new InvalidJsonRpcParameters( "Invalid hash rate parameter (index 0)", RpcErrorType.INVALID_HASH_RATE_PARAMS, e); } - final String id = message.getRequiredParameter(1, String.class); + final String id; + try { + id = message.getRequiredParameter(1, String.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid sealer ID parameter (index 1)", RpcErrorType.INVALID_SEALER_ID_PARAMS, e); + } String response; try { response = From dff99f7c17a87a45467e65a570941da9477848cb Mon Sep 17 00:00:00 2001 From: Karim Taam Date: Fri, 16 Aug 2024 13:58:24 +0100 Subject: [PATCH 128/259] Implement getNearest methods (#7258) Signed-off-by: Karim Taam --- plugin-api/build.gradle | 2 +- .../storage/SegmentedKeyValueStorage.java | 34 +- .../RocksDBColumnarKeyValueSnapshot.java | 13 +- .../RocksDBColumnarKeyValueStorage.java | 15 +- .../rocksdb/NearestKeyValueStorageTest.java | 336 ++++++++++++++++++ .../besu/services/kvstore/KeyComparator.java | 61 ++++ .../kvstore/LayeredKeyValueStorage.java | 71 +++- .../SegmentedInMemoryKeyValueStorage.java | 73 +++- .../AbstractSegmentedKeyValueStorageTest.java | 81 ----- .../kvstore/InMemoryKeyValueStorageTest.java | 31 -- .../services/kvstore/KeyComparatorTest.java | 63 ++++ .../kvstore/LayeredKeyValueStorageTest.java | 32 -- 12 files changed, 634 insertions(+), 178 deletions(-) create mode 100644 plugins/rocksdb/src/test/java/org/hyperledger/besu/plugin/services/storage/rocksdb/NearestKeyValueStorageTest.java create mode 100644 services/kvstore/src/main/java/org/hyperledger/besu/services/kvstore/KeyComparator.java delete mode 100644 services/kvstore/src/test/java/org/hyperledger/besu/services/kvstore/AbstractSegmentedKeyValueStorageTest.java delete mode 100644 services/kvstore/src/test/java/org/hyperledger/besu/services/kvstore/InMemoryKeyValueStorageTest.java create mode 100644 services/kvstore/src/test/java/org/hyperledger/besu/services/kvstore/KeyComparatorTest.java delete mode 100644 services/kvstore/src/test/java/org/hyperledger/besu/services/kvstore/LayeredKeyValueStorageTest.java diff --git a/plugin-api/build.gradle b/plugin-api/build.gradle index fe7308993b..4440a4f069 100644 --- a/plugin-api/build.gradle +++ b/plugin-api/build.gradle @@ -70,7 +70,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 = 'W1gv5UjqU+RJZJN6xPNjVfjuz7nKIcBgmh1j2XON4EU=' + knownHash = '6Hy3eaCpnxehyDO3smSAr1i2DsB2q/V37/m8POycikI=' } check.dependsOn('checkAPIChanges') diff --git a/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/storage/SegmentedKeyValueStorage.java b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/storage/SegmentedKeyValueStorage.java index df8a8c4894..4f734c7c97 100644 --- a/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/storage/SegmentedKeyValueStorage.java +++ b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/storage/SegmentedKeyValueStorage.java @@ -39,15 +39,35 @@ public interface SegmentedKeyValueStorage extends Closeable { Optional get(SegmentIdentifier segment, byte[] key) throws StorageException; /** - * Find the key and corresponding value "nearest to" the specified key. Nearest is defined as - * either matching the supplied key or the key lexicographically prior to it. + * Finds the key and corresponding value that is "nearest before" the specified key. "Nearest + * before" is defined as the closest key that is either exactly matching the supplied key or + * lexicographically before it. * - * @param segmentIdentifier segment to scan - * @param key key for which we are searching for the nearest match. - * @return Optional of NearestKeyValue-wrapped matched key and corresponding value. - * @throws StorageException the storage exception + * @param segmentIdentifier The segment to scan for the nearest key. + * @param key The key for which we are searching for the nearest match before it. + * @return An Optional of NearestKeyValue, wrapping the matched key and its corresponding value, + * if found. + * @throws StorageException If an error occurs during the retrieval process. + */ + Optional getNearestBefore(final SegmentIdentifier segmentIdentifier, Bytes key) + throws StorageException; + + /** + * Finds the key and corresponding value that is "nearest after" the specified key. "Nearest + * after" is defined as the closest key that is either exactly matching the supplied key or + * lexicographically after it. + * + *

This method aims to find the next key in sequence after the provided key, considering the + * order of keys within the specified segment. It is particularly useful for iterating over keys + * in a sorted manner starting from a given key. + * + * @param segmentIdentifier The segment to scan for the nearest key. + * @param key The key for which we are searching for the nearest match after it. + * @return An Optional of NearestKeyValue, wrapping the matched key and its corresponding value, + * if found. + * @throws StorageException If an error occurs during the retrieval process. */ - Optional getNearestTo(final SegmentIdentifier segmentIdentifier, Bytes key) + Optional getNearestAfter(final SegmentIdentifier segmentIdentifier, Bytes key) throws StorageException; /** diff --git a/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/segmented/RocksDBColumnarKeyValueSnapshot.java b/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/segmented/RocksDBColumnarKeyValueSnapshot.java index dfc1c8a1ac..72976a9d84 100644 --- a/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/segmented/RocksDBColumnarKeyValueSnapshot.java +++ b/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/segmented/RocksDBColumnarKeyValueSnapshot.java @@ -76,7 +76,7 @@ public class RocksDBColumnarKeyValueSnapshot } @Override - public Optional getNearestTo( + public Optional getNearestBefore( final SegmentIdentifier segmentIdentifier, final Bytes key) throws StorageException { try (final RocksIterator rocksIterator = snapTx.getIterator(segmentIdentifier)) { @@ -87,6 +87,17 @@ public class RocksDBColumnarKeyValueSnapshot } } + @Override + public Optional getNearestAfter( + final SegmentIdentifier segmentIdentifier, final Bytes key) throws StorageException { + try (final RocksIterator rocksIterator = snapTx.getIterator(segmentIdentifier)) { + rocksIterator.seek(key.toArrayUnsafe()); + return Optional.of(rocksIterator) + .filter(AbstractRocksIterator::isValid) + .map(it -> new NearestKeyValue(Bytes.of(it.key()), Optional.of(it.value()))); + } + } + @Override public Stream> stream(final SegmentIdentifier segment) { throwIfClosed(); diff --git a/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/segmented/RocksDBColumnarKeyValueStorage.java b/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/segmented/RocksDBColumnarKeyValueStorage.java index 647dc7019f..0bf107ddb0 100644 --- a/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/segmented/RocksDBColumnarKeyValueStorage.java +++ b/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/segmented/RocksDBColumnarKeyValueStorage.java @@ -354,7 +354,7 @@ public abstract class RocksDBColumnarKeyValueStorage implements SegmentedKeyValu } @Override - public Optional getNearestTo( + public Optional getNearestBefore( final SegmentIdentifier segmentIdentifier, final Bytes key) throws StorageException { try (final RocksIterator rocksIterator = @@ -366,6 +366,19 @@ public abstract class RocksDBColumnarKeyValueStorage implements SegmentedKeyValu } } + @Override + public Optional getNearestAfter( + final SegmentIdentifier segmentIdentifier, final Bytes key) throws StorageException { + + try (final RocksIterator rocksIterator = + getDB().newIterator(safeColumnHandle(segmentIdentifier))) { + rocksIterator.seek(key.toArrayUnsafe()); + return Optional.of(rocksIterator) + .filter(AbstractRocksIterator::isValid) + .map(it -> new NearestKeyValue(Bytes.of(it.key()), Optional.of(it.value()))); + } + } + @Override public Stream> stream(final SegmentIdentifier segmentIdentifier) { final RocksIterator rocksIterator = getDB().newIterator(safeColumnHandle(segmentIdentifier)); diff --git a/plugins/rocksdb/src/test/java/org/hyperledger/besu/plugin/services/storage/rocksdb/NearestKeyValueStorageTest.java b/plugins/rocksdb/src/test/java/org/hyperledger/besu/plugin/services/storage/rocksdb/NearestKeyValueStorageTest.java new file mode 100644 index 0000000000..54cd03215f --- /dev/null +++ b/plugins/rocksdb/src/test/java/org/hyperledger/besu/plugin/services/storage/rocksdb/NearestKeyValueStorageTest.java @@ -0,0 +1,336 @@ +/* + * 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.services.storage.rocksdb; + +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.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_BACKGROUND_THREAD_COUNT; +import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_CACHE_CAPACITY; +import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_IS_HIGH_SPEC; +import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_MAX_OPEN_FILES; +import static org.mockito.Mockito.lenient; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier; +import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; +import org.hyperledger.besu.plugin.services.BesuConfiguration; +import org.hyperledger.besu.plugin.services.storage.DataStorageConfiguration; +import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; +import org.hyperledger.besu.plugin.services.storage.SegmentIdentifier; +import org.hyperledger.besu.plugin.services.storage.SegmentedKeyValueStorage; +import org.hyperledger.besu.plugin.services.storage.SegmentedKeyValueStorage.NearestKeyValue; +import org.hyperledger.besu.plugin.services.storage.SegmentedKeyValueStorageTransaction; +import org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBFactoryConfiguration; +import org.hyperledger.besu.services.kvstore.LayeredKeyValueStorage; +import org.hyperledger.besu.services.kvstore.SegmentedInMemoryKeyValueStorage; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.stream.IntStream; + +import org.apache.tuweni.bytes.Bytes; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.io.TempDir; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +public class NearestKeyValueStorageTest { + + @TempDir private static Path tempDir; + + private static RocksDBKeyValueStorageFactory rocksdbStorageFactory; + private static BesuConfiguration commonConfiguration; + + @BeforeAll + public static void setup() throws IOException { + rocksdbStorageFactory = + new RocksDBKeyValueStorageFactory( + () -> + new RocksDBFactoryConfiguration( + DEFAULT_MAX_OPEN_FILES, + DEFAULT_BACKGROUND_THREAD_COUNT, + DEFAULT_CACHE_CAPACITY, + DEFAULT_IS_HIGH_SPEC), + Arrays.asList(KeyValueSegmentIdentifier.values()), + RocksDBMetricsFactory.PUBLIC_ROCKS_DB_METRICS); + + Utils.createDatabaseMetadataV2(tempDir, DataStorageFormat.BONSAI, 2); + + mockCommonConfiguration(tempDir); + } + + @Test + public void testNearestRocksdbWithInMemoryKeyValueStorage() { + final SegmentedKeyValueStorage rockdDBKeyValueStorage = + getRocksDBKeyValueStorage(TRIE_BRANCH_STORAGE); + final SegmentedKeyValueStorageTransaction rocksDbTransaction = + rockdDBKeyValueStorage.startTransaction(); + + final SegmentedKeyValueStorage inMemoryDBKeyValueStorage = getInMemoryDBKeyValueStorage(); + final SegmentedKeyValueStorageTransaction inMemoryDBTransaction = + inMemoryDBKeyValueStorage.startTransaction(); + IntStream.range(1, 10) + .forEach( + i -> { + final byte[] key = Bytes.fromHexString("0x000" + i).toArrayUnsafe(); + final byte[] value = Bytes.fromHexString("0FFF").toArrayUnsafe(); + rocksDbTransaction.put(TRIE_BRANCH_STORAGE, key, value); + inMemoryDBTransaction.put(TRIE_BRANCH_STORAGE, key, value); + // different common prefix, and reversed order of bytes: + final byte[] key2 = Bytes.fromHexString("0x010" + (10 - i)).toArrayUnsafe(); + final byte[] value2 = Bytes.fromHexString("0FFF").toArrayUnsafe(); + rocksDbTransaction.put(TRIE_BRANCH_STORAGE, key2, value2); + inMemoryDBTransaction.put(TRIE_BRANCH_STORAGE, key2, value2); + // different size: + final byte[] key3 = Bytes.fromHexString("0x01011" + (10 - i)).toArrayUnsafe(); + final byte[] value3 = Bytes.fromHexString("0FFF").toArrayUnsafe(); + rocksDbTransaction.put(TRIE_BRANCH_STORAGE, key3, value3); + inMemoryDBTransaction.put(TRIE_BRANCH_STORAGE, key3, value3); + final byte[] key4 = Bytes.fromHexString("0x0" + (10 - i)).toArrayUnsafe(); + final byte[] value4 = Bytes.fromHexString("0FFF").toArrayUnsafe(); + rocksDbTransaction.put(TRIE_BRANCH_STORAGE, key4, value4); + inMemoryDBTransaction.put(TRIE_BRANCH_STORAGE, key4, value4); + }); + rocksDbTransaction.commit(); + inMemoryDBTransaction.commit(); + + // compare rocksdb implementation with inmemory implementation + rockdDBKeyValueStorage.stream(TRIE_BRANCH_STORAGE) + .forEach( + pair -> { + final Bytes key = Bytes.of(pair.getKey()); + assertThat( + isNearestKeyValueTheSame( + inMemoryDBKeyValueStorage.getNearestBefore(TRIE_BRANCH_STORAGE, key), + rockdDBKeyValueStorage.getNearestBefore(TRIE_BRANCH_STORAGE, key))) + .isTrue(); + assertThat( + isNearestKeyValueTheSame( + inMemoryDBKeyValueStorage.getNearestAfter(TRIE_BRANCH_STORAGE, key), + rockdDBKeyValueStorage.getNearestAfter(TRIE_BRANCH_STORAGE, key))) + .isTrue(); + + final Bytes biggerKey = Bytes.concatenate(key, Bytes.of(0x01)); + assertThat( + isNearestKeyValueTheSame( + inMemoryDBKeyValueStorage.getNearestBefore( + TRIE_BRANCH_STORAGE, biggerKey), + rockdDBKeyValueStorage.getNearestBefore(TRIE_BRANCH_STORAGE, biggerKey))) + .isTrue(); + assertThat( + isNearestKeyValueTheSame( + inMemoryDBKeyValueStorage.getNearestAfter(TRIE_BRANCH_STORAGE, biggerKey), + rockdDBKeyValueStorage.getNearestAfter(TRIE_BRANCH_STORAGE, biggerKey))) + .isTrue(); + + final Bytes smallerKey = key.slice(0, key.size() - 1); + assertThat( + isNearestKeyValueTheSame( + inMemoryDBKeyValueStorage.getNearestBefore( + TRIE_BRANCH_STORAGE, smallerKey), + rockdDBKeyValueStorage.getNearestBefore(TRIE_BRANCH_STORAGE, smallerKey))) + .isTrue(); + assertThat( + isNearestKeyValueTheSame( + inMemoryDBKeyValueStorage.getNearestAfter( + TRIE_BRANCH_STORAGE, smallerKey), + rockdDBKeyValueStorage.getNearestAfter(TRIE_BRANCH_STORAGE, smallerKey))) + .isTrue(); + + final Bytes reversedKey = key.reverse(); + assertThat( + isNearestKeyValueTheSame( + inMemoryDBKeyValueStorage.getNearestBefore( + TRIE_BRANCH_STORAGE, reversedKey), + rockdDBKeyValueStorage.getNearestBefore( + TRIE_BRANCH_STORAGE, reversedKey))) + .isTrue(); + assertThat( + isNearestKeyValueTheSame( + inMemoryDBKeyValueStorage.getNearestAfter( + TRIE_BRANCH_STORAGE, reversedKey), + rockdDBKeyValueStorage.getNearestAfter(TRIE_BRANCH_STORAGE, reversedKey))) + .isTrue(); + }); + } + + @Test + public void testNearestRocksdbWithLayeredKeyValueStorage() { + final SegmentedKeyValueStorage rockdDBKeyValueStorage = + getRocksDBKeyValueStorage(TRIE_BRANCH_STORAGE); + final SegmentedKeyValueStorageTransaction rocksDbTransaction = + rockdDBKeyValueStorage.startTransaction(); + + final SegmentedKeyValueStorage inMemoryDBKeyValueStorage = getInMemoryDBKeyValueStorage(); + final SegmentedKeyValueStorageTransaction inMemoryDBTransaction = + inMemoryDBKeyValueStorage.startTransaction(); + + final LayeredKeyValueStorage layeredDBKeyValueStorage = + new LayeredKeyValueStorage(inMemoryDBKeyValueStorage); + final SegmentedKeyValueStorageTransaction layeredDBTransaction = + layeredDBKeyValueStorage.startTransaction(); + + IntStream.range(1, 10) + .forEach( + i -> { + final byte[] key = Bytes.fromHexString("0x000" + i).toArrayUnsafe(); + final byte[] value = Bytes.fromHexString("0FFF").toArrayUnsafe(); + rocksDbTransaction.put(TRIE_BRANCH_STORAGE, key, value); + // as we have several layers I store sometimes in the child layer and sometimes in the + // parent + if (i % 2 == 0) { + inMemoryDBTransaction.put(TRIE_BRANCH_STORAGE, key, value); + } else { + layeredDBTransaction.put(TRIE_BRANCH_STORAGE, key, value); + } + // different common prefix, and reversed order of bytes: + final byte[] key2 = Bytes.fromHexString("0x010" + (10 - i)).toArrayUnsafe(); + final byte[] value2 = Bytes.fromHexString("0FFF").toArrayUnsafe(); + rocksDbTransaction.put(TRIE_BRANCH_STORAGE, key2, value2); + // as we have several layers I store sometimes in the child layer and sometimes in the + // parent + if (i % 2 == 0) { + inMemoryDBTransaction.put(TRIE_BRANCH_STORAGE, key2, value2); + } else { + layeredDBTransaction.put(TRIE_BRANCH_STORAGE, key2, value2); + } + // different size: + final byte[] key3 = Bytes.fromHexString("0x01011" + (10 - i)).toArrayUnsafe(); + final byte[] value3 = Bytes.fromHexString("0FFF").toArrayUnsafe(); + rocksDbTransaction.put(TRIE_BRANCH_STORAGE, key3, value3); + // as we have several layers I store sometimes in the child layer and sometimes in the + // parent + if (i % 2 == 0) { + inMemoryDBTransaction.put(TRIE_BRANCH_STORAGE, key3, value3); + } else { + layeredDBTransaction.put(TRIE_BRANCH_STORAGE, key3, value3); + } + final byte[] key4 = Bytes.fromHexString("0x0" + (10 - i)).toArrayUnsafe(); + final byte[] value4 = Bytes.fromHexString("0FFF").toArrayUnsafe(); + rocksDbTransaction.put(TRIE_BRANCH_STORAGE, key4, value4); + // as we have several layers I store sometimes in the child layer and sometimes in the + // parent + if (i % 2 == 0) { + inMemoryDBTransaction.put(TRIE_BRANCH_STORAGE, key4, value4); + } else { + layeredDBTransaction.put(TRIE_BRANCH_STORAGE, key4, value4); + } + }); + rocksDbTransaction.commit(); + inMemoryDBTransaction.commit(); + layeredDBTransaction.commit(); + + // compare rocksdb implementation with inmemory implementation + rockdDBKeyValueStorage.stream(TRIE_BRANCH_STORAGE) + .forEach( + pair -> { + final Bytes key = Bytes.of(pair.getKey()); + assertThat( + isNearestKeyValueTheSame( + layeredDBKeyValueStorage.getNearestBefore(TRIE_BRANCH_STORAGE, key), + rockdDBKeyValueStorage.getNearestBefore(TRIE_BRANCH_STORAGE, key))) + .isTrue(); + assertThat( + isNearestKeyValueTheSame( + layeredDBKeyValueStorage.getNearestAfter(TRIE_BRANCH_STORAGE, key), + rockdDBKeyValueStorage.getNearestAfter(TRIE_BRANCH_STORAGE, key))) + .isTrue(); + + final Bytes biggerKey = Bytes.concatenate(key, Bytes.of(0x01)); + assertThat( + isNearestKeyValueTheSame( + layeredDBKeyValueStorage.getNearestBefore(TRIE_BRANCH_STORAGE, biggerKey), + rockdDBKeyValueStorage.getNearestBefore(TRIE_BRANCH_STORAGE, biggerKey))) + .isTrue(); + assertThat( + isNearestKeyValueTheSame( + layeredDBKeyValueStorage.getNearestAfter(TRIE_BRANCH_STORAGE, biggerKey), + rockdDBKeyValueStorage.getNearestAfter(TRIE_BRANCH_STORAGE, biggerKey))) + .isTrue(); + + final Bytes smallerKey = key.slice(0, key.size() - 1); + assertThat( + isNearestKeyValueTheSame( + layeredDBKeyValueStorage.getNearestBefore( + TRIE_BRANCH_STORAGE, smallerKey), + rockdDBKeyValueStorage.getNearestBefore(TRIE_BRANCH_STORAGE, smallerKey))) + .isTrue(); + assertThat( + isNearestKeyValueTheSame( + layeredDBKeyValueStorage.getNearestAfter(TRIE_BRANCH_STORAGE, smallerKey), + rockdDBKeyValueStorage.getNearestAfter(TRIE_BRANCH_STORAGE, smallerKey))) + .isTrue(); + + final Bytes reversedKey = key.reverse(); + assertThat( + isNearestKeyValueTheSame( + layeredDBKeyValueStorage.getNearestBefore( + TRIE_BRANCH_STORAGE, reversedKey), + rockdDBKeyValueStorage.getNearestBefore( + TRIE_BRANCH_STORAGE, reversedKey))) + .isTrue(); + assertThat( + isNearestKeyValueTheSame( + layeredDBKeyValueStorage.getNearestAfter( + TRIE_BRANCH_STORAGE, reversedKey), + rockdDBKeyValueStorage.getNearestAfter(TRIE_BRANCH_STORAGE, reversedKey))) + .isTrue(); + }); + } + + private SegmentedKeyValueStorage getRocksDBKeyValueStorage(final SegmentIdentifier segment) { + return rocksdbStorageFactory.create( + List.of(segment), commonConfiguration, new NoOpMetricsSystem()); + } + + private SegmentedKeyValueStorage getInMemoryDBKeyValueStorage() { + return new SegmentedInMemoryKeyValueStorage(); + } + + private static void mockCommonConfiguration(final Path tempDataDir) { + commonConfiguration = mock(BesuConfiguration.class); + when(commonConfiguration.getStoragePath()).thenReturn(tempDataDir); + when(commonConfiguration.getDataPath()).thenReturn(tempDataDir); + DataStorageConfiguration dataStorageConfiguration = mock(DataStorageConfiguration.class); + when(dataStorageConfiguration.getDatabaseFormat()).thenReturn(DataStorageFormat.BONSAI); + lenient() + .when(commonConfiguration.getDataStorageConfiguration()) + .thenReturn(dataStorageConfiguration); + } + + private boolean isNearestKeyValueTheSame( + final Optional v1, final Optional v2) { + if (v1.isPresent() && v2.isPresent()) { + final NearestKeyValue nearestKeyValue1 = v1.get(); + final NearestKeyValue nearestKeyValue2 = v2.get(); + if (nearestKeyValue1.key().equals(nearestKeyValue2.key())) { + if (nearestKeyValue1.value().isPresent() && nearestKeyValue2.value().isPresent()) { + return Arrays.equals(nearestKeyValue1.value().get(), nearestKeyValue2.value().get()); + } + } else if (nearestKeyValue1.value().isEmpty() && nearestKeyValue2.value().isEmpty()) { + return true; + } + } else if (v1.isEmpty() && v2.isEmpty()) { + return true; + } + return false; + } +} diff --git a/services/kvstore/src/main/java/org/hyperledger/besu/services/kvstore/KeyComparator.java b/services/kvstore/src/main/java/org/hyperledger/besu/services/kvstore/KeyComparator.java new file mode 100644 index 0000000000..ff9dd00dd8 --- /dev/null +++ b/services/kvstore/src/main/java/org/hyperledger/besu/services/kvstore/KeyComparator.java @@ -0,0 +1,61 @@ +/* + * 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.services.kvstore; + +import org.apache.tuweni.bytes.Bytes; + +/** + * This class is a comparator that allows comparing two byte arrays from left to right. + * + *

For example: + * + *

>0x01 is smaller than 0x0101 or 0x01 is smaller than 0x02. + */ +public class KeyComparator { + + /** Instantiates a new KeyComparator */ + public KeyComparator() {} + + /** + * Compares two keys from left to right. + * + *

This method performs a byte-by-byte comparison between two keys, starting from the left + * (most significant byte). It is designed to compare keys in a way that reflects their + * hierarchical or sequential order. + * + *

The method returns: - A negative integer if {@code key1} is lexicographically less than + * key2. - Zero if key1 and key2 are equal. - A positive integer if key1 is lexicographically + * greater than key2. + * + *

If the keys are of unequal length but identical for the length of the shorter key (prefix), + * the shorter key is considered to be lexicographically less than the longer key. This is + * consistent with the lexicographic ordering used by rocksdb. + * + * @param key1 the first key compare. + * @param key2 the second key to compare with. + * @return the value 0 if key1 is equal to key2; a value less than 0 if key1 is lexicographically + * less than key2; and a value greater than 0 if key1 is lexicographically greater than key2. + */ + public static int compareKeyLeftToRight(final Bytes key1, final Bytes key2) { + int minLength = Math.min(key1.size(), key2.size()); + for (int i = 0; i < minLength; i++) { + int compare = Byte.compareUnsigned(key1.get(i), key2.get(i)); + if (compare != 0) { + return compare; + } + } + return Integer.compare(key1.size(), key2.size()); + } +} diff --git a/services/kvstore/src/main/java/org/hyperledger/besu/services/kvstore/LayeredKeyValueStorage.java b/services/kvstore/src/main/java/org/hyperledger/besu/services/kvstore/LayeredKeyValueStorage.java index 36bb5c52d8..de9abcaf29 100644 --- a/services/kvstore/src/main/java/org/hyperledger/besu/services/kvstore/LayeredKeyValueStorage.java +++ b/services/kvstore/src/main/java/org/hyperledger/besu/services/kvstore/LayeredKeyValueStorage.java @@ -33,6 +33,7 @@ import java.util.Spliterators; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.locks.Lock; +import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; import java.util.stream.StreamSupport; @@ -101,25 +102,77 @@ public class LayeredKeyValueStorage extends SegmentedInMemoryKeyValueStorage } @Override - public Optional getNearestTo( + public Optional getNearestBefore( final SegmentIdentifier segmentIdentifier, final Bytes key) throws StorageException { - Optional ourNearest = super.getNearestTo(segmentIdentifier, key); - Optional parentNearest = parent.getNearestTo(segmentIdentifier, key); + return getNearest( + key, + k -> super.getNearestBefore(segmentIdentifier, k), + k -> parent.getNearestBefore(segmentIdentifier, k), + false); + } + + @Override + public Optional getNearestAfter( + final SegmentIdentifier segmentIdentifier, final Bytes key) throws StorageException { + return getNearest( + key, + k -> super.getNearestAfter(segmentIdentifier, k), + k -> parent.getNearestAfter(segmentIdentifier, k), + true); + } + + private Optional getNearest( + final Bytes key, + final Function> ourNearestFunction, + final Function> parentNearestFunction, + final boolean isAfter) + throws StorageException { + + final Optional ourNearest = ourNearestFunction.apply(key); + final Optional parentNearest = parentNearestFunction.apply(key); if (ourNearest.isPresent() && parentNearest.isPresent()) { - // Both are present, return the one closer to the key - int ourDistance = ourNearest.get().key().commonPrefixLength(key); - int parentDistance = parentNearest.get().key().commonPrefixLength(key); - return (ourDistance <= parentDistance) ? ourNearest : parentNearest; + return compareNearest(ourNearest, parentNearest, key, isAfter); } else if (ourNearest.isPresent()) { - // Only ourNearest is present return ourNearest; } else { - // return parentNearest, which may be an empty Optional return parentNearest; } } + private Optional compareNearest( + final Optional ourNearest, + final Optional parentNearest, + final Bytes key, + final boolean isAfter) { + + final int ourDistance = ourNearest.get().key().compareTo(key); + final int parentDistance = parentNearest.get().key().compareTo(key); + if (ourDistance == 0) { + return ourNearest; + } else if (parentDistance == 0) { + return parentNearest; + } else { + final int ourCommonPrefixLength = ourNearest.get().key().commonPrefixLength(key); + final int parentCommonPrefixLength = parentNearest.get().key().commonPrefixLength(key); + if (ourCommonPrefixLength != parentCommonPrefixLength) { + return ourCommonPrefixLength > parentCommonPrefixLength ? ourNearest : parentNearest; + } else { + // When searching for a key, if isAfter is true, we choose the next smallest key after our + // target because both found keys are after it. + // If isAfter is false, meaning we're doing a seekForPrev, we select the largest key that + // comes before our target, as it's the nearest one. + // For example : if the searched key is 0x0101 and we found 0x0001 and 0x0100 when isAfter + // == false we will take 0x0100 + if (ourNearest.get().key().compareTo(parentNearest.get().key()) > 0) { + return isAfter ? parentNearest : ourNearest; + } else { + return isAfter ? ourNearest : parentNearest; + } + } + } + } + @Override public Stream> stream(final SegmentIdentifier segmentId) { throwIfClosed(); diff --git a/services/kvstore/src/main/java/org/hyperledger/besu/services/kvstore/SegmentedInMemoryKeyValueStorage.java b/services/kvstore/src/main/java/org/hyperledger/besu/services/kvstore/SegmentedInMemoryKeyValueStorage.java index beabb04d84..a7cedca362 100644 --- a/services/kvstore/src/main/java/org/hyperledger/besu/services/kvstore/SegmentedInMemoryKeyValueStorage.java +++ b/services/kvstore/src/main/java/org/hyperledger/besu/services/kvstore/SegmentedInMemoryKeyValueStorage.java @@ -15,6 +15,7 @@ package org.hyperledger.besu.services.kvstore; import static java.util.stream.Collectors.toUnmodifiableSet; +import static org.hyperledger.besu.services.kvstore.KeyComparator.compareKeyLeftToRight; import org.hyperledger.besu.plugin.services.exception.StorageException; import org.hyperledger.besu.plugin.services.storage.SegmentIdentifier; @@ -39,6 +40,7 @@ import java.util.concurrent.ConcurrentSkipListMap; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; +import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -143,26 +145,67 @@ public class SegmentedInMemoryKeyValueStorage } @Override - public Optional getNearestTo( + public Optional getNearestBefore( final SegmentIdentifier segmentIdentifier, final Bytes key) throws StorageException { + return getNearest( + segmentIdentifier, + e -> + compareKeyLeftToRight(e.getKey(), key) <= 0 + && e.getKey().commonPrefixLength(key) >= e.getKey().size(), + e -> compareKeyLeftToRight(e.getKey(), key) < 0, + false); + } + + @Override + public Optional getNearestAfter( + final SegmentIdentifier segmentIdentifier, final Bytes key) throws StorageException { + return getNearest( + segmentIdentifier, + e -> + compareKeyLeftToRight(e.getKey(), key) >= 0 + && e.getKey().commonPrefixLength(key) >= e.getKey().size(), + e -> compareKeyLeftToRight(e.getKey(), key) >= 0, + true); + } + + private Optional getNearest( + final SegmentIdentifier segmentIdentifier, + final Predicate>> samePrefixPredicate, + final Predicate>> fallbackPredicate, + final boolean useMin) + throws StorageException { final Lock lock = rwLock.readLock(); lock.lock(); try { - // TODO: revisit this for sort performance - Comparator>> comparing = - Comparator.comparing( - (Map.Entry> a) -> a.getKey().commonPrefixLength(key)) - .thenComparing(Map.Entry.comparingByKey()); - return this.hashValueStore - .computeIfAbsent(segmentIdentifier, s -> newSegmentMap()) - .entrySet() - .stream() - // only return keys equal to or less than - .filter(e -> e.getKey().compareTo(key) <= 0) - .sorted(comparing.reversed()) - .findFirst() - .map(z -> new NearestKeyValue(z.getKey(), z.getValue())); + final Map> segmentMap = + this.hashValueStore.computeIfAbsent(segmentIdentifier, s -> newSegmentMap()); + + final Function>>, Optional> + findNearest = + (predicate) -> { + final Stream>> filteredStream = + segmentMap.entrySet().stream().filter(predicate); + // Depending on the useMin flag, find either the minimum or maximum entry according + // to key order + final Optional>> sortedStream = + useMin + ? filteredStream.min( + (t1, t2) -> compareKeyLeftToRight(t1.getKey(), t2.getKey())) + : filteredStream.max( + (t1, t2) -> compareKeyLeftToRight(t1.getKey(), t2.getKey())); + return sortedStream.map( + entry -> new NearestKeyValue(entry.getKey(), entry.getValue())); + }; + + // First, attempt to find a key-value pair that matches the same prefix + final Optional withSamePrefix = findNearest.apply(samePrefixPredicate); + if (withSamePrefix.isPresent()) { + return withSamePrefix; + } + // If a matching entry with a common prefix is not found, the next step is to search for the + // nearest key that comes after or before the requested one. + return findNearest.apply(fallbackPredicate); } finally { lock.unlock(); } diff --git a/services/kvstore/src/test/java/org/hyperledger/besu/services/kvstore/AbstractSegmentedKeyValueStorageTest.java b/services/kvstore/src/test/java/org/hyperledger/besu/services/kvstore/AbstractSegmentedKeyValueStorageTest.java deleted file mode 100644 index f96cc90157..0000000000 --- a/services/kvstore/src/test/java/org/hyperledger/besu/services/kvstore/AbstractSegmentedKeyValueStorageTest.java +++ /dev/null @@ -1,81 +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.services.kvstore; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.hyperledger.besu.services.kvstore.InMemoryKeyValueStorage.SEGMENT_IDENTIFIER; - -import org.hyperledger.besu.kvstore.AbstractKeyValueStorageTest; -import org.hyperledger.besu.plugin.services.storage.SegmentedKeyValueStorage; -import org.hyperledger.besu.plugin.services.storage.SegmentedKeyValueStorageTransaction; - -import java.util.stream.IntStream; - -import org.apache.tuweni.bytes.Bytes; -import org.junit.jupiter.api.Test; - -public abstract class AbstractSegmentedKeyValueStorageTest extends AbstractKeyValueStorageTest { - public abstract SegmentedKeyValueStorage createSegmentedStore(); - - @Test - public void assertSegmentedIsNearestTo() throws Exception { - try (final var store = this.createSegmentedStore()) { - - // create 10 entries - final SegmentedKeyValueStorageTransaction tx = store.startTransaction(); - IntStream.range(1, 10) - .forEach( - i -> { - final byte[] key = bytesFromHexString("000" + i); - final byte[] value = bytesFromHexString("0FFF"); - tx.put(SEGMENT_IDENTIFIER, key, value); - // different common prefix, and reversed order of bytes: - final byte[] key2 = bytesFromHexString("010" + (10 - i)); - final byte[] value2 = bytesFromHexString("0FFF"); - tx.put(SEGMENT_IDENTIFIER, key2, value2); - }); - tx.commit(); - - // assert 0009 is closest to 000F - var val = store.getNearestTo(SEGMENT_IDENTIFIER, Bytes.fromHexString("000F")); - assertThat(val).isPresent(); - assertThat(val.get().key()).isEqualTo(Bytes.fromHexString("0009")); - - // assert 0109 is closest to 010D - var val2 = store.getNearestTo(SEGMENT_IDENTIFIER, Bytes.fromHexString("010D")); - assertThat(val2).isPresent(); - assertThat(val2.get().key()).isEqualTo(Bytes.fromHexString("0109")); - - // assert 0103 is closest to 0103 - var val3 = store.getNearestTo(SEGMENT_IDENTIFIER, Bytes.fromHexString("0103")); - assertThat(val3).isPresent(); - assertThat(val3.get().key()).isEqualTo(Bytes.fromHexString("0103")); - - // assert 0003 is closest to 0003 - var val4 = store.getNearestTo(SEGMENT_IDENTIFIER, Bytes.fromHexString("0003")); - assertThat(val4).isPresent(); - assertThat(val4.get().key()).isEqualTo(Bytes.fromHexString("0003")); - - // assert 0001 is closest to 0001 - var val5 = store.getNearestTo(SEGMENT_IDENTIFIER, Bytes.fromHexString("0001")); - assertThat(val5).isPresent(); - assertThat(val5.get().key()).isEqualTo(Bytes.fromHexString("0001")); - - // assert 0000 is not present - var val6 = store.getNearestTo(SEGMENT_IDENTIFIER, Bytes.fromHexString("0000")); - assertThat(val6).isNotPresent(); - } - } -} diff --git a/services/kvstore/src/test/java/org/hyperledger/besu/services/kvstore/InMemoryKeyValueStorageTest.java b/services/kvstore/src/test/java/org/hyperledger/besu/services/kvstore/InMemoryKeyValueStorageTest.java deleted file mode 100644 index 55a10ffa8d..0000000000 --- a/services/kvstore/src/test/java/org/hyperledger/besu/services/kvstore/InMemoryKeyValueStorageTest.java +++ /dev/null @@ -1,31 +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.services.kvstore; - -import org.hyperledger.besu.plugin.services.storage.KeyValueStorage; -import org.hyperledger.besu.plugin.services.storage.SegmentedKeyValueStorage; - -public class InMemoryKeyValueStorageTest extends AbstractSegmentedKeyValueStorageTest { - - @Override - protected KeyValueStorage createStore() { - return new InMemoryKeyValueStorage(); - } - - @Override - public SegmentedKeyValueStorage createSegmentedStore() { - return new SegmentedInMemoryKeyValueStorage(); - } -} diff --git a/services/kvstore/src/test/java/org/hyperledger/besu/services/kvstore/KeyComparatorTest.java b/services/kvstore/src/test/java/org/hyperledger/besu/services/kvstore/KeyComparatorTest.java new file mode 100644 index 0000000000..b6f536f8b6 --- /dev/null +++ b/services/kvstore/src/test/java/org/hyperledger/besu/services/kvstore/KeyComparatorTest.java @@ -0,0 +1,63 @@ +/* + * 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.services.kvstore; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.apache.tuweni.bytes.Bytes; +import org.junit.jupiter.api.Test; + +public class KeyComparatorTest { + + @Test + public void testEmptyVs01() { + Bytes key1 = Bytes.EMPTY; + Bytes key2 = Bytes.fromHexString("0x01"); + int result = KeyComparator.compareKeyLeftToRight(key1, key2); + assertEquals(-1, result, "Empty key should be considered smaller than 0x01"); + } + + @Test + public void test01Vs02() { + Bytes key1 = Bytes.fromHexString("0x01"); + Bytes key2 = Bytes.fromHexString("0x02"); + int result = KeyComparator.compareKeyLeftToRight(key1, key2); + assertEquals(-1, result, "0x01 should be considered smaller than 0x02"); + } + + @Test + public void test01Vs0100() { + Bytes key1 = Bytes.fromHexString("0x01"); + Bytes key2 = Bytes.fromHexString("0x0100"); + int result = KeyComparator.compareKeyLeftToRight(key1, key2); + assertEquals(-1, result, "0x01 should be considered smaller than 0x0100"); + } + + @Test + public void test01Vs0201() { + Bytes key1 = Bytes.fromHexString("0x01"); + Bytes key2 = Bytes.fromHexString("0x0201"); + int result = KeyComparator.compareKeyLeftToRight(key1, key2); + assertEquals(-1, result, "0x01 should be considered smaller than 0x0201"); + } + + @Test + public void test0101Vs02() { + Bytes key1 = Bytes.fromHexString("0x0101"); + Bytes key2 = Bytes.fromHexString("0x02"); + int result = KeyComparator.compareKeyLeftToRight(key1, key2); + assertEquals(-1, result, "0x0101 should be considered smaller than 0x02"); + } +} diff --git a/services/kvstore/src/test/java/org/hyperledger/besu/services/kvstore/LayeredKeyValueStorageTest.java b/services/kvstore/src/test/java/org/hyperledger/besu/services/kvstore/LayeredKeyValueStorageTest.java deleted file mode 100644 index dba0ae2a36..0000000000 --- a/services/kvstore/src/test/java/org/hyperledger/besu/services/kvstore/LayeredKeyValueStorageTest.java +++ /dev/null @@ -1,32 +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.services.kvstore; - -import static org.hyperledger.besu.services.kvstore.InMemoryKeyValueStorage.SEGMENT_IDENTIFIER; - -import org.hyperledger.besu.plugin.services.storage.KeyValueStorage; -import org.hyperledger.besu.plugin.services.storage.SegmentedKeyValueStorage; - -public class LayeredKeyValueStorageTest extends AbstractSegmentedKeyValueStorageTest { - @Override - protected KeyValueStorage createStore() { - return new SegmentedKeyValueStorageAdapter(SEGMENT_IDENTIFIER, createSegmentedStore()); - } - - @Override - public SegmentedKeyValueStorage createSegmentedStore() { - return new LayeredKeyValueStorage(new SegmentedInMemoryKeyValueStorage()); - } -} From 12576d77058f170fc3afbddf39e296c7e6302760 Mon Sep 17 00:00:00 2001 From: Fabio Di Fabio Date: Fri, 16 Aug 2024 22:06:53 +0200 Subject: [PATCH 129/259] Correctly release txpool save and restore lock in case of exceptions (#7473) Signed-off-by: Fabio Di Fabio --- CHANGELOG.md | 1 + .../besu/ethereum/eth/transactions/TransactionPool.java | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 183ca24e55..84641ea16e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ - Fix protocol schedule check for devnets [#7429](https://github.com/hyperledger/besu/pull/7429) - Fix behaviour when starting in a pre-merge network [#7431](https://github.com/hyperledger/besu/pull/7431) - Fix tracing in precompiled contracts when halting for out of gas [#7318](https://github.com/hyperledger/besu/issues/7318) +- Correctly release txpool save and restore lock in case of exceptions [#7473](https://github.com/hyperledger/besu/pull/7473) ## 24.7.1 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 c069a771eb..6bb2029960 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 @@ -706,7 +706,8 @@ public class TransactionPool implements BlockAddedObserver { isCancelled.set(false); operationInProgress.set( - CompletableFuture.runAsync(operation).thenRun(diskAccessLock::release)); + CompletableFuture.runAsync(operation) + .whenComplete((res, err) -> diskAccessLock.release())); return operationInProgress.get(); } else { CompletableFuture.failedFuture( From f50f7c09d8ce0ef146067743df49ce3b5d39cb39 Mon Sep 17 00:00:00 2001 From: garyschulte Date: Fri, 16 Aug 2024 17:03:07 -0700 Subject: [PATCH 130/259] Bump changelog ahead of 24.8.0 (#7476) * bump changelog Signed-off-by: garyschulte --- CHANGELOG.md | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 84641ea16e..9173e46fd5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,19 @@ ## Next release +### Upcoming Breaking Changes + +### Breaking Changes + +### Additions and Improvements +- Add 'inbound' field to admin_peers JSON-RPC Call [#7461](https://github.com/hyperledger/besu/pull/7461) + +### Bug fixes +- Fix tracing in precompiled contracts when halting for out of gas [#7318](https://github.com/hyperledger/besu/issues/7318) +- Correctly release txpool save and restore lock in case of exceptions [#7473](https://github.com/hyperledger/besu/pull/7473) + +## 24.8.0 + ### Upcoming Breaking Changes - Receipt compaction will be enabled by default in a future version of Besu. After this change it will not be possible to downgrade to the previous Besu version. - --Xbonsai-limit-trie-logs-enabled is deprecated, use --bonsai-limit-trie-logs-enabled instead @@ -18,15 +31,12 @@ - Added support for tracing private transactions using `priv_traceTransaction` API. [#6161](https://github.com/hyperledger/besu/pull/6161) - Wrap WorldUpdater into EVMWorldupdater [#7434](https://github.com/hyperledger/besu/pull/7434) - Bump besu-native to 0.9.4 [#7456](https://github.com/hyperledger/besu/pull/7456) -- Add 'inbound' field to admin_peers JSON-RPC Call [#7461](https://github.com/hyperledger/besu/pull/7461) ### Bug fixes - Correct entrypoint in Docker evmtool [#7430](https://github.com/hyperledger/besu/pull/7430) - Fix protocol schedule check for devnets [#7429](https://github.com/hyperledger/besu/pull/7429) - Fix behaviour when starting in a pre-merge network [#7431](https://github.com/hyperledger/besu/pull/7431) -- Fix tracing in precompiled contracts when halting for out of gas [#7318](https://github.com/hyperledger/besu/issues/7318) -- Correctly release txpool save and restore lock in case of exceptions [#7473](https://github.com/hyperledger/besu/pull/7473) ## 24.7.1 From ef8aa7c9ecfddd01f5d8511877c5084ee7e673bb Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Mon, 19 Aug 2024 11:35:58 +1000 Subject: [PATCH 131/259] 5098 branch 22 update more invalid params (#7472) * 5098: Add RpcErrorTypes Signed-off-by: Matilda Clerke --------- Signed-off-by: Matilda Clerke Signed-off-by: Matilda-Clerke Co-authored-by: Sally MacFarlane --- .../methods/IbftProposeValidatorVote.java | 8 ++++- .../methods/IbftProposeValidatorVoteTest.java | 4 +-- .../methods/QbftProposeValidatorVote.java | 8 ++++- .../methods/QbftProposeValidatorVoteTest.java | 4 +-- .../internal/methods/DebugAccountAt.java | 12 ++++++-- .../methods/DebugGetRawTransaction.java | 12 +++++++- .../DebugStandardTraceBadBlockToFile.java | 11 +++++-- .../DebugStandardTraceBlockToFile.java | 11 +++++-- .../internal/methods/DebugStorageRangeAt.java | 18 +++++++++-- .../internal/methods/DebugTraceBlock.java | 18 +++++++---- .../methods/DebugTraceBlockByHash.java | 18 +++++++---- .../methods/DebugTraceBlockByNumber.java | 18 +++++++---- .../internal/methods/DebugTraceCall.java | 15 +++++++--- .../methods/DebugTraceTransaction.java | 30 +++++++++++++++---- .../EthGetTransactionByBlockHashAndIndex.java | 22 ++++++++++++-- ...thGetTransactionByBlockNumberAndIndex.java | 10 ++++++- .../methods/EthGetTransactionByHash.java | 11 ++++++- .../methods/EthGetTransactionReceipt.java | 12 +++++++- .../methods/EthSendRawTransaction.java | 9 +++++- .../jsonrpc/internal/methods/TraceCall.java | 9 +++++- .../internal/methods/TraceCallMany.java | 2 +- .../jsonrpc/internal/methods/TraceGet.java | 21 +++++++++++-- .../internal/methods/TraceRawTransaction.java | 20 ++++++++++--- .../methods/TraceReplayBlockTransactions.java | 9 ++++-- .../internal/methods/TraceTransaction.java | 12 +++++++- .../TxPoolBesuPendingTransactions.java | 12 ++++++-- .../AbstractEngineForkchoiceUpdated.java | 2 +- .../engine/AbstractEngineNewPayload.java | 24 ++++++++------- .../methods/engine/EngineNewPayloadV3.java | 2 +- .../methods/engine/EngineNewPayloadV4.java | 2 +- .../miner/MinerChangeTargetGasLimit.java | 8 ++++- .../parameters/TraceTypeParameter.java | 5 +++- .../eea/AbstractEeaSendRawTransaction.java | 9 +++++- .../priv/PrivDistributeRawTransaction.java | 11 ++++++- .../priv/PrivGetEeaTransactionCount.java | 2 +- .../priv/PrivGetPrivateTransaction.java | 12 +++++++- .../priv/PrivGetTransactionReceipt.java | 11 ++++++- .../api/util/DomainObjectDecodeUtils.java | 7 +++-- .../internal/methods/DebugAccountAtTest.java | 6 ++-- .../AbstractEngineForkchoiceUpdatedTest.java | 2 +- .../engine/EngineForkchoiceUpdatedV1Test.java | 2 +- .../engine/EngineForkchoiceUpdatedV2Test.java | 2 +- .../miner/MinerChangeTargetGasLimitTest.java | 3 +- .../eea/EeaSendRawTransactionTest.java | 6 ++-- ...actionByBlockHashAndIndex_intOverflow.json | 2 +- ...onByBlockHashAndIndex_missingParam_00.json | 2 +- ...onByBlockHashAndIndex_missingParam_01.json | 2 +- ...tionByBlockHashAndIndex_missingParams.json | 2 +- ...ionByBlockHashAndIndex_wrongParamType.json | 2 +- ...eth_getTransactionByHash_typeMismatch.json | 2 +- ...BlockTransactions_invalidTraceOptions.json | 2 +- .../retesteth/methods/TestGetLogHash.java | 12 +++++++- .../methods/TestModifyTimestamp.java | 10 ++++++- 53 files changed, 388 insertions(+), 100 deletions(-) diff --git a/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftProposeValidatorVote.java b/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftProposeValidatorVote.java index a29187b513..9364422c57 100644 --- a/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftProposeValidatorVote.java +++ b/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftProposeValidatorVote.java @@ -60,7 +60,13 @@ public class IbftProposeValidatorVote implements JsonRpcMethod { throw new InvalidJsonRpcParameters( "Invalid address parameter (index 0)", RpcErrorType.INVALID_ADDRESS_PARAMS, e); } - final Boolean add = requestContext.getRequiredParameter(1, Boolean.class); + final Boolean add; + try { + add = requestContext.getRequiredParameter(1, Boolean.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid vote type parameter (index 1)", RpcErrorType.INVALID_VOTE_TYPE_PARAMS, e); + } LOG.trace( "Received RPC rpcName={} voteType={} address={}", getName(), diff --git a/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftProposeValidatorVoteTest.java b/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftProposeValidatorVoteTest.java index d0df723d54..dfa6f7b6e5 100644 --- a/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftProposeValidatorVoteTest.java +++ b/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftProposeValidatorVoteTest.java @@ -63,7 +63,7 @@ public class IbftProposeValidatorVoteTest { public void exceptionWhenNoAuthSupplied() { assertThatThrownBy(() -> method.response(requestWithParams(Address.fromHexString("1")))) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage("Missing required json rpc parameter at index 1"); + .hasMessage("Invalid vote type parameter (index 1)"); } @Test @@ -77,7 +77,7 @@ public class IbftProposeValidatorVoteTest { public void exceptionWhenInvalidBoolParameterSupplied() { assertThatThrownBy(() -> method.response(requestWithParams(Address.fromHexString("1"), "c"))) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Invalid json rpc parameter at index 1"); + .hasMessageContaining("Invalid vote type parameter (index 1)"); } @Test diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftProposeValidatorVote.java b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftProposeValidatorVote.java index 9eefbb8d13..aa3a8b267e 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftProposeValidatorVote.java +++ b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftProposeValidatorVote.java @@ -60,7 +60,13 @@ public class QbftProposeValidatorVote implements JsonRpcMethod { RpcErrorType.INVALID_ADDRESS_PARAMS, e); } - final Boolean add = requestContext.getRequiredParameter(1, Boolean.class); + final Boolean add; + try { + add = requestContext.getRequiredParameter(1, Boolean.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid vote type parameter (index 1)", RpcErrorType.INVALID_VOTE_TYPE_PARAMS, e); + } LOG.trace( "Received RPC rpcName={} voteType={} address={}", getName(), diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftProposeValidatorVoteTest.java b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftProposeValidatorVoteTest.java index 62f7dc6169..1f5b1466d9 100644 --- a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftProposeValidatorVoteTest.java +++ b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftProposeValidatorVoteTest.java @@ -65,7 +65,7 @@ public class QbftProposeValidatorVoteTest { public void exceptionWhenNoAuthSupplied() { assertThatThrownBy(() -> method.response(requestWithParams(Address.fromHexString("1")))) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage("Missing required json rpc parameter at index 1"); + .hasMessage("Invalid vote type parameter (index 1)"); } @Test @@ -79,7 +79,7 @@ public class QbftProposeValidatorVoteTest { public void exceptionWhenInvalidBoolParameterSupplied() { assertThatThrownBy(() -> method.response(requestWithParams(Address.fromHexString("1"), "c"))) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Invalid json rpc parameter at index 1"); + .hasMessageContaining("Invalid vote type parameter (index 1)"); } @Test diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugAccountAt.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugAccountAt.java index 550a25982d..602f3de3e0 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugAccountAt.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugAccountAt.java @@ -78,7 +78,15 @@ public class DebugAccountAt extends AbstractBlockParameterOrBlockHashMethod { @Override protected Object resultByBlockHash( final JsonRpcRequestContext requestContext, final Hash blockHash) { - final Integer txIndex = requestContext.getRequiredParameter(1, Integer.class); + final Integer txIndex; + try { + txIndex = requestContext.getRequiredParameter(1, Integer.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid transaction index parameter (index 1)", + RpcErrorType.INVALID_TRANSACTION_INDEX_PARAMS, + e); + } final Address address; try { address = requestContext.getRequiredParameter(2, Address.class); @@ -97,7 +105,7 @@ public class DebugAccountAt extends AbstractBlockParameterOrBlockHashMethod { List transactions = block.get().getTransactions(); if (transactions.isEmpty() || txIndex < 0 || txIndex > block.get().getTransactions().size()) { return new JsonRpcErrorResponse( - requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + requestContext.getRequest().getId(), RpcErrorType.INVALID_TRANSACTION_PARAMS); } return Tracer.processTracing( diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugGetRawTransaction.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugGetRawTransaction.java index ab1230ca96..d6ede25b27 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugGetRawTransaction.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugGetRawTransaction.java @@ -17,8 +17,10 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; 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.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; import org.hyperledger.besu.ethereum.core.Transaction; import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; @@ -38,7 +40,15 @@ public class DebugGetRawTransaction implements JsonRpcMethod { @Override public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { - final Hash txHash = requestContext.getRequiredParameter(0, Hash.class); + final Hash txHash; + try { + txHash = requestContext.getRequiredParameter(0, Hash.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid transaction hash parameter (index 0)", + RpcErrorType.INVALID_TRANSACTION_HASH_PARAMS, + e); + } return blockchainQueries .transactionByHash(txHash) diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStandardTraceBadBlockToFile.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStandardTraceBadBlockToFile.java index 7587e40c75..2d0c4cac4e 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStandardTraceBadBlockToFile.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStandardTraceBadBlockToFile.java @@ -60,8 +60,15 @@ public class DebugStandardTraceBadBlockToFile extends DebugStandardTraceBlockToF throw new InvalidJsonRpcParameters( "Invalid block hash parameter (index 0)", RpcErrorType.INVALID_BLOCK_HASH_PARAMS, e); } - final Optional transactionTraceParams = - requestContext.getOptionalParameter(1, TransactionTraceParams.class); + final Optional transactionTraceParams; + try { + transactionTraceParams = requestContext.getOptionalParameter(1, TransactionTraceParams.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid transaction trace parameters (index 1)", + RpcErrorType.INVALID_TRANSACTION_TRACE_PARAMS, + e); + } final BadBlockManager badBlockManager = protocolContext.getBadBlockManager(); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStandardTraceBlockToFile.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStandardTraceBlockToFile.java index 601eabeab1..5fba2911bd 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStandardTraceBlockToFile.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStandardTraceBlockToFile.java @@ -67,8 +67,15 @@ public class DebugStandardTraceBlockToFile implements JsonRpcMethod { throw new InvalidJsonRpcParameters( "Invalid block hash parameter (index 0)", RpcErrorType.INVALID_BLOCK_HASH_PARAMS, e); } - final Optional transactionTraceParams = - requestContext.getOptionalParameter(1, TransactionTraceParams.class); + final Optional transactionTraceParams; + try { + transactionTraceParams = requestContext.getOptionalParameter(1, TransactionTraceParams.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid transaction trace parameters (index 1)", + RpcErrorType.INVALID_TRANSACTION_TRACE_PARAMS, + e); + } return blockchainQueries .get() diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStorageRangeAt.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStorageRangeAt.java index f6f1601331..5aabff4b57 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStorageRangeAt.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStorageRangeAt.java @@ -77,7 +77,15 @@ public class DebugStorageRangeAt implements JsonRpcMethod { throw new InvalidJsonRpcParameters( "Invalid block or block hash parameter (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e); } - final int transactionIndex = requestContext.getRequiredParameter(1, Integer.class); + final int transactionIndex; + try { + transactionIndex = requestContext.getRequiredParameter(1, Integer.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid transaction index parameter (index 1)", + RpcErrorType.INVALID_TRANSACTION_INDEX_PARAMS, + e); + } final Address accountAddress; try { accountAddress = requestContext.getRequiredParameter(2, Address.class); @@ -92,7 +100,13 @@ public class DebugStorageRangeAt implements JsonRpcMethod { throw new InvalidJsonRpcParameters( "Invalid data start hash parameter (index 3)", RpcErrorType.INVALID_DATA_HASH_PARAMS, e); } - final int limit = requestContext.getRequiredParameter(4, Integer.class); + final int limit; + try { + limit = requestContext.getRequiredParameter(4, Integer.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid limit parameter (index 4)", RpcErrorType.INVALID_TRANSACTION_LIMIT_PARAMS, e); + } final Optional blockHashOptional = hashFromParameter(blockParameterOrBlockHash); if (blockHashOptional.isEmpty()) { diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlock.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlock.java index 44cbf153de..2d668c7f22 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlock.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlock.java @@ -77,11 +77,19 @@ public class DebugTraceBlock implements JsonRpcMethod { throw new InvalidJsonRpcParameters( "Invalid block params (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e); } - final TraceOptions traceOptions = - requestContext - .getOptionalParameter(1, TransactionTraceParams.class) - .map(TransactionTraceParams::traceOptions) - .orElse(TraceOptions.DEFAULT); + final TraceOptions traceOptions; + try { + traceOptions = + requestContext + .getOptionalParameter(1, TransactionTraceParams.class) + .map(TransactionTraceParams::traceOptions) + .orElse(TraceOptions.DEFAULT); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid transaction trace parameter (index 1)", + RpcErrorType.INVALID_TRANSACTION_TRACE_PARAMS, + e); + } if (this.blockchainQueries.blockByHash(block.getHeader().getParentHash()).isPresent()) { final Collection results = diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockByHash.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockByHash.java index b1216885f1..da795439cf 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockByHash.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockByHash.java @@ -59,11 +59,19 @@ public class DebugTraceBlockByHash implements JsonRpcMethod { throw new InvalidJsonRpcParameters( "Invalid block hash parameter (index 0)", RpcErrorType.INVALID_BLOCK_HASH_PARAMS, e); } - final TraceOptions traceOptions = - requestContext - .getOptionalParameter(1, TransactionTraceParams.class) - .map(TransactionTraceParams::traceOptions) - .orElse(TraceOptions.DEFAULT); + final TraceOptions traceOptions; + try { + traceOptions = + requestContext + .getOptionalParameter(1, TransactionTraceParams.class) + .map(TransactionTraceParams::traceOptions) + .orElse(TraceOptions.DEFAULT); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid transaction trace parameters (index 1)", + RpcErrorType.INVALID_TRANSACTION_TRACE_PARAMS, + e); + } final Collection results = Tracer.processTracing( diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockByNumber.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockByNumber.java index dce3ab1ebf..eb90edabb9 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockByNumber.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockByNumber.java @@ -61,11 +61,19 @@ public class DebugTraceBlockByNumber extends AbstractBlockParameterMethod { protected Object resultByBlockNumber( final JsonRpcRequestContext request, final long blockNumber) { final Optional blockHash = getBlockchainQueries().getBlockHashByNumber(blockNumber); - final TraceOptions traceOptions = - request - .getOptionalParameter(1, TransactionTraceParams.class) - .map(TransactionTraceParams::traceOptions) - .orElse(TraceOptions.DEFAULT); + final TraceOptions traceOptions; + try { + traceOptions = + request + .getOptionalParameter(1, TransactionTraceParams.class) + .map(TransactionTraceParams::traceOptions) + .orElse(TraceOptions.DEFAULT); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid transaction trace parameter (index 1)", + RpcErrorType.INVALID_TRANSACTION_TRACE_PARAMS, + e); + } return blockHash .flatMap( diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceCall.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceCall.java index 9de8108e67..ad46d981ac 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceCall.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceCall.java @@ -55,10 +55,17 @@ public class DebugTraceCall extends AbstractTraceCall { @Override protected TraceOptions getTraceOptions(final JsonRpcRequestContext requestContext) { - return requestContext - .getOptionalParameter(2, TransactionTraceParams.class) - .map(TransactionTraceParams::traceOptions) - .orElse(TraceOptions.DEFAULT); + try { + return requestContext + .getOptionalParameter(2, TransactionTraceParams.class) + .map(TransactionTraceParams::traceOptions) + .orElse(TraceOptions.DEFAULT); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid transaction trace parameters (index 2)", + RpcErrorType.INVALID_TRANSACTION_TRACE_PARAMS, + e); + } } @Override diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceTransaction.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceTransaction.java index 8ce0052b8b..8ec14dc4ad 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceTransaction.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceTransaction.java @@ -17,11 +17,13 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.TransactionTraceParams; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.Tracer; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.TransactionTracer; 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.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.DebugTraceTransactionResult; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; import org.hyperledger.besu.ethereum.api.query.TransactionWithMetadata; @@ -48,15 +50,31 @@ public class DebugTraceTransaction implements JsonRpcMethod { @Override public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { - final Hash hash = requestContext.getRequiredParameter(0, Hash.class); + final Hash hash; + try { + hash = requestContext.getRequiredParameter(0, Hash.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid transaction hash parameter (index 0)", + RpcErrorType.INVALID_TRANSACTION_HASH_PARAMS, + e); + } final Optional transactionWithMetadata = blockchain.transactionByHash(hash); if (transactionWithMetadata.isPresent()) { - final TraceOptions traceOptions = - requestContext - .getOptionalParameter(1, TransactionTraceParams.class) - .map(TransactionTraceParams::traceOptions) - .orElse(TraceOptions.DEFAULT); + final TraceOptions traceOptions; + try { + traceOptions = + requestContext + .getOptionalParameter(1, TransactionTraceParams.class) + .map(TransactionTraceParams::traceOptions) + .orElse(TraceOptions.DEFAULT); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid transaction trace parameter (index 1)", + RpcErrorType.INVALID_TRANSACTION_TRACE_PARAMS, + e); + } final DebugTraceTransactionResult debugTraceTransactionResult = debugTraceTransactionResult(hash, transactionWithMetadata.get(), traceOptions); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionByBlockHashAndIndex.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionByBlockHashAndIndex.java index 44fb91689d..9c7cf5e7a8 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionByBlockHashAndIndex.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionByBlockHashAndIndex.java @@ -17,9 +17,11 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.UnsignedIntParameter; 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.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.TransactionCompleteResult; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.TransactionResult; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; @@ -42,8 +44,24 @@ public class EthGetTransactionByBlockHashAndIndex implements JsonRpcMethod { @Override public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { - final Hash hash = requestContext.getRequiredParameter(0, Hash.class); - final int index = requestContext.getRequiredParameter(1, UnsignedIntParameter.class).getValue(); + final Hash hash; + try { + hash = requestContext.getRequiredParameter(0, Hash.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid transaction hash parameter (index 0)", + RpcErrorType.INVALID_TRANSACTION_HASH_PARAMS, + e); + } + final int index; + try { + index = requestContext.getRequiredParameter(1, UnsignedIntParameter.class).getValue(); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid transaction id parameter (index 1)", + RpcErrorType.INVALID_TRANSACTION_ID_PARAMS, + e); + } final Optional transactionWithMetadata = blockchain.transactionByBlockHashAndIndex(hash, index); final TransactionResult result = diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionByBlockNumberAndIndex.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionByBlockNumberAndIndex.java index 6a419d35c5..a5383f6680 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionByBlockNumberAndIndex.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionByBlockNumberAndIndex.java @@ -50,7 +50,15 @@ public class EthGetTransactionByBlockNumberAndIndex extends AbstractBlockParamet @Override protected Object resultByBlockNumber( final JsonRpcRequestContext request, final long blockNumber) { - final int index = request.getRequiredParameter(1, UnsignedIntParameter.class).getValue(); + final int index; + try { + index = request.getRequiredParameter(1, UnsignedIntParameter.class).getValue(); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid transaction index parameter (index 1)", + RpcErrorType.INVALID_TRANSACTION_INDEX_PARAMS, + e); + } final Optional transactionWithMetadata = getBlockchainQueries().transactionByBlockNumberAndIndex(blockNumber, index); return transactionWithMetadata.map(TransactionCompleteResult::new).orElse(null); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionByHash.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionByHash.java index 8221de1f3f..90e7a6a1ed 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionByHash.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionByHash.java @@ -17,6 +17,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; 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; @@ -50,7 +51,15 @@ public class EthGetTransactionByHash implements JsonRpcMethod { return new JsonRpcErrorResponse( requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAM_COUNT); } - final Hash hash = requestContext.getRequiredParameter(0, Hash.class); + final Hash hash; + try { + hash = requestContext.getRequiredParameter(0, Hash.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid transaction hash parameter (index 0)", + RpcErrorType.INVALID_TRANSACTION_HASH_PARAMS, + e); + } final JsonRpcSuccessResponse jsonRpcSuccessResponse = new JsonRpcSuccessResponse(requestContext.getRequest().getId(), getResult(hash)); return jsonRpcSuccessResponse; diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionReceipt.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionReceipt.java index 78c5f3b650..a437cd86dc 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionReceipt.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionReceipt.java @@ -17,8 +17,10 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; 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.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.TransactionReceiptResult; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.TransactionReceiptRootResult; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.TransactionReceiptStatusResult; @@ -46,7 +48,15 @@ public class EthGetTransactionReceipt implements JsonRpcMethod { @Override public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { - final Hash hash = requestContext.getRequiredParameter(0, Hash.class); + final Hash hash; + try { + hash = requestContext.getRequiredParameter(0, Hash.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid transaction hash parameter (index 0)", + RpcErrorType.INVALID_TRANSACTION_HASH_PARAMS, + e); + } final TransactionReceiptResult result = blockchainQueries .transactionReceiptByTransactionHash(hash, protocolSchedule) diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSendRawTransaction.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSendRawTransaction.java index 70b232faab..272014d3bc 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSendRawTransaction.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSendRawTransaction.java @@ -19,6 +19,7 @@ import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcErrorConverter; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcRequestException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; @@ -68,7 +69,13 @@ public class EthSendRawTransaction implements JsonRpcMethod { return new JsonRpcErrorResponse( requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAM_COUNT); } - final String rawTransaction = requestContext.getRequiredParameter(0, String.class); + final String rawTransaction; + try { + rawTransaction = requestContext.getRequiredParameter(0, String.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid transaction parameters (index 0)", RpcErrorType.INVALID_TRANSACTION_PARAMS, e); + } final Transaction transaction; try { diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceCall.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceCall.java index c50525cef8..9882257143 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceCall.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceCall.java @@ -18,9 +18,11 @@ import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErr import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.TraceTypeParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.TransactionTrace; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; import org.hyperledger.besu.ethereum.core.Block; import org.hyperledger.besu.ethereum.debug.TraceOptions; @@ -56,7 +58,12 @@ public class TraceCall extends AbstractTraceCall { private Set getTraceTypes( final JsonRpcRequestContext requestContext) { - return requestContext.getRequiredParameter(1, TraceTypeParameter.class).getTraceTypes(); + try { + return requestContext.getRequiredParameter(1, TraceTypeParameter.class).getTraceTypes(); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid trace type parameter (index 1)", RpcErrorType.INVALID_TRACE_TYPE_PARAMS, e); + } } @Override diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceCallMany.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceCallMany.java index 5b14019b07..2cbeb8ee7f 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceCallMany.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceCallMany.java @@ -98,7 +98,7 @@ public class TraceCallMany extends TraceCall implements JsonRpcMethod { } catch (final Exception e) { LOG.error("Error parsing trace_callMany parameters: {}", e.getLocalizedMessage()); return new JsonRpcErrorResponse( - requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + requestContext.getRequest().getId(), RpcErrorType.INVALID_TRACE_CALL_MANY_PARAMS); } final Optional maybeBlockHeader = diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceGet.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceGet.java index 2837e93e13..a1460c5aa2 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceGet.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceGet.java @@ -17,6 +17,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.BlockTracer; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; @@ -54,8 +55,24 @@ public class TraceGet extends AbstractTraceByHash implements JsonRpcMethod { requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAM_COUNT); } - final Hash transactionHash = requestContext.getRequiredParameter(0, Hash.class); - final List traceNumbersAsStrings = requestContext.getRequiredParameter(1, List.class); + final Hash transactionHash; + try { + transactionHash = requestContext.getRequiredParameter(0, Hash.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid transaction has parameter (index 0)", + RpcErrorType.INVALID_TRANSACTION_HASH_PARAMS, + e); + } + final List traceNumbersAsStrings; + try { + traceNumbersAsStrings = requestContext.getRequiredParameter(1, List.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid trace numbers parameters (index 1)", + RpcErrorType.INVALID_TRACE_NUMBERS_PARAMS, + e); + } final List traceAddress = traceNumbersAsStrings.stream() .map(t -> Integer.parseInt(((String) t).substring(2), 16)) diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceRawTransaction.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceRawTransaction.java index a69414900f..a720569875 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceRawTransaction.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceRawTransaction.java @@ -18,6 +18,7 @@ import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErr import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.TraceTypeParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.TransactionTrace; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; @@ -70,9 +71,20 @@ public class TraceRawTransaction extends AbstractTraceByBlock implements JsonRpc requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAM_COUNT); } - final var rawTransaction = requestContext.getRequiredParameter(0, String.class); - final TraceTypeParameter traceTypeParameter = - requestContext.getRequiredParameter(1, TraceTypeParameter.class); + final String rawTransaction; + try { + rawTransaction = requestContext.getRequiredParameter(0, String.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid transaction parameters (index 0)", RpcErrorType.INVALID_TRANSACTION_PARAMS, e); + } + final TraceTypeParameter traceTypeParameter; + try { + traceTypeParameter = requestContext.getRequiredParameter(1, TraceTypeParameter.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid trace type parameter (index 1)", RpcErrorType.INVALID_TRACE_TYPE_PARAMS, e); + } LOG.trace( "Received RPC rpcName={} rawTx={} traceType={}", getName(), @@ -85,7 +97,7 @@ public class TraceRawTransaction extends AbstractTraceByBlock implements JsonRpc LOG.trace("rawTx decoded to transaction {}", transaction); } catch (final RLPException | IllegalArgumentException e) { return new JsonRpcErrorResponse( - requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + requestContext.getRequest().getId(), RpcErrorType.INVALID_TRANSACTION_PARAMS); } final Set traceTypes = traceTypeParameter.getTraceTypes(); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceReplayBlockTransactions.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceReplayBlockTransactions.java index 50e580cd86..a8b3bbc46d 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceReplayBlockTransactions.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceReplayBlockTransactions.java @@ -83,8 +83,13 @@ public class TraceReplayBlockTransactions extends AbstractBlockParameterMethod { @Override protected ArrayNode resultByBlockNumber( final JsonRpcRequestContext request, final long blockNumber) { - final TraceTypeParameter traceTypeParameter = - request.getRequiredParameter(1, TraceTypeParameter.class); + final TraceTypeParameter traceTypeParameter; + try { + traceTypeParameter = request.getRequiredParameter(1, TraceTypeParameter.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid trace type parameter (index 1)", RpcErrorType.INVALID_TRACE_TYPE_PARAMS, e); + } LOG.trace( "Received RPC rpcName={} block={} traceType={}", diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceTransaction.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceTransaction.java index 55d1c0569d..b79b9620e8 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceTransaction.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceTransaction.java @@ -17,9 +17,11 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.BlockTracer; 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.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; @@ -45,7 +47,15 @@ public class TraceTransaction extends AbstractTraceByHash implements JsonRpcMeth @Override public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { - final Hash transactionHash = requestContext.getRequiredParameter(0, Hash.class); + final Hash transactionHash; + try { + transactionHash = requestContext.getRequiredParameter(0, Hash.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid transaction hash parameter (index 0)", + RpcErrorType.INVALID_TRANSACTION_HASH_PARAMS, + e); + } LOG.trace("Received RPC rpcName={} txHash={}", getName(), transactionHash); return new JsonRpcSuccessResponse( diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TxPoolBesuPendingTransactions.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TxPoolBesuPendingTransactions.java index 67e90d55b5..8dc38135c6 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TxPoolBesuPendingTransactions.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TxPoolBesuPendingTransactions.java @@ -54,8 +54,16 @@ public class TxPoolBesuPendingTransactions implements JsonRpcMethod { final Collection pendingTransactions = transactionPool.getPendingTransactions(); - final Integer limit = - requestContext.getOptionalParameter(0, Integer.class).orElse(pendingTransactions.size()); + final int limit; + try { + limit = + requestContext.getOptionalParameter(0, Integer.class).orElse(pendingTransactions.size()); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid transaction limit parameter (index 0)", + RpcErrorType.INVALID_TRANSACTION_LIMIT_PARAMS, + e); + } final List filters; try { filters = diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineForkchoiceUpdated.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineForkchoiceUpdated.java index df169560f5..7df76973ac 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineForkchoiceUpdated.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineForkchoiceUpdated.java @@ -186,7 +186,7 @@ public abstract class AbstractEngineForkchoiceUpdated extends ExecutionEngineJso if (!getWithdrawalsValidator( protocolSchedule.get(), newHead, maybePayloadAttributes.get().getTimestamp()) .validateWithdrawals(withdrawals)) { - return new JsonRpcErrorResponse(requestId, getInvalidParametersError()); + return new JsonRpcErrorResponse(requestId, RpcErrorType.INVALID_WITHDRAWALS_PARAMS); } } 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 369d7a387a..02ccf5d231 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 @@ -24,7 +24,6 @@ import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine. 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.WithdrawalsValidatorProvider.getWithdrawalsValidator; -import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType.INVALID_PARAMS; import org.hyperledger.besu.consensus.merge.blockcreation.MergeMiningCoordinator; import org.hyperledger.besu.datatypes.Address; @@ -42,7 +41,6 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.DepositRequ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.EnginePayloadParameter; 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; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; @@ -118,8 +116,15 @@ public abstract class AbstractEngineNewPayload extends ExecutionEngineJsonRpcMet e); } - final Optional> maybeVersionedHashParam = - requestContext.getOptionalList(1, String.class); + final Optional> maybeVersionedHashParam; + try { + maybeVersionedHashParam = requestContext.getOptionalList(1, String.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcRequestException( + "Invalid versioned hash parameters (index 1)", + RpcErrorType.INVALID_VERSIONED_HASH_PARAMS, + e); + } final Object reqId = requestContext.getRequest().getId(); @@ -174,8 +179,7 @@ public abstract class AbstractEngineNewPayload extends ExecutionEngineJsonRpcMet if (!getWithdrawalsValidator( protocolSchedule.get(), blockParam.getTimestamp(), blockParam.getBlockNumber()) .validateWithdrawals(maybeWithdrawals)) { - return new JsonRpcErrorResponse( - reqId, new JsonRpcError(INVALID_PARAMS, "Invalid withdrawals")); + return new JsonRpcErrorResponse(reqId, RpcErrorType.INVALID_WITHDRAWALS_PARAMS); } final Optional> maybeDepositRequests = @@ -197,8 +201,7 @@ public abstract class AbstractEngineNewPayload extends ExecutionEngineJsonRpcMet if (!getWithdrawalRequestValidator( protocolSchedule.get(), blockParam.getTimestamp(), blockParam.getBlockNumber()) .validateParameter(maybeWithdrawalRequests)) { - return new JsonRpcErrorResponse( - reqId, new JsonRpcError(INVALID_PARAMS, "Invalid withdrawal request")); + return new JsonRpcErrorResponse(reqId, RpcErrorType.INVALID_WITHDRAWALS_PARAMS); } final Optional> maybeConsolidationRequests = @@ -486,14 +489,15 @@ public abstract class AbstractEngineNewPayload extends ExecutionEngineJsonRpcMet if (maybeVersionedHashes.isEmpty() && !transactionVersionedHashes.isEmpty()) { return ValidationResult.invalid( - RpcErrorType.INVALID_PARAMS, "Payload must contain versioned hashes for transactions"); + RpcErrorType.INVALID_VERSIONED_HASH_PARAMS, + "Payload must contain versioned hashes for transactions"); } // Validate versionedHashesParam if (maybeVersionedHashes.isPresent() && !maybeVersionedHashes.get().equals(transactionVersionedHashes)) { return ValidationResult.invalid( - RpcErrorType.INVALID_PARAMS, + RpcErrorType.INVALID_VERSIONED_HASH_PARAMS, "Versioned hashes from blob transactions do not match expected values"); } 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 393687743e..7d13ecc02c 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 @@ -64,7 +64,7 @@ public class EngineNewPayloadV3 extends AbstractEngineNewPayload { RpcErrorType.INVALID_EXCESS_BLOB_GAS_PARAMS, "Missing excess blob gas field"); } else if (maybeVersionedHashParam == null || maybeVersionedHashParam.isEmpty()) { return ValidationResult.invalid( - RpcErrorType.INVALID_PARAMS, "Missing versioned hashes field"); + RpcErrorType.INVALID_VERSIONED_HASH_PARAMS, "Missing versioned hashes field"); } else if (maybeBeaconBlockRootParam.isEmpty()) { return ValidationResult.invalid( RpcErrorType.INVALID_PARENT_BEACON_BLOCK_ROOT_PARAMS, 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 2465cdd813..904ec08e5c 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 @@ -64,7 +64,7 @@ public class EngineNewPayloadV4 extends AbstractEngineNewPayload { RpcErrorType.INVALID_EXCESS_BLOB_GAS_PARAMS, "Missing excess blob gas field"); } else if (maybeVersionedHashParam == null || maybeVersionedHashParam.isEmpty()) { return ValidationResult.invalid( - RpcErrorType.INVALID_PARAMS, "Missing versioned hashes field"); + RpcErrorType.INVALID_VERSIONED_HASH_PARAMS, "Missing versioned hashes field"); } else if (maybeBeaconBlockRootParam.isEmpty()) { return ValidationResult.invalid( RpcErrorType.INVALID_PARENT_BEACON_BLOCK_ROOT_PARAMS, diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerChangeTargetGasLimit.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerChangeTargetGasLimit.java index 1c530c14cf..f1b949ad63 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerChangeTargetGasLimit.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerChangeTargetGasLimit.java @@ -16,6 +16,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.miner; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; @@ -43,11 +44,16 @@ public class MinerChangeTargetGasLimit implements JsonRpcMethod { return new JsonRpcSuccessResponse(requestContext.getRequest().getId()); } catch (final IllegalArgumentException invalidJsonRpcParameters) { return new JsonRpcErrorResponse( - requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAMS); + requestContext.getRequest().getId(), RpcErrorType.INVALID_TARGET_GAS_LIMIT_PARAMS); } catch (final UnsupportedOperationException unsupportedOperationException) { return new JsonRpcErrorResponse( requestContext.getRequest().getId(), RpcErrorType.TARGET_GAS_LIMIT_MODIFICATION_UNSUPPORTED); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid target gas limit parameter (index 0)", + RpcErrorType.INVALID_TARGET_GAS_LIMIT_PARAMS, + e); } } } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/TraceTypeParameter.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/TraceTypeParameter.java index 80ba8bf673..1b8e3a19d2 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/TraceTypeParameter.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/TraceTypeParameter.java @@ -17,6 +17,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters; import static java.util.Objects.isNull; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import java.util.List; import java.util.Objects; @@ -73,7 +74,9 @@ public class TraceTypeParameter { .collect(Collectors.joining(", ")); if (!unsupportedTypes.isEmpty()) { - throw new InvalidJsonRpcParameters("Invalid trace types supplied: " + unsupportedTypes); + throw new InvalidJsonRpcParameters( + "Invalid trace types supplied: " + unsupportedTypes, + RpcErrorType.INVALID_TRACE_TYPE_PARAMS); } } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/eea/AbstractEeaSendRawTransaction.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/eea/AbstractEeaSendRawTransaction.java index 7ca3e94399..12c496b639 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/eea/AbstractEeaSendRawTransaction.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/eea/AbstractEeaSendRawTransaction.java @@ -23,6 +23,7 @@ import org.hyperledger.besu.datatypes.TransactionType; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.PrivacyIdProvider; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; @@ -73,7 +74,13 @@ public abstract class AbstractEeaSendRawTransaction implements JsonRpcMethod { public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { final Object id = requestContext.getRequest().getId(); final Optional user = requestContext.getUser(); - final String rawPrivateTransaction = requestContext.getRequiredParameter(0, String.class); + final String rawPrivateTransaction; + try { + rawPrivateTransaction = requestContext.getRequiredParameter(0, String.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid transaction parameter (index 0)", RpcErrorType.INVALID_TRANSACTION_PARAMS, e); + } try { final PrivateTransaction privateTransaction = diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDistributeRawTransaction.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDistributeRawTransaction.java index 62a087dade..39003358ed 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDistributeRawTransaction.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDistributeRawTransaction.java @@ -23,6 +23,7 @@ import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErr import org.hyperledger.besu.enclave.types.PrivacyGroup; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.PrivacyIdProvider; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; @@ -70,7 +71,15 @@ public class PrivDistributeRawTransaction implements JsonRpcMethod { @Override public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { final Object id = requestContext.getRequest().getId(); - final String rawPrivateTransaction = requestContext.getRequiredParameter(0, String.class); + final String rawPrivateTransaction; + try { + rawPrivateTransaction = requestContext.getRequiredParameter(0, String.class); + } catch (Exception e) { + throw new InvalidJsonRpcParameters( + "Invalid private transaction parameter (index 0)", + RpcErrorType.INVALID_TRANSACTION_PARAMS, + e); + } try { final PrivateTransaction privateTransaction = diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetEeaTransactionCount.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetEeaTransactionCount.java index 7bdba8824a..31bfc52c80 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetEeaTransactionCount.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetEeaTransactionCount.java @@ -85,7 +85,7 @@ public class PrivGetEeaTransactionCount implements JsonRpcMethod { privateFor = requestContext.getRequiredParameter(2, String[].class); } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException throw new InvalidJsonRpcParameters( - "Invalid private for parameter (index 2)", RpcErrorType.INVALID_PRIVATE_FOR_PARAMS, e); + "Invalid private for parameters (index 2)", RpcErrorType.INVALID_PRIVATE_FOR_PARAMS, e); } final String privacyUserId = privacyIdProvider.getPrivacyUserId(requestContext.getUser()); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetPrivateTransaction.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetPrivateTransaction.java index d260647c84..0629b2d55d 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetPrivateTransaction.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetPrivateTransaction.java @@ -19,11 +19,13 @@ import org.hyperledger.besu.enclave.EnclaveClientException; import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcEnclaveErrorConverter; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.PrivacyIdProvider; 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.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.privacy.PrivateTransactionGroupResult; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.privacy.PrivateTransactionLegacyResult; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.privacy.PrivateTransactionResult; @@ -57,7 +59,15 @@ public class PrivGetPrivateTransaction implements JsonRpcMethod { public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { LOG.trace("Executing {}", RpcMethod.PRIV_GET_PRIVATE_TRANSACTION.getMethodName()); - final Hash hash = requestContext.getRequiredParameter(0, Hash.class); + final Hash hash; + try { + hash = requestContext.getRequiredParameter(0, Hash.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid transaction hash parameter (index 0)", + RpcErrorType.INVALID_TRANSACTION_HASH_PARAMS, + e); + } final String enclaveKey = privacyIdProvider.getPrivacyUserId(requestContext.getUser()); final Optional maybePrivateTx; diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetTransactionReceipt.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetTransactionReceipt.java index f9bc424104..a1844841f0 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetTransactionReceipt.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetTransactionReceipt.java @@ -20,6 +20,7 @@ import org.hyperledger.besu.enclave.EnclaveClientException; import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcEnclaveErrorConverter; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.PrivacyIdProvider; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; @@ -66,7 +67,15 @@ public class PrivGetTransactionReceipt implements JsonRpcMethod { @Override public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { LOG.trace("Executing {}", RpcMethod.PRIV_GET_TRANSACTION_RECEIPT.getMethodName()); - final Hash pmtTransactionHash = requestContext.getRequiredParameter(0, Hash.class); + final Hash pmtTransactionHash; + try { + pmtTransactionHash = requestContext.getRequiredParameter(0, Hash.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid transaction hash parameter (index 0)", + RpcErrorType.INVALID_TRANSACTION_HASH_PARAMS, + e); + } final String enclaveKey = privacyIdProvider.getPrivacyUserId(requestContext.getUser()); final ExecutedPrivateTransaction privateTransaction; diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/util/DomainObjectDecodeUtils.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/util/DomainObjectDecodeUtils.java index 7ea2de0c01..bf9d49d4e9 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/util/DomainObjectDecodeUtils.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/util/DomainObjectDecodeUtils.java @@ -15,6 +15,7 @@ package org.hyperledger.besu.ethereum.api.util; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcRequestException; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.core.Transaction; import org.hyperledger.besu.ethereum.core.encoding.EncodingContext; import org.hyperledger.besu.ethereum.core.encoding.TransactionDecoder; @@ -30,9 +31,11 @@ public class DomainObjectDecodeUtils { Bytes txnBytes = Bytes.fromHexString(rawTransaction); return TransactionDecoder.decodeOpaqueBytes(txnBytes, EncodingContext.POOLED_TRANSACTION); } catch (final IllegalArgumentException e) { - throw new InvalidJsonRpcRequestException("Invalid raw transaction hex", e); + throw new InvalidJsonRpcRequestException( + "Invalid raw transaction hex", RpcErrorType.INVALID_TRANSACTION_PARAMS, e); } catch (final RLPException r) { - throw new InvalidJsonRpcRequestException("Invalid RLP in raw transaction hex", r); + throw new InvalidJsonRpcRequestException( + "Invalid RLP in raw transaction hex", RpcErrorType.INVALID_TRANSACTION_PARAMS, r); } } } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugAccountAtTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugAccountAtTest.java index d7840241d5..7876693b4c 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugAccountAtTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugAccountAtTest.java @@ -113,7 +113,7 @@ class DebugAccountAtTest { Assertions.assertThat(response).isInstanceOf(JsonRpcErrorResponse.class); Assertions.assertThat(((JsonRpcErrorResponse) response).getErrorType()) - .isEqualByComparingTo(RpcErrorType.INVALID_PARAMS); + .isEqualByComparingTo(RpcErrorType.INVALID_TRANSACTION_PARAMS); } @Test @@ -129,7 +129,7 @@ class DebugAccountAtTest { Assertions.assertThat(response).isInstanceOf(JsonRpcErrorResponse.class); Assertions.assertThat(((JsonRpcErrorResponse) response).getErrorType()) - .isEqualByComparingTo(RpcErrorType.INVALID_PARAMS); + .isEqualByComparingTo(RpcErrorType.INVALID_TRANSACTION_PARAMS); } @Test @@ -145,7 +145,7 @@ class DebugAccountAtTest { Assertions.assertThat(response).isInstanceOf(JsonRpcErrorResponse.class); Assertions.assertThat(((JsonRpcErrorResponse) response).getErrorType()) - .isEqualByComparingTo(RpcErrorType.INVALID_PARAMS); + .isEqualByComparingTo(RpcErrorType.INVALID_TRANSACTION_PARAMS); } @Test diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineForkchoiceUpdatedTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineForkchoiceUpdatedTest.java index 5496224e25..cdca20cb00 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineForkchoiceUpdatedTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineForkchoiceUpdatedTest.java @@ -738,7 +738,7 @@ public abstract class AbstractEngineForkchoiceUpdatedTest { } protected RpcErrorType expectedInvalidPayloadError() { - return RpcErrorType.INVALID_PARAMS; + return RpcErrorType.INVALID_WITHDRAWALS_PARAMS; } protected JsonRpcResponse resp( diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineForkchoiceUpdatedV1Test.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineForkchoiceUpdatedV1Test.java index d38d399441..6993be3d7a 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineForkchoiceUpdatedV1Test.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineForkchoiceUpdatedV1Test.java @@ -46,6 +46,6 @@ public class EngineForkchoiceUpdatedV1Test extends AbstractEngineForkchoiceUpdat @Override protected RpcErrorType expectedInvalidPayloadError() { - return RpcErrorType.INVALID_PAYLOAD_ATTRIBUTES; + return RpcErrorType.INVALID_WITHDRAWALS_PARAMS; } } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineForkchoiceUpdatedV2Test.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineForkchoiceUpdatedV2Test.java index 7ae80313a1..c3558ef329 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineForkchoiceUpdatedV2Test.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineForkchoiceUpdatedV2Test.java @@ -92,6 +92,6 @@ public class EngineForkchoiceUpdatedV2Test extends AbstractEngineForkchoiceUpdat @Override protected RpcErrorType expectedInvalidPayloadError() { - return RpcErrorType.INVALID_PARAMS; + return RpcErrorType.INVALID_WITHDRAWALS_PARAMS; } } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerChangeTargetGasLimitTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerChangeTargetGasLimitTest.java index f31ac5e986..df9d9247c3 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerChangeTargetGasLimitTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerChangeTargetGasLimitTest.java @@ -50,7 +50,8 @@ public class MinerChangeTargetGasLimitTest { assertThat(minerChangeTargetGasLimit.response(request)) .isEqualTo( - new JsonRpcErrorResponse(request.getRequest().getId(), RpcErrorType.INVALID_PARAMS)); + new JsonRpcErrorResponse( + request.getRequest().getId(), RpcErrorType.INVALID_TARGET_GAS_LIMIT_PARAMS)); } @Test diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/eea/EeaSendRawTransactionTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/eea/EeaSendRawTransactionTest.java index 4d209b847b..b44100ba6c 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/eea/EeaSendRawTransactionTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/eea/EeaSendRawTransactionTest.java @@ -78,7 +78,7 @@ public class EeaSendRawTransactionTest extends BaseEeaSendRawTransaction { assertThatThrownBy(() -> method.response(request)) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage("Missing required json rpc parameter at index 0"); + .hasMessage("Invalid transaction parameter (index 0)"); } @Test @@ -88,7 +88,7 @@ public class EeaSendRawTransactionTest extends BaseEeaSendRawTransaction { assertThatThrownBy(() -> method.response(request)) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage("Missing required json rpc parameter at index 0"); + .hasMessage("Invalid transaction parameter (index 0)"); } @Test @@ -99,7 +99,7 @@ public class EeaSendRawTransactionTest extends BaseEeaSendRawTransaction { assertThatThrownBy(() -> method.response(request)) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage("Missing required json rpc parameter at index 0"); + .hasMessage("Invalid transaction parameter (index 0)"); } @Test diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByBlockHashAndIndex_intOverflow.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByBlockHashAndIndex_intOverflow.json index 7f804359ab..aac1138b58 100644 --- a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByBlockHashAndIndex_intOverflow.json +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByBlockHashAndIndex_intOverflow.json @@ -13,7 +13,7 @@ "id": 448, "error": { "code": -32602, - "message" : "Invalid params" + "message" : "Invalid transaction id params" } }, "statusCode": 200 diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByBlockHashAndIndex_missingParam_00.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByBlockHashAndIndex_missingParam_00.json index 97240170b0..b6c8becdb2 100644 --- a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByBlockHashAndIndex_missingParam_00.json +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByBlockHashAndIndex_missingParam_00.json @@ -12,7 +12,7 @@ "id": 448, "error": { "code": -32602, - "message" : "Invalid params" + "message" : "Invalid transaction hash params" } }, "statusCode": 200 diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByBlockHashAndIndex_missingParam_01.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByBlockHashAndIndex_missingParam_01.json index 6d12441ac7..5984be529b 100644 --- a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByBlockHashAndIndex_missingParam_01.json +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByBlockHashAndIndex_missingParam_01.json @@ -12,7 +12,7 @@ "id": 448, "error": { "code": -32602, - "message" : "Invalid params" + "message" : "Invalid transaction id params" } }, "statusCode": 200 diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByBlockHashAndIndex_missingParams.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByBlockHashAndIndex_missingParams.json index 64f1cdef76..f3c8fca4e5 100644 --- a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByBlockHashAndIndex_missingParams.json +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByBlockHashAndIndex_missingParams.json @@ -10,7 +10,7 @@ "id": 448, "error": { "code": -32602, - "message" : "Invalid params" + "message" : "Invalid transaction hash params" } }, "statusCode": 200 diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByBlockHashAndIndex_wrongParamType.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByBlockHashAndIndex_wrongParamType.json index 977ea64f15..f4e3dea775 100644 --- a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByBlockHashAndIndex_wrongParamType.json +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByBlockHashAndIndex_wrongParamType.json @@ -13,7 +13,7 @@ "id": 448, "error": { "code": -32602, - "message" : "Invalid params" + "message" : "Invalid transaction id params" } }, "statusCode": 200 diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByHash_typeMismatch.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByHash_typeMismatch.json index 2263de69d1..0abcb4da7e 100644 --- a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByHash_typeMismatch.json +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_getTransactionByHash_typeMismatch.json @@ -12,7 +12,7 @@ "id" : 406, "error" : { "code" : -32602, - "message" : "Invalid params" + "message" : "Invalid transaction hash params" } }, "statusCode": 200 diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/trace/specs/replay-trace-transaction/flat/trace_replayBlockTransactions_invalidTraceOptions.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/trace/specs/replay-trace-transaction/flat/trace_replayBlockTransactions_invalidTraceOptions.json index 47f13b7287..eb1bfbd30b 100644 --- a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/trace/specs/replay-trace-transaction/flat/trace_replayBlockTransactions_invalidTraceOptions.json +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/trace/specs/replay-trace-transaction/flat/trace_replayBlockTransactions_invalidTraceOptions.json @@ -13,7 +13,7 @@ "id": 415, "error": { "code": -32602, - "message": "Invalid params" + "message": "Invalid trace type params" } }, "statusCode": 200 diff --git a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestGetLogHash.java b/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestGetLogHash.java index a0790c9fcd..e4fd7bcff2 100644 --- a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestGetLogHash.java +++ b/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestGetLogHash.java @@ -16,9 +16,11 @@ package org.hyperledger.besu.ethereum.retesteth.methods; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; 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.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.query.TransactionReceiptWithMetadata; import org.hyperledger.besu.ethereum.retesteth.RetestethContext; import org.hyperledger.besu.ethereum.rlp.RLP; @@ -40,7 +42,15 @@ public class TestGetLogHash implements JsonRpcMethod { @Override public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { - final Hash txHash = requestContext.getRequiredParameter(0, Hash.class); + final Hash txHash; + try { + txHash = requestContext.getRequiredParameter(0, Hash.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid transaction hash parameter (index 0)", + RpcErrorType.INVALID_TRANSACTION_HASH_PARAMS, + e); + } final Optional receipt = context diff --git a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestModifyTimestamp.java b/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestModifyTimestamp.java index eeae7faa18..d9cfafbaea 100644 --- a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestModifyTimestamp.java +++ b/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestModifyTimestamp.java @@ -15,9 +15,11 @@ package org.hyperledger.besu.ethereum.retesteth.methods; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; 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.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.retesteth.RetestethContext; public class TestModifyTimestamp implements JsonRpcMethod { @@ -35,7 +37,13 @@ public class TestModifyTimestamp implements JsonRpcMethod { @Override public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { - final long epochSeconds = requestContext.getRequiredParameter(0, Long.class); + final long epochSeconds; + try { + epochSeconds = requestContext.getRequiredParameter(0, Long.class); + } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + throw new InvalidJsonRpcParameters( + "Invalid timestamp parameter (index 0)", RpcErrorType.INVALID_TIMESTAMP_PARAMS, e); + } context.getRetestethClock().resetTime(epochSeconds); return new JsonRpcSuccessResponse(requestContext.getRequest().getId(), true); } From 4acd7f120c6ddfe4ddef26cd734cd16c0e8ab390 Mon Sep 17 00:00:00 2001 From: Jason Frame Date: Mon, 19 Aug 2024 15:09:38 +1000 Subject: [PATCH 132/259] Change default for receipt compaction to be enabled (#7450) Signed-off-by: Jason Frame --- CHANGELOG.md | 1 + .../cli/options/stable/DataStorageOptions.java | 4 ++-- .../options/stable/DataStorageOptionsTest.java | 14 ++++++++++---- .../worldstate/DataStorageConfiguration.java | 2 +- .../RocksDBKeyValuePrivacyStorageFactory.java | 14 ++++++++------ .../rocksdb/RocksDBKeyValueStorageFactory.java | 18 +++++++++--------- .../BaseVersionedStorageFormat.java | 10 ++-------- .../configuration/DatabaseMetadata.java | 2 +- .../PrivacyVersionedStorageFormat.java | 12 +++--------- ...cksDBKeyValuePrivacyStorageFactoryTest.java | 13 ++++++------- .../RocksDBKeyValueStorageFactoryTest.java | 13 ++++++------- 11 files changed, 49 insertions(+), 54 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9173e46fd5..8945cdd1ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Upcoming Breaking Changes ### Breaking Changes +- Receipt compaction is enabled by default. It will no longer be possible to downgrade Besu to versions prior to 24.5.1. ### Additions and Improvements - Add 'inbound' field to admin_peers JSON-RPC Call [#7461](https://github.com/hyperledger/besu/pull/7461) 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 index 6f5c037c0d..3d53a595ec 100644 --- 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 @@ -95,8 +95,8 @@ public class DataStorageOptions implements CLIOptions @Option( names = "--receipt-compaction-enabled", - description = "Enables compact storing of receipts (default: ${DEFAULT-VALUE}).", - arity = "1") + description = "Enables compact storing of receipts (default: ${DEFAULT-VALUE})", + fallbackValue = "true") private Boolean receiptCompactionEnabled = DEFAULT_RECEIPT_COMPACTION_ENABLED; @CommandLine.ArgGroup(validate = false) 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 2086381825..29fa3d6607 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 @@ -126,13 +126,20 @@ public class DataStorageOptionsTest "false"); } + @Test + public void receiptCompactionCanBeEnabledWithImplicitTrueValue() { + internalTestSuccess( + dataStorageConfiguration -> + assertThat(dataStorageConfiguration.getReceiptCompactionEnabled()).isEqualTo(true), + "--receipt-compaction-enabled"); + } + @Test public void receiptCompactionCanBeEnabled() { internalTestSuccess( dataStorageConfiguration -> assertThat(dataStorageConfiguration.getReceiptCompactionEnabled()).isEqualTo(true), - "--receipt-compaction-enabled", - "true"); + "--receipt-compaction-enabled=true"); } @Test @@ -140,8 +147,7 @@ public class DataStorageOptionsTest internalTestSuccess( dataStorageConfiguration -> assertThat(dataStorageConfiguration.getReceiptCompactionEnabled()).isEqualTo(false), - "--receipt-compaction-enabled", - "false"); + "--receipt-compaction-enabled=false"); } @Override 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 8d767f442a..320e38733d 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 @@ -26,7 +26,7 @@ public interface DataStorageConfiguration { 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 = false; + boolean DEFAULT_RECEIPT_COMPACTION_ENABLED = true; DataStorageConfiguration DEFAULT_CONFIG = ImmutableDataStorageConfiguration.builder() diff --git a/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/RocksDBKeyValuePrivacyStorageFactory.java b/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/RocksDBKeyValuePrivacyStorageFactory.java index 909a2c5e90..6debcc046e 100644 --- a/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/RocksDBKeyValuePrivacyStorageFactory.java +++ b/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/RocksDBKeyValuePrivacyStorageFactory.java @@ -45,9 +45,7 @@ public class RocksDBKeyValuePrivacyStorageFactory implements PrivacyKeyValueStor LoggerFactory.getLogger(RocksDBKeyValuePrivacyStorageFactory.class); private static final Set SUPPORTED_VERSIONS = EnumSet.of( - PrivacyVersionedStorageFormat.FOREST_WITH_VARIABLES, PrivacyVersionedStorageFormat.FOREST_WITH_RECEIPT_COMPACTION, - PrivacyVersionedStorageFormat.BONSAI_WITH_VARIABLES, PrivacyVersionedStorageFormat.BONSAI_WITH_RECEIPT_COMPACTION); private static final String PRIVATE_DATABASE_PATH = "private"; private final RocksDBKeyValueStorageFactory publicFactory; @@ -230,8 +228,12 @@ public class RocksDBKeyValuePrivacyStorageFactory implements PrivacyKeyValueStor // reflect the change to the runtime version, and return it. // Besu supports both formats of receipts so no upgrade is needed other than updating metadata - if (runtimeVersion == PrivacyVersionedStorageFormat.BONSAI_WITH_RECEIPT_COMPACTION - || runtimeVersion == PrivacyVersionedStorageFormat.FOREST_WITH_RECEIPT_COMPACTION) { + final VersionedStorageFormat existingVersionedStorageFormat = + existingPrivacyMetadata.getVersionedStorageFormat(); + if ((existingVersionedStorageFormat == PrivacyVersionedStorageFormat.BONSAI_WITH_VARIABLES + && runtimeVersion == PrivacyVersionedStorageFormat.BONSAI_WITH_RECEIPT_COMPACTION) + || (existingVersionedStorageFormat == PrivacyVersionedStorageFormat.FOREST_WITH_VARIABLES + && runtimeVersion == PrivacyVersionedStorageFormat.FOREST_WITH_RECEIPT_COMPACTION)) { final DatabaseMetadata metadata = new DatabaseMetadata(runtimeVersion); try { metadata.writeToDirectory(dataDir); @@ -247,8 +249,8 @@ public class RocksDBKeyValuePrivacyStorageFactory implements PrivacyKeyValueStor "Database unsafe upgrade detect: DB at %s is %s with version %s but version %s is expected. " + "Please check your config and review release notes for supported upgrade procedures.", dataDir, - existingPrivacyMetadata.getVersionedStorageFormat().getFormat().name(), - existingPrivacyMetadata.getVersionedStorageFormat().getVersion(), + existingVersionedStorageFormat.getFormat().name(), + existingVersionedStorageFormat.getVersion(), runtimeVersion.getVersion()); throw new StorageException(error); diff --git a/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/RocksDBKeyValueStorageFactory.java b/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/RocksDBKeyValueStorageFactory.java index 8e1a4fa521..d53c9e57fd 100644 --- a/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/RocksDBKeyValueStorageFactory.java +++ b/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/RocksDBKeyValueStorageFactory.java @@ -57,11 +57,7 @@ public class RocksDBKeyValueStorageFactory implements KeyValueStorageFactory { private static final Logger LOG = LoggerFactory.getLogger(RocksDBKeyValueStorageFactory.class); private static final EnumSet SUPPORTED_VERSIONED_FORMATS = - EnumSet.of( - FOREST_WITH_VARIABLES, - FOREST_WITH_RECEIPT_COMPACTION, - BONSAI_WITH_VARIABLES, - BONSAI_WITH_RECEIPT_COMPACTION); + EnumSet.of(FOREST_WITH_RECEIPT_COMPACTION, BONSAI_WITH_RECEIPT_COMPACTION); private static final String NAME = "rocksdb"; private final RocksDBMetricsFactory rocksDBMetricsFactory; private DatabaseMetadata databaseMetadata; @@ -329,8 +325,12 @@ public class RocksDBKeyValueStorageFactory implements KeyValueStorageFactory { // reflect the change to the runtime version, and return it. // Besu supports both formats of receipts so no upgrade is needed other than updating metadata - if (runtimeVersion == BONSAI_WITH_RECEIPT_COMPACTION - || runtimeVersion == FOREST_WITH_RECEIPT_COMPACTION) { + final VersionedStorageFormat existingVersionedStorageFormat = + existingMetadata.getVersionedStorageFormat(); + if ((existingVersionedStorageFormat == BONSAI_WITH_VARIABLES + && runtimeVersion == BONSAI_WITH_RECEIPT_COMPACTION) + || (existingVersionedStorageFormat == FOREST_WITH_VARIABLES + && runtimeVersion == FOREST_WITH_RECEIPT_COMPACTION)) { final DatabaseMetadata metadata = new DatabaseMetadata(runtimeVersion); try { metadata.writeToDirectory(dataDir); @@ -346,8 +346,8 @@ public class RocksDBKeyValueStorageFactory implements KeyValueStorageFactory { "Database unsafe downgrade detect: DB at %s is %s with version %s but version %s is expected. " + "Please check your config and review release notes for supported downgrade procedures.", dataDir, - existingMetadata.getVersionedStorageFormat().getFormat().name(), - existingMetadata.getVersionedStorageFormat().getVersion(), + existingVersionedStorageFormat.getFormat().name(), + existingVersionedStorageFormat.getVersion(), runtimeVersion.getVersion()); throw new StorageException(error); diff --git a/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/configuration/BaseVersionedStorageFormat.java b/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/configuration/BaseVersionedStorageFormat.java index 658bb24a0f..ad3557636d 100644 --- a/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/configuration/BaseVersionedStorageFormat.java +++ b/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/configuration/BaseVersionedStorageFormat.java @@ -63,14 +63,8 @@ public enum BaseVersionedStorageFormat implements VersionedStorageFormat { public static BaseVersionedStorageFormat defaultForNewDB( final DataStorageConfiguration configuration) { return switch (configuration.getDatabaseFormat()) { - case FOREST -> - configuration.getReceiptCompactionEnabled() - ? FOREST_WITH_RECEIPT_COMPACTION - : FOREST_WITH_VARIABLES; - case BONSAI -> - configuration.getReceiptCompactionEnabled() - ? BONSAI_WITH_RECEIPT_COMPACTION - : BONSAI_WITH_VARIABLES; + case FOREST -> FOREST_WITH_RECEIPT_COMPACTION; + case BONSAI -> BONSAI_WITH_RECEIPT_COMPACTION; }; } diff --git a/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/configuration/DatabaseMetadata.java b/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/configuration/DatabaseMetadata.java index 46dbb9e740..a72db7c322 100644 --- a/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/configuration/DatabaseMetadata.java +++ b/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/configuration/DatabaseMetadata.java @@ -74,7 +74,7 @@ public class DatabaseMetadata { * @return the metadata to use for new db */ public static DatabaseMetadata defaultForNewPrivateDb() { - return new DatabaseMetadata(PrivacyVersionedStorageFormat.FOREST_WITH_VARIABLES); + return new DatabaseMetadata(PrivacyVersionedStorageFormat.FOREST_WITH_RECEIPT_COMPACTION); } /** diff --git a/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/configuration/PrivacyVersionedStorageFormat.java b/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/configuration/PrivacyVersionedStorageFormat.java index 87ff357e16..ca5988dc75 100644 --- a/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/configuration/PrivacyVersionedStorageFormat.java +++ b/plugins/rocksdb/src/main/java/org/hyperledger/besu/plugin/services/storage/rocksdb/configuration/PrivacyVersionedStorageFormat.java @@ -32,7 +32,7 @@ public enum PrivacyVersionedStorageFormat implements VersionedStorageFormat { * Current Forest version, with receipts using compaction, in order to make Receipts use less disk * space */ - FOREST_WITH_RECEIPT_COMPACTION(BaseVersionedStorageFormat.FOREST_WITH_VARIABLES, 2), + FOREST_WITH_RECEIPT_COMPACTION(BaseVersionedStorageFormat.FOREST_WITH_RECEIPT_COMPACTION, 2), /** Original Bonsai version, not used since replace by BONSAI_WITH_VARIABLES */ BONSAI_ORIGINAL(BaseVersionedStorageFormat.BONSAI_ORIGINAL, 1), /** @@ -64,14 +64,8 @@ public enum PrivacyVersionedStorageFormat implements VersionedStorageFormat { public static VersionedStorageFormat defaultForNewDB( final DataStorageConfiguration configuration) { return switch (configuration.getDatabaseFormat()) { - case FOREST -> - configuration.getReceiptCompactionEnabled() - ? FOREST_WITH_RECEIPT_COMPACTION - : FOREST_WITH_VARIABLES; - case BONSAI -> - configuration.getReceiptCompactionEnabled() - ? BONSAI_WITH_RECEIPT_COMPACTION - : BONSAI_WITH_VARIABLES; + case FOREST -> FOREST_WITH_RECEIPT_COMPACTION; + case BONSAI -> BONSAI_WITH_RECEIPT_COMPACTION; }; } diff --git a/plugins/rocksdb/src/test/java/org/hyperledger/besu/plugin/services/storage/rocksdb/RocksDBKeyValuePrivacyStorageFactoryTest.java b/plugins/rocksdb/src/test/java/org/hyperledger/besu/plugin/services/storage/rocksdb/RocksDBKeyValuePrivacyStorageFactoryTest.java index 5dd485cb7a..17a3fb874a 100644 --- a/plugins/rocksdb/src/test/java/org/hyperledger/besu/plugin/services/storage/rocksdb/RocksDBKeyValuePrivacyStorageFactoryTest.java +++ b/plugins/rocksdb/src/test/java/org/hyperledger/besu/plugin/services/storage/rocksdb/RocksDBKeyValuePrivacyStorageFactoryTest.java @@ -77,7 +77,7 @@ public class RocksDBKeyValuePrivacyStorageFactoryTest { try (final var storage = storageFactory.create(segment, commonConfiguration, metricsSystem)) { assertThat(DatabaseMetadata.lookUpFrom(tempDataDir).getVersionedStorageFormat()) - .isEqualTo(PrivacyVersionedStorageFormat.FOREST_WITH_VARIABLES); + .isEqualTo(PrivacyVersionedStorageFormat.FOREST_WITH_RECEIPT_COMPACTION); } } @@ -97,7 +97,7 @@ public class RocksDBKeyValuePrivacyStorageFactoryTest { // Side effect is creation of the Metadata version file try (final var storage = storageFactory.create(segment, commonConfiguration, metricsSystem)) { assertThat(DatabaseMetadata.lookUpFrom(tempDataDir).getVersionedStorageFormat()) - .isEqualTo(PrivacyVersionedStorageFormat.FOREST_WITH_VARIABLES); + .isEqualTo(PrivacyVersionedStorageFormat.FOREST_WITH_RECEIPT_COMPACTION); } } @@ -116,8 +116,8 @@ public class RocksDBKeyValuePrivacyStorageFactoryTest { try (final var storage = storageFactory.create(segment, commonConfiguration, metricsSystem)) { final BaseVersionedStorageFormat expectedBaseVersion = dataStorageFormat == BONSAI - ? BaseVersionedStorageFormat.BONSAI_WITH_VARIABLES - : BaseVersionedStorageFormat.FOREST_WITH_VARIABLES; + ? BaseVersionedStorageFormat.BONSAI_WITH_RECEIPT_COMPACTION + : BaseVersionedStorageFormat.FOREST_WITH_RECEIPT_COMPACTION; assertThat(DatabaseMetadata.lookUpFrom(tempDataDir).getVersionedStorageFormat()) .isEqualTo(expectedBaseVersion); } @@ -130,8 +130,8 @@ public class RocksDBKeyValuePrivacyStorageFactoryTest { privacyStorageFactory.create(segment, commonConfiguration, metricsSystem)) { final PrivacyVersionedStorageFormat expectedPrivacyVersion = dataStorageFormat == BONSAI - ? PrivacyVersionedStorageFormat.BONSAI_WITH_VARIABLES - : PrivacyVersionedStorageFormat.FOREST_WITH_VARIABLES; + ? PrivacyVersionedStorageFormat.BONSAI_WITH_RECEIPT_COMPACTION + : PrivacyVersionedStorageFormat.FOREST_WITH_RECEIPT_COMPACTION; assertThat(DatabaseMetadata.lookUpFrom(tempDataDir).getVersionedStorageFormat()) .isEqualTo(expectedPrivacyVersion); } @@ -145,7 +145,6 @@ public class RocksDBKeyValuePrivacyStorageFactoryTest { final Path tempDataDir = temporaryFolder.resolve("data"); final Path tempDatabaseDir = temporaryFolder.resolve("db"); mockCommonConfiguration(tempDataDir, tempDatabaseDir, dataStorageFormat); - when(dataStorageConfiguration.getReceiptCompactionEnabled()).thenReturn(true); final RocksDBKeyValueStorageFactory storageFactory = new RocksDBKeyValueStorageFactory( diff --git a/plugins/rocksdb/src/test/java/org/hyperledger/besu/plugin/services/storage/rocksdb/RocksDBKeyValueStorageFactoryTest.java b/plugins/rocksdb/src/test/java/org/hyperledger/besu/plugin/services/storage/rocksdb/RocksDBKeyValueStorageFactoryTest.java index a86c5ba807..7148f601cb 100644 --- a/plugins/rocksdb/src/test/java/org/hyperledger/besu/plugin/services/storage/rocksdb/RocksDBKeyValueStorageFactoryTest.java +++ b/plugins/rocksdb/src/test/java/org/hyperledger/besu/plugin/services/storage/rocksdb/RocksDBKeyValueStorageFactoryTest.java @@ -76,8 +76,8 @@ public class RocksDBKeyValueStorageFactoryTest { // Side effect is creation of the Metadata version file final BaseVersionedStorageFormat expectedVersion = dataStorageFormat == BONSAI - ? BaseVersionedStorageFormat.BONSAI_WITH_VARIABLES - : BaseVersionedStorageFormat.FOREST_WITH_VARIABLES; + ? BaseVersionedStorageFormat.BONSAI_WITH_RECEIPT_COMPACTION + : BaseVersionedStorageFormat.FOREST_WITH_RECEIPT_COMPACTION; assertThat(DatabaseMetadata.lookUpFrom(tempDataDir).getVersionedStorageFormat()) .isEqualTo(expectedVersion); } @@ -90,7 +90,6 @@ public class RocksDBKeyValueStorageFactoryTest { final Path tempDataDir = temporaryFolder.resolve("data"); final Path tempDatabaseDir = temporaryFolder.resolve("db"); mockCommonConfiguration(tempDataDir, tempDatabaseDir, dataStorageFormat); - when(dataStorageConfiguration.getReceiptCompactionEnabled()).thenReturn(true); final RocksDBKeyValueStorageFactory storageFactory = new RocksDBKeyValueStorageFactory( @@ -129,7 +128,7 @@ public class RocksDBKeyValueStorageFactoryTest { } @Test - public void shouldDetectCorrectMetadataV1() throws Exception { + public void shouldDetectCorrectMetadataV1AndUpgrade() throws Exception { final Path tempDataDir = temporaryFolder.resolve("data"); final Path tempDatabaseDir = temporaryFolder.resolve("db"); Files.createDirectories(tempDataDir); @@ -143,7 +142,7 @@ public class RocksDBKeyValueStorageFactoryTest { try (final var storage = storageFactory.create(segment, commonConfiguration, metricsSystem)) { assertThat(DatabaseMetadata.lookUpFrom(tempDataDir).getVersionedStorageFormat()) - .isEqualTo(BaseVersionedStorageFormat.BONSAI_WITH_VARIABLES); + .isEqualTo(BaseVersionedStorageFormat.BONSAI_WITH_RECEIPT_COMPACTION); assertThat(storageFactory.isSegmentIsolationSupported()).isTrue(); } } @@ -240,7 +239,7 @@ public class RocksDBKeyValueStorageFactoryTest { () -> rocksDbConfiguration, segments, RocksDBMetricsFactory.PUBLIC_ROCKS_DB_METRICS); try (final var storage = storageFactory.create(segment, commonConfiguration, metricsSystem)) { assertThat(DatabaseMetadata.lookUpFrom(tempDataDir).getVersionedStorageFormat()) - .isEqualTo(BaseVersionedStorageFormat.FOREST_WITH_VARIABLES); + .isEqualTo(BaseVersionedStorageFormat.FOREST_WITH_RECEIPT_COMPACTION); assertThatCode(storageFactory::isSegmentIsolationSupported).doesNotThrowAnyException(); } } @@ -299,7 +298,7 @@ public class RocksDBKeyValueStorageFactoryTest { // created correctly try (final var storage = storageFactory.create(segment, commonConfiguration, metricsSystem)) { assertThat(DatabaseMetadata.lookUpFrom(tempRealDataDir).getVersionedStorageFormat()) - .isEqualTo(BaseVersionedStorageFormat.FOREST_WITH_VARIABLES); + .isEqualTo(BaseVersionedStorageFormat.FOREST_WITH_RECEIPT_COMPACTION); } } From f9048cf3e2f772ba70802f19f37320cdff85bc49 Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Mon, 19 Aug 2024 15:50:57 +1000 Subject: [PATCH 133/259] 5098 branch 23 rename is complete transaction (#7479) * 5098: Add RpcErrorTypes Signed-off-by: Matilda Clerke --------- Signed-off-by: Matilda Clerke Signed-off-by: Matilda-Clerke Co-authored-by: Sally MacFarlane --- .../fork/frontier/EthGetBlockByNumberIntegrationTest.java | 2 +- .../api/jsonrpc/execution/TracedJsonRpcProcessor.java | 2 +- .../api/jsonrpc/internal/methods/DebugTraceBlockByHash.java | 2 +- .../ethereum/api/jsonrpc/internal/methods/DebugTraceCall.java | 2 +- .../api/jsonrpc/internal/methods/EthGetBlockByHash.java | 4 ++-- .../api/jsonrpc/internal/methods/EthGetBlockByNumber.java | 4 ++-- .../besu/ethereum/api/jsonrpc/internal/methods/TraceGet.java | 2 +- .../ethereum/api/jsonrpc/internal/response/RpcErrorType.java | 4 ++-- .../besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTest.java | 4 ++-- .../api/jsonrpc/internal/methods/EthGetBlockByHashTest.java | 4 ++-- .../api/jsonrpc/internal/methods/EthGetBlockByNumberTest.java | 4 ++-- 11 files changed, 17 insertions(+), 17 deletions(-) diff --git a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/frontier/EthGetBlockByNumberIntegrationTest.java b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/frontier/EthGetBlockByNumberIntegrationTest.java index 966cda1200..3798cbe507 100644 --- a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/frontier/EthGetBlockByNumberIntegrationTest.java +++ b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/frontier/EthGetBlockByNumberIntegrationTest.java @@ -437,7 +437,7 @@ public class EthGetBlockByNumberIntegrationTest { assertThat(thrown) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage("Invalid is transaction complete parameter (index 1)"); + .hasMessage("Invalid return complete transaction parameter (index 1)"); } /** 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 f1a799cf63..ec0e6aef64 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 @@ -84,7 +84,7 @@ public class TracedJsonRpcProcessor implements JsonRpcProcessor { case INVALID_GAS_PRICE_PARAMS: case INVALID_HASH_RATE_PARAMS: case INVALID_ID_PARAMS: - case INVALID_IS_TRANSACTION_COMPLETE_PARAMS: + case INVALID_RETURN_COMPLETE_TRANSACTION_PARAMS: case INVALID_LOG_FILTER_PARAMS: case INVALID_LOG_LEVEL_PARAMS: case INVALID_MAX_RESULTS_PARAMS: diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockByHash.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockByHash.java index da795439cf..4c1d3bfc2a 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockByHash.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockByHash.java @@ -68,7 +68,7 @@ public class DebugTraceBlockByHash implements JsonRpcMethod { .orElse(TraceOptions.DEFAULT); } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException throw new InvalidJsonRpcParameters( - "Invalid transaction trace parameters (index 1)", + "Invalid transaction trace parameter (index 1)", RpcErrorType.INVALID_TRANSACTION_TRACE_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceCall.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceCall.java index ad46d981ac..d309f8dfdd 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceCall.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceCall.java @@ -62,7 +62,7 @@ public class DebugTraceCall extends AbstractTraceCall { .orElse(TraceOptions.DEFAULT); } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException throw new InvalidJsonRpcParameters( - "Invalid transaction trace parameters (index 2)", + "Invalid transaction trace parameter (index 2)", RpcErrorType.INVALID_TRANSACTION_TRACE_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByHash.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByHash.java index 09b1c2f952..875daea7f1 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByHash.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByHash.java @@ -97,8 +97,8 @@ public class EthGetBlockByHash implements JsonRpcMethod { return requestContext.getRequiredParameter(1, Boolean.class); } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException throw new InvalidJsonRpcParameters( - "Invalid is complete transaction parameter (index 1)", - RpcErrorType.INVALID_IS_TRANSACTION_COMPLETE_PARAMS, + "Invalid return complete transaction parameter (index 1)", + RpcErrorType.INVALID_RETURN_COMPLETE_TRANSACTION_PARAMS, e); } } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByNumber.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByNumber.java index 5e0bc9c7ab..8e0954144d 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByNumber.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByNumber.java @@ -128,8 +128,8 @@ public class EthGetBlockByNumber extends AbstractBlockParameterMethod { return request.getRequiredParameter(1, Boolean.class); } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException throw new InvalidJsonRpcParameters( - "Invalid is transaction complete parameter (index 1)", - RpcErrorType.INVALID_IS_TRANSACTION_COMPLETE_PARAMS, + "Invalid return complete transaction parameter (index 1)", + RpcErrorType.INVALID_RETURN_COMPLETE_TRANSACTION_PARAMS, e); } } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceGet.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceGet.java index a1460c5aa2..b346637ec2 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceGet.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceGet.java @@ -60,7 +60,7 @@ public class TraceGet extends AbstractTraceByHash implements JsonRpcMethod { transactionHash = requestContext.getRequiredParameter(0, Hash.class); } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException throw new InvalidJsonRpcParameters( - "Invalid transaction has parameter (index 0)", + "Invalid transaction hash parameter (index 0)", RpcErrorType.INVALID_TRANSACTION_HASH_PARAMS, e); } 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 cb19d2e7a3..009fca38fc 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 @@ -66,8 +66,8 @@ public enum RpcErrorType implements RpcMethodError { INVALID_GAS_PRICE_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid gas price params"), INVALID_HASH_RATE_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid hash rate params"), INVALID_ID_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid ID params"), - INVALID_IS_TRANSACTION_COMPLETE_PARAMS( - INVALID_PARAMS_ERROR_CODE, "Invalid is transaction complete params"), + INVALID_RETURN_COMPLETE_TRANSACTION_PARAMS( + INVALID_PARAMS_ERROR_CODE, "Invalid return complete transaction params"), INVALID_LOG_FILTER_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid log filter params"), INVALID_LOG_LEVEL_PARAMS( INVALID_PARAMS_ERROR_CODE, "Invalid log level params (missing or incorrect)"), diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTest.java index dcfd198d6e..bb5cb68a2a 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTest.java @@ -784,7 +784,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { assertThat(resp.code()).isEqualTo(200); // Check general format of result final JsonObject json = new JsonObject(resp.body().string()); - final RpcErrorType expectedError = RpcErrorType.INVALID_IS_TRANSACTION_COMPLETE_PARAMS; + final RpcErrorType expectedError = RpcErrorType.INVALID_RETURN_COMPLETE_TRANSACTION_PARAMS; testHelper.assertValidJsonRpcError( json, id, expectedError.getCode(), expectedError.getMessage()); } @@ -854,7 +854,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { assertThat(resp.code()).isEqualTo(200); // Check general format of result final JsonObject json = new JsonObject(resp.body().string()); - final RpcErrorType expectedError = RpcErrorType.INVALID_IS_TRANSACTION_COMPLETE_PARAMS; + final RpcErrorType expectedError = RpcErrorType.INVALID_RETURN_COMPLETE_TRANSACTION_PARAMS; testHelper.assertValidJsonRpcError( json, id, expectedError.getCode(), expectedError.getMessage()); } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByHashTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByHashTest.java index 0fc8969c93..e79fff04f7 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByHashTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByHashTest.java @@ -69,7 +69,7 @@ public class EthGetBlockByHashTest { public void exceptionWhenNoBoolSupplied() { assertThatThrownBy(() -> method.response(requestWithParams(ZERO_HASH))) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage("Invalid is complete transaction parameter (index 1)"); + .hasMessage("Invalid return complete transaction parameter (index 1)"); verifyNoMoreInteractions(blockchainQueries); } @@ -85,7 +85,7 @@ public class EthGetBlockByHashTest { public void exceptionWhenBoolParamInvalid() { assertThatThrownBy(() -> method.response(requestWithParams(ZERO_HASH, "maybe"))) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage("Invalid is complete transaction parameter (index 1)"); + .hasMessage("Invalid return complete transaction parameter (index 1)"); verifyNoMoreInteractions(blockchainQueries); } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByNumberTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByNumberTest.java index bc6ec997f3..254d0fbe9e 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByNumberTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByNumberTest.java @@ -121,7 +121,7 @@ public class EthGetBlockByNumberTest { public void exceptionWhenNoBoolSupplied() { assertThatThrownBy(() -> method.response(requestWithParams("0"))) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage("Invalid is transaction complete parameter (index 1)"); + .hasMessage("Invalid return complete transaction parameter (index 1)"); verifyNoMoreInteractions(blockchainQueries); } @@ -137,7 +137,7 @@ public class EthGetBlockByNumberTest { public void exceptionWhenBoolParamInvalid() { assertThatThrownBy(() -> method.response(requestWithParams("0", "maybe"))) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage("Invalid is transaction complete parameter (index 1)"); + .hasMessage("Invalid return complete transaction parameter (index 1)"); verifyNoMoreInteractions(blockchainQueries); } From 0dffe63c139b54943bd3fa4f8583327caaff1f0b Mon Sep 17 00:00:00 2001 From: Fabio Di Fabio Date: Mon, 19 Aug 2024 15:20:47 +0200 Subject: [PATCH 134/259] Fix BlockchainQueries::gasPrice when chain head block body still not fully persisted (#7482) * Fix BlockchainQueries::gasPrice when chain head block body still not fully persisted Signed-off-by: Fabio Di Fabio --- CHANGELOG.md | 1 + .../ethereum/api/query/BlockchainQueries.java | 33 ++++++++++------- .../internal/methods/EthGasPriceTest.java | 35 ++++++++++--------- .../besu/ethereum/chain/Blockchain.java | 9 +++++ .../ethereum/chain/DefaultBlockchain.java | 10 +++++- .../besu/evmtool/t8n/T8nBlockchain.java | 5 +++ .../ReferenceTestBlockchain.java | 5 +++ 7 files changed, 68 insertions(+), 30 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8945cdd1ee..1ad5678b08 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ ### Bug fixes - Fix tracing in precompiled contracts when halting for out of gas [#7318](https://github.com/hyperledger/besu/issues/7318) - Correctly release txpool save and restore lock in case of exceptions [#7473](https://github.com/hyperledger/besu/pull/7473) +- Fix for `eth_gasPrice` could not retrieve block error [#7482](https://github.com/hyperledger/besu/pull/7482) ## 24.8.0 diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/query/BlockchainQueries.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/query/BlockchainQueries.java index 16b683ed71..6e0f0e3e35 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/query/BlockchainQueries.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/query/BlockchainQueries.java @@ -60,6 +60,7 @@ import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.IntStream; import java.util.stream.LongStream; +import java.util.stream.Stream; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.units.bigints.UInt256; @@ -976,27 +977,35 @@ public class BlockchainQueries { } public Wei gasPrice() { - final long blockHeight = headBlockNumber(); - final var chainHeadHeader = blockchain.getChainHeadHeader(); + final Block chainHeadBlock = blockchain.getChainHeadBlock(); + final var chainHeadHeader = chainHeadBlock.getHeader(); + final long blockHeight = chainHeadHeader.getNumber(); + final var nextBlockProtocolSpec = protocolSchedule.getForNextBlockHeader(chainHeadHeader, System.currentTimeMillis()); final var nextBlockFeeMarket = nextBlockProtocolSpec.getFeeMarket(); + final Wei[] gasCollection = - LongStream.rangeClosed( - Math.max(0, blockHeight - apiConfig.getGasPriceBlocks() + 1), blockHeight) - .mapToObj( - l -> - blockchain - .getBlockByNumber(l) - .map(Block::getBody) - .map(BlockBody::getTransactions) - .orElseThrow( - () -> new IllegalStateException("Could not retrieve block #" + l))) + Stream.concat( + LongStream.range( + Math.max(0, blockHeight - apiConfig.getGasPriceBlocks() + 1), blockHeight) + .mapToObj( + l -> + blockchain + .getBlockByNumber(l) + .orElseThrow( + () -> + new IllegalStateException( + "Could not retrieve block #" + l))), + Stream.of(chainHeadBlock)) + .map(Block::getBody) + .map(BlockBody::getTransactions) .flatMap(Collection::stream) .filter(t -> t.getGasPrice().isPresent()) .map(t -> t.getGasPrice().get()) .sorted() .toArray(Wei[]::new); + return (gasCollection == null || gasCollection.length == 0) ? gasPriceLowerBound(chainHeadHeader, nextBlockFeeMarket) : UInt256s.max( diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGasPriceTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGasPriceTest.java index 54e17cb21c..5d6aba7694 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGasPriceTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGasPriceTest.java @@ -17,7 +17,9 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; @@ -61,7 +63,6 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; import org.mockito.Mock; -import org.mockito.internal.verification.VerificationModeFactory; import org.mockito.junit.jupiter.MockitoExtension; @ExtendWith(MockitoExtension.class) @@ -106,8 +107,8 @@ public class EthGasPriceTest { final JsonRpcResponse actualResponse = method.response(request); assertThat(actualResponse).usingRecursiveComparison().isEqualTo(expectedResponse); - verify(blockchain).getChainHeadBlockNumber(); - verify(blockchain, VerificationModeFactory.times(100)).getBlockByNumber(anyLong()); + verify(blockchain).getChainHeadBlock(); + verify(blockchain, times(99)).getBlockByNumber(anyLong()); verifyNoMoreInteractions(blockchain); } @@ -127,8 +128,7 @@ public class EthGasPriceTest { final JsonRpcResponse actualResponse = method.response(request); assertThat(actualResponse).usingRecursiveComparison().isEqualTo(expectedResponse); - verify(blockchain).getChainHeadBlockNumber(); - verify(blockchain, VerificationModeFactory.times(1)).getBlockByNumber(anyLong()); + verify(blockchain).getChainHeadBlock(); verifyNoMoreInteractions(blockchain); } @@ -146,8 +146,8 @@ public class EthGasPriceTest { final JsonRpcResponse actualResponse = method.response(request); assertThat(actualResponse).usingRecursiveComparison().isEqualTo(expectedResponse); - verify(blockchain).getChainHeadBlockNumber(); - verify(blockchain, VerificationModeFactory.times(100)).getBlockByNumber(anyLong()); + verify(blockchain).getChainHeadBlock(); + verify(blockchain, times(99)).getBlockByNumber(anyLong()); verifyNoMoreInteractions(blockchain); } @@ -165,8 +165,8 @@ public class EthGasPriceTest { final JsonRpcResponse actualResponse = method.response(request); assertThat(actualResponse).usingRecursiveComparison().isEqualTo(expectedResponse); - verify(blockchain).getChainHeadBlockNumber(); - verify(blockchain, VerificationModeFactory.times(81)).getBlockByNumber(anyLong()); + verify(blockchain).getChainHeadBlock(); + verify(blockchain, times(80)).getBlockByNumber(anyLong()); verifyNoMoreInteractions(blockchain); } @@ -252,8 +252,7 @@ public class EthGasPriceTest { final JsonRpcResponse actualResponse = method.response(request); assertThat(actualResponse).usingRecursiveComparison().isEqualTo(expectedResponse); - verify(blockchain).getChainHeadBlockNumber(); - verify(blockchain, VerificationModeFactory.times(1)).getBlockByNumber(anyLong()); + verify(blockchain).getChainHeadBlock(); verifyNoMoreInteractions(blockchain); } @@ -328,12 +327,14 @@ public class EthGasPriceTest { blocksByNumber.put(i, createFakeBlock(i, txsNum, baseFee)); } - when(blockchain.getChainHeadBlockNumber()).thenReturn(chainHeadBlockNumber); - when(blockchain.getBlockByNumber(anyLong())) - .thenAnswer( - invocation -> Optional.of(blocksByNumber.get(invocation.getArgument(0, Long.class)))); - - when(blockchain.getChainHeadHeader()) + when(blockchain.getChainHeadBlock()).thenReturn(blocksByNumber.get(chainHeadBlockNumber)); + if (chainHeadBlockNumber > 1) { + when(blockchain.getBlockByNumber(anyLong())) + .thenAnswer( + invocation -> Optional.of(blocksByNumber.get(invocation.getArgument(0, Long.class)))); + } + lenient() + .when(blockchain.getChainHeadHeader()) .thenReturn(blocksByNumber.get(chainHeadBlockNumber).getHeader()); } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/chain/Blockchain.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/chain/Blockchain.java index 3c76ba69f5..49b6fea33e 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/chain/Blockchain.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/chain/Blockchain.java @@ -167,6 +167,15 @@ public interface Blockchain { */ Optional getBlockBody(Hash blockHeaderHash); + /** + * Safe version of {@code getBlockBody} (it should take any locks necessary to ensure any block + * updates that might be taking place have been completed first) + * + * @param blockHeaderHash The hash of the block whose header we want to retrieve. + * @return The block body corresponding to this block hash. + */ + Optional getBlockBodySafe(Hash blockHeaderHash); + /** * Given a block's hash, returns the list of transaction receipts associated with this block's * transactions. Associated block is not necessarily on the canonical chain. diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/chain/DefaultBlockchain.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/chain/DefaultBlockchain.java index 04eaaa6a35..5849f3e676 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/chain/DefaultBlockchain.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/chain/DefaultBlockchain.java @@ -299,7 +299,10 @@ public class DefaultBlockchain implements MutableBlockchain { @Override public Block getChainHeadBlock() { - return new Block(chainHeader, blockchainStorage.getBlockBody(chainHeader.getHash()).get()); + return new Block( + chainHeader, + getBlockBody(chainHeader.getHash()) + .orElseGet(() -> getBlockBodySafe(chainHeader.getHash()).get())); } @Override @@ -337,6 +340,11 @@ public class DefaultBlockchain implements MutableBlockchain { .orElseGet(() -> blockchainStorage.getBlockBody(blockHeaderHash)); } + @Override + public synchronized Optional getBlockBodySafe(final Hash blockHeaderHash) { + return getBlockBody(blockHeaderHash); + } + @Override public Optional> getTxReceipts(final Hash blockHeaderHash) { return transactionReceiptsCache diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/t8n/T8nBlockchain.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/t8n/T8nBlockchain.java index 5e31464ee6..c5905967fc 100644 --- a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/t8n/T8nBlockchain.java +++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/t8n/T8nBlockchain.java @@ -145,6 +145,11 @@ public class T8nBlockchain implements Blockchain { throw new UnsupportedOperationException(); } + @Override + public synchronized Optional getBlockBodySafe(final Hash blockHeaderHash) { + return getBlockBody(blockHeaderHash); + } + @Override public Optional> getTxReceipts(final Hash blockHeaderHash) { // Deterministic, but just not implemented. diff --git a/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/ReferenceTestBlockchain.java b/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/ReferenceTestBlockchain.java index 3773c8d1f0..8f03a01caa 100644 --- a/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/ReferenceTestBlockchain.java +++ b/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/ReferenceTestBlockchain.java @@ -142,6 +142,11 @@ public class ReferenceTestBlockchain implements Blockchain { throw new UnsupportedOperationException(); } + @Override + public synchronized Optional getBlockBodySafe(final Hash blockHeaderHash) { + return getBlockBody(blockHeaderHash); + } + @Override public Optional> getTxReceipts(final Hash blockHeaderHash) { // Deterministic, but just not implemented. From c24dea8474b9b3b1efdf53a7c37dbc1ef82d0ee4 Mon Sep 17 00:00:00 2001 From: garyschulte Date: Mon, 19 Aug 2024 15:46:15 -0700 Subject: [PATCH 135/259] preprocess release name for release workflow (#7486) Signed-off-by: garyschulte --- .github/workflows/release.yml | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2aff0bb48e..c743665357 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -19,6 +19,17 @@ jobs: steps: - name: checkout uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 + - name: Pre-process Release Name + id: pre_process_release_name + run: | + RELEASE_NAME="${{ github.event.release.name }}" + # strip all whitespace + RELEASE_NAME="${RELEASE_NAME//[[:space:]]/}" + if [[ ! "$RELEASE_NAME" =~ ^[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_ENV # Store in environment variable - name: Set up Java uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 with: @@ -30,7 +41,7 @@ jobs: cache-disabled: true - name: assemble release run: - ./gradlew -Prelease.releaseVersion=${{github.event.release.name}} -Pversion=${{github.event.release.name}} assemble + ./gradlew -Prelease.releaseVersion=${{env.RELEASE_NAME}} -Pversion=${{env.RELEASE_NAME}} assemble - name: hashes id: hashes run: | @@ -43,13 +54,13 @@ jobs: uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 with: path: 'build/distributions/besu*.tar.gz' - name: besu-${{ github.event.release.name }}.tar.gz + name: besu-${{ env.RELEASE_NAME }}.tar.gz compression-level: 0 - name: upload zipfile uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 with: path: 'build/distributions/besu*.zip' - name: besu-${{ github.event.release.name }}.zip + name: besu-${{ env.RELEASE_NAME }}.zip compression-level: 0 testWindows: @@ -121,7 +132,7 @@ jobs: env: ARTIFACTORY_USER: ${{ secrets.BESU_ARTIFACTORY_USER }} ARTIFACTORY_KEY: ${{ secrets.BESU_ARTIFACTORY_TOKEN }} - run: ./gradlew -Prelease.releaseVersion=${{ github.event.release.name }} -Pversion=${{github.event.release.name}} artifactoryPublish + run: ./gradlew -Prelease.releaseVersion=${{ env.RELEASE_NAME }} -Pversion=${{env.RELEASE_NAME}} artifactoryPublish hadolint: runs-on: ubuntu-22.04 @@ -195,11 +206,11 @@ jobs: architecture: ${{ steps.prep.outputs.ARCH }} with: cache-disabled: true - arguments: testDocker -PdockerOrgName=${{ env.registry }}/${{ secrets.DOCKER_ORG }} -Pversion=${{github.event.release.name}} -Prelease.releaseVersion=${{ github.event.release.name }} + arguments: testDocker -PdockerOrgName=${{ env.registry }}/${{ secrets.DOCKER_ORG }} -Pversion=${{env.RELEASE_NAME}} -Prelease.releaseVersion=${{ env.RELEASE_NAME }} - name: publish env: architecture: ${{ steps.prep.outputs.ARCH }} - run: ./gradlew --no-daemon dockerUpload -PdockerOrgName=${{ env.registry }}/${{ secrets.DOCKER_ORG }} -Pversion=${{github.event.release.name}} -Prelease.releaseVersion=${{ github.event.release.name }} + run: ./gradlew --no-daemon dockerUpload -PdockerOrgName=${{ env.registry }}/${{ secrets.DOCKER_ORG }} -Pversion=${{env.RELEASE_NAME}} -Prelease.releaseVersion=${{ env.RELEASE_NAME }} multiArch: needs: buildDocker @@ -226,7 +237,7 @@ jobs: username: ${{ secrets.DOCKER_USER_RW }} password: ${{ secrets.DOCKER_PASSWORD_RW }} - name: multi-arch docker - run: ./gradlew manifestDocker -PdockerOrgName=${{ env.registry }}/${{ secrets.DOCKER_ORG }} -Pversion=${{github.event.release.name}} -Prelease.releaseVersion=${{ github.event.release.name }} + run: ./gradlew manifestDocker -PdockerOrgName=${{ env.registry }}/${{ secrets.DOCKER_ORG }} -Pversion=${{env.RELEASE_NAME}} -Prelease.releaseVersion=${{ env.RELEASE_NAME }} amendNotes: needs: multiArch @@ -239,7 +250,7 @@ jobs: with: append_body: true body: | - `docker pull ${{env.registry}}/${{secrets.DOCKER_ORG}}/besu:${{github.event.release.name}}` + `docker pull ${{env.registry}}/${{secrets.DOCKER_ORG}}/besu:${{env.RELEASE_NAME}}` dockerPromoteX64: needs: multiArch @@ -262,9 +273,9 @@ jobs: with: cache-disabled: true - name: Docker upload - run: ./gradlew "-Prelease.releaseVersion=${{ github.event.release.name }}" "-PdockerOrgName=${{ env.registry }}/${{ secrets.DOCKER_ORG }}" dockerUploadRelease + run: ./gradlew "-Prelease.releaseVersion=${{ env.RELEASE_NAME }}" "-PdockerOrgName=${{ env.registry }}/${{ secrets.DOCKER_ORG }}" dockerUploadRelease - name: Docker manifest - run: ./gradlew "-Prelease.releaseVersion=${{ github.event.release.name }}" "-PdockerOrgName=${{ env.registry }}/${{ secrets.DOCKER_ORG }}" manifestDockerRelease + run: ./gradlew "-Prelease.releaseVersion=${{ env.RELEASE_NAME }}" "-PdockerOrgName=${{ env.registry }}/${{ secrets.DOCKER_ORG }}" manifestDockerRelease verifyContainer: needs: dockerPromoteX64 @@ -276,6 +287,6 @@ jobs: - name: Checkout uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 - name: Trigger container verify - run: echo '{"version":"${{ github.event.release.name }}","verify-latest-version":"true"}' | gh workflow run container-verify.yml --json + run: echo '{"version":"${{ env.RELEASE_NAME }}","verify-latest-version":"true"}' | gh workflow run container-verify.yml --json env: GH_TOKEN: ${{ github.token }} From 19e1a9aaf6f00eb79b70eff13e2d33963f377cf0 Mon Sep 17 00:00:00 2001 From: Fabio Di Fabio Date: Tue, 20 Aug 2024 01:50:26 +0200 Subject: [PATCH 136/259] Add pending block header to TransactionEvaluationContext (#7483) Add pending block header to TransactionEvaluationContext plugin API, so PluginTransactionSelector can access info of the pending block. --- Signed-off-by: Fabio Di Fabio Co-authored-by: Usman Saleem --- CHANGELOG.md | 1 + .../txselection/BlockSelectionContext.java | 2 +- .../txselection/BlockTransactionSelector.java | 7 ++++--- .../TransactionEvaluationContext.java | 12 ++++++++++-- .../selectors/BlockSizeTransactionSelector.java | 6 +++--- ...MinPriorityFeePerGasTransactionSelector.java | 2 +- ...riorityFeePerGasTransactionSelectorTest.java | 17 +++++++---------- .../BlobSizeTransactionSelectorTest.java | 16 ++++++++++++---- plugin-api/build.gradle | 2 +- .../TransactionEvaluationContext.java | 8 ++++++++ 10 files changed, 48 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ad5678b08..f04fcfb345 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ ### Additions and Improvements - Add 'inbound' field to admin_peers JSON-RPC Call [#7461](https://github.com/hyperledger/besu/pull/7461) +- Add pending block header to `TransactionEvaluationContext` plugin API [#7483](https://github.com/hyperledger/besu/pull/7483) ### Bug fixes - Fix tracing in precompiled contracts when halting for out of gas [#7318](https://github.com/hyperledger/besu/issues/7318) diff --git a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/BlockSelectionContext.java b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/BlockSelectionContext.java index a3dd13bd1b..f8bf6d50c5 100644 --- a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/BlockSelectionContext.java +++ b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/BlockSelectionContext.java @@ -29,7 +29,7 @@ public record BlockSelectionContext( GasCalculator gasCalculator, GasLimitCalculator gasLimitCalculator, BlockHashProcessor blockHashProcessor, - ProcessableBlockHeader processableBlockHeader, + ProcessableBlockHeader pendingBlockHeader, FeeMarket feeMarket, Wei blobGasPrice, Address miningBeneficiary, diff --git a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/BlockTransactionSelector.java b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/BlockTransactionSelector.java index ed028767d6..3d56c1fc07 100644 --- a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/BlockTransactionSelector.java +++ b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/BlockTransactionSelector.java @@ -263,9 +263,10 @@ public class BlockTransactionSelector { .getTransactionPriceCalculator() .price( pendingTransaction.getTransaction(), - blockSelectionContext.processableBlockHeader().getBaseFee()); + blockSelectionContext.pendingBlockHeader().getBaseFee()); return new TransactionEvaluationContext( + blockSelectionContext.pendingBlockHeader(), pendingTransaction, Stopwatch.createStarted(), transactionGasPriceInBlock, @@ -330,10 +331,10 @@ public class BlockTransactionSelector { private TransactionProcessingResult processTransaction( final PendingTransaction pendingTransaction, final WorldUpdater worldStateUpdater) { final BlockHashLookup blockHashLookup = - new CachingBlockHashLookup(blockSelectionContext.processableBlockHeader(), blockchain); + new CachingBlockHashLookup(blockSelectionContext.pendingBlockHeader(), blockchain); return transactionProcessor.processTransaction( worldStateUpdater, - blockSelectionContext.processableBlockHeader(), + blockSelectionContext.pendingBlockHeader(), pendingTransaction.getTransaction(), blockSelectionContext.miningBeneficiary(), pluginOperationTracer, diff --git a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/TransactionEvaluationContext.java b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/TransactionEvaluationContext.java index 0a17812b0f..7fce600a1a 100644 --- a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/TransactionEvaluationContext.java +++ b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/TransactionEvaluationContext.java @@ -17,23 +17,26 @@ package org.hyperledger.besu.ethereum.blockcreation.txselection; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.core.Transaction; import org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction; +import org.hyperledger.besu.plugin.data.ProcessableBlockHeader; import com.google.common.base.Stopwatch; public class TransactionEvaluationContext implements org.hyperledger.besu.plugin.services.txselection.TransactionEvaluationContext< PendingTransaction> { - private final org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction - pendingTransaction; + private final ProcessableBlockHeader pendingBlockHeader; + private final PendingTransaction pendingTransaction; private final Stopwatch evaluationTimer; private final Wei transactionGasPrice; private final Wei minGasPrice; public TransactionEvaluationContext( + final ProcessableBlockHeader pendingBlockHeader, final PendingTransaction pendingTransaction, final Stopwatch evaluationTimer, final Wei transactionGasPrice, final Wei minGasPrice) { + this.pendingBlockHeader = pendingBlockHeader; this.pendingTransaction = pendingTransaction; this.evaluationTimer = evaluationTimer; this.transactionGasPrice = transactionGasPrice; @@ -44,6 +47,11 @@ public class TransactionEvaluationContext return pendingTransaction.getTransaction(); } + @Override + public ProcessableBlockHeader getPendingBlockHeader() { + return pendingBlockHeader; + } + @Override public PendingTransaction getPendingTransaction() { return pendingTransaction; diff --git a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/BlockSizeTransactionSelector.java b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/BlockSizeTransactionSelector.java index 793f3e9384..2877c4ce13 100644 --- a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/BlockSizeTransactionSelector.java +++ b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/BlockSizeTransactionSelector.java @@ -91,7 +91,7 @@ public class BlockSizeTransactionSelector extends AbstractTransactionSelector { final TransactionSelectionResults transactionSelectionResults) { return transaction.getGasLimit() - > context.processableBlockHeader().getGasLimit() + > context.pendingBlockHeader().getGasLimit() - transactionSelectionResults.getCumulativeGasUsed(); } @@ -104,7 +104,7 @@ public class BlockSizeTransactionSelector extends AbstractTransactionSelector { */ private boolean blockOccupancyAboveThreshold( final TransactionSelectionResults transactionSelectionResults) { - final long gasAvailable = context.processableBlockHeader().getGasLimit(); + final long gasAvailable = context.pendingBlockHeader().getGasLimit(); final long gasUsed = transactionSelectionResults.getCumulativeGasUsed(); final long gasRemaining = gasAvailable - gasUsed; @@ -129,7 +129,7 @@ public class BlockSizeTransactionSelector extends AbstractTransactionSelector { * @return True if the block is full, false otherwise. */ private boolean blockFull(final TransactionSelectionResults transactionSelectionResults) { - final long gasAvailable = context.processableBlockHeader().getGasLimit(); + final long gasAvailable = context.pendingBlockHeader().getGasLimit(); final long gasUsed = transactionSelectionResults.getCumulativeGasUsed(); final long gasRemaining = gasAvailable - gasUsed; diff --git a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/MinPriorityFeePerGasTransactionSelector.java b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/MinPriorityFeePerGasTransactionSelector.java index fc32a5c08c..5783c7e500 100644 --- a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/MinPriorityFeePerGasTransactionSelector.java +++ b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/MinPriorityFeePerGasTransactionSelector.java @@ -68,7 +68,7 @@ public class MinPriorityFeePerGasTransactionSelector extends AbstractTransaction Wei priorityFeePerGas = pendingTransaction .getTransaction() - .getEffectivePriorityFeePerGas(context.processableBlockHeader().getBaseFee()); + .getEffectivePriorityFeePerGas(context.pendingBlockHeader().getBaseFee()); return priorityFeePerGas.lessThan(context.miningParameters().getMinPriorityFeePerGas()); } diff --git a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/MinPriorityFeePerGasTransactionSelectorTest.java b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/MinPriorityFeePerGasTransactionSelectorTest.java index 8122dc3088..6f81f4df2c 100644 --- a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/MinPriorityFeePerGasTransactionSelectorTest.java +++ b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/MinPriorityFeePerGasTransactionSelectorTest.java @@ -33,11 +33,16 @@ import org.hyperledger.besu.plugin.data.TransactionSelectionResult; import com.google.common.base.Stopwatch; 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) public class MinPriorityFeePerGasTransactionSelectorTest { private AbstractTransactionSelector transactionSelector; private final int minPriorityFeeParameter = 7; + @Mock private ProcessableBlockHeader pendingBlockHeader; @BeforeEach public void initialize() { @@ -45,15 +50,7 @@ public class MinPriorityFeePerGasTransactionSelectorTest { MiningParameters.newDefault().setMinPriorityFeePerGas(Wei.of(minPriorityFeeParameter)); BlockSelectionContext context = new BlockSelectionContext( - miningParameters, - null, - null, - null, - mock(ProcessableBlockHeader.class), - null, - null, - null, - null); + miningParameters, null, null, null, pendingBlockHeader, null, null, null, null); transactionSelector = new MinPriorityFeePerGasTransactionSelector(context); } @@ -100,6 +97,6 @@ public class MinPriorityFeePerGasTransactionSelectorTest { when(pendingTransaction.getTransaction()).thenReturn(transaction); when(transaction.getEffectivePriorityFeePerGas(any())).thenReturn(Wei.of(priorityFeePerGas)); return new TransactionEvaluationContext( - pendingTransaction, Stopwatch.createStarted(), Wei.ONE, Wei.ONE); + pendingBlockHeader, pendingTransaction, Stopwatch.createStarted(), Wei.ONE, Wei.ONE); } } diff --git a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/BlobSizeTransactionSelectorTest.java b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/BlobSizeTransactionSelectorTest.java index f52a5dfb46..123faf2d18 100644 --- a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/BlobSizeTransactionSelectorTest.java +++ b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/BlobSizeTransactionSelectorTest.java @@ -76,7 +76,9 @@ class BlobSizeTransactionSelectorTest { final var nonBlobTx = createEIP1559PendingTransaction(); - final var txEvaluationContext = new TransactionEvaluationContext(nonBlobTx, null, null, null); + final var txEvaluationContext = + new TransactionEvaluationContext( + blockSelectionContext.pendingBlockHeader(), nonBlobTx, null, null, null); final var result = selector.evaluateTransactionPreProcessing(txEvaluationContext, selectionResults); @@ -94,7 +96,9 @@ class BlobSizeTransactionSelectorTest { final var firstBlobTx = createBlobPendingTransaction(MAX_BLOBS); - final var txEvaluationContext = new TransactionEvaluationContext(firstBlobTx, null, null, null); + final var txEvaluationContext = + new TransactionEvaluationContext( + blockSelectionContext.pendingBlockHeader(), firstBlobTx, null, null, null); when(selectionResults.getCumulativeBlobGasUsed()).thenReturn(0L); @@ -112,7 +116,9 @@ class BlobSizeTransactionSelectorTest { final var firstBlobTx = createBlobPendingTransaction(1); - final var txEvaluationContext = new TransactionEvaluationContext(firstBlobTx, null, null, null); + final var txEvaluationContext = + new TransactionEvaluationContext( + blockSelectionContext.pendingBlockHeader(), firstBlobTx, null, null, null); when(selectionResults.getCumulativeBlobGasUsed()).thenReturn(MAX_BLOB_GAS); @@ -132,7 +138,9 @@ class BlobSizeTransactionSelectorTest { final var firstBlobTx = createBlobPendingTransaction(MAX_BLOBS); - final var txEvaluationContext = new TransactionEvaluationContext(firstBlobTx, null, null, null); + final var txEvaluationContext = + new TransactionEvaluationContext( + blockSelectionContext.pendingBlockHeader(), firstBlobTx, null, null, null); when(selectionResults.getCumulativeBlobGasUsed()).thenReturn(MAX_BLOB_GAS - 1); diff --git a/plugin-api/build.gradle b/plugin-api/build.gradle index 4440a4f069..af8da71a7f 100644 --- a/plugin-api/build.gradle +++ b/plugin-api/build.gradle @@ -70,7 +70,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 = '6Hy3eaCpnxehyDO3smSAr1i2DsB2q/V37/m8POycikI=' + knownHash = '2tFIKwEd8T5I37ywbFnVcMwTR8HiiCC6gO1Chd3hZp8=' } check.dependsOn('checkAPIChanges') diff --git a/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/txselection/TransactionEvaluationContext.java b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/txselection/TransactionEvaluationContext.java index 93eae92dc7..8938ef881b 100644 --- a/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/txselection/TransactionEvaluationContext.java +++ b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/txselection/TransactionEvaluationContext.java @@ -16,6 +16,7 @@ package org.hyperledger.besu.plugin.services.txselection; import org.hyperledger.besu.datatypes.PendingTransaction; import org.hyperledger.besu.datatypes.Wei; +import org.hyperledger.besu.plugin.data.ProcessableBlockHeader; import com.google.common.base.Stopwatch; @@ -27,6 +28,13 @@ import com.google.common.base.Stopwatch; */ public interface TransactionEvaluationContext { + /** + * Gets the pending block header + * + * @return the pending block header + */ + ProcessableBlockHeader getPendingBlockHeader(); + /** * Gets the pending transaction. * From 96f04a726c8fbc06b704c90155b50b0c4d5e95b4 Mon Sep 17 00:00:00 2001 From: gringsam Date: Mon, 19 Aug 2024 20:33:19 -0400 Subject: [PATCH 137/259] fix wiki (#7480) Signed-off-by: Snazzy Co-authored-by: Sally MacFarlane --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index eb4a656b0e..c2d6c57d25 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -28,7 +28,7 @@ Having the following accounts is necessary for contributing code/issues to Besu. ### Other important information -* [Roadmap](https://wiki.hyperledger.org/display/BESU/Roadmap) +* [Roadmap](https://wiki.hyperledger.org/pages/viewpage.action?pageId=24781786) * [Code of Conduct](https://wiki.hyperledger.org/display/BESU/Code+of+Conduct) * [Governance](https://wiki.hyperledger.org/display/BESU/Governance) From 4c0d7b5dbb4d7e12c325074168e34eebd4f27bb5 Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Mon, 19 Aug 2024 18:31:50 -0700 Subject: [PATCH 138/259] Update EOF validation error strings (#7487) Update the EOF validation error strings so that they can validate against expected exceptions in reference tests. Signed-off-by: Danno Ferrin --- .../evmtool/BlockchainTestSubCommand.java | 7 +- .../besu/evmtool/CodeValidateSubCommand.java | 2 +- .../besu/evmtool/EOFTestSubCommand.java | 2 +- .../besu/evmtool/PrettyPrintSubCommand.java | 2 +- .../besu/evmtool/StateTestSubCommand.java | 7 +- .../besu/evmtool/trace/create-eof-error.json | 2 +- .../ReferenceTestProtocolSchedules.java | 9 ++ .../besu/ethereum/core/TransactionTest.java | 5 +- .../ethereum/eof/EOFReferenceTestTools.java | 35 +++--- .../vm/BlockchainReferenceTestTools.java | 4 +- .../vm/GeneralStateReferenceTestTools.java | 4 +- .../templates/EOFReferenceTest.java.template | 5 +- .../besu/evm/code/CodeV1Validation.java | 108 +++++++++--------- .../hyperledger/besu/evm/code/EOFLayout.java | 7 +- .../besu/evm/code/CodeFactoryTest.java | 6 +- .../hyperledger/besu/evm/code/CodeV1Test.java | 82 ++++++------- 16 files changed, 147 insertions(+), 140 deletions(-) diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/BlockchainTestSubCommand.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/BlockchainTestSubCommand.java index 5b9bc2cdfe..bec68a3cc3 100644 --- a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/BlockchainTestSubCommand.java +++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/BlockchainTestSubCommand.java @@ -44,12 +44,10 @@ import java.nio.file.Path; import java.util.ArrayList; import java.util.List; import java.util.Map; -import java.util.function.Supplier; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.common.base.Suppliers; import org.apache.tuweni.bytes.Bytes32; import picocli.CommandLine.Command; import picocli.CommandLine.Option; @@ -81,9 +79,6 @@ public class BlockchainTestSubCommand implements Runnable { */ public static final String COMMAND_NAME = "block-test"; - static final Supplier referenceTestProtocolSchedules = - Suppliers.memoize(ReferenceTestProtocolSchedules::create); - @Option( names = {"--test-name"}, description = "Limit execution to one named test.") @@ -177,7 +172,7 @@ public class BlockchainTestSubCommand implements Runnable { .orElseThrow(); final ProtocolSchedule schedule = - referenceTestProtocolSchedules.get().getByName(spec.getNetwork()); + ReferenceTestProtocolSchedules.getInstance().getByName(spec.getNetwork()); final MutableBlockchain blockchain = spec.getBlockchain(); final ProtocolContext context = spec.getProtocolContext(); 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 6c8b9d5ad3..4c04119864 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 @@ -94,7 +94,7 @@ public class CodeValidateSubCommand implements Runnable { Suppliers.memoize( () -> { ProtocolSpec protocolSpec = - ReferenceTestProtocolSchedules.create().geSpecByName(fork); + ReferenceTestProtocolSchedules.getInstance().geSpecByName(fork); return protocolSpec.getEvm(); }); } 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 bfa873e61c..94f8b2cd49 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 @@ -93,7 +93,7 @@ public class EOFTestSubCommand implements Runnable { fork = parentCommand.getFork(); } ProtocolSpec protocolSpec = - ReferenceTestProtocolSchedules.create() + ReferenceTestProtocolSchedules.getInstance() .geSpecByName(fork == null ? EvmSpecVersion.PRAGUE.getName() : fork); evm = protocolSpec.getEvm(); 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 2e1656b13d..aeff4a96b5 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 @@ -99,7 +99,7 @@ public class PrettyPrintSubCommand implements Runnable { if (parentCommand.hasFork()) { fork = parentCommand.getFork(); } - ProtocolSpec protocolSpec = ReferenceTestProtocolSchedules.create().geSpecByName(fork); + ProtocolSpec protocolSpec = ReferenceTestProtocolSchedules.getInstance().geSpecByName(fork); EVM evm = protocolSpec.getEvm(); EOFLayout layout = evm.parseEOF(container); if (layout.isValid()) { diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/StateTestSubCommand.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/StateTestSubCommand.java index 40f36f18f1..f6e05b5a49 100644 --- a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/StateTestSubCommand.java +++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/StateTestSubCommand.java @@ -51,14 +51,12 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; -import java.util.function.Supplier; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.common.base.Stopwatch; -import com.google.common.base.Suppliers; import org.apache.tuweni.bytes.Bytes; import picocli.CommandLine.Command; import picocli.CommandLine.Option; @@ -90,9 +88,6 @@ public class StateTestSubCommand implements Runnable { */ public static final String COMMAND_NAME = "state-test"; - static final Supplier referenceTestProtocolSchedules = - Suppliers.memoize(ReferenceTestProtocolSchedules::create); - @SuppressWarnings({"FieldCanBeFinal"}) @Option( names = {"--fork"}, @@ -258,7 +253,7 @@ public class StateTestSubCommand implements Runnable { final String forkName = fork == null ? spec.getFork() : fork; final ProtocolSchedule protocolSchedule = - referenceTestProtocolSchedules.get().getByName(forkName); + ReferenceTestProtocolSchedules.getInstance().getByName(forkName); if (protocolSchedule == null) { throw new UnsupportedForkException(forkName); } 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 58402eeaa4..cd4c3fa14a 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 @@ -11,5 +11,5 @@ "CancunEOF" ], "stdin": "", - "stdout": "EOF Code Invalid : STOP is only a valid opcode in containers used for runtime operations.\n" + "stdout": "EOF Code Invalid : incompatible_container_kind opcode STOP is only valid for runtime.\n" } \ No newline at end of file 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 d6c5afdc4a..bcdf5e25d5 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 @@ -44,6 +44,15 @@ public class ReferenceTestProtocolSchedules { private static final List SPECS_PRIOR_TO_DELETING_EMPTY_ACCOUNTS = Arrays.asList("Frontier", "Homestead", "EIP150"); + private static ReferenceTestProtocolSchedules instance; + + public static ReferenceTestProtocolSchedules getInstance() { + if (instance == null) { + instance = create(); + } + return instance; + } + public static ReferenceTestProtocolSchedules create() { return create(new StubGenesisConfigOptions()); } diff --git a/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/core/TransactionTest.java b/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/core/TransactionTest.java index bf17f2f96e..9aa04bd0ff 100644 --- a/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/core/TransactionTest.java +++ b/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/core/TransactionTest.java @@ -50,11 +50,8 @@ import org.junit.jupiter.params.provider.MethodSource; public class TransactionTest { - private static final ReferenceTestProtocolSchedules REFERENCE_TEST_PROTOCOL_SCHEDULES = - ReferenceTestProtocolSchedules.create(); - private static TransactionValidator transactionValidator(final String name) { - return REFERENCE_TEST_PROTOCOL_SCHEDULES + return ReferenceTestProtocolSchedules.getInstance() .getByName(name) .getByBlockHeader(BlockHeaderBuilder.createDefault().buildBlockHeader()) .getTransactionValidatorFactory() 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 a15bcb2418..8621b5d08a 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 @@ -113,11 +113,12 @@ public class EOFReferenceTestTools { @SuppressWarnings("java:S5960") // This is not production code, this is testing code. public static void executeTest( + final String name, final String fork, final Bytes code, final String containerKind, final EOFTestCaseSpec.TestResult expected) { - EVM evm = ReferenceTestProtocolSchedules.create().geSpecByName(fork).getEvm(); + EVM evm = ReferenceTestProtocolSchedules.getInstance().geSpecByName(fork).getEvm(); assertThat(evm).isNotNull(); // hardwire in the magic byte transaction checks @@ -144,26 +145,32 @@ public class EOFReferenceTestTools { .withFailMessage("Code did not parse to valid containerKind of " + expectedMode) .isNotEqualTo(expectedMode); } else { + 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( () -> - EOFLayout.parseEOF(code).prettyPrint() - + "\nExpected exception :" - + expected.exception() - + " actual exception :" - + (parsedCode.isValid() + "Expected exception :%s actual exception: %s" + .formatted( + expected.exception(), + (parsedCode.isValid() ? null - : ((CodeInvalid) parsedCode).getInvalidReason())) - .isEqualTo(expected.result()); - - if (expected.result()) { - assertThat(code) - .withFailMessage("Container round trip failed") - .isEqualTo(layout.writeContainer(null)); + : ((CodeInvalid) parsedCode).getInvalidReason()))) + .containsIgnoringCase(expected.exception().replace("EOFException.", "")); + } } } } else { - assertThat(layout.isValid()) + assertThat(false) .withFailMessage( () -> "Expected exception - " 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 1d9ce8eefa..aabc674087 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 @@ -44,8 +44,6 @@ import org.apache.tuweni.bytes.Bytes32; import org.assertj.core.api.Assertions; public class BlockchainReferenceTestTools { - private static final ReferenceTestProtocolSchedules REFERENCE_TEST_PROTOCOL_SCHEDULES = - ReferenceTestProtocolSchedules.create(); private static final List NETWORKS_TO_RUN; @@ -114,7 +112,7 @@ public class BlockchainReferenceTestTools { .orElseThrow(); final ProtocolSchedule schedule = - REFERENCE_TEST_PROTOCOL_SCHEDULES.getByName(spec.getNetwork()); + ReferenceTestProtocolSchedules.getInstance().getByName(spec.getNetwork()); final MutableBlockchain blockchain = spec.getBlockchain(); final ProtocolContext context = spec.getProtocolContext(); diff --git a/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/vm/GeneralStateReferenceTestTools.java b/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/vm/GeneralStateReferenceTestTools.java index 18d574adc1..42934b612d 100644 --- a/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/vm/GeneralStateReferenceTestTools.java +++ b/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/vm/GeneralStateReferenceTestTools.java @@ -44,8 +44,6 @@ import org.hyperledger.besu.evm.worldstate.WorldUpdater; import org.hyperledger.besu.testutil.JsonTestParameters; public class GeneralStateReferenceTestTools { - private static final ReferenceTestProtocolSchedules REFERENCE_TEST_PROTOCOL_SCHEDULES = - ReferenceTestProtocolSchedules.create(); private static final List SPECS_PRIOR_TO_DELETING_EMPTY_ACCOUNTS = Arrays.asList("Frontier", "Homestead", "EIP150"); @@ -54,7 +52,7 @@ public class GeneralStateReferenceTestTools { } private static ProtocolSpec protocolSpec(final String name) { - return REFERENCE_TEST_PROTOCOL_SCHEDULES + return ReferenceTestProtocolSchedules.getInstance() .getByName(name) .getByBlockHeader(BlockHeaderBuilder.createDefault().buildBlockHeader()); } diff --git a/ethereum/referencetests/src/reference-test/templates/EOFReferenceTest.java.template b/ethereum/referencetests/src/reference-test/templates/EOFReferenceTest.java.template index d9e52403d7..a08efec2b6 100644 --- a/ethereum/referencetests/src/reference-test/templates/EOFReferenceTest.java.template +++ b/ethereum/referencetests/src/reference-test/templates/EOFReferenceTest.java.template @@ -6,7 +6,6 @@ import static org.junit.jupiter.api.Assumptions.assumeTrue; import org.hyperledger.besu.ethereum.referencetests.EOFTestCaseSpec; -import java.util.Arrays; import java.util.stream.Stream; import org.apache.tuweni.bytes.Bytes; @@ -14,8 +13,6 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import static org.junit.jupiter.api.Assumptions.assumeTrue; - /** The general state test operation testing framework entry point. */ public class %%TESTS_NAME%% { @@ -38,6 +35,6 @@ public class %%TESTS_NAME%% { final EOFTestCaseSpec.TestResult results, final boolean runTest) { assumeTrue(runTest, "Test " + name + " was ignored"); - executeTest(fork, code, containerKind, results); + executeTest(name, fork, code, containerKind, results); } } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/code/CodeV1Validation.java b/evm/src/main/java/org/hyperledger/besu/evm/code/CodeV1Validation.java index f968bbf36a..0192c6f578 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/code/CodeV1Validation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/code/CodeV1Validation.java @@ -80,7 +80,7 @@ public class CodeV1Validation implements EOFValidator { @Override public String validate(final EOFLayout layout) { if (layout.container().size() > maxContainerSize) { - return "EOF container is larger than maximum size of " + maxContainerSize; + return "container_size_above_limit of " + maxContainerSize; } Queue workList = new ArrayDeque<>(layout.getSubcontainerCount()); @@ -90,7 +90,7 @@ public class CodeV1Validation implements EOFValidator { EOFLayout container = workList.poll(); workList.addAll(List.of(container.subContainers())); if (container != layout && container.containerMode().get() == null) { - return "Unreferenced container #" + layout.indexOfSubcontainer(container); + return "orphan_subcontainer #" + layout.indexOfSubcontainer(container); } if (container.containerMode().get() != RUNTIME && container.data().size() != container.dataLength()) { @@ -157,7 +157,7 @@ public class CodeV1Validation implements EOFValidator { opcodeInfo = V1_OPCODES[operationNum]; if (!opcodeInfo.valid()) { // undefined instruction - return format("Invalid Instruction 0x%02x", operationNum); + return format("undefined_instruction 0x%02x", operationNum); } pos += 1; int pcPostInstruction = pos; @@ -168,7 +168,7 @@ public class CodeV1Validation implements EOFValidator { eofLayout.containerMode().set(RUNTIME); } else if (!eofContainerMode.equals(RUNTIME)) { return format( - "%s is only a valid opcode in containers used for runtime operations.", + "incompatible_container_kind opcode %s is only valid for runtime.", opcodeInfo.name()); } break; @@ -210,54 +210,55 @@ public class CodeV1Validation implements EOFValidator { break; case DataLoadNOperation.OPCODE: if (pos + 2 > size) { - return "Truncated DataLoadN offset"; + return "truncated_instruction DATALOADN"; } pcPostInstruction += 2; final int dataLoadOffset = readBigEndianU16(pos, rawCode); // only verfy the last byte of the load is within the minimum data if (dataLoadOffset > eofLayout.dataLength() - 32) { - return "DataLoadN loads data past minimum data length"; + return "invalid_dataloadn_index %d + 32 > %d" + .formatted(dataLoadOffset, eofLayout.dataLength()); } break; case RelativeJumpOperation.OPCODE, RelativeJumpIfOperation.OPCODE: if (pos + 2 > size) { - return "Truncated relative jump offset"; + return "truncated_instruction RJUMP"; } pcPostInstruction += 2; final int offset = readBigEndianI16(pos, rawCode); final int rjumpdest = pcPostInstruction + offset; if (rjumpdest < 0 || rjumpdest >= size) { - return "Relative jump destination out of bounds"; + return "invalid_rjump_destination out of bounds"; } rjumpdests.set(rjumpdest); break; case RelativeJumpVectorOperation.OPCODE: pcPostInstruction += 1; if (pcPostInstruction > size) { - return "Truncated jump table"; + return "truncated_instruction RJUMPV"; } int jumpBasis = pcPostInstruction; final int jumpTableSize = RelativeJumpVectorOperation.getVectorSize(code, pos); pcPostInstruction += 2 * jumpTableSize; if (pcPostInstruction > size) { - return "Truncated jump table"; + return "truncated_instruction RJUMPV"; } for (int offsetPos = jumpBasis; offsetPos < pcPostInstruction; offsetPos += 2) { final int rjumpvOffset = readBigEndianI16(offsetPos, rawCode); final int rjumpvDest = pcPostInstruction + rjumpvOffset; if (rjumpvDest < 0 || rjumpvDest >= size) { - return "Relative jump destination out of bounds"; + return "invalid_rjump_destination out of bounds"; } rjumpdests.set(rjumpvDest); } break; case CallFOperation.OPCODE: if (pos + 2 > size) { - return "Truncated CALLF"; + return "truncated_instruction CALLF"; } int section = readBigEndianU16(pos, rawCode); if (section >= eofLayout.getCodeSectionCount()) { - return "CALLF to non-existent section - " + Integer.toHexString(section); + return "invalid_code_section_index CALLF to " + Integer.toHexString(section); } if (!eofLayout.getCodeSection(section).returning) { return "CALLF to non-returning section - " + Integer.toHexString(section); @@ -269,17 +270,18 @@ public class CodeV1Validation implements EOFValidator { break; case JumpFOperation.OPCODE: if (pos + 2 > size) { - return "Truncated JUMPF"; + return "truncated_instruction JUMPF"; } int targetSection = readBigEndianU16(pos, rawCode); if (targetSection >= eofLayout.getCodeSectionCount()) { - return "JUMPF to non-existent section - " + Integer.toHexString(targetSection); + return "invalid_code_section_index JUMPF - " + Integer.toHexString(targetSection); } CodeSection targetCodeSection = eofLayout.getCodeSection(targetSection); - if (targetCodeSection.isReturning() - && thisCodeSection.getOutputs() < targetCodeSection.getOutputs()) { + if (targetCodeSection.isReturning() && !thisCodeSection.isReturning()) { + return "invalid_non_returning_flag non-returning JUMPF source must have non-returning target"; + } else if (thisCodeSection.getOutputs() < targetCodeSection.getOutputs()) { return format( - "JUMPF targeting a returning code section %2x with more outputs %d than current section's outputs %d", + "jumpf_destination_incompatible_outputs target %2x with more outputs %d than current section's outputs %d", targetSection, targetCodeSection.getOutputs(), thisCodeSection.getOutputs()); } hasReturningOpcode |= eofLayout.getCodeSection(targetSection).isReturning(); @@ -288,13 +290,13 @@ public class CodeV1Validation implements EOFValidator { case EOFCreateOperation.OPCODE: if (pos + 1 > size) { return format( - "Dangling immediate for %s at pc=%d", + "truncated_instruction dangling immediate for %s at pc=%d", opcodeInfo.name(), pos - opcodeInfo.pcAdvance()); } int subcontainerNum = rawCode[pos] & 0xff; if (subcontainerNum >= eofLayout.getSubcontainerCount()) { return format( - "%s refers to non-existent subcontainer %d at pc=%d", + "invalid_container_section_index %s refers to non-existent subcontainer %d at pc=%d", opcodeInfo.name(), subcontainerNum, pos - opcodeInfo.pcAdvance()); } EOFLayout subContainer = eofLayout.getSubcontainer(subcontainerNum); @@ -303,7 +305,7 @@ public class CodeV1Validation implements EOFValidator { subContainer.containerMode().set(INITCODE); } else if (subcontainerMode == RUNTIME) { return format( - "subcontainer %d cannot be used both as initcode and runtime", subcontainerNum); + "incompatible_container_kind subcontainer %d should be initcode", subcontainerNum); } if (subContainer.dataLength() != subContainer.data().size()) { return format( @@ -320,17 +322,18 @@ public class CodeV1Validation implements EOFValidator { eofLayout.containerMode().set(INITCODE); } else if (!eofContainerMode.equals(INITCODE)) { return format( - "%s is only a valid opcode in containers used for initcode", opcodeInfo.name()); + "incompatible_container_kind opcode %s is only valid for initcode", + opcodeInfo.name()); } if (pos + 1 > size) { return format( - "Dangling immediate for %s at pc=%d", + "truncated_instruction dangling immediate for %s at pc=%d", opcodeInfo.name(), pos - opcodeInfo.pcAdvance()); } int returnedContractNum = rawCode[pos] & 0xff; if (returnedContractNum >= eofLayout.getSubcontainerCount()) { return format( - "%s refers to non-existent subcontainer %d at pc=%d", + "invalid_container_section_index %s refers to non-existent subcontainer %d at pc=%d", opcodeInfo.name(), returnedContractNum, pos - opcodeInfo.pcAdvance()); } EOFLayout returnedContract = eofLayout.getSubcontainer(returnedContractNum); @@ -339,7 +342,8 @@ public class CodeV1Validation implements EOFValidator { returnedContract.containerMode().set(RUNTIME); } else if (returnedContractMode.equals(INITCODE)) { return format( - "subcontainer %d cannot be used both as initcode and runtime", returnedContractNum); + "incompatible_container_kind subcontainer %d should be runtime", + returnedContractNum); } pcPostInstruction += 1; break; @@ -347,9 +351,9 @@ public class CodeV1Validation implements EOFValidator { // a few opcodes have potentially dangling immediates if (opcodeInfo.pcAdvance() > 1) { pcPostInstruction += opcodeInfo.pcAdvance() - 1; - if (pcPostInstruction >= size) { + if (pcPostInstruction > size) { return format( - "Dangling immediate for %s at pc=%d", + "truncated_instruction dangling immediate for %s at pc=%d", opcodeInfo.name(), pos - opcodeInfo.pcAdvance()); } } @@ -360,14 +364,14 @@ public class CodeV1Validation implements EOFValidator { } if (thisCodeSection.isReturning() != hasReturningOpcode) { return thisCodeSection.isReturning() - ? "No RETF or qualifying JUMPF" - : "Non-returing section has RETF or JUMPF into returning section"; + ? "unreachable_code_sections no RETF or qualifying JUMPF" + : "invalid_non_returning_flag RETF or JUMPF into returning section"; } if (!opcodeInfo.terminal()) { - return "No terminating instruction"; + return "missing_stop_opcode No terminating instruction"; } if (rjumpdests.intersects(immediates)) { - return "Relative jump destinations targets invalid immediate data"; + return "invalid_rjump_destination targets immediate data"; } return null; } @@ -472,7 +476,7 @@ public class CodeV1Validation implements EOFValidator { int nextPC; if (!opcodeInfo.valid()) { - return format("Invalid Instruction 0x%02x", thisOp); + return format("undefined_instruction 0x%02x", thisOp); } nextPC = currentPC + pcAdvance; @@ -483,7 +487,7 @@ public class CodeV1Validation implements EOFValidator { } if (stack_max[currentPC] < 0) { return format( - "Code that was not forward referenced in section 0x%x pc %d", + "unreachable_instructions section 0x%x pc %d was not forward referenced", codeSectionToValidate, currentPC); } currentMin = min(stack_min[currentPC], currentMin); @@ -491,7 +495,7 @@ public class CodeV1Validation implements EOFValidator { if (stackInputs > currentMin) { return format( - "Operation 0x%02X requires stack of %d but may only have %d items", + "stack_underflow operation 0x%02X wants stack of %d but may only have %d", thisOp, stackInputs, currentMin); } @@ -515,13 +519,13 @@ public class CodeV1Validation implements EOFValidator { } else { if (stack_min[targetPC] != currentMin) { return format( - "Stack minimum violation on backwards jump from %d to %d, %d != %d", - currentPC, targetPC, stack_min[currentPC], currentMax); + "stack_height_mismatch backwards RJUMP from %d to %d, min %d != %d", + currentPC, targetPC, stack_min[targetPC], currentMin); } if (stack_max[targetPC] != currentMax) { return format( - "Stack maximum violation on backwards jump from %d to %d, %d != %d", - currentPC, targetPC, stack_max[currentPC], currentMax); + "stack_height_mismatch backwards RJUMP from %d to %d, max %d != %d", + currentPC, targetPC, stack_max[targetPC], currentMax); } } @@ -542,13 +546,13 @@ public class CodeV1Validation implements EOFValidator { } else { if (stack_min[targetPCi] != currentMin) { return format( - "Stack minimum violation on backwards jump from %d to %d, %d != %d", - currentPC, targetPCi, stack_min[currentPC], currentMin); + "stack_height_mismatch backwards RJUMPI from %d to %d, min %d != %d", + currentPC, targetPCi, stack_min[targetPCi], currentMin); } if (stack_max[targetPCi] != currentMax) { return format( - "Stack maximum violation on backwards jump from %d to %d, %d != %d", - currentPC, targetPCi, stack_max[currentPC], currentMax); + "stack_height_mismatch backwards RJUMPI from %d to %d, max %d != %d", + currentPC, targetPCi, stack_max[targetPCi], currentMax); } } break; @@ -568,13 +572,13 @@ public class CodeV1Validation implements EOFValidator { } else { if (stack_min[targetPCv] != currentMin) { return format( - "Stack minimum violation on backwards jump from %d to %d, %d != %d", - currentPC, targetPCv, stack_min[currentPC], currentMin); + "stack_height_mismatch backwards RJUMPV from %d to %d, min %d != %d", + currentPC, targetPCv, stack_min[targetPCv], currentMin); } if (stack_max[targetPCv] != currentMax) { return format( - "Stack maximum violation on backwards jump from %d to %d, %d != %d", - currentPC, targetPCv, stack_max[currentPC], currentMax); + "stack_height_mismatch backwards RJUMPV from %d to %d, max %d != %d", + currentPC, targetPCv, stack_max[targetPCv], currentMax); } } } @@ -589,7 +593,7 @@ public class CodeV1Validation implements EOFValidator { if (stack_min[currentPC] != returnStackItems || stack_min[currentPC] != stack_max[currentPC]) { return format( - "RETF in section %d calculated height %d does not match configured return stack %d, min height %d, and max height %d", + "stack_higher_than_outputs RETF in section %d calculated height %d does not match configured return stack %d, min height %d, and max height %d", codeSectionToValidate, currentMin, returnStackItems, @@ -620,9 +624,11 @@ public class CodeV1Validation implements EOFValidator { "JUMPF at section %d pc %d has a variable stack height %d/%d", codeSectionToValidate, currentPC, currentMin, currentMax); } - if (currentMax != toValidate.outputs + targetCs.inputs - targetCs.outputs) { + int expectedMax = toValidate.outputs + targetCs.inputs - targetCs.outputs; + if (currentMax != expectedMax) { return format( - "JUMPF at section %d pc %d has incompatible stack height for returning section %d (%d != %d + %d - %d)", + "%s JUMPF at section %d pc %d has incompatible stack height for returning section %d (%d != %d + %d - %d)", + currentMax < expectedMax ? "stack_underflow" : "stack_higher_than_outputs", codeSectionToValidate, currentPC, jumpFTargetSectionNum, @@ -634,7 +640,7 @@ public class CodeV1Validation implements EOFValidator { } else { if (currentMin < targetCs.getInputs()) { return format( - "JUMPF at section %d pc %d has insufficient minimum stack height for non returning section %d (%d != %d)", + "stack_underflow JUMPF at section %d pc %d has insufficient minimum stack height for non returning section %d (%d != %d)", codeSectionToValidate, currentPC, jumpFTargetSectionNum, @@ -669,7 +675,7 @@ public class CodeV1Validation implements EOFValidator { if (maxStackHeight != toValidate.maxStackHeight) { return format( - "Calculated max stack height (%d) does not match reported stack height (%d)", + "invalid_max_stack_height Calculated (%d) != reported (%d)", maxStackHeight, toValidate.maxStackHeight); } if (unusedBytes != 0) { diff --git a/evm/src/main/java/org/hyperledger/besu/evm/code/EOFLayout.java b/evm/src/main/java/org/hyperledger/besu/evm/code/EOFLayout.java index 39723f7fd3..d5abb05f86 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/code/EOFLayout.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/code/EOFLayout.java @@ -766,7 +766,7 @@ public record EOFLayout( out.print(" "); } out.printf("%02x", byteCode[pc]); - for (int j = 1; j < advance; j++) { + for (int j = 1; j < advance && (pc + j) < byteCode.length; j++) { out.printf("%02x", byteCode[pc + j]); } out.printf(" # [%d] %s", pc, ci.name()); @@ -774,9 +774,12 @@ public record EOFLayout( out.printf("(%d)", byteCode[pc + 1] & 0xff); } else if (advance > 2) { out.print("(0x"); - for (int j = 1; j < advance; j++) { + for (int j = 1; j < advance && (pc + j) < byteCode.length; j++) { out.printf("%02x", byteCode[pc + j]); } + if ((pc + advance) >= byteCode.length) { + out.print(" "); + } out.print(")"); } out.printf("%n"); 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 e1f1e767d2..6f60ab7865 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 @@ -478,7 +478,7 @@ class CodeFactoryTest { # Subcontainer 0 ends # Data section (empty) """, - "STOP is only a valid opcode in containers used for runtime operations."); + "incompatible_container_kind"); } @Test @@ -527,7 +527,7 @@ class CodeFactoryTest { # Subcontainer 0 ends # Data section (empty) """, - "RETURN is only a valid opcode in containers used for runtime operations."); + "incompatible_container_kind"); } @Test @@ -590,7 +590,7 @@ class CodeFactoryTest { # Subcontainer 0 ends # Data section (empty) """, - "RETURNCONTRACT is only a valid opcode in containers used for initcode"); + "incompatible_container_kind"); } private static void validCode(final String str) { diff --git a/evm/src/test/java/org/hyperledger/besu/evm/code/CodeV1Test.java b/evm/src/test/java/org/hyperledger/besu/evm/code/CodeV1Test.java index 08cbbedf75..9b7edf80b4 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/code/CodeV1Test.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/code/CodeV1Test.java @@ -192,7 +192,7 @@ class CodeV1Test { @ParameterizedTest @MethodSource("invalidCodeArguments") void testInvalidCode(final String code) { - assertValidation("Invalid Instruction 0x", code); + assertValidation("undefined_instruction", code); } private static Stream invalidCodeArguments() { @@ -214,7 +214,7 @@ class CodeV1Test { @ParameterizedTest @MethodSource("pushTruncatedImmediateArguments") void testPushTruncatedImmediate(final String code) { - assertValidation("No terminating instruction", code); + assertValidation("missing_stop_opcode", code); } private static Stream pushTruncatedImmediateArguments() { @@ -228,13 +228,13 @@ class CodeV1Test { @ParameterizedTest @ValueSource(strings = {"e0", "e000"}) void testRjumpTruncatedImmediate(final String code) { - assertValidation("Truncated relative jump offset", code); + assertValidation("truncated_instruction", code); } @ParameterizedTest @ValueSource(strings = {"6001e1", "6001e100"}) void testRjumpiTruncatedImmediate(final String code) { - assertValidation("Truncated relative jump offset", code); + assertValidation("truncated_instruction", code); } @ParameterizedTest @@ -248,7 +248,7 @@ class CodeV1Test { "6001e2030000000100" }) void testRjumpvTruncatedImmediate(final String code) { - assertValidation("Truncated jump table", code); + assertValidation("truncated_instruction", code); } @ParameterizedTest @@ -264,7 +264,7 @@ class CodeV1Test { "6001e200fff900" }) void testRjumpsOutOfBounds(final String code) { - assertValidation("Relative jump destination out of bounds", code); + assertValidation("invalid_rjump_destination", code); } @ParameterizedTest @@ -317,7 +317,7 @@ class CodeV1Test { "6001e2000005e2010000000000" }) void testRjumpsIntoImmediate(final String code) { - assertValidation("Relative jump destinations targets invalid immediate data", code); + assertValidation("invalid_rjump_destination", code); } private static Stream rjumpsIntoImmediateExtraArguments() { @@ -357,25 +357,25 @@ class CodeV1Test { @ParameterizedTest @ValueSource(strings = {"e3", "e300"}) void testCallFTruncated(final String code) { - assertValidation("Truncated CALLF", code); + assertValidation("truncated_instruction", code); } @ParameterizedTest @ValueSource(strings = {"e5", "e500"}) void testJumpCallFTruncated(final String code) { - assertValidation("Truncated JUMPF", code); + assertValidation("truncated_instruction", code); } @ParameterizedTest @ValueSource(strings = {"e30004", "e303ff", "e3ffff"}) void testCallFWrongSection(final String code) { - assertValidation("CALLF to non-existent section -", code, false, 3); + assertValidation("invalid_code_section_index", code, false, 3); } @ParameterizedTest @ValueSource(strings = {"e50004", "e503ff", "e5ffff"}) void testJumpFWrongSection(final String code) { - assertValidation("JUMPF to non-existent section -", code, false, 3); + assertValidation("invalid_code_section_index", code, false, 3); } @ParameterizedTest @@ -476,8 +476,13 @@ class CodeV1Test { EOFLayout eofLayout = EOFLayout.parseEOF(Bytes.fromHexString(sb)); CodeV1Validation validator = new CodeV1Validation(0xc000); - assertThat(validator.validateStack(sectionToTest, eofLayout, new WorkList(sectionCount))) - .isEqualTo(expectedError); + String validation = + validator.validateStack(sectionToTest, eofLayout, new WorkList(sectionCount)); + if (expectedError != null) { + assertThat(validation).contains(expectedError); + } else { + assertThat(validation).isNull(); + } } /** @@ -517,13 +522,10 @@ class CodeV1Test { static Stream stackUnderflow() { return Stream.of( Arguments.of( - "Stack underflow", - "Operation 0x50 requires stack of 1 but may only have 0 items", - 0, - List.of(List.of("50 00", 0, 0x80, 1))), + "Stack underflow", "stack_underflow", 0, List.of(List.of("50 00", 0, 0x80, 1))), Arguments.of( "double rjumpi", - "Operation 0xF3 requires stack of 2 but may only have 1 items", + "stack_underflow", 0, List.of(List.of("5f 5f e10005 5f 5f e10000 f3", 0, 0x80, 1)))); } @@ -533,17 +535,17 @@ class CodeV1Test { Arguments.of("RJUMP 0", null, 0, List.of(List.of("e00000 00", 0, 0x80, 0))), Arguments.of( "RJUMP 1 w/ dead code", - "Code that was not forward referenced in section 0x0 pc 3", + "unreachable_instructions", 0, List.of(List.of("e00001 43 00", 0, 0x80, 0))), Arguments.of( "RJUMP 2 w/ dead code", - "Code that was not forward referenced in section 0x0 pc 3", + "unreachable_instructions", 0, List.of(List.of("e00002 43 50 00", 0, 0x80, 0))), Arguments.of( "RJUMP 3 and -10", - "Code that was not forward referenced in section 0x0 pc 3", + "unreachable_instructions", 0, List.of(List.of("e00003 01 50 00 6001 6001 e0fff6", 0, 0x80, 2)))); } @@ -554,12 +556,12 @@ class CodeV1Test { Arguments.of("RJUMP -4", null, 0, List.of(List.of("5B e0fffc", 0, 0x80, 0))), Arguments.of( "RJUMP -4 unmatched stack", - "Stack minimum violation on backwards jump from 1 to 0, 1 != 1", + "stack_height_mismatch", 0, List.of(List.of("43 e0fffc", 0, 0x80, 0))), Arguments.of( "RJUMP -4 unmatched stack", - "Stack minimum violation on backwards jump from 2 to 1, 0 != 0", + "stack_height_mismatch", 0, List.of(List.of("43 50 e0fffc 00", 0, 0x80, 0))), Arguments.of( @@ -570,7 +572,7 @@ class CodeV1Test { "RJUMP -5 matched stack", null, 0, List.of(List.of("43 50 43 e0fffb", 0, 0x80, 1))), Arguments.of( "RJUMP -4 unmatched stack", - "Stack minimum violation on backwards jump from 3 to 2, 1 != 1", + "stack_height_mismatch", 0, List.of(List.of("43 50 43 e0fffc 50 00", 0, 0x80, 0)))); } @@ -611,17 +613,17 @@ class CodeV1Test { List.of(List.of("6001 e10003 30 50 00 30 30 30 50 50 50 00", 0, 0x80, 3))), Arguments.of( "RJUMPI Missing stack argument", - "Operation 0xE1 requires stack of 1 but may only have 0 items", + "stack_underflow", 0, List.of(List.of("e10000 00", 0, 0x80, 0))), Arguments.of( "Stack underflow one branch", - "Operation 0x02 requires stack of 2 but may only have 1 items", + "stack_underflow", 0, List.of(List.of("60ff 6001 e10002 50 00 02 50 00", 0, 0x80, 0))), Arguments.of( "Stack underflow another branch", - "Operation 0x02 requires stack of 2 but may only have 1 items", + "stack_underflow", 0, List.of(List.of("60ff 6001 e10002 02 00 19 50 00", 0, 0x80, 0))), // this depends on requiring stacks to be "clean" returns @@ -722,22 +724,22 @@ class CodeV1Test { List.of("e4", 2, 2, 2))), Arguments.of( "underflow", - "Operation 0xE3 requires stack of 1 but may only have 0 items", + "stack_underflow", 0, List.of(List.of("e30001 00", 0, 0x80, 0), List.of("e4", 1, 0, 0))), Arguments.of( "underflow 2", - "Operation 0xE3 requires stack of 2 but may only have 1 items", + "stack_underflow", 0, List.of(List.of("30 e30001 00", 0, 0x80, 0), List.of("e4", 2, 0, 2))), Arguments.of( "underflow 3", - "Operation 0xE3 requires stack of 1 but may only have 0 items", + "stack_underflow", 1, List.of(List.of("00", 0, 0x80, 0), List.of("50 e30001 e4", 1, 0, 1))), Arguments.of( "underflow 4", - "Operation 0xE3 requires stack of 3 but may only have 2 items", + "stack_underflow", 0, List.of( List.of("44 e30001 80 e30002 00", 0, 0x80, 0), @@ -816,32 +818,32 @@ class CodeV1Test { return Stream.of( Arguments.of( "Max stack not changed by unreachable code", - "Code that was not forward referenced in section 0x0 pc 3", + "unreachable_instructions", 0, List.of(List.of("30 50 00 30 30 30 50 50 50 00", 0, 0x80, 1))), Arguments.of( "Max stack not changed by unreachable code RETf", - "Code that was not forward referenced in section 0x0 pc 3", + "unreachable_instructions", 0, List.of(List.of("30 50 e4 30 30 30 50 50 50 00", 0, 0x80, 1))), Arguments.of( "Max stack not changed by unreachable code RJUMP", - "Code that was not forward referenced in section 0x0 pc 5", + "unreachable_instructions", 0, List.of(List.of("30 50 e00006 30 30 30 50 50 50 00", 0, 0x80, 1))), Arguments.of( "Stack underflow in unreachable code", - "Code that was not forward referenced in section 0x0 pc 3", + "unreachable_instructions", 0, List.of(List.of("30 50 00 50 00", 0, 0x80, 1))), Arguments.of( "Stack underflow in unreachable code RETF", - "Code that was not forward referenced in section 0x0 pc 3", + "unreachable_instructions", 0, List.of(List.of("30 50 e4 50 00", 0, 0x80, 1))), Arguments.of( "Stack underflow in unreachable code RJUMP", - "Code that was not forward referenced in section 0x0 pc 5", + "unreachable_instructions", 0, List.of(List.of("30 50 e00001 50 00", 0, 0x80, 1)))); } @@ -850,12 +852,12 @@ class CodeV1Test { return Stream.of( Arguments.of( "Stack height mismatch backwards", - "Stack minimum violation on backwards jump from 1 to 0, 1 != 1", + "stack_height_mismatch", 0, List.of(List.of("30 e0fffc00", 0, 0x80, 1))), Arguments.of( "Stack height mismatch forwards", - "Calculated max stack height (5) does not match reported stack height (2)", + "invalid_max_stack_height", 0, List.of(List.of("30e10003303030303000", 0, 0x80, 2)))); } @@ -867,7 +869,7 @@ class CodeV1Test { opcode -> Arguments.of( String.format("Invalid opcode %02x", opcode), - String.format("Invalid Instruction 0x%02x", opcode), + "undefined_instruction", 0, List.of(List.of(String.format("0x%02x", opcode), 0, 0x80, 0)))); } From 018225252397f059ee317c18bb07cb76e04f50c1 Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Tue, 20 Aug 2024 14:54:00 +1000 Subject: [PATCH 139/259] 5098 branch 24 throw checked exception to remove todos (#7481) * 5098: Add RpcErrorTypes Signed-off-by: Matilda Clerke --------- Signed-off-by: Matilda Clerke Signed-off-by: Matilda-Clerke Co-authored-by: Sally MacFarlane --- .../jsonrpc/methods/CliqueGetSigners.java | 3 ++- .../methods/CliqueGetSignersAtHash.java | 3 ++- .../clique/jsonrpc/methods/Discard.java | 3 ++- .../clique/jsonrpc/methods/Propose.java | 5 ++-- .../AbstractGetSignerMetricsMethod.java | 5 ++-- .../methods/IbftDiscardValidatorVote.java | 3 ++- .../methods/IbftGetValidatorsByBlockHash.java | 3 ++- .../IbftGetValidatorsByBlockNumber.java | 3 ++- .../methods/IbftProposeValidatorVote.java | 5 ++-- .../methods/QbftDiscardValidatorVote.java | 3 ++- .../methods/QbftGetValidatorsByBlockHash.java | 3 ++- .../QbftGetValidatorsByBlockNumber.java | 3 ++- .../methods/QbftProposeValidatorVote.java | 5 ++-- .../jsonrpc/internal/DebugReplayBlock.java | 3 ++- .../api/jsonrpc/internal/JsonRpcRequest.java | 10 ++++--- .../internal/JsonRpcRequestContext.java | 11 +++++--- .../methods/AbstractTraceByBlock.java | 3 ++- .../internal/methods/AdminChangeLogLevel.java | 5 ++-- .../methods/AdminGenerateLogBloomCache.java | 5 ++-- .../methods/AdminLogsRemoveCache.java | 5 ++-- .../methods/AdminLogsRepairCache.java | 3 ++- .../internal/methods/AdminModifyPeer.java | 3 ++- .../internal/methods/DebugAccountAt.java | 7 ++--- .../internal/methods/DebugAccountRange.java | 7 ++--- .../methods/DebugBatchSendRawTransaction.java | 13 +++++++-- .../internal/methods/DebugGetRawBlock.java | 3 ++- .../internal/methods/DebugGetRawHeader.java | 3 ++- .../internal/methods/DebugGetRawReceipts.java | 3 ++- .../methods/DebugGetRawTransaction.java | 3 ++- .../internal/methods/DebugSetHead.java | 3 ++- .../DebugStandardTraceBadBlockToFile.java | 5 ++-- .../DebugStandardTraceBlockToFile.java | 5 ++-- .../internal/methods/DebugStorageRangeAt.java | 11 ++++---- .../internal/methods/DebugTraceBlock.java | 7 ++--- .../methods/DebugTraceBlockByHash.java | 5 ++-- .../methods/DebugTraceBlockByNumber.java | 5 ++-- .../internal/methods/DebugTraceCall.java | 5 ++-- .../methods/DebugTraceTransaction.java | 5 ++-- .../api/jsonrpc/internal/methods/EthCall.java | 3 ++- .../internal/methods/EthFeeHistory.java | 7 ++--- .../internal/methods/EthGetBalance.java | 5 ++-- .../internal/methods/EthGetBlockByHash.java | 5 ++-- .../internal/methods/EthGetBlockByNumber.java | 5 ++-- .../internal/methods/EthGetBlockReceipts.java | 3 ++- .../EthGetBlockTransactionCountByHash.java | 3 ++- .../EthGetBlockTransactionCountByNumber.java | 3 ++- .../jsonrpc/internal/methods/EthGetCode.java | 5 ++-- .../internal/methods/EthGetFilterChanges.java | 3 ++- .../internal/methods/EthGetFilterLogs.java | 3 ++- .../jsonrpc/internal/methods/EthGetLogs.java | 3 ++- .../methods/EthGetMinerDataByBlockHash.java | 3 ++- .../methods/EthGetMinerDataByBlockNumber.java | 3 ++- .../jsonrpc/internal/methods/EthGetProof.java | 7 ++--- .../internal/methods/EthGetStorageAt.java | 7 ++--- .../EthGetTransactionByBlockHashAndIndex.java | 5 ++-- ...thGetTransactionByBlockNumberAndIndex.java | 5 ++-- .../methods/EthGetTransactionByHash.java | 3 ++- .../methods/EthGetTransactionCount.java | 7 ++--- .../methods/EthGetTransactionReceipt.java | 3 ++- .../EthGetUncleByBlockHashAndIndex.java | 5 ++-- .../EthGetUncleByBlockNumberAndIndex.java | 5 ++-- .../methods/EthGetUncleCountByBlockHash.java | 3 ++- .../EthGetUncleCountByBlockNumber.java | 10 ++++++- .../internal/methods/EthNewFilter.java | 3 ++- .../methods/EthSendRawTransaction.java | 3 ++- .../internal/methods/EthSubmitHashRate.java | 5 ++-- .../internal/methods/EthSubmitWork.java | 7 ++--- .../internal/methods/EthUninstallFilter.java | 3 ++- .../methods/JsonCallParameterUtil.java | 3 ++- .../methods/PluginsReloadConfiguration.java | 3 ++- .../jsonrpc/internal/methods/TraceBlock.java | 3 ++- .../jsonrpc/internal/methods/TraceCall.java | 3 ++- .../internal/methods/TraceCallMany.java | 3 ++- .../jsonrpc/internal/methods/TraceFilter.java | 3 ++- .../jsonrpc/internal/methods/TraceGet.java | 5 ++-- .../internal/methods/TraceRawTransaction.java | 5 ++-- .../methods/TraceReplayBlockTransactions.java | 5 ++-- .../internal/methods/TraceTransaction.java | 3 ++- .../TxPoolBesuPendingTransactions.java | 5 ++-- .../jsonrpc/internal/methods/Web3Sha3.java | 3 ++- .../AbstractEngineForkchoiceUpdated.java | 5 ++-- .../engine/AbstractEngineGetPayload.java | 3 ++- .../engine/AbstractEngineNewPayload.java | 7 ++--- .../engine/EngineExchangeCapabilities.java | 4 +-- ...EngineExchangeTransitionConfiguration.java | 3 ++- .../EngineGetPayloadBodiesByHashV1.java | 3 ++- .../EngineGetPayloadBodiesByRangeV1.java | 5 ++-- .../engine/EnginePreparePayloadDebug.java | 3 ++- .../miner/MinerChangeTargetGasLimit.java | 3 ++- .../methods/miner/MinerSetCoinbase.java | 3 ++- .../methods/miner/MinerSetExtraData.java | 7 +++-- .../methods/miner/MinerSetMinGasPrice.java | 3 ++- .../methods/miner/MinerSetMinPriorityFee.java | 6 ++--- .../PermAddAccountsToAllowlist.java | 3 ++- .../PermAddNodesToAllowlist.java | 3 ++- .../PermRemoveAccountsFromAllowlist.java | 3 ++- .../PermRemoveNodesFromAllowlist.java | 3 ++- .../internal/parameters/JsonRpcParameter.java | 27 +++++++------------ .../privacy/methods/PrivGetFilterChanges.java | 5 ++-- .../privacy/methods/PrivGetFilterLogs.java | 5 ++-- .../privacy/methods/PrivUninstallFilter.java | 5 ++-- .../eea/AbstractEeaSendRawTransaction.java | 3 ++- .../privacy/methods/priv/PrivCall.java | 7 ++--- .../methods/priv/PrivCreatePrivacyGroup.java | 3 ++- .../methods/priv/PrivDebugGetStateRoot.java | 5 ++-- .../methods/priv/PrivDeletePrivacyGroup.java | 3 ++- .../priv/PrivDistributeRawTransaction.java | 3 ++- .../methods/priv/PrivFindPrivacyGroup.java | 3 ++- .../privacy/methods/priv/PrivGetCode.java | 7 ++--- .../priv/PrivGetEeaTransactionCount.java | 7 ++--- .../privacy/methods/priv/PrivGetLogs.java | 3 ++- .../priv/PrivGetPrivateTransaction.java | 3 ++- .../methods/priv/PrivGetTransactionCount.java | 5 ++-- .../priv/PrivGetTransactionReceipt.java | 3 ++- .../privacy/methods/priv/PrivNewFilter.java | 7 ++--- .../methods/priv/PrivTraceTransaction.java | 22 +++++++++++++-- .../privx/PrivxFindFlexiblePrivacyGroup.java | 3 ++- .../request/SubscriptionRequestMapper.java | 19 ++++++------- .../TxPoolBesuPendingTransactionsTest.java | 8 +++--- .../engine/EnginePreparePayloadDebugTest.java | 5 ++-- .../retesteth/methods/TestGetLogHash.java | 3 ++- .../retesteth/methods/TestImportRawBlock.java | 3 ++- .../retesteth/methods/TestMineBlocks.java | 3 ++- .../methods/TestModifyTimestamp.java | 3 ++- .../retesteth/methods/TestRewindToBlock.java | 3 ++- .../ethereum/stratum/Stratum1Protocol.java | 15 ++++++++--- .../ethereum/stratum/StratumProtocol.java | 5 ++-- 127 files changed, 393 insertions(+), 234 deletions(-) diff --git a/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/CliqueGetSigners.java b/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/CliqueGetSigners.java index 813c296098..057fb30ee5 100644 --- a/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/CliqueGetSigners.java +++ b/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/CliqueGetSigners.java @@ -20,6 +20,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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; @@ -71,7 +72,7 @@ public class CliqueGetSigners implements JsonRpcMethod { final Optional blockParameter; try { blockParameter = request.getOptionalParameter(0, BlockParameter.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid block parameter (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e); } diff --git a/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/CliqueGetSignersAtHash.java b/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/CliqueGetSignersAtHash.java index c683b9d485..908ff9f412 100644 --- a/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/CliqueGetSignersAtHash.java +++ b/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/CliqueGetSignersAtHash.java @@ -20,6 +20,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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; @@ -71,7 +72,7 @@ public class CliqueGetSignersAtHash implements JsonRpcMethod { final Hash hash; try { hash = request.getRequiredParameter(0, Hash.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid block hash parameter (index 0)", RpcErrorType.INVALID_BLOCK_HASH_PARAMS, e); } diff --git a/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/Discard.java b/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/Discard.java index 467164e8c0..da3214b1ef 100644 --- a/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/Discard.java +++ b/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/Discard.java @@ -22,6 +22,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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.api.jsonrpc.internal.response.RpcErrorType; @@ -51,7 +52,7 @@ public class Discard implements JsonRpcMethod { final Address address; try { address = requestContext.getRequiredParameter(0, Address.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid address parameter (index 0)", RpcErrorType.INVALID_ADDRESS_PARAMS, e); } diff --git a/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/Propose.java b/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/Propose.java index 6e198a84fe..26ab19c988 100644 --- a/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/Propose.java +++ b/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/Propose.java @@ -23,6 +23,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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; @@ -53,14 +54,14 @@ public class Propose implements JsonRpcMethod { final Address address; try { address = requestContext.getRequiredParameter(0, Address.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid address parameter (index 0)", RpcErrorType.INVALID_ADDRESS_PARAMS, e); } final Boolean auth; try { auth = requestContext.getRequiredParameter(1, Boolean.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid auth parameter (index 1)", RpcErrorType.INVALID_PROPOSAL_PARAMS, e); } diff --git a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/jsonrpc/AbstractGetSignerMetricsMethod.java b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/jsonrpc/AbstractGetSignerMetricsMethod.java index 7ef368fb76..e3785976af 100644 --- a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/jsonrpc/AbstractGetSignerMetricsMethod.java +++ b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/jsonrpc/AbstractGetSignerMetricsMethod.java @@ -20,6 +20,7 @@ import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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; @@ -70,14 +71,14 @@ public abstract class AbstractGetSignerMetricsMethod { final Optional startBlockParameter; try { startBlockParameter = requestContext.getOptionalParameter(0, BlockParameter.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid start block parameter (index 0)", RpcErrorType.INVALID_BLOCK_NUMBER_PARAMS, e); } final Optional endBlockParameter; try { endBlockParameter = requestContext.getOptionalParameter(1, BlockParameter.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid end block parameter (index 1)", RpcErrorType.INVALID_BLOCK_NUMBER_PARAMS, e); } diff --git a/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftDiscardValidatorVote.java b/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftDiscardValidatorVote.java index 7e6c001088..8953468937 100644 --- a/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftDiscardValidatorVote.java +++ b/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftDiscardValidatorVote.java @@ -22,6 +22,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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.api.jsonrpc.internal.response.RpcErrorType; @@ -55,7 +56,7 @@ public class IbftDiscardValidatorVote implements JsonRpcMethod { final Address validatorAddress; try { validatorAddress = requestContext.getRequiredParameter(0, Address.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid validator address parameter (index 0)", RpcErrorType.INVALID_ADDRESS_PARAMS, e); } diff --git a/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftGetValidatorsByBlockHash.java b/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftGetValidatorsByBlockHash.java index 3c3346cd43..dfefe22c53 100644 --- a/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftGetValidatorsByBlockHash.java +++ b/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftGetValidatorsByBlockHash.java @@ -20,6 +20,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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.api.jsonrpc.internal.response.RpcErrorType; @@ -66,7 +67,7 @@ public class IbftGetValidatorsByBlockHash implements JsonRpcMethod { final Hash hash; try { hash = request.getRequiredParameter(0, Hash.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid block hash parameter (index 0)", RpcErrorType.INVALID_BLOCK_HASH_PARAMS, e); } diff --git a/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftGetValidatorsByBlockNumber.java b/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftGetValidatorsByBlockNumber.java index 7992f0918c..a878ebc66e 100644 --- a/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftGetValidatorsByBlockNumber.java +++ b/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftGetValidatorsByBlockNumber.java @@ -21,6 +21,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonR import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.AbstractBlockParameterMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; import org.hyperledger.besu.ethereum.core.BlockHeader; @@ -54,7 +55,7 @@ public class IbftGetValidatorsByBlockNumber extends AbstractBlockParameterMethod protected BlockParameter blockParameter(final JsonRpcRequestContext request) { try { return request.getRequiredParameter(0, BlockParameter.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid block parameter (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e); } diff --git a/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftProposeValidatorVote.java b/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftProposeValidatorVote.java index 9364422c57..f010633e63 100644 --- a/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftProposeValidatorVote.java +++ b/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftProposeValidatorVote.java @@ -23,6 +23,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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.api.jsonrpc.internal.response.RpcErrorType; @@ -56,14 +57,14 @@ public class IbftProposeValidatorVote implements JsonRpcMethod { final Address validatorAddress; try { validatorAddress = requestContext.getRequiredParameter(0, Address.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid address parameter (index 0)", RpcErrorType.INVALID_ADDRESS_PARAMS, e); } final Boolean add; try { add = requestContext.getRequiredParameter(1, Boolean.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid vote type parameter (index 1)", RpcErrorType.INVALID_VOTE_TYPE_PARAMS, e); } diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftDiscardValidatorVote.java b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftDiscardValidatorVote.java index 98856caaa6..66e9cf6014 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftDiscardValidatorVote.java +++ b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftDiscardValidatorVote.java @@ -20,6 +20,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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; @@ -53,7 +54,7 @@ public class QbftDiscardValidatorVote implements JsonRpcMethod { final Address validatorAddress; try { validatorAddress = requestContext.getRequiredParameter(0, Address.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid validator address parameter (index 0)", RpcErrorType.INVALID_ADDRESS_PARAMS, diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftGetValidatorsByBlockHash.java b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftGetValidatorsByBlockHash.java index e991f7f355..75000bde5d 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftGetValidatorsByBlockHash.java +++ b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftGetValidatorsByBlockHash.java @@ -21,6 +21,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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.api.jsonrpc.internal.response.RpcErrorType; @@ -67,7 +68,7 @@ public class QbftGetValidatorsByBlockHash implements JsonRpcMethod { final Hash hash; try { hash = request.getRequiredParameter(0, Hash.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid block hash parameter (index 0)", RpcErrorType.INVALID_BLOCK_HASH_PARAMS, e); } diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftGetValidatorsByBlockNumber.java b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftGetValidatorsByBlockNumber.java index 7a64a7ab22..b33490f0c2 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftGetValidatorsByBlockNumber.java +++ b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftGetValidatorsByBlockNumber.java @@ -22,6 +22,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonR import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.AbstractBlockParameterMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; import org.hyperledger.besu.ethereum.core.BlockHeader; @@ -54,7 +55,7 @@ public class QbftGetValidatorsByBlockNumber extends AbstractBlockParameterMethod protected BlockParameter blockParameter(final JsonRpcRequestContext request) { try { return request.getRequiredParameter(0, BlockParameter.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid block parameter (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e); } diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftProposeValidatorVote.java b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftProposeValidatorVote.java index aa3a8b267e..e6ad3ff6a8 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftProposeValidatorVote.java +++ b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftProposeValidatorVote.java @@ -21,6 +21,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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; @@ -54,7 +55,7 @@ public class QbftProposeValidatorVote implements JsonRpcMethod { final Address validatorAddress; try { validatorAddress = requestContext.getRequiredParameter(0, Address.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid validator address parameter (index 0)", RpcErrorType.INVALID_ADDRESS_PARAMS, @@ -63,7 +64,7 @@ public class QbftProposeValidatorVote implements JsonRpcMethod { final Boolean add; try { add = requestContext.getRequiredParameter(1, Boolean.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid vote type parameter (index 1)", RpcErrorType.INVALID_VOTE_TYPE_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/DebugReplayBlock.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/DebugReplayBlock.java index 6dbf9f586f..ab53e415dd 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/DebugReplayBlock.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/DebugReplayBlock.java @@ -22,6 +22,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.AbstractBlockParameterMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; @@ -60,7 +61,7 @@ public class DebugReplayBlock extends AbstractBlockParameterMethod { protected BlockParameter blockParameter(final JsonRpcRequestContext request) { try { return request.getRequiredParameter(0, BlockParameter.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid block parameter (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/JsonRpcRequest.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/JsonRpcRequest.java index 06b495624e..a7c1e15e01 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/JsonRpcRequest.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/JsonRpcRequest.java @@ -16,6 +16,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcRequestException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import java.util.Arrays; @@ -132,15 +133,18 @@ public class JsonRpcRequest { return Objects.hash(id, method, Arrays.hashCode(params), version, isNotification); } - public T getRequiredParameter(final int index, final Class paramClass) { + public T getRequiredParameter(final int index, final Class paramClass) + throws JsonRpcParameterException { return parameterAccessor.required(params, index, paramClass); } - public Optional getOptionalParameter(final int index, final Class paramClass) { + public Optional getOptionalParameter(final int index, final Class paramClass) + throws JsonRpcParameterException { return parameterAccessor.optional(params, index, paramClass); } - public Optional> getOptionalList(final int index, final Class paramClass) { + public Optional> getOptionalList(final int index, final Class paramClass) + throws JsonRpcParameterException { return parameterAccessor.optionalList(params, index, paramClass); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/JsonRpcRequestContext.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/JsonRpcRequestContext.java index b489259eb8..cc96384005 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/JsonRpcRequestContext.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/JsonRpcRequestContext.java @@ -14,6 +14,8 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.internal; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; + import java.util.List; import java.util.Objects; import java.util.Optional; @@ -61,15 +63,18 @@ public class JsonRpcRequestContext { return user; } - public T getRequiredParameter(final int index, final Class paramClass) { + public T getRequiredParameter(final int index, final Class paramClass) + throws JsonRpcParameterException { return jsonRpcRequest.getRequiredParameter(index, paramClass); } - public Optional getOptionalParameter(final int index, final Class paramClass) { + public Optional getOptionalParameter(final int index, final Class paramClass) + throws JsonRpcParameterException { return jsonRpcRequest.getOptionalParameter(index, paramClass); } - public Optional> getOptionalList(final int index, final Class listOf) { + public Optional> getOptionalList(final int index, final Class listOf) + throws JsonRpcParameterException { return jsonRpcRequest.getOptionalList(index, listOf); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AbstractTraceByBlock.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AbstractTraceByBlock.java index a596521175..36991796b5 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AbstractTraceByBlock.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AbstractTraceByBlock.java @@ -19,6 +19,7 @@ import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.Trac import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.TraceTypeParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.TransactionTrace; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; @@ -67,7 +68,7 @@ public abstract class AbstractTraceByBlock extends AbstractBlockParameterMethod final Optional maybeBlockParameter; try { maybeBlockParameter = request.getOptionalParameter(2, BlockParameter.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid block parameter (index 2)", RpcErrorType.INVALID_BLOCK_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminChangeLogLevel.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminChangeLogLevel.java index 3cfd524c14..6081f8f340 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminChangeLogLevel.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminChangeLogLevel.java @@ -17,6 +17,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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; @@ -47,7 +48,7 @@ public class AdminChangeLogLevel implements JsonRpcMethod { final String logLevel; try { logLevel = requestContext.getRequiredParameter(0, String.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid log level parameter (index 0)", RpcErrorType.INVALID_LOG_LEVEL_PARAMS, e); } @@ -58,7 +59,7 @@ public class AdminChangeLogLevel implements JsonRpcMethod { final Optional optionalLogFilters; try { optionalLogFilters = requestContext.getOptionalParameter(1, String[].class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid log filter parameters (index 1)", RpcErrorType.INVALID_LOG_FILTER_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminGenerateLogBloomCache.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminGenerateLogBloomCache.java index 437f7f5821..cad60660c3 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminGenerateLogBloomCache.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminGenerateLogBloomCache.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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.api.jsonrpc.internal.response.RpcErrorType; @@ -43,7 +44,7 @@ public class AdminGenerateLogBloomCache implements JsonRpcMethod { final Optional startBlockParam; try { startBlockParam = requestContext.getOptionalParameter(0, BlockParameter.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid start block parameter (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e); } @@ -60,7 +61,7 @@ public class AdminGenerateLogBloomCache implements JsonRpcMethod { final Optional stopBlockParam; try { stopBlockParam = requestContext.getOptionalParameter(1, BlockParameter.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid stop block parameter (index 1)", RpcErrorType.INVALID_BLOCK_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminLogsRemoveCache.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminLogsRemoveCache.java index 94430c526f..c7b67b2827 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminLogsRemoveCache.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminLogsRemoveCache.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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; @@ -46,14 +47,14 @@ public class AdminLogsRemoveCache implements JsonRpcMethod { final Optional startBlockParameter; try { startBlockParameter = requestContext.getOptionalParameter(0, BlockParameter.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid start block parameter (index 0)", RpcErrorType.INVALID_BLOCK_NUMBER_PARAMS, e); } final Optional stopBlockParameter; try { stopBlockParameter = requestContext.getOptionalParameter(1, BlockParameter.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid stop block parameter (index 1)", RpcErrorType.INVALID_BLOCK_NUMBER_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminLogsRepairCache.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminLogsRepairCache.java index 7336faff0e..650a9f74eb 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminLogsRepairCache.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminLogsRepairCache.java @@ -17,6 +17,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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.api.jsonrpc.internal.response.RpcErrorType; @@ -43,7 +44,7 @@ public class AdminLogsRepairCache implements JsonRpcMethod { final Optional blockNumber; try { blockNumber = requestContext.getOptionalParameter(0, Long.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid block number parameter (index 0)", RpcErrorType.INVALID_BLOCK_NUMBER_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminModifyPeer.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminModifyPeer.java index f1c134ed91..5b70668c32 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminModifyPeer.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminModifyPeer.java @@ -15,6 +15,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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.RpcErrorType; @@ -65,7 +66,7 @@ public abstract class AdminModifyPeer implements JsonRpcMethod { } catch (final P2PDisabledException e) { return new JsonRpcErrorResponse( requestContext.getRequest().getId(), RpcErrorType.P2P_DISABLED); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { return new JsonRpcErrorResponse( requestContext.getRequest().getId(), RpcErrorType.INVALID_ENODE_PARAMS); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugAccountAt.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugAccountAt.java index 602f3de3e0..318d8a0b8d 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugAccountAt.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugAccountAt.java @@ -20,6 +20,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameterOrBlockHash; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.BlockTrace; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.BlockTracer; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.Tracer; @@ -69,7 +70,7 @@ public class DebugAccountAt extends AbstractBlockParameterOrBlockHashMethod { final JsonRpcRequestContext requestContext) { try { return requestContext.getRequiredParameter(0, BlockParameterOrBlockHash.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid block or block hash parameter (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e); } @@ -81,7 +82,7 @@ public class DebugAccountAt extends AbstractBlockParameterOrBlockHashMethod { final Integer txIndex; try { txIndex = requestContext.getRequiredParameter(1, Integer.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid transaction index parameter (index 1)", RpcErrorType.INVALID_TRANSACTION_INDEX_PARAMS, @@ -90,7 +91,7 @@ public class DebugAccountAt extends AbstractBlockParameterOrBlockHashMethod { final Address address; try { address = requestContext.getRequiredParameter(2, Address.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid address parameter (index 2)", RpcErrorType.INVALID_ADDRESS_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugAccountRange.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugAccountRange.java index fc787031da..852972f4d8 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugAccountRange.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugAccountRange.java @@ -19,6 +19,7 @@ import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameterOrBlockHash; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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.api.jsonrpc.internal.response.RpcErrorType; @@ -62,7 +63,7 @@ public class DebugAccountRange implements JsonRpcMethod { try { blockParameterOrBlockHash = requestContext.getRequiredParameter(0, BlockParameterOrBlockHash.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid block parameter or block hash parameter (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, @@ -71,14 +72,14 @@ public class DebugAccountRange implements JsonRpcMethod { final String addressHash; try { addressHash = requestContext.getRequiredParameter(2, String.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid address hash parameter (index 2)", RpcErrorType.INVALID_ADDRESS_HASH_PARAMS, e); } final int maxResults; try { maxResults = requestContext.getRequiredParameter(3, Integer.TYPE); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid max results parameter (index 3)", RpcErrorType.INVALID_MAX_RESULTS_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugBatchSendRawTransaction.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugBatchSendRawTransaction.java index 83553dc874..d78f9fb6be 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugBatchSendRawTransaction.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugBatchSendRawTransaction.java @@ -16,8 +16,11 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.util.DomainObjectDecodeUtils; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool; import org.hyperledger.besu.ethereum.mainnet.ValidationResult; @@ -56,9 +59,15 @@ public class DebugBatchSendRawTransaction implements JsonRpcMethod { final List executionStatuses = new ArrayList<>(); IntStream.range(0, requestContext.getRequest().getParamLength()) .forEach( - i -> + i -> { + try { executionStatuses.add( - process(i, requestContext.getRequiredParameter(i, String.class)))); + process(i, requestContext.getRequiredParameter(i, String.class))); + } catch (JsonRpcParameterException e) { + throw new InvalidJsonRpcParameters( + "Invalid parameter (index " + i + ")", RpcErrorType.INVALID_PARAMS, e); + } + }); return new JsonRpcSuccessResponse(requestContext.getRequest().getId(), executionStatuses); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugGetRawBlock.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugGetRawBlock.java index 28d886bd81..c9097583e3 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugGetRawBlock.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugGetRawBlock.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; @@ -40,7 +41,7 @@ public class DebugGetRawBlock extends AbstractBlockParameterMethod { protected BlockParameter blockParameter(final JsonRpcRequestContext request) { try { return request.getRequiredParameter(0, BlockParameter.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid block parameter (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugGetRawHeader.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugGetRawHeader.java index e2f2c89e1a..8e4f9ce6ea 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugGetRawHeader.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugGetRawHeader.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; @@ -40,7 +41,7 @@ public class DebugGetRawHeader extends AbstractBlockParameterMethod { protected BlockParameter blockParameter(final JsonRpcRequestContext request) { try { return request.getRequiredParameter(0, BlockParameter.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid block parameter (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugGetRawReceipts.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugGetRawReceipts.java index cddba5086e..1c634c3c73 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugGetRawReceipts.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugGetRawReceipts.java @@ -19,6 +19,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameterOrBlockHash; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; import org.hyperledger.besu.ethereum.core.TransactionReceipt; @@ -44,7 +45,7 @@ public class DebugGetRawReceipts extends AbstractBlockParameterOrBlockHashMethod final JsonRpcRequestContext request) { try { return request.getRequiredParameter(0, BlockParameterOrBlockHash.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid block or block hash parameter (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugGetRawTransaction.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugGetRawTransaction.java index d6ede25b27..2b1e756d22 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugGetRawTransaction.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugGetRawTransaction.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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.api.jsonrpc.internal.response.RpcErrorType; @@ -43,7 +44,7 @@ public class DebugGetRawTransaction implements JsonRpcMethod { final Hash txHash; try { txHash = requestContext.getRequiredParameter(0, Hash.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid transaction hash parameter (index 0)", RpcErrorType.INVALID_TRANSACTION_HASH_PARAMS, diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugSetHead.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugSetHead.java index a3b423675f..7958f8e759 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugSetHead.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugSetHead.java @@ -22,6 +22,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; @@ -47,7 +48,7 @@ public class DebugSetHead extends AbstractBlockParameterMethod { protected BlockParameter blockParameter(final JsonRpcRequestContext request) { try { return request.getRequiredParameter(0, BlockParameter.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid block parameter (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStandardTraceBadBlockToFile.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStandardTraceBadBlockToFile.java index 2d0c4cac4e..b49c94fd6a 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStandardTraceBadBlockToFile.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStandardTraceBadBlockToFile.java @@ -19,6 +19,7 @@ import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.TransactionTraceParams; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.TransactionTracer; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; @@ -56,14 +57,14 @@ public class DebugStandardTraceBadBlockToFile extends DebugStandardTraceBlockToF final Hash blockHash; try { blockHash = requestContext.getRequiredParameter(0, Hash.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid block hash parameter (index 0)", RpcErrorType.INVALID_BLOCK_HASH_PARAMS, e); } final Optional transactionTraceParams; try { transactionTraceParams = requestContext.getOptionalParameter(1, TransactionTraceParams.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid transaction trace parameters (index 1)", RpcErrorType.INVALID_TRANSACTION_TRACE_PARAMS, diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStandardTraceBlockToFile.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStandardTraceBlockToFile.java index 5fba2911bd..b3bb32370e 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStandardTraceBlockToFile.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStandardTraceBlockToFile.java @@ -20,6 +20,7 @@ import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.TransactionTraceParams; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.Tracer; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.TransactionTracer; @@ -63,14 +64,14 @@ public class DebugStandardTraceBlockToFile implements JsonRpcMethod { final Hash blockHash; try { blockHash = requestContext.getRequiredParameter(0, Hash.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid block hash parameter (index 0)", RpcErrorType.INVALID_BLOCK_HASH_PARAMS, e); } final Optional transactionTraceParams; try { transactionTraceParams = requestContext.getOptionalParameter(1, TransactionTraceParams.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid transaction trace parameters (index 1)", RpcErrorType.INVALID_TRANSACTION_TRACE_PARAMS, diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStorageRangeAt.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStorageRangeAt.java index 5aabff4b57..1fde6610ef 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStorageRangeAt.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugStorageRangeAt.java @@ -20,6 +20,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameterOrBlockHash; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.BlockReplay; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.Tracer; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.Tracer.TraceableState; @@ -73,14 +74,14 @@ public class DebugStorageRangeAt implements JsonRpcMethod { try { blockParameterOrBlockHash = requestContext.getRequiredParameter(0, BlockParameterOrBlockHash.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid block or block hash parameter (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e); } final int transactionIndex; try { transactionIndex = requestContext.getRequiredParameter(1, Integer.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid transaction index parameter (index 1)", RpcErrorType.INVALID_TRANSACTION_INDEX_PARAMS, @@ -89,21 +90,21 @@ public class DebugStorageRangeAt implements JsonRpcMethod { final Address accountAddress; try { accountAddress = requestContext.getRequiredParameter(2, Address.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid account address parameter (index 2)", RpcErrorType.INVALID_ADDRESS_PARAMS, e); } final Hash startKey; try { startKey = Hash.fromHexStringLenient(requestContext.getRequiredParameter(3, String.class)); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid data start hash parameter (index 3)", RpcErrorType.INVALID_DATA_HASH_PARAMS, e); } final int limit; try { limit = requestContext.getRequiredParameter(4, Integer.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid limit parameter (index 4)", RpcErrorType.INVALID_TRANSACTION_LIMIT_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlock.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlock.java index 2d668c7f22..edfb816bb9 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlock.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlock.java @@ -17,6 +17,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.TransactionTraceParams; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.BlockTrace; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.BlockTracer; @@ -65,15 +66,15 @@ public class DebugTraceBlock implements JsonRpcMethod { @Override public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { - final String input = requestContext.getRequiredParameter(0, String.class); final Block block; try { + final String input = requestContext.getRequiredParameter(0, String.class); block = Block.readFrom(RLP.input(Bytes.fromHexString(input)), this.blockHeaderFunctions); } catch (final RLPException e) { LOG.debug("Failed to parse block RLP (index 0)", e); return new JsonRpcErrorResponse( requestContext.getRequest().getId(), RpcErrorType.INVALID_BLOCK_PARAMS); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid block params (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e); } @@ -84,7 +85,7 @@ public class DebugTraceBlock implements JsonRpcMethod { .getOptionalParameter(1, TransactionTraceParams.class) .map(TransactionTraceParams::traceOptions) .orElse(TraceOptions.DEFAULT); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid transaction trace parameter (index 1)", RpcErrorType.INVALID_TRANSACTION_TRACE_PARAMS, diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockByHash.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockByHash.java index 4c1d3bfc2a..d98e8abd8d 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockByHash.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockByHash.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.TransactionTraceParams; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.BlockTrace; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.BlockTracer; @@ -55,7 +56,7 @@ public class DebugTraceBlockByHash implements JsonRpcMethod { final Hash blockHash; try { blockHash = requestContext.getRequiredParameter(0, Hash.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid block hash parameter (index 0)", RpcErrorType.INVALID_BLOCK_HASH_PARAMS, e); } @@ -66,7 +67,7 @@ public class DebugTraceBlockByHash implements JsonRpcMethod { .getOptionalParameter(1, TransactionTraceParams.class) .map(TransactionTraceParams::traceOptions) .orElse(TraceOptions.DEFAULT); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid transaction trace parameter (index 1)", RpcErrorType.INVALID_TRANSACTION_TRACE_PARAMS, diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockByNumber.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockByNumber.java index eb90edabb9..99c96c99be 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockByNumber.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockByNumber.java @@ -19,6 +19,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.TransactionTraceParams; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.BlockTrace; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.BlockTracer; @@ -51,7 +52,7 @@ public class DebugTraceBlockByNumber extends AbstractBlockParameterMethod { protected BlockParameter blockParameter(final JsonRpcRequestContext request) { try { return request.getRequiredParameter(0, BlockParameter.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid block parameter (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e); } @@ -68,7 +69,7 @@ public class DebugTraceBlockByNumber extends AbstractBlockParameterMethod { .getOptionalParameter(1, TransactionTraceParams.class) .map(TransactionTraceParams::traceOptions) .orElse(TraceOptions.DEFAULT); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid transaction trace parameter (index 1)", RpcErrorType.INVALID_TRANSACTION_TRACE_PARAMS, diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceCall.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceCall.java index d309f8dfdd..e808e79ddc 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceCall.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceCall.java @@ -20,6 +20,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.TransactionTraceParams; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.TransactionTrace; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError; @@ -60,7 +61,7 @@ public class DebugTraceCall extends AbstractTraceCall { .getOptionalParameter(2, TransactionTraceParams.class) .map(TransactionTraceParams::traceOptions) .orElse(TraceOptions.DEFAULT); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid transaction trace parameter (index 2)", RpcErrorType.INVALID_TRANSACTION_TRACE_PARAMS, @@ -73,7 +74,7 @@ public class DebugTraceCall extends AbstractTraceCall { final Optional maybeBlockParameter; try { maybeBlockParameter = request.getOptionalParameter(1, BlockParameter.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid block parameter (index 1)", RpcErrorType.INVALID_BLOCK_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceTransaction.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceTransaction.java index 8ec14dc4ad..1e85e6530a 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceTransaction.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceTransaction.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.TransactionTraceParams; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.Tracer; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.TransactionTracer; @@ -53,7 +54,7 @@ public class DebugTraceTransaction implements JsonRpcMethod { final Hash hash; try { hash = requestContext.getRequiredParameter(0, Hash.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid transaction hash parameter (index 0)", RpcErrorType.INVALID_TRANSACTION_HASH_PARAMS, @@ -69,7 +70,7 @@ public class DebugTraceTransaction implements JsonRpcMethod { .getOptionalParameter(1, TransactionTraceParams.class) .map(TransactionTraceParams::traceOptions) .orElse(TraceOptions.DEFAULT); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid transaction trace parameter (index 1)", RpcErrorType.INVALID_TRANSACTION_TRACE_PARAMS, diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCall.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCall.java index a08b17dfc6..0e0318f9c2 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCall.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCall.java @@ -25,6 +25,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameterOrBlockHash; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonCallParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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; @@ -60,7 +61,7 @@ public class EthCall extends AbstractBlockParameterOrBlockHashMethod { final JsonRpcRequestContext request) { try { return request.getRequiredParameter(1, BlockParameterOrBlockHash.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid block or block hash parameters (index 1)", RpcErrorType.INVALID_BLOCK_PARAMS, e); } 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 01a0802279..b95746dad9 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 @@ -24,6 +24,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.UnsignedIntParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; @@ -91,7 +92,7 @@ public class EthFeeHistory implements JsonRpcMethod { final int blockCount; try { blockCount = request.getRequiredParameter(0, UnsignedIntParameter.class).getValue(); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid block count parameter (index 0)", RpcErrorType.INVALID_BLOCK_COUNT_PARAMS, e); } @@ -101,7 +102,7 @@ public class EthFeeHistory implements JsonRpcMethod { final BlockParameter highestBlock; try { highestBlock = request.getRequiredParameter(1, BlockParameter.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid highest block parameter (index 1)", RpcErrorType.INVALID_BLOCK_PARAMS, e); } @@ -109,7 +110,7 @@ public class EthFeeHistory implements JsonRpcMethod { final Optional> maybeRewardPercentiles; try { maybeRewardPercentiles = request.getOptionalParameter(2, Double[].class).map(Arrays::asList); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid reward percentiles parameter (index 2)", RpcErrorType.INVALID_REWARD_PERCENTILES_PARAMS, diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBalance.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBalance.java index e863626c96..cb1d879a05 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBalance.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBalance.java @@ -20,6 +20,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameterOrBlockHash; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.Quantity; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; @@ -45,7 +46,7 @@ public class EthGetBalance extends AbstractBlockParameterOrBlockHashMethod { final JsonRpcRequestContext request) { try { return request.getRequiredParameter(1, BlockParameterOrBlockHash.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid block or block hash parameter (index 1)", RpcErrorType.INVALID_BLOCK_PARAMS, e); } @@ -56,7 +57,7 @@ public class EthGetBalance extends AbstractBlockParameterOrBlockHashMethod { final Address address; try { address = request.getRequiredParameter(0, Address.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid address parameter (index 0)", RpcErrorType.INVALID_ADDRESS_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByHash.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByHash.java index 875daea7f1..f5b633253a 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByHash.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByHash.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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.api.jsonrpc.internal.response.RpcErrorType; @@ -64,7 +65,7 @@ public class EthGetBlockByHash implements JsonRpcMethod { final Hash hash; try { hash = request.getRequiredParameter(0, Hash.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid block hash parameter (index 0)", RpcErrorType.INVALID_BLOCK_HASH_PARAMS, e); } @@ -95,7 +96,7 @@ public class EthGetBlockByHash implements JsonRpcMethod { private boolean isCompleteTransactions(final JsonRpcRequestContext requestContext) { try { return requestContext.getRequiredParameter(1, Boolean.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid return complete transaction parameter (index 1)", RpcErrorType.INVALID_RETURN_COMPLETE_TRANSACTION_PARAMS, diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByNumber.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByNumber.java index 8e0954144d..0a26a24ee3 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByNumber.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockByNumber.java @@ -19,6 +19,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.BlockResult; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.BlockResultFactory; @@ -66,7 +67,7 @@ public class EthGetBlockByNumber extends AbstractBlockParameterMethod { protected BlockParameter blockParameter(final JsonRpcRequestContext request) { try { return request.getRequiredParameter(0, BlockParameter.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid block parameter (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e); } @@ -126,7 +127,7 @@ public class EthGetBlockByNumber extends AbstractBlockParameterMethod { private boolean isCompleteTransactions(final JsonRpcRequestContext request) { try { return request.getRequiredParameter(1, Boolean.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid return complete transaction parameter (index 1)", RpcErrorType.INVALID_RETURN_COMPLETE_TRANSACTION_PARAMS, 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 d9592db8c1..a113e4ee8e 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 @@ -19,6 +19,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameterOrBlockHash; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.BlockReceiptsResult; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.TransactionReceiptResult; @@ -57,7 +58,7 @@ public class EthGetBlockReceipts extends AbstractBlockParameterOrBlockHashMethod final JsonRpcRequestContext request) { try { return request.getRequiredParameter(0, BlockParameterOrBlockHash.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid block or block hash parameters (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockTransactionCountByHash.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockTransactionCountByHash.java index e1fbd79086..fc7c3cc70c 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockTransactionCountByHash.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockTransactionCountByHash.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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.api.jsonrpc.internal.response.RpcErrorType; @@ -42,7 +43,7 @@ public class EthGetBlockTransactionCountByHash implements JsonRpcMethod { final Hash hash; try { hash = requestContext.getRequiredParameter(0, Hash.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid block header hash parameter (index 0)", RpcErrorType.INVALID_BLOCK_HASH_PARAMS, diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockTransactionCountByNumber.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockTransactionCountByNumber.java index 2a068a6174..95bd7cc507 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockTransactionCountByNumber.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetBlockTransactionCountByNumber.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.Quantity; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; @@ -37,7 +38,7 @@ public class EthGetBlockTransactionCountByNumber extends AbstractBlockParameterM protected BlockParameter blockParameter(final JsonRpcRequestContext request) { try { return request.getRequiredParameter(0, BlockParameter.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid block parameters (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetCode.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetCode.java index 8a9881a012..0c9194b0b3 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetCode.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetCode.java @@ -20,6 +20,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameterOrBlockHash; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; @@ -47,7 +48,7 @@ public class EthGetCode extends AbstractBlockParameterOrBlockHashMethod { final JsonRpcRequestContext request) { try { return request.getRequiredParameter(1, BlockParameterOrBlockHash.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid block or block hash parameter (index 1)", RpcErrorType.INVALID_BLOCK_PARAMS, e); } @@ -58,7 +59,7 @@ public class EthGetCode extends AbstractBlockParameterOrBlockHashMethod { final Address address; try { address = request.getRequiredParameter(0, Address.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid address parameter (index 0)", RpcErrorType.INVALID_ADDRESS_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetFilterChanges.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetFilterChanges.java index 0773651b61..b3fa7565d6 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetFilterChanges.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetFilterChanges.java @@ -19,6 +19,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.filter.FilterManager; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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; @@ -47,7 +48,7 @@ public class EthGetFilterChanges implements JsonRpcMethod { final String filterId; try { filterId = requestContext.getRequiredParameter(0, String.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid filter ID parameter (index 0)", RpcErrorType.INVALID_FILTER_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetFilterLogs.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetFilterLogs.java index b66b7963e1..0fd32455b2 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetFilterLogs.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetFilterLogs.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.filter.FilterManager; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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; @@ -45,7 +46,7 @@ public class EthGetFilterLogs implements JsonRpcMethod { final String filterId; try { filterId = requestContext.getRequiredParameter(0, String.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid filter ID parameter (index 0)", RpcErrorType.INVALID_FILTER_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetLogs.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetLogs.java index c9645d53e0..225870ba3a 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetLogs.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetLogs.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.FilterParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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; @@ -55,7 +56,7 @@ public class EthGetLogs implements JsonRpcMethod { final FilterParameter filter; try { filter = requestContext.getRequiredParameter(0, FilterParameter.class); - } catch (Exception e) { + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid filter parameter (index 0)", RpcErrorType.INVALID_FILTER_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetMinerDataByBlockHash.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetMinerDataByBlockHash.java index 8e3d55f1ea..8b54364a99 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetMinerDataByBlockHash.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetMinerDataByBlockHash.java @@ -19,6 +19,7 @@ import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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.api.jsonrpc.internal.response.RpcErrorType; @@ -65,7 +66,7 @@ public class EthGetMinerDataByBlockHash implements JsonRpcMethod { final Hash hash; try { hash = requestContext.getRequest().getRequiredParameter(0, Hash.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid block hash parameter (index 0)", RpcErrorType.INVALID_BLOCK_HASH_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetMinerDataByBlockNumber.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetMinerDataByBlockNumber.java index c2df712686..e0fe246062 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetMinerDataByBlockNumber.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetMinerDataByBlockNumber.java @@ -19,6 +19,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.MinerDataResult; import org.hyperledger.besu.ethereum.api.query.BlockWithMetadata; @@ -44,7 +45,7 @@ public class EthGetMinerDataByBlockNumber extends AbstractBlockParameterMethod { protected BlockParameter blockParameter(final JsonRpcRequestContext request) { try { return request.getRequiredParameter(0, BlockParameter.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid block parameter (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetProof.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetProof.java index 7c2f67b724..d1920b5c1a 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetProof.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetProof.java @@ -20,6 +20,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameterOrBlockHash; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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; @@ -51,7 +52,7 @@ public class EthGetProof extends AbstractBlockParameterOrBlockHashMethod { final JsonRpcRequestContext request) { try { return request.getRequiredParameter(2, BlockParameterOrBlockHash.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid block or block hash parameter (index 2)", RpcErrorType.INVALID_BLOCK_PARAMS, e); } @@ -64,7 +65,7 @@ public class EthGetProof extends AbstractBlockParameterOrBlockHashMethod { final Address address; try { address = requestContext.getRequiredParameter(0, Address.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid address parameter (index 0)", RpcErrorType.INVALID_ADDRESS_PARAMS, e); } @@ -110,7 +111,7 @@ public class EthGetProof extends AbstractBlockParameterOrBlockHashMethod { return Arrays.stream(request.getRequiredParameter(1, String[].class)) .map(UInt256::fromHexString) .collect(Collectors.toList()); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid storage keys parameters (index 1)", RpcErrorType.INVALID_STORAGE_KEYS_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetStorageAt.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetStorageAt.java index 34ed62b632..a171fc16d1 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetStorageAt.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetStorageAt.java @@ -20,6 +20,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameterOrBlockHash; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.UInt256Parameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; @@ -41,7 +42,7 @@ public class EthGetStorageAt extends AbstractBlockParameterOrBlockHashMethod { final JsonRpcRequestContext request) { try { return request.getRequiredParameter(2, BlockParameterOrBlockHash.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid block or block hash parameter (index 2)", RpcErrorType.INVALID_BLOCK_PARAMS, e); } @@ -52,14 +53,14 @@ public class EthGetStorageAt extends AbstractBlockParameterOrBlockHashMethod { final Address address; try { address = request.getRequiredParameter(0, Address.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid address parameter (index 0)", RpcErrorType.INVALID_ADDRESS_PARAMS, e); } final UInt256 position; try { position = request.getRequiredParameter(1, UInt256Parameter.class).getValue(); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid position parameter (index 1)", RpcErrorType.INVALID_POSITION_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionByBlockHashAndIndex.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionByBlockHashAndIndex.java index 9c7cf5e7a8..917c09a326 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionByBlockHashAndIndex.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionByBlockHashAndIndex.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.UnsignedIntParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; @@ -47,7 +48,7 @@ public class EthGetTransactionByBlockHashAndIndex implements JsonRpcMethod { final Hash hash; try { hash = requestContext.getRequiredParameter(0, Hash.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid transaction hash parameter (index 0)", RpcErrorType.INVALID_TRANSACTION_HASH_PARAMS, @@ -56,7 +57,7 @@ public class EthGetTransactionByBlockHashAndIndex implements JsonRpcMethod { final int index; try { index = requestContext.getRequiredParameter(1, UnsignedIntParameter.class).getValue(); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid transaction id parameter (index 1)", RpcErrorType.INVALID_TRANSACTION_ID_PARAMS, diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionByBlockNumberAndIndex.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionByBlockNumberAndIndex.java index a5383f6680..338a878368 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionByBlockNumberAndIndex.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionByBlockNumberAndIndex.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.UnsignedIntParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.TransactionCompleteResult; @@ -41,7 +42,7 @@ public class EthGetTransactionByBlockNumberAndIndex extends AbstractBlockParamet protected BlockParameter blockParameter(final JsonRpcRequestContext request) { try { return request.getRequiredParameter(0, BlockParameter.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid block parameter (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e); } @@ -53,7 +54,7 @@ public class EthGetTransactionByBlockNumberAndIndex extends AbstractBlockParamet final int index; try { index = request.getRequiredParameter(1, UnsignedIntParameter.class).getValue(); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid transaction index parameter (index 1)", RpcErrorType.INVALID_TRANSACTION_INDEX_PARAMS, diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionByHash.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionByHash.java index 90e7a6a1ed..5d8b008522 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionByHash.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionByHash.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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; @@ -54,7 +55,7 @@ public class EthGetTransactionByHash implements JsonRpcMethod { final Hash hash; try { hash = requestContext.getRequiredParameter(0, Hash.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid transaction hash parameter (index 0)", RpcErrorType.INVALID_TRANSACTION_HASH_PARAMS, diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionCount.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionCount.java index a9916099ea..4e26f8ee98 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionCount.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionCount.java @@ -20,6 +20,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameterOrBlockHash; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.Quantity; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; @@ -54,7 +55,7 @@ public class EthGetTransactionCount extends AbstractBlockParameterOrBlockHashMet final JsonRpcRequestContext request) { try { return request.getRequiredParameter(1, BlockParameterOrBlockHash.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid block or block hash parameter (index 1)", RpcErrorType.INVALID_BLOCK_PARAMS, e); } @@ -65,7 +66,7 @@ public class EthGetTransactionCount extends AbstractBlockParameterOrBlockHashMet final Address address; try { address = request.getRequiredParameter(0, Address.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid address parameter (index 0)", RpcErrorType.INVALID_ADDRESS_PARAMS, e); } @@ -88,7 +89,7 @@ public class EthGetTransactionCount extends AbstractBlockParameterOrBlockHashMet final Address address; try { address = request.getRequiredParameter(0, Address.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid address parameter (index 0)", RpcErrorType.INVALID_ADDRESS_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionReceipt.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionReceipt.java index a437cd86dc..44e4cfe0d6 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionReceipt.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionReceipt.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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.api.jsonrpc.internal.response.RpcErrorType; @@ -51,7 +52,7 @@ public class EthGetTransactionReceipt implements JsonRpcMethod { final Hash hash; try { hash = requestContext.getRequiredParameter(0, Hash.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid transaction hash parameter (index 0)", RpcErrorType.INVALID_TRANSACTION_HASH_PARAMS, diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetUncleByBlockHashAndIndex.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetUncleByBlockHashAndIndex.java index 9269bf965c..f76b461cef 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetUncleByBlockHashAndIndex.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetUncleByBlockHashAndIndex.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.UnsignedIntParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; @@ -49,14 +50,14 @@ public class EthGetUncleByBlockHashAndIndex implements JsonRpcMethod { final Hash hash; try { hash = requestContext.getRequiredParameter(0, Hash.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid block hash parameter (index 0)", RpcErrorType.INVALID_BLOCK_HASH_PARAMS, e); } final int index; try { index = requestContext.getRequiredParameter(1, UnsignedIntParameter.class).getValue(); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid block index parameter (index 1)", RpcErrorType.INVALID_BLOCK_INDEX_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetUncleByBlockNumberAndIndex.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetUncleByBlockNumberAndIndex.java index a6c5e6d89d..f7c9ecb0dd 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetUncleByBlockNumberAndIndex.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetUncleByBlockNumberAndIndex.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.UnsignedIntParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.BlockResult; @@ -39,7 +40,7 @@ public class EthGetUncleByBlockNumberAndIndex extends AbstractBlockParameterMeth protected BlockParameter blockParameter(final JsonRpcRequestContext request) { try { return request.getRequiredParameter(0, BlockParameter.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid block parameter (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e); } @@ -51,7 +52,7 @@ public class EthGetUncleByBlockNumberAndIndex extends AbstractBlockParameterMeth final int index; try { index = request.getRequiredParameter(1, UnsignedIntParameter.class).getValue(); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid block index (index 1)", RpcErrorType.INVALID_BLOCK_INDEX_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetUncleCountByBlockHash.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetUncleCountByBlockHash.java index 9a5a3b225b..02cd3c4242 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetUncleCountByBlockHash.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetUncleCountByBlockHash.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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.api.jsonrpc.internal.response.RpcErrorType; @@ -42,7 +43,7 @@ public class EthGetUncleCountByBlockHash implements JsonRpcMethod { final Hash hash; try { hash = requestContext.getRequiredParameter(0, Hash.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid block hash parameter (index 0)", RpcErrorType.INVALID_BLOCK_HASH_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetUncleCountByBlockNumber.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetUncleCountByBlockNumber.java index ddd130542c..8d935942ad 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetUncleCountByBlockNumber.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetUncleCountByBlockNumber.java @@ -16,7 +16,10 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.Quantity; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; @@ -33,7 +36,12 @@ public class EthGetUncleCountByBlockNumber extends AbstractBlockParameterMethod @Override protected BlockParameter blockParameter(final JsonRpcRequestContext request) { - return request.getRequiredParameter(0, BlockParameter.class); + try { + return request.getRequiredParameter(0, BlockParameter.class); + } catch (JsonRpcParameterException e) { + throw new InvalidJsonRpcParameters( + "Invalid block parameter (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e); + } } @Override diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthNewFilter.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthNewFilter.java index 7578b43a2e..d6edccd2e7 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthNewFilter.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthNewFilter.java @@ -19,6 +19,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.filter.FilterManager; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.FilterParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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; @@ -42,7 +43,7 @@ public class EthNewFilter implements JsonRpcMethod { final FilterParameter filter; try { filter = requestContext.getRequiredParameter(0, FilterParameter.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid filter paramters (index 0)", RpcErrorType.INVALID_FILTER_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSendRawTransaction.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSendRawTransaction.java index 272014d3bc..10582e7a1c 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSendRawTransaction.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSendRawTransaction.java @@ -21,6 +21,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcRequestException; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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; @@ -72,7 +73,7 @@ public class EthSendRawTransaction implements JsonRpcMethod { final String rawTransaction; try { rawTransaction = requestContext.getRequiredParameter(0, String.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid transaction parameters (index 0)", RpcErrorType.INVALID_TRANSACTION_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSubmitHashRate.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSubmitHashRate.java index c0763e77f6..488f89b3a5 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSubmitHashRate.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSubmitHashRate.java @@ -17,6 +17,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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.api.jsonrpc.internal.response.RpcErrorType; @@ -42,14 +43,14 @@ public class EthSubmitHashRate implements JsonRpcMethod { final String hashRate; try { hashRate = requestContext.getRequiredParameter(0, String.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid hash rate parameter (index 0)", RpcErrorType.INVALID_HASH_RATE_PARAMS, e); } final String id; try { id = requestContext.getRequiredParameter(1, String.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid sealer ID parameter (index 1)", RpcErrorType.INVALID_SEALER_ID_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSubmitWork.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSubmitWork.java index 9474fec7ba..9002b2a0dd 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSubmitWork.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSubmitWork.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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; @@ -54,21 +55,21 @@ public class EthSubmitWork implements JsonRpcMethod { try { nonce = Bytes.fromHexString(requestContext.getRequiredParameter(0, String.class)).getLong(0); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid nonce parameter (index 0)", RpcErrorType.INVALID_NONCE_PARAMS, e); } Hash mixHash; try { mixHash = requestContext.getRequiredParameter(2, Hash.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid mix hash parameter (index 2)", RpcErrorType.INVALID_MIX_HASH_PARAMS, e); } Bytes powHash; try { powHash = Bytes.fromHexString(requestContext.getRequiredParameter(1, String.class)); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid PoW hash parameter (index 1)", RpcErrorType.INVALID_POW_HASH_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthUninstallFilter.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthUninstallFilter.java index b51dc1f4fd..8771343ecf 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthUninstallFilter.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthUninstallFilter.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.filter.FilterManager; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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.api.jsonrpc.internal.response.RpcErrorType; @@ -40,7 +41,7 @@ public class EthUninstallFilter implements JsonRpcMethod { final String filterId; try { filterId = requestContext.getRequiredParameter(0, String.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid filter ID parameter (index 0)", RpcErrorType.INVALID_FILTER_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/JsonCallParameterUtil.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/JsonCallParameterUtil.java index 7d7bd013be..df593f9fbc 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/JsonCallParameterUtil.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/JsonCallParameterUtil.java @@ -17,6 +17,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonCallParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; public class JsonCallParameterUtil { @@ -27,7 +28,7 @@ public class JsonCallParameterUtil { final JsonCallParameter callParams; try { callParams = request.getRequiredParameter(0, JsonCallParameter.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid call parameters (index 0)", RpcErrorType.INVALID_CALL_PARAMS); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/PluginsReloadConfiguration.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/PluginsReloadConfiguration.java index f895008e23..3761b8114a 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/PluginsReloadConfiguration.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/PluginsReloadConfiguration.java @@ -16,6 +16,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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; @@ -55,7 +56,7 @@ public class PluginsReloadConfiguration implements JsonRpcMethod { } reloadPluginConfig(namedPlugins.get(pluginName)); return new JsonRpcSuccessResponse(requestContext.getRequest().getId()); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { return new JsonRpcErrorResponse( requestContext.getRequest().getId(), RpcErrorType.INVAlID_PLUGIN_NAME_PARAMS); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceBlock.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceBlock.java index 5ec46e08cc..adacf01e76 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceBlock.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceBlock.java @@ -21,6 +21,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.FilterParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.Tracer; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.TransactionTrace; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; @@ -72,7 +73,7 @@ public class TraceBlock extends AbstractBlockParameterMethod { protected BlockParameter blockParameter(final JsonRpcRequestContext request) { try { return request.getRequiredParameter(0, BlockParameter.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid block parameter (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceCall.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceCall.java index 9882257143..082283a815 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceCall.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceCall.java @@ -19,6 +19,7 @@ import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErr import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.TraceTypeParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.TransactionTrace; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; @@ -60,7 +61,7 @@ public class TraceCall extends AbstractTraceCall { final JsonRpcRequestContext requestContext) { try { return requestContext.getRequiredParameter(1, TraceTypeParameter.class).getTraceTypes(); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid trace type parameter (index 1)", RpcErrorType.INVALID_TRACE_TYPE_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceCallMany.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceCallMany.java index 2cbeb8ee7f..10d4018bce 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceCallMany.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceCallMany.java @@ -22,6 +22,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonCallParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.TraceCallManyParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.TraceTypeParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.TransactionTrace; @@ -67,7 +68,7 @@ public class TraceCallMany extends TraceCall implements JsonRpcMethod { final Optional maybeBlockParameter; try { maybeBlockParameter = request.getOptionalParameter(1, BlockParameter.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid block parameter (index 1)", RpcErrorType.INVALID_BLOCK_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceFilter.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceFilter.java index a3d6b2561f..74bfec87c2 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceFilter.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceFilter.java @@ -22,6 +22,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.FilterParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.BlockTracer; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.Tracer; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.TransactionTrace; @@ -90,7 +91,7 @@ public class TraceFilter extends TraceBlock { final FilterParameter filterParameter; try { filterParameter = requestContext.getRequiredParameter(0, FilterParameter.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid filter parameter (index 0)", RpcErrorType.INVALID_FILTER_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceGet.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceGet.java index b346637ec2..e1c27aed79 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceGet.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceGet.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.BlockTracer; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; @@ -58,7 +59,7 @@ public class TraceGet extends AbstractTraceByHash implements JsonRpcMethod { final Hash transactionHash; try { transactionHash = requestContext.getRequiredParameter(0, Hash.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid transaction hash parameter (index 0)", RpcErrorType.INVALID_TRANSACTION_HASH_PARAMS, @@ -67,7 +68,7 @@ public class TraceGet extends AbstractTraceByHash implements JsonRpcMethod { final List traceNumbersAsStrings; try { traceNumbersAsStrings = requestContext.getRequiredParameter(1, List.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid trace numbers parameters (index 1)", RpcErrorType.INVALID_TRACE_NUMBERS_PARAMS, diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceRawTransaction.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceRawTransaction.java index a720569875..71c8247784 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceRawTransaction.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceRawTransaction.java @@ -19,6 +19,7 @@ import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErr import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.TraceTypeParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.TransactionTrace; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; @@ -74,14 +75,14 @@ public class TraceRawTransaction extends AbstractTraceByBlock implements JsonRpc final String rawTransaction; try { rawTransaction = requestContext.getRequiredParameter(0, String.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid transaction parameters (index 0)", RpcErrorType.INVALID_TRANSACTION_PARAMS, e); } final TraceTypeParameter traceTypeParameter; try { traceTypeParameter = requestContext.getRequiredParameter(1, TraceTypeParameter.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid trace type parameter (index 1)", RpcErrorType.INVALID_TRACE_TYPE_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceReplayBlockTransactions.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceReplayBlockTransactions.java index a8b3bbc46d..202d2ddbbb 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceReplayBlockTransactions.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceReplayBlockTransactions.java @@ -21,6 +21,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.TraceBlock.ChainUpdater; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.TraceTypeParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.Tracer; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.TransactionTrace; @@ -74,7 +75,7 @@ public class TraceReplayBlockTransactions extends AbstractBlockParameterMethod { protected BlockParameter blockParameter(final JsonRpcRequestContext request) { try { return request.getRequiredParameter(0, BlockParameter.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid block parameter (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e); } @@ -86,7 +87,7 @@ public class TraceReplayBlockTransactions extends AbstractBlockParameterMethod { final TraceTypeParameter traceTypeParameter; try { traceTypeParameter = request.getRequiredParameter(1, TraceTypeParameter.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid trace type parameter (index 1)", RpcErrorType.INVALID_TRACE_TYPE_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceTransaction.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceTransaction.java index b79b9620e8..be69423681 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceTransaction.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceTransaction.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.BlockTracer; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; @@ -50,7 +51,7 @@ public class TraceTransaction extends AbstractTraceByHash implements JsonRpcMeth final Hash transactionHash; try { transactionHash = requestContext.getRequiredParameter(0, Hash.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid transaction hash parameter (index 0)", RpcErrorType.INVALID_TRANSACTION_HASH_PARAMS, diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TxPoolBesuPendingTransactions.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TxPoolBesuPendingTransactions.java index 8dc38135c6..81c366926a 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TxPoolBesuPendingTransactions.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TxPoolBesuPendingTransactions.java @@ -17,6 +17,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.PendingTransactionsParams; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; @@ -58,7 +59,7 @@ public class TxPoolBesuPendingTransactions implements JsonRpcMethod { try { limit = requestContext.getOptionalParameter(0, Integer.class).orElse(pendingTransactions.size()); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid transaction limit parameter (index 0)", RpcErrorType.INVALID_TRANSACTION_LIMIT_PARAMS, @@ -71,7 +72,7 @@ public class TxPoolBesuPendingTransactions implements JsonRpcMethod { .getOptionalParameter(1, PendingTransactionsParams.class) .map(PendingTransactionsParams::filters) .orElse(Collections.emptyList()); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid pending transactions parameter (index 1)", RpcErrorType.INVALID_PENDING_TRANSACTIONS_PARAMS, diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/Web3Sha3.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/Web3Sha3.java index b70ad76051..e34a462800 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/Web3Sha3.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/Web3Sha3.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.crypto.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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; @@ -45,7 +46,7 @@ public class Web3Sha3 implements JsonRpcMethod { final String data; try { data = requestContext.getRequiredParameter(0, String.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid data parameter (index 0)", RpcErrorType.INVALID_DATA_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineForkchoiceUpdated.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineForkchoiceUpdated.java index 7df76973ac..11ec3d04c5 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineForkchoiceUpdated.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineForkchoiceUpdated.java @@ -31,6 +31,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonR import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.EngineForkchoiceUpdatedParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.EnginePayloadAttributesParameter; +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.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; @@ -84,7 +85,7 @@ public abstract class AbstractEngineForkchoiceUpdated extends ExecutionEngineJso final EngineForkchoiceUpdatedParameter forkChoice; try { forkChoice = requestContext.getRequiredParameter(0, EngineForkchoiceUpdatedParameter.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid engine forkchoice updated parameter (index 0)", RpcErrorType.INVALID_ENGINE_FORKCHOICE_UPDATED_PARAMS, @@ -94,7 +95,7 @@ public abstract class AbstractEngineForkchoiceUpdated extends ExecutionEngineJso try { maybePayloadAttributes = requestContext.getOptionalParameter(1, EnginePayloadAttributesParameter.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid engine payload attributes parameter (index 1)", RpcErrorType.INVALID_ENGINE_FORKCHOICE_UPDATED_PAYLOAD_ATTRIBUTES, diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineGetPayload.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineGetPayload.java index a6f94ac00e..d95b532e77 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineGetPayload.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineGetPayload.java @@ -21,6 +21,7 @@ import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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.RpcErrorType; @@ -72,7 +73,7 @@ public abstract class AbstractEngineGetPayload extends ExecutionEngineJsonRpcMet final PayloadIdentifier payloadId; try { payloadId = request.getRequiredParameter(0, PayloadIdentifier.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid payload ID parameter (index 0)", RpcErrorType.INVALID_PAYLOAD_ID_PARAMS, e); } 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 02ccf5d231..78b96796cb 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 @@ -39,6 +39,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngin 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.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.JsonRpcErrorResponse; @@ -109,7 +110,7 @@ public abstract class AbstractEngineNewPayload extends ExecutionEngineJsonRpcMet final EnginePayloadParameter blockParam; try { blockParam = requestContext.getRequiredParameter(0, EnginePayloadParameter.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcRequestException( "Invalid engine payload parameter (index 0)", RpcErrorType.INVALID_ENGINE_NEW_PAYLOAD_PARAMS, @@ -119,7 +120,7 @@ public abstract class AbstractEngineNewPayload extends ExecutionEngineJsonRpcMet final Optional> maybeVersionedHashParam; try { maybeVersionedHashParam = requestContext.getOptionalList(1, String.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcRequestException( "Invalid versioned hash parameters (index 1)", RpcErrorType.INVALID_VERSIONED_HASH_PARAMS, @@ -131,7 +132,7 @@ public abstract class AbstractEngineNewPayload extends ExecutionEngineJsonRpcMet Optional maybeParentBeaconBlockRootParam; try { maybeParentBeaconBlockRootParam = requestContext.getOptionalParameter(2, String.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcRequestException( "Invalid parent beacon block root parameters (index 2)", RpcErrorType.INVALID_PARENT_BEACON_BLOCK_ROOT_PARAMS, diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineExchangeCapabilities.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineExchangeCapabilities.java index 624d9bebdd..2666888ed6 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineExchangeCapabilities.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineExchangeCapabilities.java @@ -22,6 +22,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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.api.jsonrpc.internal.response.RpcErrorType; @@ -61,8 +62,7 @@ public class EngineExchangeCapabilities extends ExecutionEngineJsonRpcMethod { () -> { try { return requestContext.getRequiredParameter(0, String[].class); - } catch ( - Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid remote capabilities parameters (index 0)", RpcErrorType.INVALID_REMOTE_CAPABILITIES_PARAMS, diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineExchangeTransitionConfiguration.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineExchangeTransitionConfiguration.java index 67b8657533..924e8ac989 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineExchangeTransitionConfiguration.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineExchangeTransitionConfiguration.java @@ -23,6 +23,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.EngineExchangeTransitionConfigurationParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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.api.jsonrpc.internal.response.RpcErrorType; @@ -72,7 +73,7 @@ public class EngineExchangeTransitionConfiguration extends ExecutionEngineJsonRp remoteTransitionConfiguration = requestContext.getRequiredParameter( 0, EngineExchangeTransitionConfigurationParameter.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid engine exchange transition configuration parameters (index 0)", RpcErrorType.INVALID_ENGINE_EXCHANGE_TRANSITION_CONFIGURATION_PARAMS, diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadBodiesByHashV1.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadBodiesByHashV1.java index 0e6b62d320..facbd026d4 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadBodiesByHashV1.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadBodiesByHashV1.java @@ -20,6 +20,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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; @@ -64,7 +65,7 @@ public class EngineGetPayloadBodiesByHashV1 extends ExecutionEngineJsonRpcMethod final Hash[] blockHashes; try { blockHashes = request.getRequiredParameter(0, Hash[].class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid block hash parameters (index 0)", RpcErrorType.INVALID_BLOCK_HASH_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadBodiesByRangeV1.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadBodiesByRangeV1.java index ec5d5bf604..2d21a7282a 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadBodiesByRangeV1.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadBodiesByRangeV1.java @@ -19,6 +19,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.UnsignedLongParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; @@ -61,7 +62,7 @@ public class EngineGetPayloadBodiesByRangeV1 extends ExecutionEngineJsonRpcMetho final long startBlockNumber; try { startBlockNumber = request.getRequiredParameter(0, UnsignedLongParameter.class).getValue(); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid start block number parameter (index 0)", RpcErrorType.INVALID_BLOCK_NUMBER_PARAMS, @@ -70,7 +71,7 @@ public class EngineGetPayloadBodiesByRangeV1 extends ExecutionEngineJsonRpcMetho final long count; try { count = request.getRequiredParameter(1, UnsignedLongParameter.class).getValue(); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid block count params (index 1)", RpcErrorType.INVALID_BLOCK_COUNT_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EnginePreparePayloadDebug.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EnginePreparePayloadDebug.java index e55cfb1506..c4bca21803 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EnginePreparePayloadDebug.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EnginePreparePayloadDebug.java @@ -26,6 +26,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.EnginePreparePayloadParameter; +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.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; @@ -72,7 +73,7 @@ public class EnginePreparePayloadDebug extends ExecutionEngineJsonRpcMethod { Optional.empty(), Optional.empty(), Optional.empty())); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid engine prepare payload parameter (index 0)", RpcErrorType.INVALID_ENGINE_PREPARE_PAYLOAD_PARAMS, diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerChangeTargetGasLimit.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerChangeTargetGasLimit.java index f1b949ad63..cd1b033dc4 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerChangeTargetGasLimit.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerChangeTargetGasLimit.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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; @@ -49,7 +50,7 @@ public class MinerChangeTargetGasLimit implements JsonRpcMethod { return new JsonRpcErrorResponse( requestContext.getRequest().getId(), RpcErrorType.TARGET_GAS_LIMIT_MODIFICATION_UNSUPPORTED); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid target gas limit parameter (index 0)", RpcErrorType.INVALID_TARGET_GAS_LIMIT_PARAMS, diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetCoinbase.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetCoinbase.java index d6676a6074..f30db35e77 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetCoinbase.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetCoinbase.java @@ -19,6 +19,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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; @@ -47,7 +48,7 @@ public class MinerSetCoinbase implements JsonRpcMethod { } catch (final UnsupportedOperationException ex) { return new JsonRpcErrorResponse( requestContext.getRequest().getId(), RpcErrorType.INVALID_REQUEST); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid address parameter (index 0)", RpcErrorType.INVALID_ADDRESS_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetExtraData.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetExtraData.java index 5b9bc581db..51395e24f7 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetExtraData.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetExtraData.java @@ -17,6 +17,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.miner; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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; @@ -60,12 +61,10 @@ public class MinerSetExtraData implements JsonRpcMethod { .addArgument(() -> new String(extraData.toArray(), StandardCharsets.UTF_8)) .log(); return new JsonRpcSuccessResponse(requestContext.getRequest().getId(), true); - } catch (Exception invalidJsonRpcParameters) { // TODO:replace with "IllegalArgumentException | - // JsonRpcParameter.JsonRpcParameterException" + } catch (IllegalArgumentException | JsonRpcParameterException e) { return new JsonRpcErrorResponse( requestContext.getRequest().getId(), - new JsonRpcError( - RpcErrorType.INVALID_EXTRA_DATA_PARAMS, invalidJsonRpcParameters.getMessage())); + new JsonRpcError(RpcErrorType.INVALID_EXTRA_DATA_PARAMS, e.getMessage())); } } } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetMinGasPrice.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetMinGasPrice.java index 59c18b80db..733ed3a8f3 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetMinGasPrice.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetMinGasPrice.java @@ -19,6 +19,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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; @@ -56,7 +57,7 @@ public class MinerSetMinGasPrice implements JsonRpcMethod { requestContext.getRequest().getId(), new JsonRpcError( RpcErrorType.INVALID_MIN_GAS_PRICE_PARAMS, invalidJsonRpcParameters.getMessage())); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid min gas price parameter (index 0)", RpcErrorType.INVALID_MIN_GAS_PRICE_PARAMS, diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetMinPriorityFee.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetMinPriorityFee.java index 9c217b0c23..b1bf4338f7 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetMinPriorityFee.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetMinPriorityFee.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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; @@ -51,11 +52,10 @@ public class MinerSetMinPriorityFee implements JsonRpcMethod { LOG.debug( "min priority fee per gas changed to {}", minPriorityFeePerGas.toHumanReadableString()); return new JsonRpcSuccessResponse(requestContext.getRequest().getId(), true); - } catch (final IllegalArgumentException invalidJsonRpcParameters) { + } catch (final IllegalArgumentException | JsonRpcParameterException e) { return new JsonRpcErrorResponse( requestContext.getRequest().getId(), - new JsonRpcError( - RpcErrorType.INVALID_MIN_PRIORITY_FEE_PARAMS, invalidJsonRpcParameters.getMessage())); + new JsonRpcError(RpcErrorType.INVALID_MIN_PRIORITY_FEE_PARAMS, e.getMessage())); } } } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermAddAccountsToAllowlist.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermAddAccountsToAllowlist.java index f3407ba10d..32459b3b4c 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermAddAccountsToAllowlist.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermAddAccountsToAllowlist.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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; @@ -48,7 +49,7 @@ public class PermAddAccountsToAllowlist implements JsonRpcMethod { final List accountsList; try { accountsList = requestContext.getRequiredParameter(0, List.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid accounts list parameter (index 0)", RpcErrorType.INVALID_ACCOUNT_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermAddNodesToAllowlist.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermAddNodesToAllowlist.java index 2aec3b6f95..5f8374a884 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermAddNodesToAllowlist.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermAddNodesToAllowlist.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.StringListParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; @@ -50,7 +51,7 @@ public class PermAddNodesToAllowlist implements JsonRpcMethod { final StringListParameter enodeListParam; try { enodeListParam = requestContext.getRequiredParameter(0, StringListParameter.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid enode list parameter (index 0)", RpcErrorType.INVALID_ENODE_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermRemoveAccountsFromAllowlist.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermRemoveAccountsFromAllowlist.java index a39acd5e9c..ac7bffdf57 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermRemoveAccountsFromAllowlist.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermRemoveAccountsFromAllowlist.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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; @@ -48,7 +49,7 @@ public class PermRemoveAccountsFromAllowlist implements JsonRpcMethod { final List accountsList; try { accountsList = requestContext.getRequiredParameter(0, List.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid accounts list parameter (index 0)", RpcErrorType.INVALID_ACCOUNT_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermRemoveNodesFromAllowlist.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermRemoveNodesFromAllowlist.java index 862b694f4f..16e3bc234a 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermRemoveNodesFromAllowlist.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/permissioning/PermRemoveNodesFromAllowlist.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.StringListParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; @@ -50,7 +51,7 @@ public class PermRemoveNodesFromAllowlist implements JsonRpcMethod { final StringListParameter enodeListParam; try { enodeListParam = requestContext.getRequiredParameter(0, StringListParameter.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid enode list parameter (index 0)", RpcErrorType.INVALID_ENODE_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/JsonRpcParameter.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/JsonRpcParameter.java index a8b5fb7dc8..22fb511ef4 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/JsonRpcParameter.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/JsonRpcParameter.java @@ -14,8 +14,6 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; - import java.util.List; import java.util.Optional; @@ -40,13 +38,12 @@ public class JsonRpcParameter { * @param The type of parameter. * @return Returns the parameter cast as T if available, otherwise throws exception. */ - // TODO: update to throw JsonRpcParameterException as a checked exception, forcing callers to - // handle it to supply appropriate context - public T required(final Object[] params, final int index, final Class paramClass) { + public T required(final Object[] params, final int index, final Class paramClass) + throws JsonRpcParameterException { return optional(params, index, paramClass) .orElseThrow( () -> - new InvalidJsonRpcParameters( + new JsonRpcParameterException( "Missing required json rpc parameter at index " + index)); } @@ -60,11 +57,8 @@ public class JsonRpcParameter { * @param The type of parameter. * @return Returns the parameter cast as T if available. */ - // TODO: update to throw JsonRpcParameterException as a checked exception, forcing callers to - // handle it to supply appropriate context - @SuppressWarnings("unchecked") - public Optional optional( - final Object[] params, final int index, final Class paramClass) { + public Optional optional(final Object[] params, final int index, final Class paramClass) + throws JsonRpcParameterException { if (params == null || params.length <= index || params[index] == null) { return Optional.empty(); } @@ -73,14 +67,14 @@ public class JsonRpcParameter { final Object rawParam = params[index]; if (paramClass.isAssignableFrom(rawParam.getClass())) { // If we're dealing with a simple type, just cast the value - param = (T) rawParam; + param = paramClass.cast(rawParam); } else { // Otherwise, serialize param back to json and then deserialize to the paramClass type try { final String json = mapper.writeValueAsString(rawParam); param = mapper.readValue(json, paramClass); } catch (final JsonProcessingException e) { - throw new InvalidJsonRpcParameters( + throw new JsonRpcParameterException( String.format( "Invalid json rpc parameter at index %d. Supplied value was: '%s' of type: '%s' - expected type: '%s'", index, rawParam, rawParam.getClass().getName(), paramClass.getName()), @@ -91,10 +85,9 @@ public class JsonRpcParameter { return Optional.of(param); } - // TODO: update to throw JsonRpcParameterException as a checked exception, forcing callers to - // handle it to supply appropriate context public Optional> optionalList( - final Object[] params, final int index, final Class listClass) { + final Object[] params, final int index, final Class listClass) + throws JsonRpcParameterException { if (params == null || params.length <= index || params[index] == null) { return Optional.empty(); } @@ -105,7 +98,7 @@ public class JsonRpcParameter { List returnedList = mapper.readValue(listJson, new TypeReference>() {}); return Optional.of(returnedList); } catch (JsonProcessingException e) { - throw new InvalidJsonRpcParameters( + throw new JsonRpcParameterException( String.format( "Invalid json rpc parameter at index %d. Supplied value was: '%s' of type: '%s' - expected type: '%s'", index, rawParam, rawParam.getClass().getName(), listClass.getName()), diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivGetFilterChanges.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivGetFilterChanges.java index bbd7189ffa..4ef7e0aa1c 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivGetFilterChanges.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivGetFilterChanges.java @@ -19,6 +19,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.filter.FilterManager; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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; @@ -55,7 +56,7 @@ public class PrivGetFilterChanges implements JsonRpcMethod { final String privacyGroupId; try { privacyGroupId = requestContext.getRequiredParameter(0, String.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid privacy group ID parameter (index 0)", RpcErrorType.INVALID_PRIVACY_GROUP_PARAMS, @@ -64,7 +65,7 @@ public class PrivGetFilterChanges implements JsonRpcMethod { final String filterId; try { filterId = requestContext.getRequiredParameter(1, String.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid filter ID parameter (index 1)", RpcErrorType.INVALID_FILTER_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivGetFilterLogs.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivGetFilterLogs.java index 4436c33b50..ea6a5894a3 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivGetFilterLogs.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivGetFilterLogs.java @@ -19,6 +19,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.filter.FilterManager; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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; @@ -55,7 +56,7 @@ public class PrivGetFilterLogs implements JsonRpcMethod { final String privacyGroupId; try { privacyGroupId = request.getRequiredParameter(0, String.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid privacy group ID parameter (index 0)", RpcErrorType.INVALID_PRIVACY_GROUP_PARAMS, @@ -64,7 +65,7 @@ public class PrivGetFilterLogs implements JsonRpcMethod { final String filterId; try { filterId = request.getRequiredParameter(1, String.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid filter ID parameter (index 1)", RpcErrorType.INVALID_FILTER_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivUninstallFilter.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivUninstallFilter.java index c1e122578a..eb41a1dad4 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivUninstallFilter.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivUninstallFilter.java @@ -19,6 +19,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.filter.FilterManager; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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.api.jsonrpc.internal.response.RpcErrorType; @@ -50,7 +51,7 @@ public class PrivUninstallFilter implements JsonRpcMethod { final String privacyGroupId; try { privacyGroupId = request.getRequiredParameter(0, String.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid privacy group ID parameter (index 0)", RpcErrorType.INVALID_PRIVACY_GROUP_PARAMS, @@ -59,7 +60,7 @@ public class PrivUninstallFilter implements JsonRpcMethod { final String filterId; try { filterId = request.getRequiredParameter(1, String.class); - } catch (Exception e) { + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid filter ID parameter (index 1)", RpcErrorType.INVALID_FILTER_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/eea/AbstractEeaSendRawTransaction.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/eea/AbstractEeaSendRawTransaction.java index 12c496b639..e96a08eb7d 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/eea/AbstractEeaSendRawTransaction.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/eea/AbstractEeaSendRawTransaction.java @@ -25,6 +25,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.PrivacyIdProvider; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; @@ -77,7 +78,7 @@ public abstract class AbstractEeaSendRawTransaction implements JsonRpcMethod { final String rawPrivateTransaction; try { rawPrivateTransaction = requestContext.getRequiredParameter(0, String.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid transaction parameter (index 0)", RpcErrorType.INVALID_TRANSACTION_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCall.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCall.java index e09d5966cf..5d9edc63b9 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCall.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCall.java @@ -21,6 +21,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonR import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.AbstractBlockParameterMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonCallParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.PrivacyIdProvider; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; @@ -55,7 +56,7 @@ public class PrivCall extends AbstractBlockParameterMethod { protected BlockParameter blockParameter(final JsonRpcRequestContext request) { try { return request.getRequiredParameter(2, BlockParameter.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid block parameter (index 2)", RpcErrorType.INVALID_BLOCK_PARAMS, e); } @@ -68,7 +69,7 @@ public class PrivCall extends AbstractBlockParameterMethod { final String privacyGroupId; try { privacyGroupId = request.getRequiredParameter(0, String.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid privacy group ID parameter (index 0)", RpcErrorType.INVALID_PRIVACY_GROUP_PARAMS, @@ -115,7 +116,7 @@ public class PrivCall extends AbstractBlockParameterMethod { final JsonCallParameter callParams; try { callParams = request.getRequiredParameter(1, JsonCallParameter.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid call parameters (index 1)", RpcErrorType.INVALID_CALL_PARAMS); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCreatePrivacyGroup.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCreatePrivacyGroup.java index ae35506298..568125a276 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCreatePrivacyGroup.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCreatePrivacyGroup.java @@ -20,6 +20,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.PrivacyIdProvider; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.parameters.CreatePrivacyGroupParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; @@ -55,7 +56,7 @@ public class PrivCreatePrivacyGroup implements JsonRpcMethod { final CreatePrivacyGroupParameter parameter; try { parameter = requestContext.getRequiredParameter(0, CreatePrivacyGroupParameter.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid create privacy group parameter (index 0)", RpcErrorType.INVALID_CREATE_PRIVACY_GROUP_PARAMS, diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDebugGetStateRoot.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDebugGetStateRoot.java index 9ee5d57b3b..dc0fc90f66 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDebugGetStateRoot.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDebugGetStateRoot.java @@ -23,6 +23,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.AbstractBlockParameterMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.PrivacyIdProvider; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; @@ -63,7 +64,7 @@ public class PrivDebugGetStateRoot extends AbstractBlockParameterMethod { protected BlockParameter blockParameter(final JsonRpcRequestContext request) { try { return request.getRequiredParameter(1, BlockParameter.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid block parameter (index 1)", RpcErrorType.INVALID_BLOCK_PARAMS, e); } @@ -75,7 +76,7 @@ public class PrivDebugGetStateRoot extends AbstractBlockParameterMethod { final String privacyGroupId; try { privacyGroupId = requestContext.getRequiredParameter(0, String.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid privacy group ID parameter (index 0)", RpcErrorType.INVALID_PRIVACY_GROUP_PARAMS, diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDeletePrivacyGroup.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDeletePrivacyGroup.java index 5c6f929c5c..61b7791b3c 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDeletePrivacyGroup.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDeletePrivacyGroup.java @@ -20,6 +20,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.PrivacyIdProvider; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; @@ -55,7 +56,7 @@ public class PrivDeletePrivacyGroup implements JsonRpcMethod { final String privacyGroupId; try { privacyGroupId = requestContext.getRequiredParameter(0, String.class); - } catch (Exception e) { + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid privacy group ID parameter (index 0)", RpcErrorType.INVALID_PRIVACY_GROUP_PARAMS, diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDistributeRawTransaction.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDistributeRawTransaction.java index 39003358ed..aac4df3d2c 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDistributeRawTransaction.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDistributeRawTransaction.java @@ -25,6 +25,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.PrivacyIdProvider; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; @@ -74,7 +75,7 @@ public class PrivDistributeRawTransaction implements JsonRpcMethod { final String rawPrivateTransaction; try { rawPrivateTransaction = requestContext.getRequiredParameter(0, String.class); - } catch (Exception e) { + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid private transaction parameter (index 0)", RpcErrorType.INVALID_TRANSACTION_PARAMS, diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivFindPrivacyGroup.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivFindPrivacyGroup.java index 8f0e829084..7e82323223 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivFindPrivacyGroup.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivFindPrivacyGroup.java @@ -21,6 +21,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.PrivacyIdProvider; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; @@ -60,7 +61,7 @@ public class PrivFindPrivacyGroup implements JsonRpcMethod { final String[] addresses; try { addresses = requestContext.getRequiredParameter(0, String[].class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid address parameters (index 0)", RpcErrorType.INVALID_ADDRESS_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetCode.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetCode.java index 5d9498f3bd..7042d357f1 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetCode.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetCode.java @@ -20,6 +20,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.AbstractBlockParameterMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.PrivacyIdProvider; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; @@ -50,7 +51,7 @@ public class PrivGetCode extends AbstractBlockParameterMethod { protected BlockParameter blockParameter(final JsonRpcRequestContext request) { try { return request.getRequiredParameter(2, BlockParameter.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid block parameter (index 2)", RpcErrorType.INVALID_BLOCK_PARAMS, e); } @@ -62,7 +63,7 @@ public class PrivGetCode extends AbstractBlockParameterMethod { final String privacyGroupId; try { privacyGroupId = request.getRequiredParameter(0, String.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid privacy group ID parameter (index 0)", RpcErrorType.INVALID_PRIVACY_GROUP_PARAMS, @@ -71,7 +72,7 @@ public class PrivGetCode extends AbstractBlockParameterMethod { final Address address; try { address = request.getRequiredParameter(1, Address.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid address parameter (index 1)", RpcErrorType.INVALID_ADDRESS_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetEeaTransactionCount.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetEeaTransactionCount.java index 31bfc52c80..9f231f41c0 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetEeaTransactionCount.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetEeaTransactionCount.java @@ -22,6 +22,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.PrivacyIdProvider; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; @@ -69,21 +70,21 @@ public class PrivGetEeaTransactionCount implements JsonRpcMethod { final Address address; try { address = requestContext.getRequiredParameter(0, Address.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid address parameter (index 0)", RpcErrorType.INVALID_ADDRESS_PARAMS, e); } final String privateFrom; try { privateFrom = requestContext.getRequiredParameter(1, String.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid private from parameter (index 1)", RpcErrorType.INVALID_PRIVATE_FROM_PARAMS, e); } final String[] privateFor; try { privateFor = requestContext.getRequiredParameter(2, String[].class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid private for parameters (index 2)", RpcErrorType.INVALID_PRIVATE_FOR_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetLogs.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetLogs.java index d0c75da33f..6947ea5e54 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetLogs.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetLogs.java @@ -20,6 +20,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.FilterParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.PrivacyIdProvider; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; @@ -74,7 +75,7 @@ public class PrivGetLogs implements JsonRpcMethod { final FilterParameter filter; try { filter = requestContext.getRequiredParameter(1, FilterParameter.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid filter parameter (index 1)", RpcErrorType.INVALID_FILTER_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetPrivateTransaction.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetPrivateTransaction.java index 0629b2d55d..8779181599 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetPrivateTransaction.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetPrivateTransaction.java @@ -21,6 +21,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.PrivacyIdProvider; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; @@ -62,7 +63,7 @@ public class PrivGetPrivateTransaction implements JsonRpcMethod { final Hash hash; try { hash = requestContext.getRequiredParameter(0, Hash.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid transaction hash parameter (index 0)", RpcErrorType.INVALID_TRANSACTION_HASH_PARAMS, diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetTransactionCount.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetTransactionCount.java index 2cbcc65535..d8757dc2fb 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetTransactionCount.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetTransactionCount.java @@ -21,6 +21,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.PrivacyIdProvider; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; @@ -60,14 +61,14 @@ public class PrivGetTransactionCount implements JsonRpcMethod { final Address address; try { address = requestContext.getRequiredParameter(0, Address.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid address parameter (index 0)", RpcErrorType.INVALID_ADDRESS_PARAMS, e); } final String privacyGroupId; try { privacyGroupId = requestContext.getRequiredParameter(1, String.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid privacy group ID parameter (index 1)", RpcErrorType.INVALID_PRIVACY_GROUP_PARAMS, diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetTransactionReceipt.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetTransactionReceipt.java index a1844841f0..287793ddc0 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetTransactionReceipt.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetTransactionReceipt.java @@ -22,6 +22,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.PrivacyIdProvider; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; @@ -70,7 +71,7 @@ public class PrivGetTransactionReceipt implements JsonRpcMethod { final Hash pmtTransactionHash; try { pmtTransactionHash = requestContext.getRequiredParameter(0, Hash.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid transaction hash parameter (index 0)", RpcErrorType.INVALID_TRANSACTION_HASH_PARAMS, diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivNewFilter.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivNewFilter.java index e73b0c141c..49fc11f4b8 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivNewFilter.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivNewFilter.java @@ -20,6 +20,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonR import org.hyperledger.besu.ethereum.api.jsonrpc.internal.filter.FilterManager; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.FilterParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.PrivacyIdProvider; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; @@ -51,9 +52,9 @@ public class PrivNewFilter implements JsonRpcMethod { @Override public JsonRpcResponse response(final JsonRpcRequestContext request) { final String privacyGroupId; - try { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + try { privacyGroupId = request.getRequiredParameter(0, String.class); - } catch (Exception e) { + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid privacy group ID parameter (index 0)", RpcErrorType.INVALID_PRIVACY_GROUP_PARAMS, @@ -62,7 +63,7 @@ public class PrivNewFilter implements JsonRpcMethod { final FilterParameter filter; try { filter = request.getRequiredParameter(1, FilterParameter.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid filter parameter (index 1)", RpcErrorType.INVALID_FILTER_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivTraceTransaction.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivTraceTransaction.java index b1802b07eb..07d663bef5 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivTraceTransaction.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivTraceTransaction.java @@ -17,8 +17,10 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.TraceTransaction; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.PrivacyIdProvider; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.privateProcessor.PrivateBlockTracer; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; @@ -69,8 +71,24 @@ public class PrivTraceTransaction extends AbstractPrivateTraceByHash implements @Override public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { - final String privacyGroupId = requestContext.getRequiredParameter(0, String.class); - final Hash transactionHash = requestContext.getRequiredParameter(1, Hash.class); + final String privacyGroupId; + try { + privacyGroupId = requestContext.getRequiredParameter(0, String.class); + } catch (JsonRpcParameterException e) { + throw new InvalidJsonRpcParameters( + "Invalid privacy group ID parameter (index 0)", + RpcErrorType.INVALID_PRIVACY_GROUP_PARAMS, + e); + } + final Hash transactionHash; + try { + transactionHash = requestContext.getRequiredParameter(1, Hash.class); + } catch (JsonRpcParameterException e) { + throw new InvalidJsonRpcParameters( + "Invalid transaction hash parameter (index 1)", + RpcErrorType.INVALID_TRANSACTION_HASH_PARAMS, + e); + } LOG.trace("Received RPC rpcName={} txHash={}", getName(), transactionHash); if (privacyGroupId.isEmpty() || transactionHash.isEmpty()) { diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/privx/PrivxFindFlexiblePrivacyGroup.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/privx/PrivxFindFlexiblePrivacyGroup.java index e6cf056989..0a66d1aa73 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/privx/PrivxFindFlexiblePrivacyGroup.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/privx/PrivxFindFlexiblePrivacyGroup.java @@ -21,6 +21,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.PrivacyIdProvider; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; @@ -59,7 +60,7 @@ public class PrivxFindFlexiblePrivacyGroup implements JsonRpcMethod { final String[] addresses; try { addresses = requestContext.getRequiredParameter(0, String[].class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid address parameters (index 0)", RpcErrorType.INVALID_ADDRESS_PARAMS, e); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/subscription/request/SubscriptionRequestMapper.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/subscription/request/SubscriptionRequestMapper.java index 7235a81987..8bc3579849 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/subscription/request/SubscriptionRequestMapper.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/subscription/request/SubscriptionRequestMapper.java @@ -17,6 +17,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.websocket.subscription.request import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.FilterParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.UnsignedLongParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.websocket.methods.WebSocketRpcRequest; @@ -35,7 +36,7 @@ public class SubscriptionRequestMapper { final SubscriptionType subscriptionType; try { subscriptionType = webSocketRpcRequestBody.getRequiredParameter(0, SubscriptionType.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid subscription type parameter (index 0)", RpcErrorType.INVALID_SUBSCRIPTION_PARAMS, @@ -70,7 +71,7 @@ public class SubscriptionRequestMapper { final Optional params; try { params = webSocketRpcRequestBody.getOptionalParameter(1, SubscriptionParam.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid subscription parameter (index 1)", RpcErrorType.INVALID_SUBSCRIPTION_PARAMS, e); } @@ -87,7 +88,7 @@ public class SubscriptionRequestMapper { final FilterParameter filterParameter; try { filterParameter = request.getRequiredParameter(1, FilterParameter.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid filter parameters (index 1)", RpcErrorType.INVALID_FILTER_PARAMS, e); } @@ -104,7 +105,7 @@ public class SubscriptionRequestMapper { try { subscriptionId = webSocketRpcRequestBody.getRequiredParameter(0, UnsignedLongParameter.class).getValue(); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid subscription ID parameter (index 0)", RpcErrorType.INVALID_SUBSCRIPTION_PARAMS, @@ -125,7 +126,7 @@ public class SubscriptionRequestMapper { final String privacyGroupId; try { privacyGroupId = webSocketRpcRequestBody.getRequiredParameter(0, String.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid privacy group ID parameter (index 0)", RpcErrorType.INVALID_PRIVACY_GROUP_PARAMS, @@ -134,7 +135,7 @@ public class SubscriptionRequestMapper { final SubscriptionType subscriptionType; try { subscriptionType = webSocketRpcRequestBody.getRequiredParameter(1, SubscriptionType.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid subscription type parameter (index 1)", RpcErrorType.INVALID_SUBSCRIPTION_PARAMS, @@ -148,7 +149,7 @@ public class SubscriptionRequestMapper { try { filterParameter = jsonRpcRequestContext.getRequiredParameter(2, FilterParameter.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid filter parameter (index 2)", RpcErrorType.INVALID_FILTER_PARAMS, e); } @@ -180,7 +181,7 @@ public class SubscriptionRequestMapper { final String privacyGroupId; try { privacyGroupId = webSocketRpcRequestBody.getRequiredParameter(0, String.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid privacy group ID parameter (index 0)", RpcErrorType.INVALID_PRIVACY_GROUP_PARAMS, @@ -190,7 +191,7 @@ public class SubscriptionRequestMapper { try { subscriptionId = webSocketRpcRequestBody.getRequiredParameter(1, UnsignedLongParameter.class).getValue(); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid subscription ID parameter (index 1)", RpcErrorType.INVALID_SUBSCRIPTION_PARAMS, diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TxPoolBesuPendingTransactionsTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TxPoolBesuPendingTransactionsTest.java index 9cc6947b26..1eef04fb93 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TxPoolBesuPendingTransactionsTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TxPoolBesuPendingTransactionsTest.java @@ -201,7 +201,7 @@ public class TxPoolBesuPendingTransactionsTest { assertThatThrownBy(() -> method.response(request)) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Invalid pending transactions parameter (index 1)"); + .hasMessageContaining("Unknown field expected one of `eq`, `gt`, `lt`, `action`"); } @Test @@ -229,7 +229,7 @@ public class TxPoolBesuPendingTransactionsTest { assertThatThrownBy(() -> method.response(request)) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Invalid pending transactions parameter (index 1)"); + .hasMessageContaining("Only one operator per filter type allowed"); } @Test @@ -256,7 +256,7 @@ public class TxPoolBesuPendingTransactionsTest { assertThatThrownBy(() -> method.response(request)) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Invalid pending transactions parameter (index 1)"); + .hasMessageContaining("The `from` filter only supports the `eq` operator"); } @Test @@ -283,7 +283,7 @@ public class TxPoolBesuPendingTransactionsTest { assertThatThrownBy(() -> method.response(request)) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Invalid pending transactions parameter (index 1)"); + .hasMessageContaining("The `to` filter only supports the `eq` or `action` operator"); } private Set getTransactionPool() { diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EnginePreparePayloadDebugTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EnginePreparePayloadDebugTest.java index 4de9f8bb56..9c5067f7a8 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EnginePreparePayloadDebugTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EnginePreparePayloadDebugTest.java @@ -28,6 +28,7 @@ import org.hyperledger.besu.consensus.merge.blockcreation.PayloadIdentifier; import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.EnginePreparePayloadParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.EnginePreparePayloadResult; @@ -56,7 +57,7 @@ public class EnginePreparePayloadDebugTest { @Mock private EnginePreparePayloadParameter param; @BeforeEach - public void setUp() { + public void setUp() throws JsonRpcParameterException { when(protocolContext.safeConsensusContext(MergeContext.class)) .thenReturn(Optional.of(mergeContext)); when(requestContext.getOptionalParameter(0, EnginePreparePayloadParameter.class)) @@ -84,7 +85,7 @@ public class EnginePreparePayloadDebugTest { } @Test - public void shouldReturnPayloadIdWhenNoParams() { + public void shouldReturnPayloadIdWhenNoParams() throws JsonRpcParameterException { when(requestContext.getOptionalParameter(0, EnginePreparePayloadParameter.class)) .thenReturn(Optional.empty()); checkForPayloadId(); diff --git a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestGetLogHash.java b/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestGetLogHash.java index e4fd7bcff2..398d72d665 100644 --- a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestGetLogHash.java +++ b/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestGetLogHash.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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.api.jsonrpc.internal.response.RpcErrorType; @@ -45,7 +46,7 @@ public class TestGetLogHash implements JsonRpcMethod { final Hash txHash; try { txHash = requestContext.getRequiredParameter(0, Hash.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid transaction hash parameter (index 0)", RpcErrorType.INVALID_TRANSACTION_HASH_PARAMS, diff --git a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestImportRawBlock.java b/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestImportRawBlock.java index 516dc2f55f..580b107a8b 100644 --- a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestImportRawBlock.java +++ b/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestImportRawBlock.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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; @@ -56,7 +57,7 @@ public class TestImportRawBlock implements JsonRpcMethod { final String input; try { input = requestContext.getRequiredParameter(0, String.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid block parameter (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e); } diff --git a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestMineBlocks.java b/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestMineBlocks.java index 7907cee3f7..80a4872442 100644 --- a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestMineBlocks.java +++ b/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestMineBlocks.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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.api.jsonrpc.internal.response.RpcErrorType; @@ -49,7 +50,7 @@ public class TestMineBlocks implements JsonRpcMethod { long blocksToMine = 0; try { blocksToMine = requestContext.getRequiredParameter(0, Long.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid blocks to mine (index 0)", RpcErrorType.INVALID_BLOCK_COUNT_PARAMS, e); } diff --git a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestModifyTimestamp.java b/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestModifyTimestamp.java index d9cfafbaea..717cf41b45 100644 --- a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestModifyTimestamp.java +++ b/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestModifyTimestamp.java @@ -17,6 +17,7 @@ package org.hyperledger.besu.ethereum.retesteth.methods; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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.api.jsonrpc.internal.response.RpcErrorType; @@ -40,7 +41,7 @@ public class TestModifyTimestamp implements JsonRpcMethod { final long epochSeconds; try { epochSeconds = requestContext.getRequiredParameter(0, Long.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid timestamp parameter (index 0)", RpcErrorType.INVALID_TIMESTAMP_PARAMS, e); } diff --git a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestRewindToBlock.java b/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestRewindToBlock.java index d5adb36a24..d9b847af42 100644 --- a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestRewindToBlock.java +++ b/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestRewindToBlock.java @@ -17,6 +17,7 @@ package org.hyperledger.besu.ethereum.retesteth.methods; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; 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.api.jsonrpc.internal.response.RpcErrorType; @@ -41,7 +42,7 @@ public class TestRewindToBlock implements JsonRpcMethod { final long blockNumber; try { blockNumber = requestContext.getRequiredParameter(0, Long.TYPE); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid block number parameter (index 0)", RpcErrorType.INVALID_BLOCK_NUMBER_PARAMS, e); } diff --git a/ethereum/stratum/src/main/java/org/hyperledger/besu/ethereum/stratum/Stratum1Protocol.java b/ethereum/stratum/src/main/java/org/hyperledger/besu/ethereum/stratum/Stratum1Protocol.java index 308d15f6f1..4311647948 100644 --- a/ethereum/stratum/src/main/java/org/hyperledger/besu/ethereum/stratum/Stratum1Protocol.java +++ b/ethereum/stratum/src/main/java/org/hyperledger/besu/ethereum/stratum/Stratum1Protocol.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.blockcreation.MiningCoordinator; @@ -175,18 +176,24 @@ public class Stratum1Protocol implements StratumProtocol { long nonce; try { nonce = Bytes.fromHexString(message.getRequiredParameter(2, String.class)).getLong(0); - } catch (Exception e) { + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid nonce parameter (index 2)", RpcErrorType.INVALID_NONCE_PARAMS, e); } - Hash mixHash = null; + Hash mixHash; try { mixHash = Hash.fromHexString(message.getRequiredParameter(4, String.class)); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid mix hash parameter (index 4)", RpcErrorType.INVALID_MIX_HASH_PARAMS, e); } - Bytes powHash = Bytes.fromHexString(message.getRequiredParameter(3, String.class)); + Bytes powHash; + try { + powHash = Bytes.fromHexString(message.getRequiredParameter(3, String.class)); + } catch (JsonRpcParameterException e) { + throw new InvalidJsonRpcParameters( + "Invalid PoW hash parameter (index 3)", RpcErrorType.INVALID_POW_HASH_PARAMS, e); + } boolean result = false; final PoWSolution solution = new PoWSolution(nonce, mixHash, null, powHash); if (currentInput.getPrePowHash().equals(solution.getPowHash())) { diff --git a/ethereum/stratum/src/main/java/org/hyperledger/besu/ethereum/stratum/StratumProtocol.java b/ethereum/stratum/src/main/java/org/hyperledger/besu/ethereum/stratum/StratumProtocol.java index 3f13a56880..a6a8ac8807 100644 --- a/ethereum/stratum/src/main/java/org/hyperledger/besu/ethereum/stratum/StratumProtocol.java +++ b/ethereum/stratum/src/main/java/org/hyperledger/besu/ethereum/stratum/StratumProtocol.java @@ -16,6 +16,7 @@ package org.hyperledger.besu.ethereum.stratum; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.blockcreation.MiningCoordinator; @@ -83,14 +84,14 @@ public interface StratumProtocol { final String hashRate; try { hashRate = message.getRequiredParameter(0, String.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid hash rate parameter (index 0)", RpcErrorType.INVALID_HASH_RATE_PARAMS, e); } final String id; try { id = message.getRequiredParameter(1, String.class); - } catch (Exception e) { // TODO:replace with JsonRpcParameter.JsonRpcParameterException + } catch (JsonRpcParameterException e) { throw new InvalidJsonRpcParameters( "Invalid sealer ID parameter (index 1)", RpcErrorType.INVALID_SEALER_ID_PARAMS, e); } From bfeb74864a2d24f59560aa35f11cc64795cbe127 Mon Sep 17 00:00:00 2001 From: Sally MacFarlane Date: Wed, 21 Aug 2024 02:29:50 +1000 Subject: [PATCH 140/259] update error message in test files (#7493) Signed-off-by: Sally MacFarlane --- .../05_shanghai_prepare_payload_invalid_null_withdrawals.json | 2 +- .../09_shanghai_newPayloadV2_invalid_null_withdrawals.json | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/shanghai/test-cases/05_shanghai_prepare_payload_invalid_null_withdrawals.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/shanghai/test-cases/05_shanghai_prepare_payload_invalid_null_withdrawals.json index ac5947c79b..ec5e225179 100644 --- a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/shanghai/test-cases/05_shanghai_prepare_payload_invalid_null_withdrawals.json +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/shanghai/test-cases/05_shanghai_prepare_payload_invalid_null_withdrawals.json @@ -21,7 +21,7 @@ "id" : 67, "error" : { "code" : -32602, - "message" : "Invalid params" + "message" : "Invalid withdrawals" } }, "statusCode" : 200 diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/shanghai/test-cases/09_shanghai_newPayloadV2_invalid_null_withdrawals.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/shanghai/test-cases/09_shanghai_newPayloadV2_invalid_null_withdrawals.json index 4171864804..0fe0a15dfc 100644 --- a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/shanghai/test-cases/09_shanghai_newPayloadV2_invalid_null_withdrawals.json +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/shanghai/test-cases/09_shanghai_newPayloadV2_invalid_null_withdrawals.json @@ -28,8 +28,7 @@ "id": 67, "error": { "code": -32602, - "message": "Invalid params", - "data": "Invalid withdrawals" + "message": "Invalid withdrawals" } }, "statusCode": 200 From aaf74a60f7399a144d8aadc6992491939fad80e9 Mon Sep 17 00:00:00 2001 From: Fabio Di Fabio Date: Wed, 21 Aug 2024 01:02:53 +0200 Subject: [PATCH 141/259] Update parameterized acceptance tests so they enumerate with --dry-run (#7498) Signed-off-by: Fabio Di Fabio --- .../besu/tests/acceptance/dsl/AcceptanceTestBase.java | 8 ++++++++ .../tests/acceptance/dsl/AcceptanceTestBaseJunit5.java | 8 ++++++++ .../tests/acceptance/jsonrpc/AbstractJsonRpcTest.java | 8 ++++++++ 3 files changed, 24 insertions(+) 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 cac4deb9d9..4072c6f1bc 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 @@ -57,6 +57,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import org.junit.After; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -183,4 +184,11 @@ public class AcceptanceTestBase { assertThat(node.execute(ethTransactions.blockNumber())) .isGreaterThanOrEqualTo(BigInteger.valueOf(blockchainHeight))); } + + @Test + public 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/AcceptanceTestBaseJunit5.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/AcceptanceTestBaseJunit5.java index 92d9273e8f..0cf24b5736 100644 --- 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 @@ -58,6 +58,7 @@ 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; @@ -196,4 +197,11 @@ public class AcceptanceTestBaseJunit5 { 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/tests/src/test/java/org/hyperledger/besu/tests/acceptance/jsonrpc/AbstractJsonRpcTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/jsonrpc/AbstractJsonRpcTest.java index d88b1ed8b5..1290749176 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/jsonrpc/AbstractJsonRpcTest.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/jsonrpc/AbstractJsonRpcTest.java @@ -40,6 +40,7 @@ import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response; +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; @@ -147,4 +148,11 @@ abstract class AbstractJsonRpcTest { return Arrays.stream(testCasesList).sorted().map(File::toURI).map(Arguments::of); } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } From fd077a72731c8610cffcf3d0fecde8353ffc2fc2 Mon Sep 17 00:00:00 2001 From: Fabio Di Fabio Date: Wed, 21 Aug 2024 01:24:46 +0200 Subject: [PATCH 142/259] Revert "Dagger controller tests (#7341)" (#7497) This reverts commit 38a025b8708f2c8f0daa31db1f30e995d9d15dd8. # Conflicts: # acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/ThreadBesuNodeRunner.java Signed-off-by: Fabio Di Fabio --- .../perm/AllowListContainsKeyAndValue.java | 6 - .../dsl/node/ThreadBesuNodeRunner.java | 378 ++++++------------ .../acceptance/dsl/privacy/PrivacyNode.java | 2 +- ...ClusterThreadNodeRunnerAcceptanceTest.java | 2 +- besu/build.gradle | 2 - .../controller/BesuControllerBuilder.java | 1 - .../besu/services/BlockchainServiceImpl.java | 2 - .../services/PermissioningServiceImpl.java | 2 - .../besu/services/RpcEndpointServiceImpl.java | 2 - .../services/SecurityModuleServiceImpl.java | 7 +- .../besu/services/StorageServiceImpl.java | 2 - .../TransactionPoolValidatorServiceImpl.java | 6 +- .../TransactionSelectionServiceImpl.java | 6 +- .../TransactionSimulationServiceImpl.java | 2 - .../besu/FlexGroupPrivacyTest.java | 168 -------- .../hyperledger/besu/PrivacyReorgTest.java | 151 ++----- .../org/hyperledger/besu/PrivacyTest.java | 171 ++++---- .../java/org/hyperledger/besu/RunnerTest.java | 3 - .../chainexport/RlpBlockExporterTest.java | 3 - .../chainimport/JsonBlockImporterTest.java | 3 - .../chainimport/RlpBlockImporterTest.java | 5 - .../besu/components/EnclaveModule.java | 98 ----- .../besu/components/GenesisConfigModule.java | 38 -- .../components/MockBesuCommandModule.java | 50 --- .../components/NoOpMetricsSystemModule.java | 40 -- .../components/PrivacyParametersModule.java | 47 --- .../besu/components/PrivacyTestModule.java | 111 ----- .../AbstractBftBesuControllerBuilderTest.java | 2 - .../CliqueBesuControllerBuilderTest.java | 2 - .../MergeBesuControllerBuilderTest.java | 2 - .../besu/ethereum/p2p/peers/EnodeURLImpl.java | 13 +- 31 files changed, 262 insertions(+), 1065 deletions(-) delete mode 100644 besu/src/test/java/org/hyperledger/besu/FlexGroupPrivacyTest.java delete mode 100644 besu/src/test/java/org/hyperledger/besu/components/EnclaveModule.java delete mode 100644 besu/src/test/java/org/hyperledger/besu/components/GenesisConfigModule.java delete mode 100644 besu/src/test/java/org/hyperledger/besu/components/MockBesuCommandModule.java delete mode 100644 besu/src/test/java/org/hyperledger/besu/components/NoOpMetricsSystemModule.java delete mode 100644 besu/src/test/java/org/hyperledger/besu/components/PrivacyParametersModule.java delete mode 100644 besu/src/test/java/org/hyperledger/besu/components/PrivacyTestModule.java diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/perm/AllowListContainsKeyAndValue.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/perm/AllowListContainsKeyAndValue.java index 0913fd227f..a2ffc9b36d 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/perm/AllowListContainsKeyAndValue.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/perm/AllowListContainsKeyAndValue.java @@ -24,16 +24,11 @@ import org.hyperledger.besu.tests.acceptance.dsl.node.Node; import java.nio.file.Path; import java.util.Collection; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - public class AllowListContainsKeyAndValue implements Condition { private final ALLOWLIST_TYPE allowlistType; private final Collection allowlistValues; private final Path configFilePath; - private static final Logger LOG = LoggerFactory.getLogger(AllowListContainsKeyAndValue.class); - public AllowListContainsKeyAndValue( final ALLOWLIST_TYPE allowlistType, final Collection allowlistValues, @@ -52,7 +47,6 @@ public class AllowListContainsKeyAndValue implements Condition { allowlistType, allowlistValues, configFilePath); } catch (final Exception e) { result = false; - LOG.error("Error verifying allowlist contains key and value", e); } assertThat(result).isTrue(); } 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 001406cb78..c662196092 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 @@ -18,13 +18,8 @@ import static org.hyperledger.besu.controller.BesuController.DATABASE_PATH; import org.hyperledger.besu.Runner; import org.hyperledger.besu.RunnerBuilder; -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.config.EthNetworkConfig; import org.hyperledger.besu.cli.config.NetworkName; -import org.hyperledger.besu.components.BesuComponent; import org.hyperledger.besu.config.GenesisConfigFile; import org.hyperledger.besu.controller.BesuController; import org.hyperledger.besu.controller.BesuControllerBuilder; @@ -36,28 +31,23 @@ import org.hyperledger.besu.ethereum.api.ApiConfiguration; import org.hyperledger.besu.ethereum.api.graphql.GraphQLConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.InProcessRpcConfiguration; import org.hyperledger.besu.ethereum.core.ImmutableMiningParameters; -import org.hyperledger.besu.ethereum.core.MiningParameters; import org.hyperledger.besu.ethereum.core.plugins.PluginConfiguration; import org.hyperledger.besu.ethereum.eth.EthProtocolConfiguration; import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration; -import org.hyperledger.besu.ethereum.eth.transactions.BlobCacheModule; import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration; import org.hyperledger.besu.ethereum.p2p.peers.EnodeURLImpl; 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.trie.diffbased.bonsai.cache.BonsaiCachedMerkleTrieLoaderModule; import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; import org.hyperledger.besu.evm.internal.EvmConfiguration; -import org.hyperledger.besu.metrics.MetricsSystemModule; +import org.hyperledger.besu.metrics.MetricsSystemFactory; import org.hyperledger.besu.metrics.ObservableMetricsSystem; -import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration; import org.hyperledger.besu.plugin.data.EnodeURL; import org.hyperledger.besu.plugin.services.BesuConfiguration; import org.hyperledger.besu.plugin.services.BesuEvents; import org.hyperledger.besu.plugin.services.BlockchainService; -import org.hyperledger.besu.plugin.services.MetricsSystem; import org.hyperledger.besu.plugin.services.PermissioningService; import org.hyperledger.besu.plugin.services.PicoCLIOptions; import org.hyperledger.besu.plugin.services.PrivacyPluginService; @@ -81,27 +71,17 @@ import org.hyperledger.besu.services.StorageServiceImpl; 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 java.io.File; -import java.io.IOException; -import java.nio.file.Files; import java.nio.file.Path; import java.time.Clock; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; -import javax.inject.Inject; -import javax.inject.Named; -import javax.inject.Singleton; -import dagger.Component; -import dagger.Module; -import dagger.Provides; import io.opentelemetry.api.GlobalOpenTelemetry; import io.vertx.core.Vertx; import org.slf4j.Logger; @@ -117,6 +97,60 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner { private final Map besuPluginContextMap = new ConcurrentHashMap<>(); + private BesuPluginContextImpl buildPluginContext( + final BesuNode node, + final StorageServiceImpl storageService, + final SecurityModuleServiceImpl securityModuleService, + final TransactionSimulationServiceImpl transactionSimulationServiceImpl, + final TransactionSelectionServiceImpl transactionSelectionServiceImpl, + final TransactionPoolValidatorServiceImpl transactionPoolValidatorServiceImpl, + final BlockchainServiceImpl blockchainServiceImpl, + final RpcEndpointServiceImpl rpcEndpointServiceImpl, + final BesuConfiguration commonPluginConfiguration, + final PermissioningServiceImpl permissioningService) { + final CommandLine commandLine = new CommandLine(CommandSpec.create()); + final BesuPluginContextImpl besuPluginContext = new BesuPluginContextImpl(); + besuPluginContext.addService(StorageService.class, storageService); + besuPluginContext.addService(SecurityModuleService.class, securityModuleService); + besuPluginContext.addService(PicoCLIOptions.class, new PicoCLIOptionsImpl(commandLine)); + besuPluginContext.addService(RpcEndpointService.class, rpcEndpointServiceImpl); + besuPluginContext.addService( + TransactionSelectionService.class, transactionSelectionServiceImpl); + besuPluginContext.addService( + TransactionPoolValidatorService.class, transactionPoolValidatorServiceImpl); + besuPluginContext.addService( + TransactionSimulationService.class, transactionSimulationServiceImpl); + besuPluginContext.addService(BlockchainService.class, blockchainServiceImpl); + besuPluginContext.addService(BesuConfiguration.class, commonPluginConfiguration); + + final Path pluginsPath; + final String pluginDir = System.getProperty("besu.plugins.dir"); + if (pluginDir == null || pluginDir.isEmpty()) { + pluginsPath = node.homeDirectory().resolve("plugins"); + final File pluginsDirFile = pluginsPath.toFile(); + if (!pluginsDirFile.isDirectory()) { + pluginsDirFile.mkdirs(); + pluginsDirFile.deleteOnExit(); + } + System.setProperty("besu.plugins.dir", pluginsPath.toString()); + } else { + pluginsPath = Path.of(pluginDir); + } + + besuPluginContext.addService(BesuConfiguration.class, commonPluginConfiguration); + besuPluginContext.addService(PermissioningService.class, permissioningService); + besuPluginContext.addService(PrivacyPluginService.class, new PrivacyPluginServiceImpl()); + + besuPluginContext.registerPlugins( + new PluginConfiguration.Builder().pluginsDir(pluginsPath).build()); + + commandLine.parseArgs(node.getConfiguration().getExtraCLIOptions().toArray(new String[0])); + + // register built-in plugins + new RocksDBPlugin().register(besuPluginContext); + return besuPluginContext; + } + @Override public void startNode(final BesuNode node) { @@ -129,9 +163,8 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner { throw new UnsupportedOperationException("commands are not supported with thread runner"); } - AcceptanceTestBesuComponent component = - DaggerThreadBesuNodeRunner_AcceptanceTestBesuComponent.create(); - + final StorageServiceImpl storageService = new StorageServiceImpl(); + final SecurityModuleServiceImpl securityModuleService = new SecurityModuleServiceImpl(); final TransactionSimulationServiceImpl transactionSimulationServiceImpl = new TransactionSimulationServiceImpl(); final TransactionSelectionServiceImpl transactionSelectionServiceImpl = @@ -154,22 +187,49 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner { .withMiningParameters(miningParameters); final BesuPluginContextImpl besuPluginContext = - besuPluginContextMap.computeIfAbsent(node, n -> component.getBesuPluginContext()); + besuPluginContextMap.computeIfAbsent( + node, + n -> + buildPluginContext( + node, + storageService, + securityModuleService, + transactionSimulationServiceImpl, + transactionSelectionServiceImpl, + transactionPoolValidatorServiceImpl, + blockchainServiceImpl, + rpcEndpointServiceImpl, + commonPluginConfiguration, + permissioningService)); GlobalOpenTelemetry.resetForTest(); - final ObservableMetricsSystem metricsSystem = component.getObservableMetricsSystem(); + final ObservableMetricsSystem metricsSystem = + MetricsSystemFactory.create(node.getMetricsConfiguration()); final List bootnodes = node.getConfiguration().getBootnodes().stream() .map(EnodeURLImpl::fromURI) .collect(Collectors.toList()); - - final EthNetworkConfig.Builder networkConfigBuilder = component.ethNetworkConfigBuilder(); - networkConfigBuilder.setBootNodes(bootnodes); + final NetworkName network = node.getNetwork() == null ? NetworkName.DEV : node.getNetwork(); + final EthNetworkConfig.Builder networkConfigBuilder = + new EthNetworkConfig.Builder(EthNetworkConfig.getNetworkConfig(network)) + .setBootNodes(bootnodes); node.getConfiguration() .getGenesisConfig() .map(GenesisConfigFile::fromConfig) .ifPresent(networkConfigBuilder::setGenesisConfigFile); final EthNetworkConfig ethNetworkConfig = networkConfigBuilder.build(); + final SynchronizerConfiguration synchronizerConfiguration = + new SynchronizerConfiguration.Builder().build(); + final BesuControllerBuilder builder = + new BesuController.Builder() + .fromEthNetworkConfig(ethNetworkConfig, synchronizerConfiguration.getSyncMode()); + + final KeyValueStorageProvider storageProvider = + new KeyValueStorageProviderBuilder() + .withStorageFactory(storageService.getByName("rocksdb").get()) + .withCommonConfiguration(commonPluginConfiguration) + .withMetricsSystem(metricsSystem) + .build(); final TransactionPoolConfiguration txPoolConfig = ImmutableTransactionPoolConfiguration.builder() @@ -178,20 +238,35 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner { .transactionPoolValidatorService(transactionPoolValidatorServiceImpl) .build(); - final BesuControllerBuilder builder = component.besuControllerBuilder(); - builder.isRevertReasonEnabled(node.isRevertReasonEnabled()); - builder.networkConfiguration(node.getNetworkingConfiguration()); - builder.transactionPoolConfiguration(txPoolConfig); - builder.dataDirectory(dataDir); - builder.nodeKey(new NodeKey(new KeyPairSecurityModule(KeyPairUtil.loadKeyPair(dataDir)))); - builder.privacyParameters(node.getPrivacyParameters()); final InProcessRpcConfiguration inProcessRpcConfiguration = node.inProcessRpcConfiguration(); + final int maxPeers = 25; + + builder + .synchronizerConfiguration(new SynchronizerConfiguration.Builder().build()) + .dataDirectory(node.homeDirectory()) + .miningParameters(miningParameters) + .privacyParameters(node.getPrivacyParameters()) + .nodeKey(new NodeKey(new KeyPairSecurityModule(KeyPairUtil.loadKeyPair(dataDir)))) + .metricsSystem(metricsSystem) + .transactionPoolConfiguration(txPoolConfig) + .dataStorageConfiguration(DataStorageConfiguration.DEFAULT_FOREST_CONFIG) + .ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig()) + .clock(Clock.systemUTC()) + .isRevertReasonEnabled(node.isRevertReasonEnabled()) + .storageProvider(storageProvider) + .gasLimitCalculator(GasLimitCalculator.constant()) + .evmConfiguration(EvmConfiguration.DEFAULT) + .maxPeers(maxPeers) + .maxRemotelyInitiatedPeers(15) + .networkConfiguration(node.getNetworkingConfiguration()) + .randomPeerPriority(false); + node.getGenesisConfig() .map(GenesisConfigFile::fromConfig) .ifPresent(builder::genesisConfigFile); - final BesuController besuController = component.besuController(); + final BesuController besuController = builder.build(); initTransactionSimulationService( transactionSimulationServiceImpl, besuController, node.getApiConfiguration()); @@ -225,10 +300,11 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner { .collect(Collectors.toList())) .besuPluginContext(besuPluginContext) .autoLogBloomCaching(false) - .storageProvider(besuController.getStorageProvider()) + .storageProvider(storageProvider) .rpcEndpointService(rpcEndpointServiceImpl) .inProcessRpcConfiguration(inProcessRpcConfiguration); node.engineRpcConfiguration().ifPresent(runnerBuilder::engineJsonRpcConfiguration); + besuPluginContext.beforeExternalServices(); final Runner runner = runnerBuilder.build(); @@ -321,230 +397,4 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner { public String getConsoleContents() { throw new RuntimeException("Console contents can only be captured in process execution"); } - - @Module - @SuppressWarnings("CloseableProvides") - static class BesuControllerModule { - @Provides - @Singleton - public SynchronizerConfiguration provideSynchronizationConfiguration() { - final SynchronizerConfiguration synchronizerConfiguration = - SynchronizerConfiguration.builder().build(); - return synchronizerConfiguration; - } - - @Singleton - @Provides - public BesuControllerBuilder provideBesuControllerBuilder( - final EthNetworkConfig ethNetworkConfig, - final SynchronizerConfiguration synchronizerConfiguration) { - - final BesuControllerBuilder builder = - new BesuController.Builder() - .fromEthNetworkConfig(ethNetworkConfig, synchronizerConfiguration.getSyncMode()); - return builder; - } - - @Provides - public BesuController provideBesuController( - final SynchronizerConfiguration synchronizerConfiguration, - final BesuControllerBuilder builder, - final ObservableMetricsSystem metricsSystem, - final KeyValueStorageProvider storageProvider, - final MiningParameters miningParameters) { - - builder - .synchronizerConfiguration(synchronizerConfiguration) - .metricsSystem(metricsSystem) - .dataStorageConfiguration(DataStorageConfiguration.DEFAULT_FOREST_CONFIG) - .ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig()) - .clock(Clock.systemUTC()) - .storageProvider(storageProvider) - .gasLimitCalculator(GasLimitCalculator.constant()) - .evmConfiguration(EvmConfiguration.DEFAULT) - .maxPeers(25) - .maxRemotelyInitiatedPeers(15) - .miningParameters(miningParameters) - .randomPeerPriority(false) - .besuComponent(null); - return builder.build(); - } - - @Provides - @Singleton - public EthNetworkConfig.Builder provideEthNetworkConfigBuilder() { - final EthNetworkConfig.Builder networkConfigBuilder = - new EthNetworkConfig.Builder(EthNetworkConfig.getNetworkConfig(NetworkName.DEV)); - return networkConfigBuilder; - } - - @Provides - public EthNetworkConfig provideEthNetworkConfig( - final EthNetworkConfig.Builder networkConfigBuilder) { - - final EthNetworkConfig ethNetworkConfig = networkConfigBuilder.build(); - return ethNetworkConfig; - } - - @Provides - @Named("besuPluginContext") - public BesuPluginContextImpl providePluginContext( - final StorageServiceImpl storageService, - final SecurityModuleServiceImpl securityModuleService, - final TransactionSimulationServiceImpl transactionSimulationServiceImpl, - final TransactionSelectionServiceImpl transactionSelectionServiceImpl, - final TransactionPoolValidatorServiceImpl transactionPoolValidatorServiceImpl, - final BlockchainServiceImpl blockchainServiceImpl, - final RpcEndpointServiceImpl rpcEndpointServiceImpl, - final BesuConfiguration commonPluginConfiguration, - final PermissioningServiceImpl permissioningService) { - final CommandLine commandLine = new CommandLine(CommandSpec.create()); - final BesuPluginContextImpl besuPluginContext = new BesuPluginContextImpl(); - besuPluginContext.addService(StorageService.class, storageService); - besuPluginContext.addService(SecurityModuleService.class, securityModuleService); - besuPluginContext.addService(PicoCLIOptions.class, new PicoCLIOptionsImpl(commandLine)); - besuPluginContext.addService(RpcEndpointService.class, rpcEndpointServiceImpl); - besuPluginContext.addService( - TransactionSelectionService.class, transactionSelectionServiceImpl); - besuPluginContext.addService( - TransactionPoolValidatorService.class, transactionPoolValidatorServiceImpl); - besuPluginContext.addService( - TransactionSimulationService.class, transactionSimulationServiceImpl); - besuPluginContext.addService(BlockchainService.class, blockchainServiceImpl); - besuPluginContext.addService(BesuConfiguration.class, commonPluginConfiguration); - - final Path pluginsPath; - final String pluginDir = System.getProperty("besu.plugins.dir"); - if (pluginDir == null || pluginDir.isEmpty()) { - // pluginsPath = node.homeDirectory().resolve("plugins"); - pluginsPath = commonPluginConfiguration.getDataPath().resolve("plugins"); - final File pluginsDirFile = pluginsPath.toFile(); - if (!pluginsDirFile.isDirectory()) { - pluginsDirFile.mkdirs(); - pluginsDirFile.deleteOnExit(); - } - System.setProperty("besu.plugins.dir", pluginsPath.toString()); - } else { - pluginsPath = Path.of(pluginDir); - } - - besuPluginContext.addService(BesuConfiguration.class, commonPluginConfiguration); - besuPluginContext.addService(PermissioningService.class, permissioningService); - besuPluginContext.addService(PrivacyPluginService.class, new PrivacyPluginServiceImpl()); - - besuPluginContext.registerPlugins( - new PluginConfiguration.Builder().pluginsDir(pluginsPath).build()); - - // register built-in plugins - new RocksDBPlugin().register(besuPluginContext); - return besuPluginContext; - } - - @Provides - public KeyValueStorageProvider provideKeyValueStorageProvider( - final BesuConfiguration commonPluginConfiguration, final MetricsSystem metricsSystem) { - - final StorageServiceImpl storageService = new StorageServiceImpl(); - storageService.registerKeyValueStorage( - new InMemoryStoragePlugin.InMemoryKeyValueStorageFactory("memory")); - final KeyValueStorageProvider storageProvider = - new KeyValueStorageProviderBuilder() - .withStorageFactory(storageService.getByName("memory").get()) - .withCommonConfiguration(commonPluginConfiguration) - .withMetricsSystem(metricsSystem) - .build(); - - return storageProvider; - } - - @Provides - public MiningParameters provideMiningParameters( - final TransactionSelectionServiceImpl transactionSelectionServiceImpl) { - final var miningParameters = - ImmutableMiningParameters.builder() - .transactionSelectionService(transactionSelectionServiceImpl) - .build(); - - return miningParameters; - } - - @Provides - Path provideDataDir() { - try { - return Files.createTempDirectory("acctest"); - } catch (final IOException e) { - throw new RuntimeException("Unable to create temporary data directory", e); - } - } - - @Provides - @Inject - BesuConfiguration provideBesuConfiguration(final Path dataDir) { - final BesuConfigurationImpl commonPluginConfiguration = new BesuConfigurationImpl(); - commonPluginConfiguration.init( - dataDir, dataDir.resolve(DATABASE_PATH), DataStorageConfiguration.DEFAULT_FOREST_CONFIG); - return commonPluginConfiguration; - } - - @Provides - TransactionPoolConfiguration provideTransactionPoolConfiguration( - final BesuNode node, - final TransactionPoolValidatorServiceImpl transactionPoolValidatorServiceImpl) { - return ImmutableTransactionPoolConfiguration.builder() - .from(node.getTransactionPoolConfiguration()) - .strictTransactionReplayProtectionEnabled(node.isStrictTxReplayProtectionEnabled()) - .transactionPoolValidatorService(transactionPoolValidatorServiceImpl) - .build(); - } - } - - @Module - static class MockBesuCommandModule { - - @Provides - BesuCommand provideBesuCommand(final AcceptanceTestBesuComponent component) { - final BesuCommand besuCommand = - new BesuCommand( - component, - RlpBlockImporter::new, - JsonBlockImporter::new, - RlpBlockExporter::new, - new RunnerBuilder(), - new BesuController.Builder(), - Optional.ofNullable(component.getBesuPluginContext()).orElse(null), - System.getenv()); - besuCommand.toCommandLine(); - return besuCommand; - } - - @Provides - @Singleton - MetricsConfiguration provideMetricsConfiguration() { - return MetricsConfiguration.builder().build(); - } - - @Provides - @Named("besuCommandLogger") - @Singleton - Logger provideBesuCommandLogger() { - return LoggerFactory.getLogger(MockBesuCommandModule.class); - } - } - - @Singleton - @Component( - modules = { - ThreadBesuNodeRunner.BesuControllerModule.class, - ThreadBesuNodeRunner.MockBesuCommandModule.class, - BonsaiCachedMerkleTrieLoaderModule.class, - MetricsSystemModule.class, - BlobCacheModule.class - }) - public interface AcceptanceTestBesuComponent extends BesuComponent { - BesuController besuController(); - - BesuControllerBuilder besuControllerBuilder(); // TODO: needing this sucks - - EthNetworkConfig.Builder ethNetworkConfigBuilder(); - } } diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/PrivacyNode.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/PrivacyNode.java index d54bf90872..520cd7d574 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/PrivacyNode.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/PrivacyNode.java @@ -276,7 +276,7 @@ public class PrivacyNode implements AutoCloseable { final Path dataLocation, final Path dbLocation) { final var besuConfiguration = new BesuConfigurationImpl(); besuConfiguration - .init(dataLocation, dbLocation, besuConfig.getDataStorageConfiguration()) + .init(dataLocation, dbLocation, null) .withMiningParameters(besuConfig.getMiningParameters()); return new PrivacyKeyValueStorageProviderBuilder() .withStorageFactory( diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bootstrap/ClusterThreadNodeRunnerAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bootstrap/ClusterThreadNodeRunnerAcceptanceTest.java index 39cc5ad26f..8fbd0d3d62 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bootstrap/ClusterThreadNodeRunnerAcceptanceTest.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bootstrap/ClusterThreadNodeRunnerAcceptanceTest.java @@ -38,7 +38,7 @@ public class ClusterThreadNodeRunnerAcceptanceTest extends AcceptanceTestBase { final BesuNodeRunner besuNodeRunner = new ThreadBesuNodeRunner(); noDiscoveryCluster = new Cluster(clusterConfiguration, net, besuNodeRunner); final BesuNode noDiscoveryNode = besu.createNodeWithNoDiscovery("noDiscovery"); - fullNode = besu.createArchiveNode("archive"); + fullNode = besu.createArchiveNode("node2"); noDiscoveryCluster.start(noDiscoveryNode, fullNode); } diff --git a/besu/build.gradle b/besu/build.gradle index 7eef4a216c..286ca7a30f 100644 --- a/besu/build.gradle +++ b/besu/build.gradle @@ -104,8 +104,6 @@ dependencies { testImplementation 'org.mockito:mockito-core' testImplementation 'org.testcontainers:testcontainers' testImplementation 'tech.pegasys.discovery:discovery' - testImplementation 'com.google.dagger:dagger' annotationProcessor 'com.google.dagger:dagger-compiler' - testAnnotationProcessor 'com.google.dagger:dagger-compiler' } 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 6bb3fb117c..ddb75fcded 100644 --- a/besu/src/main/java/org/hyperledger/besu/controller/BesuControllerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/controller/BesuControllerBuilder.java @@ -552,7 +552,6 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides checkNotNull(evmConfiguration, "Missing evm config"); checkNotNull(networkingConfiguration, "Missing network configuration"); checkNotNull(dataStorageConfiguration, "Missing data storage configuration"); - prepForBuild(); final ProtocolSchedule protocolSchedule = createProtocolSchedule(); diff --git a/besu/src/main/java/org/hyperledger/besu/services/BlockchainServiceImpl.java b/besu/src/main/java/org/hyperledger/besu/services/BlockchainServiceImpl.java index f10ebcce47..1f014ee061 100644 --- a/besu/src/main/java/org/hyperledger/besu/services/BlockchainServiceImpl.java +++ b/besu/src/main/java/org/hyperledger/besu/services/BlockchainServiceImpl.java @@ -34,7 +34,6 @@ import java.util.List; import java.util.Optional; import java.util.function.Supplier; import java.util.stream.Collectors; -import javax.inject.Inject; /** The Blockchain service implementation. */ @Unstable @@ -45,7 +44,6 @@ public class BlockchainServiceImpl implements BlockchainService { private MutableBlockchain blockchain; /** Instantiates a new Blockchain service implementation. */ - @Inject public BlockchainServiceImpl() {} /** diff --git a/besu/src/main/java/org/hyperledger/besu/services/PermissioningServiceImpl.java b/besu/src/main/java/org/hyperledger/besu/services/PermissioningServiceImpl.java index e43bf1c054..eda202f6d4 100644 --- a/besu/src/main/java/org/hyperledger/besu/services/PermissioningServiceImpl.java +++ b/besu/src/main/java/org/hyperledger/besu/services/PermissioningServiceImpl.java @@ -19,7 +19,6 @@ import org.hyperledger.besu.plugin.services.permissioning.NodeConnectionPermissi import org.hyperledger.besu.plugin.services.permissioning.NodeMessagePermissioningProvider; import java.util.List; -import javax.inject.Inject; import com.google.common.collect.Lists; @@ -30,7 +29,6 @@ public class PermissioningServiceImpl implements PermissioningService { Lists.newArrayList(); /** Default Constructor. */ - @Inject public PermissioningServiceImpl() {} @Override diff --git a/besu/src/main/java/org/hyperledger/besu/services/RpcEndpointServiceImpl.java b/besu/src/main/java/org/hyperledger/besu/services/RpcEndpointServiceImpl.java index 5d7df73b2e..dcfe29146e 100644 --- a/besu/src/main/java/org/hyperledger/besu/services/RpcEndpointServiceImpl.java +++ b/besu/src/main/java/org/hyperledger/besu/services/RpcEndpointServiceImpl.java @@ -36,7 +36,6 @@ import java.util.Map; import java.util.NoSuchElementException; import java.util.function.Function; import java.util.stream.Collectors; -import javax.inject.Inject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -49,7 +48,6 @@ public class RpcEndpointServiceImpl implements RpcEndpointService { private Map inProcessRpcMethods; /** Default Constructor. */ - @Inject public RpcEndpointServiceImpl() {} /** diff --git a/besu/src/main/java/org/hyperledger/besu/services/SecurityModuleServiceImpl.java b/besu/src/main/java/org/hyperledger/besu/services/SecurityModuleServiceImpl.java index 5605fe49b5..c3905c304b 100644 --- a/besu/src/main/java/org/hyperledger/besu/services/SecurityModuleServiceImpl.java +++ b/besu/src/main/java/org/hyperledger/besu/services/SecurityModuleServiceImpl.java @@ -21,18 +21,15 @@ import java.util.Map; import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Supplier; -import javax.inject.Inject; /** The Security module service implementation. */ public class SecurityModuleServiceImpl implements SecurityModuleService { + private final Map> securityModuleSuppliers = + new ConcurrentHashMap<>(); /** Default Constructor. */ - @Inject public SecurityModuleServiceImpl() {} - private final Map> securityModuleSuppliers = - new ConcurrentHashMap<>(); - @Override public void register(final String name, final Supplier securityModuleSupplier) { securityModuleSuppliers.put(name, securityModuleSupplier); diff --git a/besu/src/main/java/org/hyperledger/besu/services/StorageServiceImpl.java b/besu/src/main/java/org/hyperledger/besu/services/StorageServiceImpl.java index dd5d822ccc..6629da690e 100644 --- a/besu/src/main/java/org/hyperledger/besu/services/StorageServiceImpl.java +++ b/besu/src/main/java/org/hyperledger/besu/services/StorageServiceImpl.java @@ -23,7 +23,6 @@ import java.util.List; import java.util.Map; import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; -import javax.inject.Inject; /** The Storage service implementation. */ public class StorageServiceImpl implements StorageService { @@ -32,7 +31,6 @@ public class StorageServiceImpl implements StorageService { private final Map factories; /** Instantiates a new Storage service. */ - @Inject public StorageServiceImpl() { this.segments = List.of(KeyValueSegmentIdentifier.values()); this.factories = new ConcurrentHashMap<>(); diff --git a/besu/src/main/java/org/hyperledger/besu/services/TransactionPoolValidatorServiceImpl.java b/besu/src/main/java/org/hyperledger/besu/services/TransactionPoolValidatorServiceImpl.java index 46af0a6ea5..1e1f94fb32 100644 --- a/besu/src/main/java/org/hyperledger/besu/services/TransactionPoolValidatorServiceImpl.java +++ b/besu/src/main/java/org/hyperledger/besu/services/TransactionPoolValidatorServiceImpl.java @@ -19,17 +19,15 @@ import org.hyperledger.besu.plugin.services.txvalidator.PluginTransactionPoolVal import org.hyperledger.besu.plugin.services.txvalidator.PluginTransactionPoolValidatorFactory; import java.util.Optional; -import javax.inject.Inject; /** The Transaction pool validator service implementation. */ public class TransactionPoolValidatorServiceImpl implements TransactionPoolValidatorService { + private Optional factory = Optional.empty(); + /** Default Constructor. */ - @Inject public TransactionPoolValidatorServiceImpl() {} - private Optional factory = Optional.empty(); - @Override public PluginTransactionPoolValidator createTransactionValidator() { return factory diff --git a/besu/src/main/java/org/hyperledger/besu/services/TransactionSelectionServiceImpl.java b/besu/src/main/java/org/hyperledger/besu/services/TransactionSelectionServiceImpl.java index c7049c9aa0..8595a3c030 100644 --- a/besu/src/main/java/org/hyperledger/besu/services/TransactionSelectionServiceImpl.java +++ b/besu/src/main/java/org/hyperledger/besu/services/TransactionSelectionServiceImpl.java @@ -19,17 +19,15 @@ import org.hyperledger.besu.plugin.services.txselection.PluginTransactionSelecto import org.hyperledger.besu.plugin.services.txselection.PluginTransactionSelectorFactory; import java.util.Optional; -import javax.inject.Inject; /** The Transaction Selection service implementation. */ public class TransactionSelectionServiceImpl implements TransactionSelectionService { + private Optional factory = Optional.empty(); + /** Default Constructor. */ - @Inject public TransactionSelectionServiceImpl() {} - private Optional factory = Optional.empty(); - @Override public PluginTransactionSelector createPluginTransactionSelector() { return factory diff --git a/besu/src/main/java/org/hyperledger/besu/services/TransactionSimulationServiceImpl.java b/besu/src/main/java/org/hyperledger/besu/services/TransactionSimulationServiceImpl.java index 8ec00e8170..54cce205a3 100644 --- a/besu/src/main/java/org/hyperledger/besu/services/TransactionSimulationServiceImpl.java +++ b/besu/src/main/java/org/hyperledger/besu/services/TransactionSimulationServiceImpl.java @@ -30,7 +30,6 @@ import org.hyperledger.besu.plugin.data.TransactionSimulationResult; import org.hyperledger.besu.plugin.services.TransactionSimulationService; import java.util.Optional; -import javax.inject.Inject; /** TransactionSimulationServiceImpl */ @Unstable @@ -44,7 +43,6 @@ public class TransactionSimulationServiceImpl implements TransactionSimulationSe private TransactionSimulator transactionSimulator; /** Create an instance to be configured */ - @Inject public TransactionSimulationServiceImpl() {} /** diff --git a/besu/src/test/java/org/hyperledger/besu/FlexGroupPrivacyTest.java b/besu/src/test/java/org/hyperledger/besu/FlexGroupPrivacyTest.java deleted file mode 100644 index a246d18d2f..0000000000 --- a/besu/src/test/java/org/hyperledger/besu/FlexGroupPrivacyTest.java +++ /dev/null @@ -1,168 +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; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.hyperledger.besu.ethereum.core.PrivacyParameters.FLEXIBLE_PRIVACY; - -import org.hyperledger.besu.components.BesuComponent; -import org.hyperledger.besu.components.BesuPluginContextModule; -import org.hyperledger.besu.components.MockBesuCommandModule; -import org.hyperledger.besu.components.NoOpMetricsSystemModule; -import org.hyperledger.besu.components.PrivacyTestModule; -import org.hyperledger.besu.config.GenesisConfigFile; -import org.hyperledger.besu.controller.BesuController; -import org.hyperledger.besu.cryptoservices.NodeKeyUtils; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.enclave.EnclaveFactory; -import org.hyperledger.besu.ethereum.GasLimitCalculator; -import org.hyperledger.besu.ethereum.core.BlockHeader; -import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture; -import org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider; -import org.hyperledger.besu.ethereum.core.MiningParameters; -import org.hyperledger.besu.ethereum.core.PrivacyParameters; -import org.hyperledger.besu.ethereum.eth.EthProtocolConfiguration; -import org.hyperledger.besu.ethereum.eth.sync.SyncMode; -import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration; -import org.hyperledger.besu.ethereum.eth.transactions.BlobCacheModule; -import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration; -import org.hyperledger.besu.ethereum.p2p.config.NetworkingConfiguration; -import org.hyperledger.besu.ethereum.privacy.storage.PrivacyStorageProvider; -import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.cache.BonsaiCachedMerkleTrieLoaderModule; -import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; -import org.hyperledger.besu.evm.internal.EvmConfiguration; -import org.hyperledger.besu.evm.precompile.PrecompiledContract; -import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; -import org.hyperledger.besu.testutil.TestClock; - -import java.math.BigInteger; -import java.net.URI; -import java.net.URISyntaxException; -import java.nio.file.Path; -import javax.inject.Named; -import javax.inject.Singleton; - -import dagger.Component; -import dagger.Module; -import dagger.Provides; -import io.vertx.core.Vertx; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Test; - -class FlexGroupPrivacyTest { - - private final Vertx vertx = Vertx.vertx(); - - @AfterEach - public void cleanUp() { - vertx.close(); - } - - @Test - void flexibleEnabledPrivacy() { - final BesuController besuController = - DaggerFlexGroupPrivacyTest_FlexGroupPrivacyTestComponent.builder() - .build() - .getBesuController(); - - final PrecompiledContract flexiblePrecompiledContract = - getPrecompile(besuController, FLEXIBLE_PRIVACY); - - assertThat(flexiblePrecompiledContract.getName()).isEqualTo("FlexiblePrivacy"); - } - - private PrecompiledContract getPrecompile( - final BesuController besuController, final Address defaultPrivacy) { - return besuController - .getProtocolSchedule() - .getByBlockHeader(blockHeader(0)) - .getPrecompileContractRegistry() - .get(defaultPrivacy); - } - - private BlockHeader blockHeader(final long number) { - return new BlockHeaderTestFixture().number(number).buildHeader(); - } - - @Singleton - @Component( - modules = { - FlexGroupPrivacyParametersModule.class, - FlexGroupPrivacyTest.PrivacyTestBesuControllerModule.class, - PrivacyTestModule.class, - MockBesuCommandModule.class, - BonsaiCachedMerkleTrieLoaderModule.class, - NoOpMetricsSystemModule.class, - BesuPluginContextModule.class, - BlobCacheModule.class - }) - interface FlexGroupPrivacyTestComponent extends BesuComponent { - BesuController getBesuController(); - } - - @Module - static class FlexGroupPrivacyParametersModule { - - @Provides - PrivacyParameters providePrivacyParameters( - final PrivacyStorageProvider storageProvider, final Vertx vertx) { - try { - return new PrivacyParameters.Builder() - .setEnabled(true) - .setEnclaveUrl(new URI("http://127.0.0.1:8000")) - .setStorageProvider(storageProvider) - .setEnclaveFactory(new EnclaveFactory(vertx)) - .setFlexiblePrivacyGroupsEnabled(true) - .build(); - } catch (URISyntaxException e) { - throw new RuntimeException(e); - } - } - } - - @Module - static class PrivacyTestBesuControllerModule { - - @Provides - @Singleton - @SuppressWarnings("CloseableProvides") - BesuController provideBesuController( - final PrivacyParameters privacyParameters, - final DataStorageConfiguration dataStorageConfiguration, - final FlexGroupPrivacyTestComponent context, - @Named("dataDir") final Path dataDir) { - - return new BesuController.Builder() - .fromGenesisFile(GenesisConfigFile.mainnet(), SyncMode.FULL) - .synchronizerConfiguration(SynchronizerConfiguration.builder().build()) - .ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig()) - .storageProvider(new InMemoryKeyValueStorageProvider()) - .networkId(BigInteger.ONE) - .miningParameters(MiningParameters.newDefault()) - .dataStorageConfiguration(dataStorageConfiguration) - .nodeKey(NodeKeyUtils.generate()) - .metricsSystem(new NoOpMetricsSystem()) - .dataDirectory(dataDir) - .clock(TestClock.fixed()) - .privacyParameters(privacyParameters) - .transactionPoolConfiguration(TransactionPoolConfiguration.DEFAULT) - .gasLimitCalculator(GasLimitCalculator.constant()) - .evmConfiguration(EvmConfiguration.DEFAULT) - .networkConfiguration(NetworkingConfiguration.create()) - .besuComponent(context) - .build(); - } - } -} diff --git a/besu/src/test/java/org/hyperledger/besu/PrivacyReorgTest.java b/besu/src/test/java/org/hyperledger/besu/PrivacyReorgTest.java index 6298b70a95..ceb0be40fe 100644 --- a/besu/src/test/java/org/hyperledger/besu/PrivacyReorgTest.java +++ b/besu/src/test/java/org/hyperledger/besu/PrivacyReorgTest.java @@ -21,12 +21,6 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import org.hyperledger.besu.components.BesuComponent; -import org.hyperledger.besu.components.BesuPluginContextModule; -import org.hyperledger.besu.components.EnclaveModule; -import org.hyperledger.besu.components.MockBesuCommandModule; -import org.hyperledger.besu.components.NoOpMetricsSystemModule; -import org.hyperledger.besu.components.PrivacyTestModule; import org.hyperledger.besu.config.GenesisConfigFile; import org.hyperledger.besu.controller.BesuController; import org.hyperledger.besu.crypto.KeyPair; @@ -53,9 +47,7 @@ import org.hyperledger.besu.ethereum.core.Transaction; import org.hyperledger.besu.ethereum.eth.EthProtocolConfiguration; import org.hyperledger.besu.ethereum.eth.sync.SyncMode; import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration; -import org.hyperledger.besu.ethereum.eth.transactions.BlobCacheModule; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration; -import org.hyperledger.besu.ethereum.mainnet.BlockImportResult; import org.hyperledger.besu.ethereum.mainnet.HeaderValidationMode; import org.hyperledger.besu.ethereum.p2p.config.NetworkingConfiguration; import org.hyperledger.besu.ethereum.privacy.PrivateStateRootResolver; @@ -64,7 +56,6 @@ import org.hyperledger.besu.ethereum.privacy.storage.PrivacyGroupHeadBlockMap; import org.hyperledger.besu.ethereum.privacy.storage.PrivacyStorageProvider; import org.hyperledger.besu.ethereum.privacy.storage.PrivateStateStorage; import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; -import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.cache.BonsaiCachedMerkleTrieLoaderModule; import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.evm.log.LogsBloomFilter; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; @@ -79,21 +70,19 @@ import java.nio.file.Path; import java.util.Collections; import java.util.Optional; import java.util.function.Supplier; -import javax.inject.Named; -import javax.inject.Singleton; import com.google.common.base.Suppliers; -import dagger.Component; -import dagger.Module; -import dagger.Provides; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; @SuppressWarnings("rawtypes") public class PrivacyReorgTest { + @TempDir private Path folder; + private static final Supplier SIGNATURE_ALGORITHM = Suppliers.memoize(SignatureAlgorithmFactory::getInstance); @@ -141,15 +130,11 @@ public class PrivacyReorgTest { .signAndBuild(KEY_PAIR); private final BlockDataGenerator gen = new BlockDataGenerator(); + private BesuController besuController; + private PrivateStateRootResolver privateStateRootResolver; private PrivacyParameters privacyParameters; private Enclave mockEnclave; private Transaction privacyMarkerTransaction; - private final PrivacyReorgTestComponent component = - DaggerPrivacyReorgTest_PrivacyReorgTestComponent.create(); - - private final BesuController besuController = component.getBesuController(); - private final PrivateStateRootResolver privateStateRootResolver = - component.getPrivacyParameters().getPrivateStateRootResolver(); @BeforeEach public void setUp() throws IOException { @@ -189,6 +174,29 @@ public class PrivacyReorgTest { .build(); privacyParameters.setPrivacyUserId(ENCLAVE_PUBLIC_KEY.toBase64String()); + + privateStateRootResolver = + new PrivateStateRootResolver(privacyParameters.getPrivateStateStorage()); + + besuController = + new BesuController.Builder() + .fromGenesisFile( + GenesisConfigFile.fromResource("/privacy_reorg_genesis.json"), SyncMode.FULL) + .synchronizerConfiguration(SynchronizerConfiguration.builder().build()) + .ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig()) + .storageProvider(new InMemoryKeyValueStorageProvider()) + .networkId(BigInteger.ONE) + .miningParameters(MiningParameters.newDefault()) + .nodeKey(NodeKeyUtils.generate()) + .metricsSystem(new NoOpMetricsSystem()) + .dataDirectory(folder) + .clock(TestClock.fixed()) + .privacyParameters(privacyParameters) + .transactionPoolConfiguration(TransactionPoolConfiguration.DEFAULT) + .gasLimitCalculator(GasLimitCalculator.constant()) + .evmConfiguration(EvmConfiguration.DEFAULT) + .networkConfiguration(NetworkingConfiguration.create()) + .build(); } @Test @@ -196,8 +204,7 @@ public class PrivacyReorgTest { // Setup an initial blockchain with one private transaction final ProtocolContext protocolContext = besuController.getProtocolContext(); final DefaultBlockchain blockchain = (DefaultBlockchain) protocolContext.getBlockchain(); - final PrivateStateStorage privateStateStorage = - component.getPrivacyParameters().getPrivateStateStorage(); + final PrivateStateStorage privateStateStorage = privacyParameters.getPrivateStateStorage(); final Block firstBlock = gen.block( @@ -237,7 +244,7 @@ public class PrivacyReorgTest { // Setup an initial blockchain with one private transaction final ProtocolContext protocolContext = besuController.getProtocolContext(); final DefaultBlockchain blockchain = (DefaultBlockchain) protocolContext.getBlockchain(); - assertThat(blockchain.getChainHeadBlockNumber()).isEqualTo(0); + final Block firstBlock = gen.block( getBlockOptionsWithTransaction( @@ -245,9 +252,8 @@ public class PrivacyReorgTest { privacyMarkerTransaction, FIRST_BLOCK_WITH_SINGLE_TRANSACTION_STATE_ROOT)); - var importResult = appendBlock(besuController, blockchain, protocolContext, firstBlock); - assertThat(importResult.isImported()).isTrue(); - assertThat(blockchain.getChainHeadBlockNumber()).isEqualTo(1); + appendBlock(besuController, blockchain, protocolContext, firstBlock); + // Check that the private state root is not the empty state assertPrivateStateRoot( privateStateRootResolver, blockchain, STATE_ROOT_AFTER_TRANSACTION_APPENDED_TO_EMPTY_STATE); @@ -388,12 +394,12 @@ public class PrivacyReorgTest { } @SuppressWarnings("unchecked") - private BlockImportResult appendBlock( + private void appendBlock( final BesuController besuController, final DefaultBlockchain blockchain, final ProtocolContext protocolContext, final Block block) { - return besuController + besuController .getProtocolSchedule() .getByBlockHeader(blockchain.getChainHeadHeader()) .getBlockImporter() @@ -481,93 +487,4 @@ public class PrivacyReorgTest { .hasOmmers(false) .setLogsBloom(LogsBloomFilter.empty()); } - - @Singleton - @Component( - modules = { - PrivacyReorgTest.PrivacyReorgParametersModule.class, - PrivacyReorgTest.PrivacyReorgTestBesuControllerModule.class, - PrivacyReorgTest.PrivacyReorgTestGenesisConfigModule.class, - EnclaveModule.class, - PrivacyTestModule.class, - MockBesuCommandModule.class, - NoOpMetricsSystemModule.class, - BonsaiCachedMerkleTrieLoaderModule.class, - BlobCacheModule.class, - BesuPluginContextModule.class - }) - interface PrivacyReorgTestComponent extends BesuComponent { - - BesuController getBesuController(); - - PrivacyParameters getPrivacyParameters(); - } - - @Module - static class PrivacyReorgParametersModule { - - // TODO: copypasta, get this from the enclave factory - private static final Bytes ENCLAVE_PUBLIC_KEY = - Bytes.fromBase64String("A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo="); - - @Provides - PrivacyParameters providePrivacyReorgParameters( - final PrivacyStorageProvider storageProvider, final EnclaveFactory enclaveFactory) { - - PrivacyParameters retval = - new PrivacyParameters.Builder() - .setEnabled(true) - .setStorageProvider(storageProvider) - .setEnclaveUrl(URI.create("http//1.1.1.1:1234")) - .setEnclaveFactory(enclaveFactory) - .build(); - retval.setPrivacyUserId(ENCLAVE_PUBLIC_KEY.toBase64String()); - return retval; - } - } - - @Module - static class PrivacyReorgTestBesuControllerModule { - - @Provides - @Singleton - @SuppressWarnings("CloseableProvides") - BesuController provideBesuController( - final PrivacyParameters privacyParameters, - final GenesisConfigFile genesisConfigFile, - final PrivacyReorgTestComponent context, - final @Named("dataDir") Path dataDir) { - - // dataStorageConfiguration default - // named privacyReorgParams - BesuController retval = - new BesuController.Builder() - .fromGenesisFile(genesisConfigFile, SyncMode.FULL) - .synchronizerConfiguration(SynchronizerConfiguration.builder().build()) - .ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig()) - .storageProvider(new InMemoryKeyValueStorageProvider()) - .networkId(BigInteger.ONE) - .miningParameters(MiningParameters.newDefault()) - .nodeKey(NodeKeyUtils.generate()) - .metricsSystem(new NoOpMetricsSystem()) - .dataDirectory(dataDir) - .clock(TestClock.fixed()) - .privacyParameters(privacyParameters) - .transactionPoolConfiguration(TransactionPoolConfiguration.DEFAULT) - .gasLimitCalculator(GasLimitCalculator.constant()) - .evmConfiguration(EvmConfiguration.DEFAULT) - .networkConfiguration(NetworkingConfiguration.create()) - .besuComponent(context) - .build(); - return retval; - } - } - - @Module - static class PrivacyReorgTestGenesisConfigModule { - @Provides - GenesisConfigFile providePrivacyReorgGenesisConfigFile() { - return GenesisConfigFile.fromResource("/privacy_reorg_genesis.json"); - } - } } diff --git a/besu/src/test/java/org/hyperledger/besu/PrivacyTest.java b/besu/src/test/java/org/hyperledger/besu/PrivacyTest.java index 4d488ced3b..dc5b7003c8 100644 --- a/besu/src/test/java/org/hyperledger/besu/PrivacyTest.java +++ b/besu/src/test/java/org/hyperledger/besu/PrivacyTest.java @@ -1,5 +1,5 @@ /* - * Copyright contributors to Hyperledger Besu. + * 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 @@ -16,17 +16,18 @@ package org.hyperledger.besu; import static org.assertj.core.api.Assertions.assertThat; import static org.hyperledger.besu.ethereum.core.PrivacyParameters.DEFAULT_PRIVACY; - -import org.hyperledger.besu.components.BesuComponent; -import org.hyperledger.besu.components.BesuPluginContextModule; -import org.hyperledger.besu.components.MockBesuCommandModule; -import org.hyperledger.besu.components.NoOpMetricsSystemModule; -import org.hyperledger.besu.components.PrivacyParametersModule; -import org.hyperledger.besu.components.PrivacyTestModule; -import org.hyperledger.besu.config.GenesisConfigFile; +import static org.hyperledger.besu.ethereum.core.PrivacyParameters.FLEXIBLE_PRIVACY; +import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_BACKGROUND_THREAD_COUNT; +import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_CACHE_CAPACITY; +import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_IS_HIGH_SPEC; +import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_MAX_OPEN_FILES; + +import org.hyperledger.besu.cli.config.EthNetworkConfig; +import org.hyperledger.besu.cli.config.NetworkName; import org.hyperledger.besu.controller.BesuController; import org.hyperledger.besu.cryptoservices.NodeKeyUtils; import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.enclave.EnclaveFactory; import org.hyperledger.besu.ethereum.GasLimitCalculator; import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture; @@ -36,47 +37,126 @@ import org.hyperledger.besu.ethereum.core.PrivacyParameters; import org.hyperledger.besu.ethereum.eth.EthProtocolConfiguration; import org.hyperledger.besu.ethereum.eth.sync.SyncMode; import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration; -import org.hyperledger.besu.ethereum.eth.transactions.BlobCacheModule; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration; import org.hyperledger.besu.ethereum.p2p.config.NetworkingConfiguration; -import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.cache.BonsaiCachedMerkleTrieLoaderModule; +import org.hyperledger.besu.ethereum.privacy.storage.PrivacyStorageProvider; +import org.hyperledger.besu.ethereum.privacy.storage.keyvalue.PrivacyKeyValueStorageProviderBuilder; +import org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier; import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.evm.precompile.PrecompiledContract; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; +import org.hyperledger.besu.plugin.services.storage.rocksdb.RocksDBKeyValuePrivacyStorageFactory; +import org.hyperledger.besu.plugin.services.storage.rocksdb.RocksDBKeyValueStorageFactory; +import org.hyperledger.besu.plugin.services.storage.rocksdb.RocksDBMetricsFactory; +import org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBFactoryConfiguration; +import org.hyperledger.besu.services.BesuConfigurationImpl; import org.hyperledger.besu.testutil.TestClock; +import java.io.IOException; import java.math.BigInteger; +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.file.Files; import java.nio.file.Path; -import javax.inject.Named; -import javax.inject.Singleton; +import java.util.Arrays; -import dagger.Component; -import dagger.Module; -import dagger.Provides; import io.vertx.core.Vertx; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; -class PrivacyTest { +public class PrivacyTest { private final Vertx vertx = Vertx.vertx(); + @TempDir private Path dataDir; + @AfterEach public void cleanUp() { vertx.close(); } @Test - void defaultPrivacy() { - final BesuController besuController = - DaggerPrivacyTest_PrivacyTestComponent.builder().build().getBesuController(); + public void defaultPrivacy() throws IOException, URISyntaxException { + final BesuController besuController = setUpControllerWithPrivacyEnabled(false); final PrecompiledContract precompiledContract = getPrecompile(besuController, DEFAULT_PRIVACY); assertThat(precompiledContract.getName()).isEqualTo("Privacy"); } + @Test + public void flexibleEnabledPrivacy() throws IOException, URISyntaxException { + final BesuController besuController = setUpControllerWithPrivacyEnabled(true); + + final PrecompiledContract flexiblePrecompiledContract = + getPrecompile(besuController, FLEXIBLE_PRIVACY); + + assertThat(flexiblePrecompiledContract.getName()).isEqualTo("FlexiblePrivacy"); + } + + private BesuController setUpControllerWithPrivacyEnabled(final boolean flexibleEnabled) + throws IOException, URISyntaxException { + final Path dbDir = Files.createTempDirectory(dataDir, "database"); + final var miningParameters = MiningParameters.newDefault(); + final var dataStorageConfiguration = DataStorageConfiguration.DEFAULT_FOREST_CONFIG; + final PrivacyParameters privacyParameters = + new PrivacyParameters.Builder() + .setEnabled(true) + .setEnclaveUrl(new URI("http://127.0.0.1:8000")) + .setStorageProvider( + createKeyValueStorageProvider( + dataDir, dbDir, dataStorageConfiguration, miningParameters)) + .setEnclaveFactory(new EnclaveFactory(vertx)) + .setFlexiblePrivacyGroupsEnabled(flexibleEnabled) + .build(); + return new BesuController.Builder() + .fromEthNetworkConfig(EthNetworkConfig.getNetworkConfig(NetworkName.MAINNET), SyncMode.FULL) + .synchronizerConfiguration(SynchronizerConfiguration.builder().build()) + .ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig()) + .storageProvider(new InMemoryKeyValueStorageProvider()) + .networkId(BigInteger.ONE) + .miningParameters(miningParameters) + .dataStorageConfiguration(dataStorageConfiguration) + .nodeKey(NodeKeyUtils.generate()) + .metricsSystem(new NoOpMetricsSystem()) + .dataDirectory(dataDir) + .clock(TestClock.fixed()) + .privacyParameters(privacyParameters) + .transactionPoolConfiguration(TransactionPoolConfiguration.DEFAULT) + .gasLimitCalculator(GasLimitCalculator.constant()) + .evmConfiguration(EvmConfiguration.DEFAULT) + .networkConfiguration(NetworkingConfiguration.create()) + .build(); + } + + private PrivacyStorageProvider createKeyValueStorageProvider( + final Path dataDir, + final Path dbDir, + final DataStorageConfiguration dataStorageConfiguration, + final MiningParameters miningParameters) { + final var besuConfiguration = new BesuConfigurationImpl(); + besuConfiguration + .init(dataDir, dbDir, dataStorageConfiguration) + .withMiningParameters(miningParameters); + return new PrivacyKeyValueStorageProviderBuilder() + .withStorageFactory( + new RocksDBKeyValuePrivacyStorageFactory( + new RocksDBKeyValueStorageFactory( + () -> + new RocksDBFactoryConfiguration( + DEFAULT_MAX_OPEN_FILES, + DEFAULT_BACKGROUND_THREAD_COUNT, + DEFAULT_CACHE_CAPACITY, + DEFAULT_IS_HIGH_SPEC), + Arrays.asList(KeyValueSegmentIdentifier.values()), + RocksDBMetricsFactory.PRIVATE_ROCKS_DB_METRICS))) + .withCommonConfiguration(besuConfiguration) + .withMetricsSystem(new NoOpMetricsSystem()) + .build(); + } + private PrecompiledContract getPrecompile( final BesuController besuController, final Address defaultPrivacy) { return besuController @@ -89,55 +169,4 @@ class PrivacyTest { private BlockHeader blockHeader(final long number) { return new BlockHeaderTestFixture().number(number).buildHeader(); } - - @Singleton - @Component( - modules = { - PrivacyParametersModule.class, - PrivacyTest.PrivacyTestBesuControllerModule.class, - PrivacyTestModule.class, - MockBesuCommandModule.class, - BonsaiCachedMerkleTrieLoaderModule.class, - NoOpMetricsSystemModule.class, - BesuPluginContextModule.class, - BlobCacheModule.class - }) - interface PrivacyTestComponent extends BesuComponent { - - BesuController getBesuController(); - } - - @Module - static class PrivacyTestBesuControllerModule { - - @Provides - @Singleton - @SuppressWarnings("CloseableProvides") - BesuController provideBesuController( - final PrivacyParameters privacyParameters, - final DataStorageConfiguration dataStorageConfiguration, - final PrivacyTestComponent context, - @Named("dataDir") final Path dataDir) { - - return new BesuController.Builder() - .fromGenesisFile(GenesisConfigFile.mainnet(), SyncMode.FULL) - .synchronizerConfiguration(SynchronizerConfiguration.builder().build()) - .ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig()) - .storageProvider(new InMemoryKeyValueStorageProvider()) - .networkId(BigInteger.ONE) - .miningParameters(MiningParameters.newDefault()) - .dataStorageConfiguration(dataStorageConfiguration) - .nodeKey(NodeKeyUtils.generate()) - .metricsSystem(new NoOpMetricsSystem()) - .dataDirectory(dataDir) - .clock(TestClock.fixed()) - .privacyParameters(privacyParameters) - .transactionPoolConfiguration(TransactionPoolConfiguration.DEFAULT) - .gasLimitCalculator(GasLimitCalculator.constant()) - .evmConfiguration(EvmConfiguration.DEFAULT) - .networkConfiguration(NetworkingConfiguration.create()) - .besuComponent(context) - .build(); - } - } } diff --git a/besu/src/test/java/org/hyperledger/besu/RunnerTest.java b/besu/src/test/java/org/hyperledger/besu/RunnerTest.java index 5fefc7ef22..5b2a56078f 100644 --- a/besu/src/test/java/org/hyperledger/besu/RunnerTest.java +++ b/besu/src/test/java/org/hyperledger/besu/RunnerTest.java @@ -22,10 +22,8 @@ import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_CACHE_CAPACITY; import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_IS_HIGH_SPEC; import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_MAX_OPEN_FILES; -import static org.mockito.Mockito.mock; 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; @@ -485,7 +483,6 @@ public final class RunnerTest { .evmConfiguration(EvmConfiguration.DEFAULT) .networkConfiguration(NetworkingConfiguration.create()) .randomPeerPriority(Boolean.FALSE) - .besuComponent(mock(BesuComponent.class)) .maxPeers(25) .maxRemotelyInitiatedPeers(15) .build(); diff --git a/besu/src/test/java/org/hyperledger/besu/chainexport/RlpBlockExporterTest.java b/besu/src/test/java/org/hyperledger/besu/chainexport/RlpBlockExporterTest.java index bbc7dea1ab..05057f15c8 100644 --- a/besu/src/test/java/org/hyperledger/besu/chainexport/RlpBlockExporterTest.java +++ b/besu/src/test/java/org/hyperledger/besu/chainexport/RlpBlockExporterTest.java @@ -16,12 +16,10 @@ package org.hyperledger.besu.chainexport; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.Mockito.mock; import org.hyperledger.besu.chainimport.RlpBlockImporter; import org.hyperledger.besu.cli.config.EthNetworkConfig; import org.hyperledger.besu.cli.config.NetworkName; -import org.hyperledger.besu.components.BesuComponent; import org.hyperledger.besu.controller.BesuController; import org.hyperledger.besu.cryptoservices.NodeKeyUtils; import org.hyperledger.besu.ethereum.GasLimitCalculator; @@ -104,7 +102,6 @@ public final class RlpBlockExporterTest { .gasLimitCalculator(GasLimitCalculator.constant()) .evmConfiguration(EvmConfiguration.DEFAULT) .networkConfiguration(NetworkingConfiguration.create()) - .besuComponent(mock(BesuComponent.class)) .build(); } diff --git a/besu/src/test/java/org/hyperledger/besu/chainimport/JsonBlockImporterTest.java b/besu/src/test/java/org/hyperledger/besu/chainimport/JsonBlockImporterTest.java index 7b1a4bc7d2..73015afd00 100644 --- a/besu/src/test/java/org/hyperledger/besu/chainimport/JsonBlockImporterTest.java +++ b/besu/src/test/java/org/hyperledger/besu/chainimport/JsonBlockImporterTest.java @@ -17,9 +17,7 @@ package org.hyperledger.besu.chainimport; import static java.nio.charset.StandardCharsets.UTF_8; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.Mockito.mock; -import org.hyperledger.besu.components.BesuComponent; import org.hyperledger.besu.config.GenesisConfigFile; import org.hyperledger.besu.config.JsonUtil; import org.hyperledger.besu.controller.BesuController; @@ -465,7 +463,6 @@ public abstract class JsonBlockImporterTest { .gasLimitCalculator(GasLimitCalculator.constant()) .evmConfiguration(EvmConfiguration.DEFAULT) .networkConfiguration(NetworkingConfiguration.create()) - .besuComponent(mock(BesuComponent.class)) .build(); } } 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..e37b8a5fd0 100644 --- a/besu/src/test/java/org/hyperledger/besu/chainimport/RlpBlockImporterTest.java +++ b/besu/src/test/java/org/hyperledger/besu/chainimport/RlpBlockImporterTest.java @@ -16,11 +16,9 @@ package org.hyperledger.besu.chainimport; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -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.controller.BesuController; import org.hyperledger.besu.cryptoservices.NodeKeyUtils; @@ -79,7 +77,6 @@ public final class RlpBlockImporterTest { .gasLimitCalculator(GasLimitCalculator.constant()) .evmConfiguration(EvmConfiguration.DEFAULT) .networkConfiguration(NetworkingConfiguration.create()) - .besuComponent(mock(BesuComponent.class)) .build(); final RlpBlockImporter.ImportResult result = rlpBlockImporter.importBlockchain(source, targetController, false); @@ -113,7 +110,6 @@ public final class RlpBlockImporterTest { .gasLimitCalculator(GasLimitCalculator.constant()) .evmConfiguration(EvmConfiguration.DEFAULT) .networkConfiguration(NetworkingConfiguration.create()) - .besuComponent(mock(BesuComponent.class)) .build(); assertThatThrownBy( @@ -144,7 +140,6 @@ public final class RlpBlockImporterTest { .gasLimitCalculator(GasLimitCalculator.constant()) .evmConfiguration(EvmConfiguration.DEFAULT) .networkConfiguration(NetworkingConfiguration.create()) - .besuComponent(mock(BesuComponent.class)) .build(); final RlpBlockImporter.ImportResult result = diff --git a/besu/src/test/java/org/hyperledger/besu/components/EnclaveModule.java b/besu/src/test/java/org/hyperledger/besu/components/EnclaveModule.java deleted file mode 100644 index 20f9c1bf49..0000000000 --- a/besu/src/test/java/org/hyperledger/besu/components/EnclaveModule.java +++ /dev/null @@ -1,98 +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.components; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import org.hyperledger.besu.crypto.KeyPair; -import org.hyperledger.besu.crypto.SignatureAlgorithm; -import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; -import org.hyperledger.besu.datatypes.Wei; -import org.hyperledger.besu.enclave.Enclave; -import org.hyperledger.besu.enclave.EnclaveFactory; -import org.hyperledger.besu.enclave.types.ReceiveResponse; -import org.hyperledger.besu.ethereum.privacy.PrivateTransaction; -import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; -import org.hyperledger.besu.plugin.data.Restriction; - -import java.math.BigInteger; -import java.nio.charset.StandardCharsets; -import java.util.Collections; -import java.util.function.Supplier; - -import com.google.common.base.Suppliers; -import dagger.Module; -import dagger.Provides; -import org.apache.tuweni.bytes.Bytes; -import org.apache.tuweni.bytes.Bytes32; - -@Module -public class EnclaveModule { - - private static final Supplier SIGNATURE_ALGORITHM = - Suppliers.memoize(SignatureAlgorithmFactory::getInstance); - - private static final Bytes ENCLAVE_PUBLIC_KEY = - Bytes.fromBase64String("A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo="); - - private static final Bytes32 PRIVACY_GROUP_BYTES32 = - Bytes32.fromHexString("0xf250d523ae9164722b06ca25cfa2a7f3c45df96b09e215236f886c876f715bfa"); - - private static final Bytes MOCK_PAYLOAD = - Bytes.fromHexString( - "0x608060405234801561001057600080fd5b5060008054600160a060020a03191633179055610199806100326000396000f3fe6080604052600436106100565763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416633fa4f245811461005b5780636057361d1461008257806367e404ce146100ae575b600080fd5b34801561006757600080fd5b506100706100ec565b60408051918252519081900360200190f35b34801561008e57600080fd5b506100ac600480360360208110156100a557600080fd5b50356100f2565b005b3480156100ba57600080fd5b506100c3610151565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b60025490565b604080513381526020810183905281517fc9db20adedc6cf2b5d25252b101ab03e124902a73fcb12b753f3d1aaa2d8f9f5929181900390910190a16002556001805473ffffffffffffffffffffffffffffffffffffffff191633179055565b60015473ffffffffffffffffffffffffffffffffffffffff169056fea165627a7a72305820c7f729cb24e05c221f5aa913700793994656f233fe2ce3b9fd9a505ea17e8d8a0029"); - - private static final KeyPair KEY_PAIR = - SIGNATURE_ALGORITHM - .get() - .createKeyPair( - SIGNATURE_ALGORITHM - .get() - .createPrivateKey( - new BigInteger( - "8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63", 16))); - - private static final PrivateTransaction PRIVATE_TRANSACTION = - PrivateTransaction.builder() - .chainId(BigInteger.valueOf(1337)) - .gasLimit(1000) - .gasPrice(Wei.ZERO) - .nonce(0) - .payload(MOCK_PAYLOAD) - .to(null) - .privateFrom(ENCLAVE_PUBLIC_KEY) - .privateFor(Collections.singletonList(ENCLAVE_PUBLIC_KEY)) - .restriction(Restriction.RESTRICTED) - .value(Wei.ZERO) - .signAndBuild(KEY_PAIR); - - @Provides - EnclaveFactory provideMockableEnclaveFactory() { - Enclave mockEnclave = mock(Enclave.class); - final BytesValueRLPOutput rlpOutput = new BytesValueRLPOutput(); - PRIVATE_TRANSACTION.writeTo(rlpOutput); - when(mockEnclave.receive(any())) - .thenReturn( - new ReceiveResponse( - rlpOutput.encoded().toBase64String().getBytes(StandardCharsets.UTF_8), - PRIVACY_GROUP_BYTES32.toBase64String(), - ENCLAVE_PUBLIC_KEY.toBase64String())); - EnclaveFactory enclaveFactory = mock(EnclaveFactory.class); - when(enclaveFactory.createVertxEnclave(any())).thenReturn(mockEnclave); - return enclaveFactory; - } -} diff --git a/besu/src/test/java/org/hyperledger/besu/components/GenesisConfigModule.java b/besu/src/test/java/org/hyperledger/besu/components/GenesisConfigModule.java deleted file mode 100644 index ae82b8b928..0000000000 --- a/besu/src/test/java/org/hyperledger/besu/components/GenesisConfigModule.java +++ /dev/null @@ -1,38 +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.components; - -import org.hyperledger.besu.config.GenesisConfigFile; - -import javax.inject.Named; - -import dagger.Module; -import dagger.Provides; - -@Module -public class GenesisConfigModule { - - @Named("default") - @Provides - GenesisConfigFile provideDefaultGenesisConfigFile() { - return GenesisConfigFile.DEFAULT; - } - - @Named("mainnet") - @Provides - GenesisConfigFile provideMainnetGenesisConfigFile() { - return GenesisConfigFile.mainnet(); - } -} diff --git a/besu/src/test/java/org/hyperledger/besu/components/MockBesuCommandModule.java b/besu/src/test/java/org/hyperledger/besu/components/MockBesuCommandModule.java deleted file mode 100644 index 743b4ee8de..0000000000 --- a/besu/src/test/java/org/hyperledger/besu/components/MockBesuCommandModule.java +++ /dev/null @@ -1,50 +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.components; - -import static org.mockito.Mockito.mock; - -import org.hyperledger.besu.cli.BesuCommand; -import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration; - -import javax.inject.Named; -import javax.inject.Singleton; - -import dagger.Module; -import dagger.Provides; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -@Module -public class MockBesuCommandModule { - - @Provides - BesuCommand provideBesuCommand() { - return mock(BesuCommand.class); - } - - @Provides - @Singleton - MetricsConfiguration provideMetricsConfiguration() { - return MetricsConfiguration.builder().build(); - } - - @Provides - @Named("besuCommandLogger") - @Singleton - Logger provideBesuCommandLogger() { - return LoggerFactory.getLogger(MockBesuCommandModule.class); - } -} diff --git a/besu/src/test/java/org/hyperledger/besu/components/NoOpMetricsSystemModule.java b/besu/src/test/java/org/hyperledger/besu/components/NoOpMetricsSystemModule.java deleted file mode 100644 index e7807e3d75..0000000000 --- a/besu/src/test/java/org/hyperledger/besu/components/NoOpMetricsSystemModule.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.components; - -import org.hyperledger.besu.metrics.ObservableMetricsSystem; -import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; -import org.hyperledger.besu.plugin.services.MetricsSystem; - -import javax.inject.Singleton; - -import dagger.Module; -import dagger.Provides; - -@Module -public class NoOpMetricsSystemModule { - - @Provides - @Singleton - MetricsSystem provideMetricsSystem() { - return new NoOpMetricsSystem(); - } - - @Provides - @Singleton - ObservableMetricsSystem provideObservableMetricsSystem() { - return new NoOpMetricsSystem(); - } -} diff --git a/besu/src/test/java/org/hyperledger/besu/components/PrivacyParametersModule.java b/besu/src/test/java/org/hyperledger/besu/components/PrivacyParametersModule.java deleted file mode 100644 index 0b8fcf744f..0000000000 --- a/besu/src/test/java/org/hyperledger/besu/components/PrivacyParametersModule.java +++ /dev/null @@ -1,47 +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.components; - -import org.hyperledger.besu.enclave.EnclaveFactory; -import org.hyperledger.besu.ethereum.core.PrivacyParameters; -import org.hyperledger.besu.ethereum.privacy.storage.PrivacyStorageProvider; - -import java.net.URI; -import java.net.URISyntaxException; - -import dagger.Module; -import dagger.Provides; -import io.vertx.core.Vertx; - -/** Provides a general use PrivacyParameters instance for testing. */ -@Module -public class PrivacyParametersModule { - - @Provides - PrivacyParameters providePrivacyParameters( - final PrivacyStorageProvider storageProvider, final Vertx vertx) { - try { - return new PrivacyParameters.Builder() - .setEnabled(true) - .setEnclaveUrl(new URI("http://127.0.0.1:8000")) - .setStorageProvider(storageProvider) - .setEnclaveFactory(new EnclaveFactory(vertx)) - .setFlexiblePrivacyGroupsEnabled(false) - .build(); - } catch (URISyntaxException e) { - throw new RuntimeException(e); - } - } -} diff --git a/besu/src/test/java/org/hyperledger/besu/components/PrivacyTestModule.java b/besu/src/test/java/org/hyperledger/besu/components/PrivacyTestModule.java deleted file mode 100644 index 13cafe1ab4..0000000000 --- a/besu/src/test/java/org/hyperledger/besu/components/PrivacyTestModule.java +++ /dev/null @@ -1,111 +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.components; - -import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_BACKGROUND_THREAD_COUNT; -import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_CACHE_CAPACITY; -import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_IS_HIGH_SPEC; -import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_MAX_OPEN_FILES; - -import org.hyperledger.besu.ethereum.privacy.storage.PrivacyStorageProvider; -import org.hyperledger.besu.ethereum.privacy.storage.keyvalue.PrivacyKeyValueStorageProviderBuilder; -import org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier; -import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; -import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; -import org.hyperledger.besu.plugin.services.storage.rocksdb.RocksDBKeyValuePrivacyStorageFactory; -import org.hyperledger.besu.plugin.services.storage.rocksdb.RocksDBKeyValueStorageFactory; -import org.hyperledger.besu.plugin.services.storage.rocksdb.RocksDBMetricsFactory; -import org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBFactoryConfiguration; -import org.hyperledger.besu.services.BesuConfigurationImpl; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Arrays; -import javax.inject.Named; -import javax.inject.Singleton; - -import dagger.Module; -import dagger.Provides; -import io.vertx.core.Vertx; - -@Module -public class PrivacyTestModule { - - @Provides - @Named("dataDir") - Path provideDataDir() { - try { - return Files.createTempDirectory("PrivacyTestDatadir"); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - @Provides - Vertx provideVertx() { - return Vertx.vertx(); - } - - @Provides - DataStorageConfiguration provideDataStorageConfiguration() { - return DataStorageConfiguration.DEFAULT_FOREST_CONFIG; - } - - @Provides - @Singleton - @Named("dbDir") - Path provideDbDir(@Named("dataDir") final Path dataDir) { - try { - final Path dbDir = Files.createTempDirectory(dataDir, "database"); - return dbDir; - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - @Provides - @Singleton - @Named("flexibleEnabled") - Boolean provideFlexibleEnabled() { - return true; - } - - @Provides - @Singleton - @SuppressWarnings("CloseableProvides") - PrivacyStorageProvider provideKeyValueStorageProvider( - @Named("dbDir") final Path dbDir, - final DataStorageConfiguration dataStorageConfiguration, - @Named("dataDir") final Path dataDir) { - final var besuConfiguration = new BesuConfigurationImpl(); - besuConfiguration.init(dataDir, dbDir, dataStorageConfiguration); - return new PrivacyKeyValueStorageProviderBuilder() - .withStorageFactory( - new RocksDBKeyValuePrivacyStorageFactory( - new RocksDBKeyValueStorageFactory( - () -> - new RocksDBFactoryConfiguration( - DEFAULT_MAX_OPEN_FILES, - DEFAULT_BACKGROUND_THREAD_COUNT, - DEFAULT_CACHE_CAPACITY, - DEFAULT_IS_HIGH_SPEC), - Arrays.asList(KeyValueSegmentIdentifier.values()), - RocksDBMetricsFactory.PRIVATE_ROCKS_DB_METRICS))) - .withCommonConfiguration(besuConfiguration) - .withMetricsSystem(new NoOpMetricsSystem()) - .build(); - } -} diff --git a/besu/src/test/java/org/hyperledger/besu/controller/AbstractBftBesuControllerBuilderTest.java b/besu/src/test/java/org/hyperledger/besu/controller/AbstractBftBesuControllerBuilderTest.java index c7caf62ec2..731fd2ac56 100644 --- a/besu/src/test/java/org/hyperledger/besu/controller/AbstractBftBesuControllerBuilderTest.java +++ b/besu/src/test/java/org/hyperledger/besu/controller/AbstractBftBesuControllerBuilderTest.java @@ -19,7 +19,6 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.mock; -import org.hyperledger.besu.components.BesuComponent; import org.hyperledger.besu.config.CheckpointConfigOptions; import org.hyperledger.besu.config.GenesisConfigFile; import org.hyperledger.besu.config.GenesisConfigOptions; @@ -158,7 +157,6 @@ public abstract class AbstractBftBesuControllerBuilderTest { .storageProvider(storageProvider) .gasLimitCalculator(gasLimitCalculator) .evmConfiguration(EvmConfiguration.DEFAULT) - .besuComponent(mock(BesuComponent.class)) .networkConfiguration(NetworkingConfiguration.create()); } diff --git a/besu/src/test/java/org/hyperledger/besu/controller/CliqueBesuControllerBuilderTest.java b/besu/src/test/java/org/hyperledger/besu/controller/CliqueBesuControllerBuilderTest.java index aa79b944a1..82f98ba826 100644 --- a/besu/src/test/java/org/hyperledger/besu/controller/CliqueBesuControllerBuilderTest.java +++ b/besu/src/test/java/org/hyperledger/besu/controller/CliqueBesuControllerBuilderTest.java @@ -20,7 +20,6 @@ import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import org.hyperledger.besu.components.BesuComponent; import org.hyperledger.besu.config.CheckpointConfigOptions; import org.hyperledger.besu.config.GenesisConfigFile; import org.hyperledger.besu.config.GenesisConfigOptions; @@ -191,7 +190,6 @@ public class CliqueBesuControllerBuilderTest { .storageProvider(storageProvider) .gasLimitCalculator(gasLimitCalculator) .evmConfiguration(EvmConfiguration.DEFAULT) - .besuComponent(mock(BesuComponent.class)) .networkConfiguration(NetworkingConfiguration.create()); } diff --git a/besu/src/test/java/org/hyperledger/besu/controller/MergeBesuControllerBuilderTest.java b/besu/src/test/java/org/hyperledger/besu/controller/MergeBesuControllerBuilderTest.java index c788f41710..0e4948ddd5 100644 --- a/besu/src/test/java/org/hyperledger/besu/controller/MergeBesuControllerBuilderTest.java +++ b/besu/src/test/java/org/hyperledger/besu/controller/MergeBesuControllerBuilderTest.java @@ -23,7 +23,6 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; -import org.hyperledger.besu.components.BesuComponent; import org.hyperledger.besu.config.CheckpointConfigOptions; import org.hyperledger.besu.config.GenesisConfigFile; import org.hyperledger.besu.config.GenesisConfigOptions; @@ -191,7 +190,6 @@ public class MergeBesuControllerBuilderTest { .storageProvider(storageProvider) .evmConfiguration(EvmConfiguration.DEFAULT) .networkConfiguration(NetworkingConfiguration.create()) - .besuComponent(mock(BesuComponent.class)) .networkId(networkId); } diff --git a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/peers/EnodeURLImpl.java b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/peers/EnodeURLImpl.java index e087edd431..e1d158f3fc 100644 --- a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/peers/EnodeURLImpl.java +++ b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/peers/EnodeURLImpl.java @@ -381,11 +381,10 @@ public class EnodeURLImpl implements EnodeURL { return ipAddress(ip, EnodeDnsConfiguration.dnsDisabled()); } - public Builder ipAddress( - final String hostField, final EnodeDnsConfiguration enodeDnsConfiguration) { + public Builder ipAddress(final String ip, final EnodeDnsConfiguration enodeDnsConfiguration) { if (enodeDnsConfiguration.dnsEnabled()) { try { - this.ip = InetAddress.getByName(hostField); + this.ip = InetAddress.getByName(ip); if (enodeDnsConfiguration.updateEnabled()) { if (this.ip.isLoopbackAddress()) { this.ip = InetAddress.getLocalHost(); @@ -399,10 +398,10 @@ public class EnodeURLImpl implements EnodeURL { this.ip = InetAddresses.forString("127.0.0.1"); } } - } else if (InetAddresses.isUriInetAddress(hostField)) { - this.ip = InetAddresses.forUriString(hostField); - } else if (InetAddresses.isInetAddress(hostField)) { - this.ip = InetAddresses.forString(hostField); + } else if (InetAddresses.isUriInetAddress(ip)) { + this.ip = InetAddresses.forUriString(ip); + } else if (InetAddresses.isInetAddress(ip)) { + this.ip = InetAddresses.forString(ip); } else { throw new IllegalArgumentException("Invalid ip address."); } From c555775c1f0413a6f37e683509a21e5dfc34337c Mon Sep 17 00:00:00 2001 From: Sally MacFarlane Date: Wed, 21 Aug 2024 09:50:07 +1000 Subject: [PATCH 143/259] Refactor how genesis file overrides are applied (#7489) * added tests that fail * separate getConfigOptions() logic from applying overrides Signed-off-by: Sally MacFarlane --------- Signed-off-by: Sally MacFarlane --- .../org/hyperledger/besu/cli/BesuCommand.java | 12 +++-- .../hyperledger/besu/cli/BesuCommandTest.java | 54 +++++++++++++++++++ .../AbstractBftBesuControllerBuilderTest.java | 1 - .../CliqueBesuControllerBuilderTest.java | 1 - .../MergeBesuControllerBuilderTest.java | 1 - .../besu/config/GenesisConfigFile.java | 36 +++++++------ .../besu/config/GenesisConfigFileTest.java | 42 +++++++++------ .../mainnet/DifficultyCalculatorTests.java | 2 +- 8 files changed, 110 insertions(+), 39 deletions(-) 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 ba61a869ff..00ea6e1efd 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java @@ -1651,15 +1651,17 @@ public class BesuCommand implements DefaultCommandValues, Runnable { } private GenesisConfigFile readGenesisConfigFile() { - return genesisFile != null - ? GenesisConfigFile.fromSource(genesisConfigSource(genesisFile)) - : GenesisConfigFile.fromResource( - Optional.ofNullable(network).orElse(MAINNET).getGenesisFile()); + final GenesisConfigFile effectiveGenesisFile = + genesisFile != null + ? GenesisConfigFile.fromSource(genesisConfigSource(genesisFile)) + : GenesisConfigFile.fromResource( + Optional.ofNullable(network).orElse(MAINNET).getGenesisFile()); + return effectiveGenesisFile.withOverrides(genesisConfigOverrides); } private GenesisConfigOptions readGenesisConfigOptions() { try { - return genesisConfigFileSupplier.get().getConfigOptions(genesisConfigOverrides); + return genesisConfigFileSupplier.get().getConfigOptions(); } catch (final Exception e) { throw new ParameterException( this.commandLine, "Unable to load genesis file. " + e.getCause()); 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 23ba593a38..e6e0e85951 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java @@ -171,6 +171,60 @@ public class BesuCommandTest extends CommandTestAbstract { MergeConfigOptions.setMergeEnabled(false); } + @Test + public void testGenesisOverrideOptions() throws Exception { + parseCommand("--override-genesis-config", "shanghaiTime=123"); + + final ArgumentCaptor networkArg = + ArgumentCaptor.forClass(EthNetworkConfig.class); + + verify(mockControllerBuilderFactory).fromEthNetworkConfig(networkArg.capture(), any()); + verify(mockControllerBuilder).build(); + + final EthNetworkConfig config = networkArg.getValue(); + // mainnet defaults + assertThat(config.networkId()).isEqualTo(BigInteger.valueOf(1)); + + // assert that shanghaiTime override is applied + final GenesisConfigFile actualGenesisConfigFile = (config.genesisConfigFile()); + assertThat(actualGenesisConfigFile).isNotNull(); + assertThat(actualGenesisConfigFile.getConfigOptions().getShanghaiTime()).isNotEmpty(); + assertThat(actualGenesisConfigFile.getConfigOptions().getShanghaiTime().getAsLong()) + .isEqualTo(123); + + assertThat(commandOutput.toString(UTF_8)).isEmpty(); + assertThat(commandErrorOutput.toString(UTF_8)).isEmpty(); + } + + @Test + public void testGenesisOverrideOptionsWithCustomGenesis() throws Exception { + final Path genesisFile = createFakeGenesisFile(GENESIS_VALID_JSON); + + parseCommand( + "--genesis-file", genesisFile.toString(), "--override-genesis-config", "shanghaiTime=123"); + + final ArgumentCaptor networkArg = + ArgumentCaptor.forClass(EthNetworkConfig.class); + + verify(mockControllerBuilderFactory).fromEthNetworkConfig(networkArg.capture(), any()); + verify(mockControllerBuilder).build(); + + final EthNetworkConfig config = networkArg.getValue(); + assertThat(config.bootNodes()).isEmpty(); + assertThat(config.dnsDiscoveryUrl()).isNull(); + assertThat(config.networkId()).isEqualTo(BigInteger.valueOf(3141592)); + + // then assert that the shanghaiTime is applied + final GenesisConfigFile actualGenesisConfigFile = (config.genesisConfigFile()); + assertThat(actualGenesisConfigFile).isNotNull(); + assertThat(actualGenesisConfigFile.getConfigOptions().getShanghaiTime()).isNotEmpty(); + assertThat(actualGenesisConfigFile.getConfigOptions().getShanghaiTime().getAsLong()) + .isEqualTo(123); + + assertThat(commandOutput.toString(UTF_8)).isEmpty(); + assertThat(commandErrorOutput.toString(UTF_8)).isEmpty(); + } + @Test public void callingHelpSubCommandMustDisplayUsage() { parseCommand("--help"); diff --git a/besu/src/test/java/org/hyperledger/besu/controller/AbstractBftBesuControllerBuilderTest.java b/besu/src/test/java/org/hyperledger/besu/controller/AbstractBftBesuControllerBuilderTest.java index 731fd2ac56..f9e671f522 100644 --- a/besu/src/test/java/org/hyperledger/besu/controller/AbstractBftBesuControllerBuilderTest.java +++ b/besu/src/test/java/org/hyperledger/besu/controller/AbstractBftBesuControllerBuilderTest.java @@ -104,7 +104,6 @@ public abstract class AbstractBftBesuControllerBuilderTest { lenient().when(genesisConfigFile.getDifficulty()).thenReturn(Bytes.of(0).toHexString()); lenient().when(genesisConfigFile.getMixHash()).thenReturn(Hash.ZERO.toHexString()); lenient().when(genesisConfigFile.getNonce()).thenReturn(Long.toHexString(1)); - lenient().when(genesisConfigFile.getConfigOptions(any())).thenReturn(genesisConfigOptions); lenient().when(genesisConfigFile.getConfigOptions()).thenReturn(genesisConfigOptions); lenient().when(genesisConfigOptions.getCheckpointOptions()).thenReturn(checkpointConfigOptions); lenient() diff --git a/besu/src/test/java/org/hyperledger/besu/controller/CliqueBesuControllerBuilderTest.java b/besu/src/test/java/org/hyperledger/besu/controller/CliqueBesuControllerBuilderTest.java index 82f98ba826..39904df798 100644 --- a/besu/src/test/java/org/hyperledger/besu/controller/CliqueBesuControllerBuilderTest.java +++ b/besu/src/test/java/org/hyperledger/besu/controller/CliqueBesuControllerBuilderTest.java @@ -113,7 +113,6 @@ public class CliqueBesuControllerBuilderTest { "0x0000000000000000000000000000000000000000000000000000000000000000b9b81ee349c3807e46bc71aa2632203c5b4620340000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"); lenient().when(genesisConfigFile.getMixHash()).thenReturn(Hash.ZERO.toHexString()); lenient().when(genesisConfigFile.getNonce()).thenReturn(Long.toHexString(1)); - lenient().when(genesisConfigFile.getConfigOptions(any())).thenReturn(genesisConfigOptions); lenient().when(genesisConfigFile.getConfigOptions()).thenReturn(genesisConfigOptions); lenient().when(genesisConfigOptions.getCheckpointOptions()).thenReturn(checkpointConfigOptions); lenient() diff --git a/besu/src/test/java/org/hyperledger/besu/controller/MergeBesuControllerBuilderTest.java b/besu/src/test/java/org/hyperledger/besu/controller/MergeBesuControllerBuilderTest.java index 0e4948ddd5..544b633015 100644 --- a/besu/src/test/java/org/hyperledger/besu/controller/MergeBesuControllerBuilderTest.java +++ b/besu/src/test/java/org/hyperledger/besu/controller/MergeBesuControllerBuilderTest.java @@ -124,7 +124,6 @@ public class MergeBesuControllerBuilderTest { lenient().when(genesisConfigFile.getExtraData()).thenReturn(Bytes.EMPTY.toHexString()); lenient().when(genesisConfigFile.getMixHash()).thenReturn(Hash.ZERO.toHexString()); lenient().when(genesisConfigFile.getNonce()).thenReturn(Long.toHexString(1)); - lenient().when(genesisConfigFile.getConfigOptions(any())).thenReturn(genesisConfigOptions); lenient().when(genesisConfigFile.getConfigOptions()).thenReturn(genesisConfigOptions); lenient().when(genesisConfigOptions.getCheckpointOptions()).thenReturn(checkpointConfigOptions); when(genesisConfigOptions.getTerminalTotalDifficulty()) 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 bd1e117773..453c38dac2 100644 --- a/config/src/main/java/org/hyperledger/besu/config/GenesisConfigFile.java +++ b/config/src/main/java/org/hyperledger/besu/config/GenesisConfigFile.java @@ -18,7 +18,6 @@ import org.hyperledger.besu.datatypes.Wei; import java.net.URL; import java.util.Arrays; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -41,6 +40,7 @@ public class GenesisConfigFile { private final GenesisReader loader; private final ObjectNode genesisRoot; + private Map overrides; private GenesisConfigFile(final GenesisReader loader) { this.loader = loader; @@ -107,36 +107,42 @@ public class GenesisConfigFile { } /** - * Gets config options. + * Gets config options, including any overrides. * * @return the config options */ public GenesisConfigOptions getConfigOptions() { - return getConfigOptions(Collections.emptyMap()); - } - - /** - * Gets config options. - * - * @param overrides the overrides - * @return the config options - */ - public GenesisConfigOptions getConfigOptions(final Map overrides) { final ObjectNode config = loader.getConfig(); - - Map overridesRef = overrides; + // are there any overrides to apply? + if (this.overrides == null) { + return JsonGenesisConfigOptions.fromJsonObject(config); + } + // otherwise apply overrides + Map overridesRef = this.overrides; // if baseFeePerGas has been explicitly configured, pass it as an override: final var optBaseFee = getBaseFeePerGas(); if (optBaseFee.isPresent()) { // streams and maps cannot handle null values. - overridesRef = new HashMap<>(overrides); + overridesRef = new HashMap<>(this.overrides); overridesRef.put("baseFeePerGas", optBaseFee.get().toShortHexString()); } return JsonGenesisConfigOptions.fromJsonObjectWithOverrides(config, overridesRef); } + /** + * Sets overrides for genesis options. + * + * @param overrides the overrides + * @return the config options + */ + public GenesisConfigFile withOverrides(final Map overrides) { + + this.overrides = overrides; + return this; + } + /** * Stream allocations stream. * diff --git a/config/src/test/java/org/hyperledger/besu/config/GenesisConfigFileTest.java b/config/src/test/java/org/hyperledger/besu/config/GenesisConfigFileTest.java index 9f014b7d4d..3e6b488b9b 100644 --- a/config/src/test/java/org/hyperledger/besu/config/GenesisConfigFileTest.java +++ b/config/src/test/java/org/hyperledger/besu/config/GenesisConfigFileTest.java @@ -187,7 +187,9 @@ class GenesisConfigFileTest { @Test void shouldOverrideConfigOptionsBaseFeeWhenSpecified() { GenesisConfigOptions withOverrides = - EMPTY_CONFIG.getConfigOptions(Map.of("baseFeePerGas", Wei.of(8).toString())); + EMPTY_CONFIG + .withOverrides(Map.of("baseFeePerGas", Wei.of(8).toString())) + .getConfigOptions(); assertThat(withOverrides.getBaseFeePerGas()).contains(Wei.of(8L)); } @@ -229,7 +231,8 @@ class GenesisConfigFileTest { void assertTerminalTotalDifficultyOverride() { GenesisConfigOptions sepoliaOverrideOptions = GenesisConfigFile.fromResource("/sepolia.json") - .getConfigOptions(Map.of("terminalTotalDifficulty", String.valueOf(Long.MAX_VALUE))); + .withOverrides(Map.of("terminalTotalDifficulty", String.valueOf(Long.MAX_VALUE))) + .getConfigOptions(); assertThat(sepoliaOverrideOptions.getTerminalTotalDifficulty()).isPresent(); assertThat(sepoliaOverrideOptions.getTerminalTotalDifficulty()) @@ -355,10 +358,12 @@ class GenesisConfigFileTest { override.put("contractSizeLimit", bigBlockString); assertThat(config.getForkBlockNumbers()).isNotEmpty(); - assertThat(config.getConfigOptions(override).getIstanbulBlockNumber()).hasValue(bigBlock); - assertThat(config.getConfigOptions(override).getChainId()) + assertThat(config.withOverrides(override).getConfigOptions().getIstanbulBlockNumber()) + .hasValue(bigBlock); + assertThat(config.withOverrides(override).getConfigOptions().getChainId()) .hasValue(BigInteger.valueOf(bigBlock)); - assertThat(config.getConfigOptions(override).getContractSizeLimit()).hasValue(bigBlock); + assertThat(config.withOverrides(override).getConfigOptions().getContractSizeLimit()) + .hasValue(bigBlock); } @Test @@ -370,9 +375,11 @@ class GenesisConfigFileTest { override.put("contractSizeLimit", null); assertThat(config.getForkBlockNumbers()).isNotEmpty(); - assertThat(config.getConfigOptions(override).getIstanbulBlockNumber()).isNotPresent(); - assertThat(config.getConfigOptions(override).getChainId()).isNotPresent(); - assertThat(config.getConfigOptions(override).getContractSizeLimit()).isNotPresent(); + assertThat(config.withOverrides(override).getConfigOptions().getIstanbulBlockNumber()) + .isNotPresent(); + assertThat(config.withOverrides(override).getConfigOptions().getChainId()).isNotPresent(); + assertThat(config.withOverrides(override).getConfigOptions().getContractSizeLimit()) + .isNotPresent(); } @Test @@ -388,10 +395,12 @@ class GenesisConfigFileTest { // all lower case override.put("contractsizelimit", bigBlockString); - assertThat(config.getConfigOptions(override).getIstanbulBlockNumber()).hasValue(bigBlock); - assertThat(config.getConfigOptions(override).getChainId()) + assertThat(config.withOverrides(override).getConfigOptions().getIstanbulBlockNumber()) + .hasValue(bigBlock); + assertThat(config.withOverrides(override).getConfigOptions().getChainId()) .hasValue(BigInteger.valueOf(bigBlock)); - assertThat(config.getConfigOptions(override).getContractSizeLimit()).hasValue(bigBlock); + assertThat(config.withOverrides(override).getConfigOptions().getContractSizeLimit()) + .hasValue(bigBlock); } @Test @@ -402,9 +411,11 @@ class GenesisConfigFileTest { override.put("chainId", ""); override.put("contractSizeLimit", ""); - assertThat(config.getConfigOptions(override).getIstanbulBlockNumber()).isNotPresent(); - assertThat(config.getConfigOptions(override).getChainId()).isNotPresent(); - assertThat(config.getConfigOptions(override).getContractSizeLimit()).isNotPresent(); + assertThat(config.withOverrides(override).getConfigOptions().getIstanbulBlockNumber()) + .isNotPresent(); + assertThat(config.withOverrides(override).getConfigOptions().getChainId()).isNotPresent(); + assertThat(config.withOverrides(override).getConfigOptions().getContractSizeLimit()) + .isNotPresent(); } @Test @@ -431,7 +442,8 @@ class GenesisConfigFileTest { override.put("constantinopleFixBlock", "1000"); assertThatExceptionOfType(RuntimeException.class) - .isThrownBy(() -> config.getConfigOptions(override).getPetersburgBlockNumber()) + .isThrownBy( + () -> config.withOverrides(override).getConfigOptions().getPetersburgBlockNumber()) .withMessage( "Genesis files cannot specify both petersburgBlock and constantinopleFixBlock."); } diff --git a/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/mainnet/DifficultyCalculatorTests.java b/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/mainnet/DifficultyCalculatorTests.java index 00733de1f8..cfb56d1ebc 100644 --- a/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/mainnet/DifficultyCalculatorTests.java +++ b/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/mainnet/DifficultyCalculatorTests.java @@ -60,7 +60,7 @@ public class DifficultyCalculatorTests { "/BasicTests/difficultyMainNetwork.json", MainnetProtocolSchedule.fromConfig( GenesisConfigFile.mainnet() - .getConfigOptions(postMergeOverrides), + .withOverrides(postMergeOverrides).getConfigOptions(), EvmConfiguration.DEFAULT, MiningParameters.newDefault(), new BadBlockManager(), false, new NoOpMetricsSystem())), Arguments.of( "/DifficultyTests/dfGrayGlacier/difficultyGrayGlacierForkBlock.json", From 5b8764d648ec08f28df98a26facbfa0f2d13ad65 Mon Sep 17 00:00:00 2001 From: Simon Dudley Date: Wed, 21 Aug 2024 16:27:21 +1000 Subject: [PATCH 144/259] Add new lodestar bootnode for holesky (#7500) Signed-off-by: Simon Dudley --- CHANGELOG.md | 1 + config/src/main/resources/holesky.json | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f04fcfb345..82a60615a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ ### Additions and Improvements - Add 'inbound' field to admin_peers JSON-RPC Call [#7461](https://github.com/hyperledger/besu/pull/7461) - Add pending block header to `TransactionEvaluationContext` plugin API [#7483](https://github.com/hyperledger/besu/pull/7483) +- Add bootnode to holesky config [#7500](https://github.com/hyperledger/besu/pull/7500) ### Bug fixes - Fix tracing in precompiled contracts when halting for out of gas [#7318](https://github.com/hyperledger/besu/issues/7318) diff --git a/config/src/main/resources/holesky.json b/config/src/main/resources/holesky.json index 6ae6942a8c..d91971b351 100644 --- a/config/src/main/resources/holesky.json +++ b/config/src/main/resources/holesky.json @@ -20,7 +20,8 @@ "dns": "enrtree://AKA3AM6LPBYEUDMVNU3BSVQJ5AD45Y7YPOHJLEF6W26QOE4VTUDPE@all.holesky.ethdisco.net", "bootnodes": [ "enode://ac906289e4b7f12df423d654c5a962b6ebe5b3a74cc9e06292a85221f9a64a6f1cfdd6b714ed6dacef51578f92b34c60ee91e9ede9c7f8fadc4d347326d95e2b@146.190.13.128:30303", - "enode://a3435a0155a3e837c02f5e7f5662a2f1fbc25b48e4dc232016e1c51b544cb5b4510ef633ea3278c0e970fa8ad8141e2d4d0f9f95456c537ff05fdf9b31c15072@178.128.136.233:30303" + "enode://a3435a0155a3e837c02f5e7f5662a2f1fbc25b48e4dc232016e1c51b544cb5b4510ef633ea3278c0e970fa8ad8141e2d4d0f9f95456c537ff05fdf9b31c15072@178.128.136.233:30303", + "enode://7fa09f1e8bb179ab5e73f45d3a7169a946e7b3de5ef5cea3a0d4546677e4435ee38baea4dd10b3ddfdc1f1c5e869052932af8b8aeb6f9738598ec4590d0b11a6@65.109.94.124:30303" ] } }, From d7656b98993df18488ef7fbcd66bd3039162fb0a Mon Sep 17 00:00:00 2001 From: Matt Whitehead Date: Wed, 21 Aug 2024 08:40:17 +0100 Subject: [PATCH 145/259] For test node runners use provided data storage config (#7495) Signed-off-by: Matthew Whitehead --- .../tests/acceptance/dsl/node/ProcessBesuNodeRunner.java | 8 +------- .../tests/acceptance/dsl/node/ThreadBesuNodeRunner.java | 3 +-- 2 files changed, 2 insertions(+), 9 deletions(-) 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 37906761d1..c6696b15a2 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 @@ -24,8 +24,6 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.ipc.JsonRpcIpcConfiguration; import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration; import org.hyperledger.besu.ethereum.p2p.rlpx.connections.netty.TLSConfiguration; import org.hyperledger.besu.ethereum.permissioning.PermissioningConfiguration; -import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; -import org.hyperledger.besu.ethereum.worldstate.ImmutableDataStorageConfiguration; import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration; import org.hyperledger.besu.plugin.services.metrics.MetricCategory; import org.hyperledger.besu.tests.acceptance.dsl.StaticNodesUtils; @@ -113,11 +111,7 @@ public class ProcessBesuNodeRunner implements BesuNodeRunner { .getCLIOptions()); params.addAll( - DataStorageOptions.fromConfig( - ImmutableDataStorageConfiguration.builder() - .from(DataStorageConfiguration.DEFAULT_FOREST_CONFIG) - .build()) - .getCLIOptions()); + DataStorageOptions.fromConfig(node.getDataStorageConfiguration()).getCLIOptions()); if (node.getMiningParameters().isMiningEnabled()) { params.add("--miner-enabled"); 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 c662196092..f28a1d8876 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 @@ -40,7 +40,6 @@ import org.hyperledger.besu.ethereum.p2p.peers.EnodeURLImpl; 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.evm.internal.EvmConfiguration; import org.hyperledger.besu.metrics.MetricsSystemFactory; import org.hyperledger.besu.metrics.ObservableMetricsSystem; @@ -250,7 +249,7 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner { .nodeKey(new NodeKey(new KeyPairSecurityModule(KeyPairUtil.loadKeyPair(dataDir)))) .metricsSystem(metricsSystem) .transactionPoolConfiguration(txPoolConfig) - .dataStorageConfiguration(DataStorageConfiguration.DEFAULT_FOREST_CONFIG) + .dataStorageConfiguration(node.getDataStorageConfiguration()) .ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig()) .clock(Clock.systemUTC()) .isRevertReasonEnabled(node.isRevertReasonEnabled()) From 0ec335fbf1a5b2156a47c861a1f7a281287544a1 Mon Sep 17 00:00:00 2001 From: Matt Whitehead Date: Wed, 21 Aug 2024 09:42:52 +0100 Subject: [PATCH 146/259] BFT soak test - use both db modes (#7496) * For test node runners use provided data storage config Signed-off-by: Matthew Whitehead * Make the BFT soak mining tests use both Forest and Bonsai DBs Signed-off-by: Matthew Whitehead --------- Signed-off-by: Matthew Whitehead --- .../node/configuration/BesuNodeFactory.java | 19 +++++++++++++++++-- .../BftAcceptanceTestParameterization.java | 15 +++++++++++---- .../acceptance/bftsoak/BftMiningSoakTest.java | 9 +++++---- 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeFactory.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeFactory.java index ed4a28422d..efbf91246b 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeFactory.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeFactory.java @@ -32,7 +32,9 @@ import org.hyperledger.besu.ethereum.core.MiningParameters; import org.hyperledger.besu.ethereum.core.PrivacyParameters; import org.hyperledger.besu.ethereum.permissioning.LocalPermissioningConfiguration; import org.hyperledger.besu.ethereum.permissioning.PermissioningConfiguration; +import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; import org.hyperledger.besu.pki.keystore.KeyStoreWrapper; +import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; import org.hyperledger.besu.tests.acceptance.dsl.node.BesuNode; import org.hyperledger.besu.tests.acceptance.dsl.node.Node; import org.hyperledger.besu.tests.acceptance.dsl.node.RunnableNode; @@ -476,7 +478,9 @@ public class BesuNodeFactory { .build()); } - public BesuNode createIbft2Node(final String name, final boolean fixedPort) throws IOException { + public BesuNode createIbft2Node( + final String name, final boolean fixedPort, final DataStorageFormat storageFormat) + throws IOException { JsonRpcConfiguration rpcConfig = node.createJsonRpcWithIbft2EnabledConfig(false); rpcConfig.addRpcApi("ADMIN,TXPOOL"); if (fixedPort) { @@ -484,6 +488,7 @@ public class BesuNodeFactory { Math.abs(name.hashCode() % 60000) + 1024); // Generate a consistent port for p2p based on node name } + BesuNodeConfigurationBuilder builder = new BesuNodeConfigurationBuilder() .name(name) @@ -491,6 +496,10 @@ public class BesuNodeFactory { .jsonRpcConfiguration(rpcConfig) .webSocketConfiguration(node.createWebSocketEnabledConfig()) .devMode(false) + .dataStorageConfiguration( + storageFormat == DataStorageFormat.FOREST + ? DataStorageConfiguration.DEFAULT_FOREST_CONFIG + : DataStorageConfiguration.DEFAULT_BONSAI_CONFIG) .genesisConfigProvider(GenesisConfigurationFactory::createIbft2GenesisConfig); if (fixedPort) { builder.p2pPort( @@ -527,7 +536,9 @@ public class BesuNodeFactory { return createQbftNodeWithTLS(name, KeyStoreWrapper.KEYSTORE_TYPE_PKCS11); } - public BesuNode createQbftNode(final String name, final boolean fixedPort) throws IOException { + public BesuNode createQbftNode( + final String name, final boolean fixedPort, final DataStorageFormat storageFormat) + throws IOException { JsonRpcConfiguration rpcConfig = node.createJsonRpcWithQbftEnabledConfig(false); rpcConfig.addRpcApi("ADMIN,TXPOOL"); if (fixedPort) { @@ -543,6 +554,10 @@ public class BesuNodeFactory { .jsonRpcConfiguration(rpcConfig) .webSocketConfiguration(node.createWebSocketEnabledConfig()) .devMode(false) + .dataStorageConfiguration( + storageFormat == DataStorageFormat.FOREST + ? DataStorageConfiguration.DEFAULT_FOREST_CONFIG + : DataStorageConfiguration.DEFAULT_BONSAI_CONFIG) .genesisConfigProvider(GenesisConfigurationFactory::createQbftGenesisConfig); if (fixedPort) { builder.p2pPort( diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bft/BftAcceptanceTestParameterization.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bft/BftAcceptanceTestParameterization.java index 15872070d0..2351f740bf 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bft/BftAcceptanceTestParameterization.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bft/BftAcceptanceTestParameterization.java @@ -14,6 +14,7 @@ */ package org.hyperledger.besu.tests.acceptance.bft; +import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; import org.hyperledger.besu.tests.acceptance.dsl.node.BesuNode; import org.hyperledger.besu.tests.acceptance.dsl.node.configuration.BesuNodeFactory; @@ -38,7 +39,9 @@ public class BftAcceptanceTestParameterization { @FunctionalInterface public interface NodeCreator { - BesuNode create(BesuNodeFactory factory, String name, boolean fixedPort) throws Exception; + BesuNode create( + BesuNodeFactory factory, String name, boolean fixedPort, DataStorageFormat storageFormat) + throws Exception; } @FunctionalInterface @@ -64,11 +67,15 @@ public class BftAcceptanceTestParameterization { } public BesuNode createNode(BesuNodeFactory factory, String name) throws Exception { - return creatorFn.create(factory, name, false); + return creatorFn.create(factory, name, false, DataStorageFormat.FOREST); + } + + public BesuNode createBonsaiNodeFixedPort(BesuNodeFactory factory, String name) throws Exception { + return creatorFn.create(factory, name, true, DataStorageFormat.BONSAI); } - public BesuNode createNodeFixedPort(BesuNodeFactory factory, String name) throws Exception { - return creatorFn.create(factory, name, true); + public BesuNode createForestNodeFixedPort(BesuNodeFactory factory, String name) throws Exception { + return creatorFn.create(factory, name, true, DataStorageFormat.FOREST); } public BesuNode createNodeWithValidators( 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 9861a7dab6..878e503ba3 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 @@ -60,10 +60,11 @@ public class BftMiningSoakTest extends ParameterizedBftTestBase { // in between certain steps. There should be no upper-limit to how long the test is run for assertThat(getTestDurationMins()).isGreaterThanOrEqualTo(MIN_TEST_TIME_MINS); - final BesuNode minerNode1 = nodeFactory.createNodeFixedPort(besu, "miner1"); - final BesuNode minerNode2 = nodeFactory.createNodeFixedPort(besu, "miner2"); - final BesuNode minerNode3 = nodeFactory.createNodeFixedPort(besu, "miner3"); - final BesuNode minerNode4 = nodeFactory.createNodeFixedPort(besu, "miner4"); + // Create a mix of Bonsai and Forest DB nodes + final BesuNode minerNode1 = nodeFactory.createBonsaiNodeFixedPort(besu, "miner1"); + final BesuNode minerNode2 = nodeFactory.createForestNodeFixedPort(besu, "miner2"); + final BesuNode minerNode3 = nodeFactory.createBonsaiNodeFixedPort(besu, "miner3"); + final BesuNode minerNode4 = nodeFactory.createForestNodeFixedPort(besu, "miner4"); // Each step should be given a minimum of 3 minutes to complete successfully. If the time // give to run the soak test results in a time-per-step lower than this then the time From 1598e6be6775a56ab42c7f27df4a59c00c7c118f Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Wed, 21 Aug 2024 13:01:35 -0700 Subject: [PATCH 147/259] EOF Differential Layout Fuzzer (#7488) Differential EOF Layout Fuzzer guided by Besu's layout parser. Signed-off-by: Danno Ferrin --- build.gradle | 4 + .../besu/evmtool/CodeValidateSubCommand.java | 10 +- .../evmtool/CodeValidationSubCommandTest.java | 20 +- .../evmtool/code-validate/createdata.json | 7 + .../besu/evmtool/code-validate/runtime.json | 2 +- .../besu/evmtool/trace/eof-section.json | 4 +- .../vm/GeneralStateReferenceTestTools.java | 4 +- .../besu/evm/tracing/StandardJsonTracer.java | 2 +- gradle/verification-metadata.xml | 21 ++ gradle/versions.gradle | 11 +- settings.gradle | 1 + testfuzz/README.md | 29 ++ testfuzz/build.gradle | 148 ++++++++++ .../hyperledger/besu/testfuzz/BesuFuzz.java | 38 +++ .../besu/testfuzz/BesuFuzzCommand.java | 78 ++++++ .../besu/testfuzz/EofContainerSubCommand.java | 258 ++++++++++++++++++ .../besu/testfuzz/ExternalClient.java | 22 ++ .../org/hyperledger/besu/testfuzz/Fuzzer.java | 239 ++++++++++++++++ .../besu/testfuzz/SingleQueryClient.java | 89 ++++++ .../besu/testfuzz/StreamingClient.java | 52 ++++ .../besu/testfuzz/VersionProvider.java | 47 ++++ testfuzz/src/main/scripts/unixStartScript.txt | 200 ++++++++++++++ .../src/main/scripts/windowsStartScript.txt | 91 ++++++ 23 files changed, 1351 insertions(+), 26 deletions(-) create mode 100644 ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/code-validate/createdata.json create mode 100644 testfuzz/README.md create mode 100644 testfuzz/build.gradle create mode 100644 testfuzz/src/main/java/org/hyperledger/besu/testfuzz/BesuFuzz.java create mode 100644 testfuzz/src/main/java/org/hyperledger/besu/testfuzz/BesuFuzzCommand.java create mode 100644 testfuzz/src/main/java/org/hyperledger/besu/testfuzz/EofContainerSubCommand.java create mode 100644 testfuzz/src/main/java/org/hyperledger/besu/testfuzz/ExternalClient.java create mode 100644 testfuzz/src/main/java/org/hyperledger/besu/testfuzz/Fuzzer.java create mode 100644 testfuzz/src/main/java/org/hyperledger/besu/testfuzz/SingleQueryClient.java create mode 100644 testfuzz/src/main/java/org/hyperledger/besu/testfuzz/StreamingClient.java create mode 100644 testfuzz/src/main/java/org/hyperledger/besu/testfuzz/VersionProvider.java create mode 100644 testfuzz/src/main/scripts/unixStartScript.txt create mode 100644 testfuzz/src/main/scripts/windowsStartScript.txt diff --git a/build.gradle b/build.gradle index 7d2293b61e..6a4f279666 100644 --- a/build.gradle +++ b/build.gradle @@ -160,6 +160,10 @@ allprojects { url 'https://splunk.jfrog.io/splunk/ext-releases-local' content { includeGroupByRegex('com\\.splunk\\..*') } } + maven { + url 'https://gitlab.com/api/v4/projects/19871573/packages/maven' + content { includeGroupByRegex('com\\.gitlab\\.javafuzz(\\..*)?') } + } mavenCentral() 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 4c04119864..a3fff8e5dc 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 @@ -36,8 +36,6 @@ import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; import java.util.function.Supplier; -import java.util.stream.Collectors; -import java.util.stream.IntStream; import com.google.common.base.Suppliers; import org.apache.tuweni.bytes.Bytes; @@ -175,12 +173,8 @@ public class CodeValidateSubCommand implements Runnable { ((CodeV1) code).getEofLayout().containerMode().get())) { return "err: code is valid initcode. Runtime code expected"; } else { - return "OK " - + IntStream.range(0, code.getCodeSectionCount()) - .mapToObj(code::getCodeSection) - .map(cs -> code.getBytes().slice(cs.getEntryPoint(), cs.getLength())) - .map(Bytes::toUnprefixedHexString) - .collect(Collectors.joining(",")); + return "OK %d/%d/%d" + .formatted(code.getCodeSectionCount(), code.getSubcontainerCount(), code.getDataSize()); } } } diff --git a/ethereum/evmtool/src/test/java/org/hyperledger/besu/evmtool/CodeValidationSubCommandTest.java b/ethereum/evmtool/src/test/java/org/hyperledger/besu/evmtool/CodeValidationSubCommandTest.java index dd7133f862..d6b7359413 100644 --- a/ethereum/evmtool/src/test/java/org/hyperledger/besu/evmtool/CodeValidationSubCommandTest.java +++ b/ethereum/evmtool/src/test/java/org/hyperledger/besu/evmtool/CodeValidationSubCommandTest.java @@ -47,7 +47,7 @@ class CodeValidationSubCommandTest { EvmToolCommand parentCommand = new EvmToolCommand(bais, new PrintWriter(baos, true, UTF_8)); final CodeValidateSubCommand codeValidateSubCommand = new CodeValidateSubCommand(parentCommand); codeValidateSubCommand.run(); - assertThat(baos.toString(UTF_8)).contains("OK 00\n"); + assertThat(baos.toString(UTF_8)).contains("OK 1/0/0\n"); } @Test @@ -70,9 +70,9 @@ class CodeValidationSubCommandTest { assertThat(baos.toString(UTF_8)) .contains( """ - OK 00 + OK 1/0/0 err: layout - EOF header byte 1 incorrect - OK 5f5ff3 + OK 1/0/0 """); } @@ -85,7 +85,7 @@ class CodeValidationSubCommandTest { final CommandLine cmd = new CommandLine(codeValidateSubCommand); cmd.parseArgs(CODE_STOP_ONLY); codeValidateSubCommand.run(); - assertThat(baos.toString(UTF_8)).contains("OK 00\n"); + assertThat(baos.toString(UTF_8)).contains("OK 1/0/0\n"); } @Test @@ -112,9 +112,9 @@ class CodeValidationSubCommandTest { assertThat(baos.toString(UTF_8)) .contains( """ - OK 00 + OK 1/0/0 err: layout - EOF header byte 1 incorrect - OK 5f5ff3 + OK 1/0/0 """); } @@ -127,7 +127,7 @@ class CodeValidationSubCommandTest { final CommandLine cmd = new CommandLine(codeValidateSubCommand); cmd.parseArgs(CODE_RETURN_ONLY); codeValidateSubCommand.run(); - assertThat(baos.toString(UTF_8)).contains("OK 5f5ff3\n"); + assertThat(baos.toString(UTF_8)).contains("OK 1/0/0\n"); } @Test @@ -139,7 +139,7 @@ class CodeValidationSubCommandTest { final CommandLine cmd = new CommandLine(codeValidateSubCommand); cmd.parseArgs(CODE_INTERIOR_COMMENTS); codeValidateSubCommand.run(); - assertThat(baos.toString(UTF_8)).contains("OK 59595959e300015000,f8e4\n"); + assertThat(baos.toString(UTF_8)).contains("OK 2/0/0\n"); } @Test @@ -153,9 +153,9 @@ class CodeValidationSubCommandTest { assertThat(baos.toString(UTF_8)) .isEqualTo( """ - OK 00 + OK 1/0/0 err: layout - EOF header byte 1 incorrect - OK 5f5ff3 + OK 1/0/0 """); } } diff --git a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/code-validate/createdata.json b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/code-validate/createdata.json new file mode 100644 index 0000000000..9207cd65e0 --- /dev/null +++ b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/code-validate/createdata.json @@ -0,0 +1,7 @@ +{ + "cli": [ + "code-validate" + ], + "stdin": "0xef0001010004020001000b0300010014040004000080000436600060ff6000ec005000ef000101000402000100010400000000800000feda7ac0de", + "stdout": "OK 1/1/4\n" +} diff --git a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/code-validate/runtime.json b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/code-validate/runtime.json index 7965815559..fedeaa1bc0 100644 --- a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/code-validate/runtime.json +++ b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/code-validate/runtime.json @@ -3,5 +3,5 @@ "code-validate" ], "stdin": "ef00010100040200010001040000000080000000", - "stdout": "OK 00\n" + "stdout": "OK 1/0/0\n" } 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 061d8f0940..439c69195a 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 @@ -12,8 +12,8 @@ "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,"fdepth":1,"refund":0,"opName":"JUMPF"}, - {"pc":0,"section":1,"op":228,"gas":"0x2540be3f6","gasCost":"0x3","memSize":0,"stack":[],"depth":1,"fdepth":1,"refund":0,"opName":"RETF"}, + {"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":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"}, diff --git a/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/vm/GeneralStateReferenceTestTools.java b/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/vm/GeneralStateReferenceTestTools.java index 42934b612d..354642f1ad 100644 --- a/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/vm/GeneralStateReferenceTestTools.java +++ b/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/vm/GeneralStateReferenceTestTools.java @@ -151,11 +151,11 @@ public class GeneralStateReferenceTestTools { .blobGasPricePerGas(blockHeader.getExcessBlobGas().orElse(BlobGas.ZERO)); final TransactionProcessingResult result = processor.processTransaction( - worldStateUpdater, + worldStateUpdater, blockHeader, transaction, blockHeader.getCoinbase(), - new CachingBlockHashLookup(blockHeader, blockchain), + new CachingBlockHashLookup(blockHeader, blockchain), false, TransactionValidationParams.processingBlock(), blobGasPrice); 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 2a71fb70cd..a289c665d2 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 @@ -216,7 +216,7 @@ public class StandardJsonTracer implements OperationTracer { } sb.append("\"depth\":").append(depth).append(","); if (subdepth >= 1) { - sb.append("\"fdepth\":").append(subdepth).append(","); + sb.append("\"functionDepth\":").append(subdepth).append(","); } sb.append("\"refund\":").append(messageFrame.getGasRefund()).append(","); sb.append("\"opName\":\"").append(currentOp.getName()).append("\""); diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index 46029c87c8..49c1e7f00c 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -546,6 +546,19 @@ + + + + + + + + + + + + + @@ -5372,6 +5385,14 @@ + + + + + + + + diff --git a/gradle/versions.gradle b/gradle/versions.gradle index 57f2acae37..e0baf3bb46 100644 --- a/gradle/versions.gradle +++ b/gradle/versions.gradle @@ -41,6 +41,8 @@ dependencyManagement { dependency 'org.hyperledger.besu:besu-errorprone-checks:1.0.0' + dependency 'com.gitlab.javafuzz:core:1.26' + dependency 'com.google.guava:guava:33.0.0-jre' dependency 'com.graphql-java:graphql-java:21.5' @@ -153,8 +155,6 @@ dependencyManagement { } dependency 'org.fusesource.jansi:jansi:2.4.1' - dependency 'org.openjdk.jol:jol-core:0.17' - dependency 'tech.pegasys:jc-kzg-4844:1.0.0' dependencySet(group: 'org.hyperledger.besu', version: '0.9.4') { entry 'arithmetic' @@ -173,6 +173,9 @@ dependencyManagement { dependency 'org.java-websocket:Java-WebSocket:1.5.5' + dependency 'org.jacoco:org.jacoco.agent:0.8.11' + dependency 'org.jacoco:org.jacoco.core:0.8.11' + dependency 'org.jetbrains.kotlin:kotlin-stdlib:1.9.22' dependencySet(group: 'org.junit.jupiter', version: '5.10.1') { @@ -182,6 +185,8 @@ dependencyManagement { 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' @@ -232,6 +237,8 @@ dependencyManagement { dependency 'org.apache.maven:maven-artifact:3.9.6' + dependency 'tech.pegasys:jc-kzg-4844:1.0.0' + dependency 'tech.pegasys.discovery:discovery:22.12.0' } } diff --git a/settings.gradle b/settings.gradle index 09a8d20d4c..322383b32c 100644 --- a/settings.gradle +++ b/settings.gradle @@ -68,5 +68,6 @@ include 'privacy-contracts' include 'services:kvstore' include 'services:pipeline' include 'services:tasks' +include 'testfuzz' include 'testutil' include 'util' diff --git a/testfuzz/README.md b/testfuzz/README.md new file mode 100644 index 0000000000..8f436d7011 --- /dev/null +++ b/testfuzz/README.md @@ -0,0 +1,29 @@ +# BesuFuzz + +BesuFuzz is where all the besu guided fuzzing tools live. + +## eof-container + +Performs differential fuzzing between Ethereum clients based on +the [txparse eofparse](https://github.com/holiman/txparse/blob/main/README.md#eof-parser-eofparse) +format. Note that only the inital `OK` and `err` values are used to determine if +there is a difference. + +### Prototypical CLI Usage: + +```shell +BesuFuzz eof-container \ + --tests-dir=~/git/ethereum/tests/EOFTests \ + --client=evm1=evmone-eofparse \ + --client=revm=revme bytecode +``` + +### Prototypical Gradle usage: + +```shell +./gradlew fuzzEvmone fuzzReth +``` + +There are pre-written Gradle targets for `fuzzEthereumJS`, `fuzzEvmone`, +`fuzzGeth`, `fuzzNethermind`, and `fuzzReth`. Besu is always a fuzzing target. +The `fuzzAll` target will fuzz all clients. \ No newline at end of file diff --git a/testfuzz/build.gradle b/testfuzz/build.gradle new file mode 100644 index 0000000000..1c96798155 --- /dev/null +++ b/testfuzz/build.gradle @@ -0,0 +1,148 @@ +/* + * 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 + */ + +apply plugin: 'application' +apply plugin: 'java-library' +apply plugin: 'jacoco' + +jar { + archiveBaseName = 'besu-test-fuzz' + manifest { + attributes( + 'Specification-Title': archiveBaseName, + 'Specification-Version': project.version, + 'Implementation-Title': archiveBaseName, + 'Implementation-Version': calculateVersion() + ) + } +} + +dependencies { + implementation project(':besu') + implementation project(':crypto:algorithms') + implementation project(':datatypes') + implementation project(':ethereum:referencetests') + implementation project(':evm') + implementation project(':util') + + implementation 'com.fasterxml.jackson.core:jackson-databind' + implementation 'com.gitlab.javafuzz:core' + implementation 'info.picocli:picocli' + implementation 'io.tmio:tuweni-bytes' + implementation 'org.jacoco:org.jacoco.agent' + implementation 'org.jacoco:org.jacoco.core' +} + +application { + applicationName = 'BesuFuzz' + mainClass = 'org.hyperledger.besu.testfuzz.BesuFuzz' + applicationDefaultJvmArgs = [ + '-javaagent:$APP_HOME/lib/jacocoagent.jar' + ] +} + +def corpusDir = "${buildDir}/generated/corpus" + +tasks.register("runFuzzer", JavaExec) { + classpath = sourceSets.main.runtimeClasspath + mainClass = 'org.hyperledger.besu.testfuzz.BesuFuzz' + + args = [ + "eof-container", + "--tests-dir=${projectDir}/../ethereum/referencetests/src/reference-test/external-resources/EOFTests", + "--corpus-dir=${corpusDir}" + ] + doFirst { + mkdir corpusDir + } +} + +tasks.register("fuzzEvmone") { + doLast { + runFuzzer.args += "--client=evm1=evmone-eofparse" + } + finalizedBy("runFuzzer") +} + +tasks.register("fuzzEthereumJS") { + doLast { + runFuzzer.args += "--client=etjs=tsx ../../../ethereumjs/ethereumjs-monorepo/packages/evm/scripts/eofContainerValidator.ts" + } + finalizedBy("runFuzzer") +} + +tasks.register("fuzzGeth") { + doLast { + runFuzzer.args += "--client=geth=eofdump eofparser" + } + finalizedBy("runFuzzer") +} + +tasks.register("fuzzNethermind") { + doLast { + runFuzzer.args += "--client=neth=netheofparse -x" + } + finalizedBy("runFuzzer") +} + +tasks.register("fuzzReth") { + doLast { + runFuzzer.args += "--client=revm=revme bytecode" + } + finalizedBy("runFuzzer") +} + +tasks.register("fuzzAll") { + dependsOn fuzzEvm1, fuzzEthJS, fuzzGeth, fuzzNethermind, fuzzReth +} + +jacoco { + applyTo run + applyTo runFuzzer +} + +// Copies jacoco into the lib directory +tasks.register("copyJacoco", Copy) { + // The jacocoagent.jar is embedded within the jar + from zipTree(configurations.jacocoAgent.singleFile).filter { it.name == 'jacocoagent.jar' }.singleFile + into layout.buildDirectory.dir("install/${application.applicationName}/lib") +} + +installDist.finalizedBy copyJacoco + +startScripts { + defaultJvmOpts = [ + "-Dsecp256k1.randomize=false" + ] + unixStartScriptGenerator.template = resources.text.fromFile("${projectDir}/src/main/scripts/unixStartScript.txt") + windowsStartScriptGenerator.template = resources.text.fromFile("${projectDir}/src/main/scripts/windowsStartScript.txt") + doLast { tweakStartScript(startScripts) } +} + +static def tweakStartScript(createScriptTask) { + def shortenWindowsClasspath = { line -> + line.replaceAll(/^set CLASSPATH=.*$/, "set CLASSPATH=%APP_HOME%/lib/*") + } + + createScriptTask.unixScript.text = createScriptTask.unixScript.text.replace('BESU_HOME', '\$APP_HOME') + createScriptTask.windowsScript.text = createScriptTask.windowsScript.text.replace('BESU_HOME', '%~dp0..') + + // Prevent the error originating from the 8191 chars limit on Windows + createScriptTask.windowsScript.text = + createScriptTask.windowsScript + .readLines() + .collect(shortenWindowsClasspath) + .join('\r\n') +} diff --git a/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/BesuFuzz.java b/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/BesuFuzz.java new file mode 100644 index 0000000000..6cde758804 --- /dev/null +++ b/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/BesuFuzz.java @@ -0,0 +1,38 @@ +/* + * 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.testfuzz; + +import org.hyperledger.besu.util.LogConfigurator; + +/** The main entry point for the EVM (Ethereum Virtual Machine) tool. */ +public final class BesuFuzz { + + /** Default constructor for the EvmTool class. */ + public BesuFuzz() { + // this is here only for Javadoc linting + } + + /** + * The main entry point for the EVM (Ethereum Virtual Machine) tool. + * + * @param args The command line arguments. + */ + public static void main(final String... args) { + LogConfigurator.setLevel("", "DEBUG"); + final BesuFuzzCommand besuFuzzCommand = new BesuFuzzCommand(); + + besuFuzzCommand.execute(args); + } +} diff --git a/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/BesuFuzzCommand.java b/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/BesuFuzzCommand.java new file mode 100644 index 0000000000..22165b5ffe --- /dev/null +++ b/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/BesuFuzzCommand.java @@ -0,0 +1,78 @@ +/* + * 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.testfuzz; + +import static java.nio.charset.StandardCharsets.UTF_8; + +import org.hyperledger.besu.util.LogConfigurator; + +import java.io.InputStream; +import java.io.PrintWriter; + +import picocli.CommandLine; +import picocli.CommandLine.Command; + +/** + * This is the root command for the `BesuFuzz` command line tool. It is a collection of fuzzers that + * are guided by Besu's implementations. + */ +@Command( + description = "Executes Besu based fuzz tests", + abbreviateSynopsis = true, + name = "evm", + mixinStandardHelpOptions = true, + versionProvider = VersionProvider.class, + sortOptions = false, + header = "Usage:", + synopsisHeading = "%n", + descriptionHeading = "%nDescription:%n%n", + optionListHeading = "%nOptions:%n", + footerHeading = "%n", + footer = "Hyperledger Besu is licensed under the Apache License 2.0", + subcommands = {EofContainerSubCommand.class}) +@SuppressWarnings("java:S106") +public class BesuFuzzCommand implements Runnable { + + PrintWriter out; + InputStream in; + + /** Default Constructor */ + BesuFuzzCommand() { + // this method is here only for JavaDoc linting + } + + void execute(final String... args) { + execute(System.in, new PrintWriter(System.out, true, UTF_8), args); + } + + void execute(final InputStream input, final PrintWriter output, final String[] args) { + final CommandLine commandLine = new CommandLine(this).setOut(output); + out = output; + in = input; + + // don't require exact case to match enum values + commandLine.setCaseInsensitiveEnumValuesAllowed(true); + + commandLine.setExecutionStrategy(new CommandLine.RunLast()); + commandLine.execute(args); + } + + @Override + public void run() { + LogConfigurator.setLevel("", "OFF"); + System.out.println("No default command, please select a subcommand"); + System.exit(1); + } +} diff --git a/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/EofContainerSubCommand.java b/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/EofContainerSubCommand.java new file mode 100644 index 0000000000..efe84296cf --- /dev/null +++ b/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/EofContainerSubCommand.java @@ -0,0 +1,258 @@ +/* + * 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.testfuzz; + +import static org.hyperledger.besu.testfuzz.EofContainerSubCommand.COMMAND_NAME; + +import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.ethereum.referencetests.EOFTestCaseSpec; +import org.hyperledger.besu.evm.Code; +import org.hyperledger.besu.evm.EVM; +import org.hyperledger.besu.evm.MainnetEVMs; +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.evm.code.EOFLayout.EOFContainerMode; +import org.hyperledger.besu.evm.internal.EvmConfiguration; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +import com.fasterxml.jackson.core.JsonParser.Feature; +import com.fasterxml.jackson.core.util.DefaultIndenter; +import com.fasterxml.jackson.core.util.DefaultPrettyPrinter; +import com.fasterxml.jackson.core.util.Separators; +import com.fasterxml.jackson.core.util.Separators.Spacing; +import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import com.gitlab.javafuzz.core.AbstractFuzzTarget; +import org.apache.tuweni.bytes.Bytes; +import picocli.CommandLine; +import picocli.CommandLine.Option; + +/** Fuzzes the parsing and validation of an EOF container. */ +@SuppressWarnings({"java:S106", "CallToPrintStackTrace"}) // we use lots the console, on purpose +@CommandLine.Command( + name = COMMAND_NAME, + description = "Fuzzes EOF container parsing and validation", + mixinStandardHelpOptions = true, + versionProvider = VersionProvider.class) +public class EofContainerSubCommand extends AbstractFuzzTarget implements Runnable { + + static final String COMMAND_NAME = "eof-container"; + + @Option( + names = {"--corpus-dir"}, + paramLabel = "", + description = "Directory to store corpus files") + private final Path corpusDir = Path.of("corpus"); + + @Option( + names = {"--tests-dir"}, + paramLabel = "", + description = "Directory where EOF tests references file tree lives") + private final Path testsDir = null; + + @Option( + names = {"--client"}, + paramLabel = "=", + description = "Add a client for differential fuzzing") + private final Map clients = new LinkedHashMap<>(); + + @CommandLine.ParentCommand private final BesuFuzzCommand parentCommand; + + static final ObjectMapper eofTestMapper = createObjectMapper(); + static final JavaType javaType = + eofTestMapper + .getTypeFactory() + .constructParametricType(Map.class, String.class, EOFTestCaseSpec.class); + + List externalClients = new ArrayList<>(); + EVM evm = MainnetEVMs.pragueEOF(EvmConfiguration.DEFAULT); + long validContainers; + long totalContainers; + + /** + * Default constructor for the EofContainerSubCommand class. This constructor initializes the + * parentCommand to null. + */ + public EofContainerSubCommand() { + this(null); + } + + /** + * Constructs a new EofContainerSubCommand with the specified parent command. + * + * @param parentCommand The parent command for this subcommand. + */ + public EofContainerSubCommand(final BesuFuzzCommand parentCommand) { + this.parentCommand = parentCommand; + } + + private static ObjectMapper createObjectMapper() { + final ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.setDefaultPrettyPrinter( + (new DefaultPrettyPrinter()) + .withSeparators( + Separators.createDefaultInstance().withObjectFieldValueSpacing(Spacing.BOTH)) + .withObjectIndenter(DefaultIndenter.SYSTEM_LINEFEED_INSTANCE.withIndent(" ")) + .withArrayIndenter(DefaultIndenter.SYSTEM_LINEFEED_INSTANCE.withIndent(" "))); + objectMapper.disable(Feature.AUTO_CLOSE_SOURCE); + SimpleModule serializers = new SimpleModule("Serializers"); + serializers.addSerializer(Address.class, ToStringSerializer.instance); + serializers.addSerializer(Bytes.class, ToStringSerializer.instance); + objectMapper.registerModule(serializers); + + return objectMapper; + } + + @Override + public void run() { + // load test dir into corpus dir + if (testsDir != null) { + File f = testsDir.toFile(); + if (f.isDirectory()) { + try (var files = Files.walk(f.toPath(), Integer.MAX_VALUE)) { + files.forEach( + ff -> { + File file = ff.toFile(); + if (file.isFile()) { + extractFile(file, corpusDir.toFile()); + } + }); + } catch (IOException e) { + parentCommand.out.println("Exception walking " + f + ": " + e.getMessage()); + } + } + } + + clients.forEach((k, v) -> externalClients.add(new StreamingClient(k, v.split(" ")))); + System.out.println("Fuzzing client set: " + clients.keySet()); + + try { + new Fuzzer(this, corpusDir.toString(), this::fuzzStats).start(); + } catch (NoSuchAlgorithmException + | ClassNotFoundException + | InvocationTargetException + | IllegalAccessException + | NoSuchMethodException e) { + throw new RuntimeException(e); + } + } + + private void extractFile(final File f, final File initialCorpus) { + final Map eofTests; + try { + eofTests = eofTestMapper.readValue(f, javaType); + } catch (IOException e) { + // presume parse failed because it's a corpus file + return; + } + for (var entry : eofTests.entrySet()) { + int index = 0; + for (var vector : entry.getValue().getVector().entrySet()) { + try (FileOutputStream fos = + new FileOutputStream( + new File( + initialCorpus, + f.toPath().getFileName() + "_" + (index++) + "_" + vector.getKey()))) { + Bytes codeBytes = Bytes.fromHexString(vector.getValue().code()); + evm.getCodeUncached(codeBytes); + fos.write(codeBytes.toArrayUnsafe()); + } catch (IOException e) { + parentCommand.out.println("Invalid file " + f + ": " + e.getMessage()); + e.printStackTrace(); + System.exit(1); + } + } + } + } + + @Override + public void fuzz(final byte[] bytes) { + Bytes eofUnderTest = Bytes.wrap(bytes); + String eofUnderTestHexString = eofUnderTest.toHexString(); + Code code = evm.getCodeUncached(eofUnderTest); + Map results = new LinkedHashMap<>(); + boolean mismatch = false; + for (var client : externalClients) { + String value = client.differentialFuzz(eofUnderTestHexString); + results.put(client.getName(), value); + if (value == null || value.startsWith("fail: ")) { + mismatch = true; // if an external client fails, always report it as an error + } + } + boolean besuValid = false; + String besuReason; + if (!code.isValid()) { + besuReason = ((CodeInvalid) code).getInvalidReason(); + } else if (code.getEofVersion() != 1) { + EOFLayout layout = EOFLayout.parseEOF(eofUnderTest); + if (layout.isValid()) { + besuReason = "Besu Parsing Error"; + parentCommand.out.println(layout.version()); + parentCommand.out.println(layout.invalidReason()); + parentCommand.out.println(code.getEofVersion()); + parentCommand.out.println(code.getClass().getName()); + System.exit(1); + mismatch = true; + } else { + besuReason = layout.invalidReason(); + } + } else if (EOFContainerMode.INITCODE.equals( + ((CodeV1) code).getEofLayout().containerMode().get())) { + besuReason = "Code is initcode, not runtime"; + } else { + besuReason = "OK"; + besuValid = true; + } + for (var entry : results.entrySet()) { + mismatch = + mismatch + || besuValid != entry.getValue().toUpperCase(Locale.getDefault()).startsWith("OK"); + } + if (mismatch) { + parentCommand.out.println("besu: " + besuReason); + for (var entry : results.entrySet()) { + parentCommand.out.println(entry.getKey() + ": " + entry.getValue()); + } + parentCommand.out.println("code: " + eofUnderTest.toUnprefixedHexString()); + parentCommand.out.println("size: " + eofUnderTest.size()); + parentCommand.out.println(); + } else { + if (besuValid) { + validContainers++; + } + totalContainers++; + } + } + + String fuzzStats() { + return " / %5.2f%% valid %d/%d" + .formatted((100.0 * validContainers) / totalContainers, validContainers, totalContainers); + } +} diff --git a/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/ExternalClient.java b/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/ExternalClient.java new file mode 100644 index 0000000000..e5505239ab --- /dev/null +++ b/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/ExternalClient.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.testfuzz; + +interface ExternalClient { + + String getName(); + + String differentialFuzz(String data); +} diff --git a/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/Fuzzer.java b/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/Fuzzer.java new file mode 100644 index 0000000000..e4ebb68cc8 --- /dev/null +++ b/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/Fuzzer.java @@ -0,0 +1,239 @@ +/* + * 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.testfuzz; + +import org.hyperledger.besu.crypto.Hash; +import org.hyperledger.besu.crypto.MessageDigestFactory; + +import java.io.ByteArrayInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.math.BigInteger; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Supplier; + +import com.gitlab.javafuzz.core.AbstractFuzzTarget; +import com.gitlab.javafuzz.core.Corpus; +import org.apache.tuweni.bytes.Bytes; +import org.jacoco.core.data.ExecutionData; +import org.jacoco.core.data.ExecutionDataReader; +import org.jacoco.core.data.IExecutionDataVisitor; +import org.jacoco.core.data.ISessionInfoVisitor; +import org.jacoco.core.data.SessionInfo; + +/** Ported from javafuzz because JaCoCo APIs changed. */ +@SuppressWarnings({"java:S106", "CallToPrintStackTrace"}) // we use lots the console, on purpose +public class Fuzzer { + private final AbstractFuzzTarget target; + private final Corpus corpus; + private final Object agent; + private final Method getExecutionDataMethod; + private long executionsInSample; + private long lastSampleTime; + private long totalExecutions; + private long totalCoverage; + + Supplier fuzzStats; + + /** + * Create a new fuzzer + * + * @param target The target to fuzz + * @param dirs the list of corpus dirs and files, comma separated. + * @param fuzzStats additional fuzzing data from the client + * @throws ClassNotFoundException If Jacoco RT is not found (because jacocoagent.jar is not + * loaded) + * @throws NoSuchMethodException If the wrong version of Jacoco is loaded + * @throws InvocationTargetException If the wrong version of Jacoco is loaded + * @throws IllegalAccessException If the wrong version of Jacoco is loaded + * @throws NoSuchAlgorithmException If the SHA-256 crypto algo cannot be loaded. + */ + public Fuzzer( + final AbstractFuzzTarget target, final String dirs, final Supplier fuzzStats) + throws ClassNotFoundException, + NoSuchMethodException, + InvocationTargetException, + IllegalAccessException, + NoSuchAlgorithmException { + this.target = target; + this.corpus = new Corpus(dirs); + this.fuzzStats = fuzzStats; + Class c = Class.forName("org.jacoco.agent.rt.RT"); + Method getAgentMethod = c.getMethod("getAgent"); + this.agent = getAgentMethod.invoke(null); + this.getExecutionDataMethod = agent.getClass().getMethod("getExecutionData", boolean.class); + fileNameForBuffer(new byte[0]); + } + + void writeCrash(final byte[] buf) { + Bytes hash = Hash.sha256(Bytes.wrap(buf)); + String filepath = "crash-" + hash.toUnprefixedHexString(); + try (FileOutputStream fos = new FileOutputStream(filepath)) { + fos.write(buf); + System.out.printf("crash was written to %s%n", filepath); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + void logStats(final String type) { + long rss = + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / 1024 / 1024; + long endTime = System.currentTimeMillis(); + long execs_per_second = -1; + if ((endTime - this.lastSampleTime) != 0) { + execs_per_second = (this.executionsInSample * 1000 / (endTime - this.lastSampleTime)); + } + this.lastSampleTime = endTime; + this.executionsInSample = 0; + + System.out.printf( + "#%d %s cov: %d corp: %d exec/s: %d rss: %d MB %s%n", + this.totalExecutions, + type, + this.totalCoverage, + this.corpus.getLength(), + execs_per_second, + rss, + fuzzStats.get()); + } + + /** + * Runs the fuzzer until the VM is shut down + * + * @throws InvocationTargetException if the wrong version of jacoco is loaded + * @throws IllegalAccessException if the wrong version of jacoco is loaded + * @throws NoSuchAlgorithmException if our favorite hash algo is not loaded + */ + @SuppressWarnings("java:S2189") // the endless loop is on purpose + public void start() + throws InvocationTargetException, IllegalAccessException, NoSuchAlgorithmException { + System.out.printf("#0 READ units: %d%n", this.corpus.getLength()); + this.totalCoverage = 0; + this.totalExecutions = 0; + this.executionsInSample = 0; + this.lastSampleTime = System.currentTimeMillis(); + + Map hitMap = new HashMap<>(); + + while (true) { + byte[] buf = this.corpus.generateInput(); + // The next version will run this in a different thread. + try { + this.target.fuzz(buf); + } catch (Exception e) { + e.printStackTrace(System.out); + this.writeCrash(buf); + System.exit(1); + break; + } + + this.totalExecutions++; + this.executionsInSample++; + + long newCoverage = getHitCount(hitMap); + if (newCoverage > this.totalCoverage) { + this.totalCoverage = newCoverage; + this.corpus.putBuffer(buf); + this.logStats("NEW"); + + // If you want hex strings of new hits, uncomment the following. + // String filename = fileNameForBuffer(buf); + // try (var pw = + // new PrintWriter( + // new BufferedWriter( + // new OutputStreamWriter(new FileOutputStream(filename), UTF_8)))) { + // pw.println(Bytes.wrap(buf).toHexString()); + // System.out.println(filename); + // } catch (IOException e) { + // e.printStackTrace(System.out); + // } + } else if ((System.currentTimeMillis() - this.lastSampleTime) > 30000) { + this.logStats("PULSE"); + } + } + } + + private static String fileNameForBuffer(final byte[] buf) throws NoSuchAlgorithmException { + MessageDigest md = MessageDigestFactory.create(MessageDigestFactory.SHA256_ALG); + md.update(buf); + byte[] digest = md.digest(); + return String.format("./new-%064x.hex", new BigInteger(1, digest)); + } + + private long getHitCount(final Map hitMap) + throws IllegalAccessException, InvocationTargetException { + byte[] dumpData = (byte[]) this.getExecutionDataMethod.invoke(this.agent, false); + ExecutionDataReader edr = new ExecutionDataReader(new ByteArrayInputStream(dumpData)); + HitCounter hc = new HitCounter(hitMap); + edr.setExecutionDataVisitor(hc); + edr.setSessionInfoVisitor(hc); + try { + edr.read(); + } catch (IOException e) { + e.printStackTrace(); + this.writeCrash(dumpData); + } + + return hc.getHits(); + } + + static class HitCounter implements IExecutionDataVisitor, ISessionInfoVisitor { + long hits = 0; + Map hitMap; + + public HitCounter(final Map hitMap) { + this.hitMap = hitMap; + } + + @Override + public void visitClassExecution(final ExecutionData executionData) { + int hit = 0; + for (boolean b : executionData.getProbes()) { + if (executionData.getName().startsWith("org/hyperledger/besu/testfuzz/") + || executionData.getName().startsWith("org/bouncycastle/") + || executionData.getName().startsWith("com/gitlab/javafuzz/")) { + continue; + } + if (b) { + hit++; + } + } + String name = executionData.getName(); + if (hitMap.containsKey(name)) { + if (hitMap.get(name) < hit) { + hitMap.put(name, hit); + } + } else { + hitMap.put(name, hit); + } + hits += hit; + } + + public long getHits() { + return hits; + } + + @Override + public void visitSessionInfo(final SessionInfo sessionInfo) { + // nothing to do. Data parser requires a session listener. + } + } +} diff --git a/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/SingleQueryClient.java b/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/SingleQueryClient.java new file mode 100644 index 0000000000..802a6011aa --- /dev/null +++ b/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/SingleQueryClient.java @@ -0,0 +1,89 @@ +/* + * 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.testfuzz; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +@SuppressWarnings({"java:S106", "CallToPrintStackTrace"}) // we use lots the console, on purpose +class SingleQueryClient implements ExternalClient { + final String name; + String[] command; + Pattern okRegexp; + String okRegexpStr; + int okGroup; + Pattern failRegexp; + int failGroup; + String failRegexpStr; + + public SingleQueryClient( + final String clientName, + final String okRegexp, + final int okGroup, + final String errorRegexp, + final int failGroup, + final String... command) { + this.name = clientName; + this.okRegexp = Pattern.compile(okRegexp); + this.okRegexpStr = okRegexp; + this.okGroup = okGroup; + this.failRegexp = Pattern.compile(errorRegexp); + this.failGroup = failGroup; + this.failRegexpStr = errorRegexp; + this.command = command; + } + + @Override + public String getName() { + return name; + } + + @Override + @SuppressWarnings("java:S2142") + public String differentialFuzz(final String data) { + if (!data.startsWith("0xef")) { + return "err: invalid_magic"; + } + try { + List localCommand = new ArrayList<>(command.length + 1); + localCommand.addAll(Arrays.asList(command)); + localCommand.add(data); + Process p = new ProcessBuilder().command(localCommand).redirectErrorStream(true).start(); + if (!p.waitFor(1, TimeUnit.SECONDS)) { + System.out.println("Process Hang for " + name); + return "fail: process took more than 1 sec " + p.pid(); + } + String s = new String(p.getInputStream().readAllBytes(), StandardCharsets.UTF_8); + Matcher m = okRegexp.matcher(s); + if (m.find()) { + return "OK " + m.group(okGroup); + } + m = failRegexp.matcher(s); + if (m.find()) { + return "err: " + m.group(failGroup); + } + return "fail: SingleClientQuery failed to get data"; + } catch (InterruptedException | IOException e) { + e.printStackTrace(); + return "fail: " + e.getMessage(); + } + } +} diff --git a/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/StreamingClient.java b/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/StreamingClient.java new file mode 100644 index 0000000000..a59cd9326f --- /dev/null +++ b/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/StreamingClient.java @@ -0,0 +1,52 @@ +/* + * 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.testfuzz; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.PrintWriter; +import java.nio.charset.StandardCharsets; + +class StreamingClient implements ExternalClient { + final String name; + final BufferedReader reader; + final PrintWriter writer; + + public StreamingClient(final String clientName, final String... command) { + try { + Process p = new ProcessBuilder().redirectErrorStream(true).command(command).start(); + this.name = clientName; + this.reader = new BufferedReader(p.inputReader(StandardCharsets.UTF_8)); + this.writer = new PrintWriter(p.getOutputStream(), true, StandardCharsets.UTF_8); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Override + public String getName() { + return name; + } + + @Override + public String differentialFuzz(final String data) { + try { + writer.println(data); + return reader.readLine(); + } catch (IOException ioe) { + throw new RuntimeException(ioe); + } + } +} diff --git a/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/VersionProvider.java b/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/VersionProvider.java new file mode 100644 index 0000000000..6a184dd90e --- /dev/null +++ b/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/VersionProvider.java @@ -0,0 +1,47 @@ +/* + * 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.testfuzz; + +import org.hyperledger.besu.BesuInfo; + +import picocli.CommandLine; + +/** + * The VersionProvider class is responsible for providing the version of the Hyperledger Besu EVM + * tool. It implements the IVersionProvider interface from the picocli library. + * + *

The getVersion method returns a string array containing the version of the Hyperledger Besu + * EVM tool. + */ +public class VersionProvider implements CommandLine.IVersionProvider { + + /** + * Default constructor for the VersionProvider class. This constructor does not perform any + * operations. + */ + public VersionProvider() { + // this constructor is here only for javadoc linting + } + + /** + * This method returns the version of the Hyperledger Besu EVM tool. + * + * @return A string array containing the version of the Hyperledger Besu EVM tool. + */ + @Override + public String[] getVersion() { + return new String[] {"Hyperledger Besu evm " + BesuInfo.shortVersion()}; + } +} diff --git a/testfuzz/src/main/scripts/unixStartScript.txt b/testfuzz/src/main/scripts/unixStartScript.txt new file mode 100644 index 0000000000..59d8b83fbc --- /dev/null +++ b/testfuzz/src/main/scripts/unixStartScript.txt @@ -0,0 +1,200 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# 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 +# +# https://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. +# + +############################################################################## +## +## ${applicationName} start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: \$0 may be a link +PRG="\$0" +# Need this for relative symlinks. +while [ -h "\$PRG" ] ; do + ls=`ls -ld "\$PRG"` + link=`expr "\$ls" : '.*-> \\(.*\\)\$'` + if expr "\$link" : '/.*' > /dev/null; then + PRG="\$link" + else + PRG=`dirname "\$PRG"`"/\$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"\$PRG\"`/${appHomeRelativePath}" >/dev/null +APP_HOME="`pwd -P`" +cd "\$SAVED" >/dev/null + +APP_NAME="${applicationName}" +APP_BASE_NAME=`basename "\$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and ${optsEnvironmentVar} to pass JVM options to this script. +DEFAULT_JVM_OPTS=${defaultJvmOpts} + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "\$*" +} + +die () { + echo + echo "\$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MSYS* | MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$classpath +<% if ( mainClassName.startsWith('--module ') ) { %>MODULE_PATH=$modulePath<% } %> + +# Determine the Java command to use to start the JVM. +if [ -n "\$JAVA_HOME" ] ; then + if [ -x "\$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="\$JAVA_HOME/jre/sh/java" + else + JAVACMD="\$JAVA_HOME/bin/java" + fi + if [ ! -x "\$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: \$JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "\$cygwin" = "false" -a "\$darwin" = "false" -a "\$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ \$? -eq 0 ] ; then + if [ "\$MAX_FD" = "maximum" -o "\$MAX_FD" = "max" ] ; then + MAX_FD="\$MAX_FD_LIMIT" + fi + ulimit -n \$MAX_FD + if [ \$? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: \$MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: \$MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if \$darwin; then + GRADLE_OPTS="\$GRADLE_OPTS \\"-Xdock:name=\$APP_NAME\\" \\"-Xdock:icon=\$APP_HOME/media/gradle.icns\\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "\$cygwin" = "true" -o "\$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "\$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "\$CLASSPATH"` +<% if ( mainClassName.startsWith('--module ') ) { %> MODULE_PATH=`cygpath --path --mixed "\$MODULE_PATH"`<% } %> + JAVACMD=`cygpath --unix "\$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in \$ROOTDIRSRAW ; do + ROOTDIRS="\$ROOTDIRS\$SEP\$dir" + SEP="|" + done + OURCYGPATTERN="(^(\$ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "\$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="\$OURCYGPATTERN|(\$GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "\$@" ; do + CHECK=`echo "\$arg"|egrep -c "\$OURCYGPATTERN" -` + CHECK2=`echo "\$arg"|egrep -c "^-"` ### Determine if an option + + if [ \$CHECK -ne 0 ] && [ \$CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args\$i`=`cygpath --path --ignore --mixed "\$arg"` + else + eval `echo args\$i`="\"\$arg\"" + fi + i=`expr \$i + 1` + done + case \$i in + 0) set -- ;; + 1) set -- "\$args0" ;; + 2) set -- "\$args0" "\$args1" ;; + 3) set -- "\$args0" "\$args1" "\$args2" ;; + 4) set -- "\$args0" "\$args1" "\$args2" "\$args3" ;; + 5) set -- "\$args0" "\$args1" "\$args2" "\$args3" "\$args4" ;; + 6) set -- "\$args0" "\$args1" "\$args2" "\$args3" "\$args4" "\$args5" ;; + 7) set -- "\$args0" "\$args1" "\$args2" "\$args3" "\$args4" "\$args5" "\$args6" ;; + 8) set -- "\$args0" "\$args1" "\$args2" "\$args3" "\$args4" "\$args5" "\$args6" "\$args7" ;; + 9) set -- "\$args0" "\$args1" "\$args2" "\$args3" "\$args4" "\$args5" "\$args6" "\$args7" "\$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\\\n "\$i" | sed "s/'/'\\\\\\\\''/g;1s/^/'/;\\\$s/\\\$/' \\\\\\\\/" ; done + echo " " +} +APP_ARGS=`save "\$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- -javaagent:\$APP_HOME/lib/jacocoagent.jar \$DEFAULT_JVM_OPTS \$JAVA_OPTS \$${optsEnvironmentVar} <% if ( appNameSystemProperty ) { %>"\"-D${appNameSystemProperty}=\$APP_BASE_NAME\"" <% } %>-classpath "\"\$CLASSPATH\"" <% if ( mainClassName.startsWith('--module ') ) { %>--module-path "\"\$MODULE_PATH\"" <% } %>${mainClassName} "\$APP_ARGS" + +unset BESU_USING_JEMALLOC +if [ "\$darwin" = "false" -a "\$msys" = "false" ]; then + # check if jemalloc is available + TEST_JEMALLOC=\$(LD_PRELOAD=libjemalloc.so sh -c true 2>&1) + + # if jemalloc is available the output is empty, otherwise the output has an error line + if [ -z "\$TEST_JEMALLOC" ]; then + export LD_PRELOAD=libjemalloc.so + export BESU_USING_JEMALLOC=true + else + # jemalloc not available, as fallback limit malloc to 2 arenas + export MALLOC_ARENA_MAX=2 + fi +fi + +exec "\$JAVACMD" "\$@" diff --git a/testfuzz/src/main/scripts/windowsStartScript.txt b/testfuzz/src/main/scripts/windowsStartScript.txt new file mode 100644 index 0000000000..2ce40892ef --- /dev/null +++ b/testfuzz/src/main/scripts/windowsStartScript.txt @@ -0,0 +1,91 @@ +@rem +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem ${applicationName} startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=.\ + +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME%${appHomeRelativePath} + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and ${optsEnvironmentVar} to pass JVM options to this script. +set DEFAULT_JVM_OPTS=${defaultJvmOpts} + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=$classpath +<% if ( mainClassName.startsWith('--module ') ) { %>set MODULE_PATH=$modulePath<% } %> + +@rem Execute ${applicationName} +"%JAVA_EXE%" -javaagent:%APP_HOME%/lib/jacocoagent.jar %DEFAULT_JVM_OPTS% %JAVA_OPTS% %${optsEnvironmentVar}% <% if ( appNameSystemProperty ) { %>"-D${appNameSystemProperty}=%APP_BASE_NAME%"<% } %> -classpath "%CLASSPATH%" <% if ( mainClassName.startsWith('--module ') ) { %>--module-path "%MODULE_PATH%" <% } %>${mainClassName} %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable ${exitEnvironmentVar} if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%${exitEnvironmentVar}%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega From c3f455c691da9f19ec4bc83e97203ad69004597c Mon Sep 17 00:00:00 2001 From: Ade Lucas <37906710+cloudspores@users.noreply.github.com> Date: Thu, 22 Aug 2024 18:06:03 -0600 Subject: [PATCH 148/259] Fix ClassCastException in DebugMetrics nested structures [#7383] (#7499) * Fix ClassCastException in DebugMetrics nested structures This commit resolves an issue where Double values in nested metric structures were incorrectly cast to Map objects, causing a ClassCastException. The fix allows for proper handling of both direct values and nested structures at the same level. A comprehensive test case has been added to reproduce the bug and verify the fix, ensuring that complex, dynamically nested metric structures can be handled without errors. Resolves: #7383 Signed-off-by: Ade Lucas --------- Signed-off-by: Ade Lucas Signed-off-by: garyschulte Signed-off-by: Snazzy Signed-off-by: Danno Ferrin Signed-off-by: Matilda Clerke Signed-off-by: Matilda-Clerke Signed-off-by: Sally MacFarlane Co-authored-by: garyschulte Co-authored-by: Fabio Di Fabio Co-authored-by: gringsam Co-authored-by: Sally MacFarlane Co-authored-by: Danno Ferrin Co-authored-by: Matilda-Clerke --- CHANGELOG.md | 9 ++++++ .../internal/methods/DebugMetrics.java | 21 +++++++++++- .../internal/methods/DebugMetricsTest.java | 32 +++++++++++++++++++ 3 files changed, 61 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 82a60615a5..1cd3f0126b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## [Unreleased] + +### Fixed +- **DebugMetrics**: Fixed a `ClassCastException` occurring in `DebugMetrics` when handling nested metric structures. Previously, `Double` values within these structures were incorrectly cast to `Map` objects, leading to errors. This update allows for proper handling of both direct values and nested structures at the same level. Issue# [#7383] + +### Tests +- Added a comprehensive test case to reproduce the bug and verify the fix for the `ClassCastException` in `DebugMetrics`. This ensures that complex, dynamically nested metric structures can be handled without errors. + ## Next release ### Upcoming Breaking Changes @@ -17,6 +25,7 @@ - Correctly release txpool save and restore lock in case of exceptions [#7473](https://github.com/hyperledger/besu/pull/7473) - Fix for `eth_gasPrice` could not retrieve block error [#7482](https://github.com/hyperledger/besu/pull/7482) + ## 24.8.0 ### Upcoming Breaking Changes diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugMetrics.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugMetrics.java index 89e6e4a2ae..b5c74245ce 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugMetrics.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugMetrics.java @@ -71,7 +71,26 @@ public class DebugMetrics implements JsonRpcMethod { @SuppressWarnings("unchecked") private Map getNextMapLevel( final Map current, final String name) { + // Use compute to either return the existing map or create a new one return (Map) - current.computeIfAbsent(name, key -> new HashMap()); + current.compute( + name, + (k, v) -> { + if (v instanceof Map) { + // If the value is already a Map, return it as is + return v; + } else { + // If the value is not a Map, create a new Map + Map newMap = new HashMap<>(); + if (v != null) { + // If v is not null and not a Map, we store it as a leaf value + // If the original value was not null, store it under the "value" key + // This handles cases where a metric value (e.g., Double) was previously stored + // directly + newMap.put("value", v); + } + return newMap; + } + }); } } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugMetricsTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugMetricsTest.java index 6e41fc9c1b..d4830cb85a 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugMetricsTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugMetricsTest.java @@ -16,6 +16,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import static java.util.Arrays.asList; import static org.assertj.core.api.Assertions.assertThat; +import static org.hyperledger.besu.metrics.BesuMetricCategory.BLOCKCHAIN; import static org.hyperledger.besu.metrics.BesuMetricCategory.PEERS; import static org.hyperledger.besu.metrics.BesuMetricCategory.RPC; import static org.mockito.Mockito.mock; @@ -28,6 +29,7 @@ import org.hyperledger.besu.metrics.ObservableMetricsSystem; import org.hyperledger.besu.metrics.Observation; import java.util.Collections; +import java.util.List; import java.util.stream.Stream; import com.google.common.collect.ImmutableMap; @@ -84,6 +86,36 @@ public class DebugMetricsTest { ImmutableMap.of("label2B", "value3"))))); } + @Test + public void shouldHandleDoubleValuesInNestedStructureWithoutClassCastException() { + // Tests fix for issue# 7383: debug_metrics method error + when(metricsSystem.streamObservations()) + .thenReturn( + Stream.of( + // This creates a double value for "a" + new Observation(BLOCKCHAIN, "nested_metric", 1.0, List.of("a")), + // This attempts to create a nested structure under "a", which was previously a + // double + new Observation(BLOCKCHAIN, "nested_metric", 2.0, asList("a", "b")), + // This adds another level of nesting + new Observation(BLOCKCHAIN, "nested_metric", 3.0, asList("a", "b", "c")))); + + assertResponse( + ImmutableMap.of( + BLOCKCHAIN.getName(), + ImmutableMap.of( + "nested_metric", + ImmutableMap.of( + "a", + ImmutableMap.of( + "value", + 1.0, + "b", + ImmutableMap.of( + "value", 2.0, + "c", 3.0)))))); + } + private void assertResponse(final ImmutableMap expectedResponse) { final JsonRpcSuccessResponse response = (JsonRpcSuccessResponse) method.response(REQUEST); assertThat(response.getResult()).isEqualTo(expectedResponse); From 4801106674288cc68d71cb2a3bb5eb0fd61c755e Mon Sep 17 00:00:00 2001 From: shubham kesri Date: Fri, 23 Aug 2024 06:12:12 +0530 Subject: [PATCH 149/259] Fixed | Initialising the encodedPubKey with empty String in case userInfo is null (#7508) Signed-off-by: kesrishubham2510 Co-authored-by: Sally MacFarlane --- CHANGELOG.md | 1 + .../hyperledger/besu/ethereum/p2p/discovery/dns/DNSEntry.java | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1cd3f0126b..b9fccf29c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -50,6 +50,7 @@ - Correct entrypoint in Docker evmtool [#7430](https://github.com/hyperledger/besu/pull/7430) - Fix protocol schedule check for devnets [#7429](https://github.com/hyperledger/besu/pull/7429) - Fix behaviour when starting in a pre-merge network [#7431](https://github.com/hyperledger/besu/pull/7431) +- Fix Null pointer from DNS daemon [#7505](https://github.com/hyperledger/besu/issues/7505) ## 24.7.1 diff --git a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/dns/DNSEntry.java b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/dns/DNSEntry.java index bb85a3612f..cd439eea06 100644 --- a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/dns/DNSEntry.java +++ b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/dns/DNSEntry.java @@ -243,7 +243,7 @@ public interface DNSEntry { public ENRTreeLink(final String enrTreeLink) { final URI uri = URI.create(enrTreeLink); this.domainName = uri.getHost(); - this.encodedPubKey = uri.getUserInfo(); + this.encodedPubKey = uri.getUserInfo() == null ? "" : uri.getUserInfo(); this.pubKey = fromBase32(encodedPubKey); } From 58bb931efeab12f472ba7aee5f363fd0fcf4b141 Mon Sep 17 00:00:00 2001 From: neowangreal Date: Fri, 23 Aug 2024 07:45:16 +0630 Subject: [PATCH 150/259] update link (#7506) Signed-off-by: Neo Co-authored-by: Sally MacFarlane --- docs/tracing/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tracing/README.md b/docs/tracing/README.md index 0acac729d4..77deadd16a 100644 --- a/docs/tracing/README.md +++ b/docs/tracing/README.md @@ -21,4 +21,4 @@ Open the Zipkin UI by browsing to http://localhost:9411/ You will be able to see the detail of your traces. References: -* [OpenTelemetry Environment Variable Specification](https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/sdk-environment-variables.md) +* [OpenTelemetry Environment Variable Specification](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md) From d87650b944631cd645c2663edb7c00a9e145d842 Mon Sep 17 00:00:00 2001 From: garyschulte Date: Fri, 23 Aug 2024 16:35:18 -0700 Subject: [PATCH 151/259] Fleet-mode safe behavior for fcU in SynchronizationService (#7517) * fleet-mode safe behavior for fcU in SynchronizationService Signed-off-by: garyschulte * spotless Signed-off-by: garyschulte --------- Signed-off-by: garyschulte --- .../services/SynchronizationServiceImpl.java | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/besu/src/main/java/org/hyperledger/besu/services/SynchronizationServiceImpl.java b/besu/src/main/java/org/hyperledger/besu/services/SynchronizationServiceImpl.java index 898ede5d0d..2e15e2ab82 100644 --- a/besu/src/main/java/org/hyperledger/besu/services/SynchronizationServiceImpl.java +++ b/besu/src/main/java/org/hyperledger/besu/services/SynchronizationServiceImpl.java @@ -74,17 +74,11 @@ public class SynchronizationServiceImpl implements SynchronizationService { @Override public void fireNewUnverifiedForkchoiceEvent( final Hash head, final Hash safeBlock, final Hash finalizedBlock) { - final MergeContext mergeContext = protocolContext.getConsensusContext(MergeContext.class); - if (mergeContext != null) { - mergeContext.fireNewUnverifiedForkchoiceEvent(head, safeBlock, finalizedBlock); - protocolContext.getBlockchain().setFinalized(finalizedBlock); - protocolContext.getBlockchain().setSafeBlock(safeBlock); - } else { - LOG.atWarn() - .setMessage( - "The merge context is unavailable, hence the fork choice event cannot be triggered") - .log(); - } + protocolContext + .safeConsensusContext(MergeContext.class) + .ifPresent(mc -> mc.fireNewUnverifiedForkchoiceEvent(head, safeBlock, finalizedBlock)); + protocolContext.getBlockchain().setFinalized(finalizedBlock); + protocolContext.getBlockchain().setSafeBlock(safeBlock); } @Override From a851507cb3ced6daaedb7596662efda23ca0a3e9 Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Sun, 25 Aug 2024 22:33:05 -0600 Subject: [PATCH 152/259] evmtool was not respecting the --genesis option (#7518) * EVMTool should respect --genesis option Update the code so that the genesis file option will be respected when set. Also, default --fork options should set a rational base fee. Signed-off-by: Danno Ferrin --------- Signed-off-by: Danno Ferrin --- CHANGELOG.md | 3 ++- .../besu/datatypes/HardforkId.java | 16 ++++++++++++ .../besu/ethereum/core/BlockHeader.java | 21 ++++++++------- .../besu/evmtool/EvmToolCommand.java | 26 ++++++++++++------- .../besu/evmtool/GenesisFileModule.java | 4 ++- .../evmtool/MainnetGenesisFileModule.java | 14 +++++----- 6 files changed, 54 insertions(+), 30 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b9fccf29c4..8c31d55fb7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,8 @@ ## [Unreleased] ### Fixed -- **DebugMetrics**: Fixed a `ClassCastException` occurring in `DebugMetrics` when handling nested metric structures. Previously, `Double` values within these structures were incorrectly cast to `Map` objects, leading to errors. This update allows for proper handling of both direct values and nested structures at the same level. Issue# [#7383] +- **DebugMetrics**: Fixed a `ClassCastException` occurring in `DebugMetrics` when handling nested metric structures. Previously, `Double` values within these structures were incorrectly cast to `Map` objects, leading to errors. This update allows for proper handling of both direct values and nested structures at the same level. Issue# [#7383](https://github.com/hyperledger/besu/pull/7383) +- `evmtool` was not respecting the `--genesis` setting, resulting in unexpected trace results. [#7433](https://github.com/hyperledger/besu/pull/7433) ### Tests - Added a comprehensive test case to reproduce the bug and verify the fix for the `ClassCastException` in `DebugMetrics`. This ensures that complex, dynamically nested metric structures can be handled without errors. 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 73eaddb7ca..85ec84b4ad 100644 --- a/datatypes/src/main/java/org/hyperledger/besu/datatypes/HardforkId.java +++ b/datatypes/src/main/java/org/hyperledger/besu/datatypes/HardforkId.java @@ -14,6 +14,9 @@ */ package org.hyperledger.besu.datatypes; +import java.util.Comparator; +import java.util.stream.Stream; + /** Description and metadata for a hard fork */ public interface HardforkId { @@ -112,6 +115,19 @@ public interface HardforkId { public String description() { return description; } + + /** + * The most recent finalized mainnet hardfork Besu supports. This will change across versions + * and will be updated after mainnet activations. + * + * @return the most recently activated mainnet spec. + */ + public static MainnetHardforkId mostRecent() { + return Stream.of(MainnetHardforkId.values()) + .filter(MainnetHardforkId::finalized) + .max(Comparator.naturalOrder()) + .orElseThrow(); + } } /** List of all Ethereum Classic hard forks. */ 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 46d2f0847a..42f99fafb6 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 @@ -158,22 +158,23 @@ public class BlockHeader extends SealableBlockHeader out.writeBytes(extraData); out.writeBytes(mixHashOrPrevRandao); out.writeLong(nonce); - if (baseFee != null) { + do { + if (baseFee == null) break; out.writeUInt256Scalar(baseFee); - } - if (withdrawalsRoot != null) { + + if (withdrawalsRoot == null) break; out.writeBytes(withdrawalsRoot); - } - if (excessBlobGas != null && blobGasUsed != null) { + + if (excessBlobGas == null || blobGasUsed == null) break; out.writeLongScalar(blobGasUsed); out.writeUInt64Scalar(excessBlobGas); - } - if (parentBeaconBlockRoot != null) { + + if (parentBeaconBlockRoot == null) break; out.writeBytes(parentBeaconBlockRoot); - } - if (requestsRoot != null) { + + if (requestsRoot == null) break; out.writeBytes(requestsRoot); - } + } while (false); out.endList(); } 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 06ee967620..f9d7c0db47 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 @@ -478,7 +478,14 @@ public class EvmToolCommand implements Runnable { .mixHash(Hash.ZERO) .nonce(0) .blockHeaderFunctions(new MainnetBlockHeaderFunctions()) - .baseFee(component.getBlockchain().getChainHeadHeader().getBaseFee().orElse(null)) + .baseFee( + component + .getBlockchain() + .getChainHeadHeader() + .getBaseFee() + .or(() -> genesisFileModule.providesGenesisConfigFile().getBaseFeePerGas()) + .orElse( + protocolSpec.getFeeMarket().implementsBaseFee() ? Wei.of(0xa) : null)) .buildBlockHeader(); Address contractAddress = @@ -519,13 +526,12 @@ public class EvmToolCommand implements Runnable { lastTime = stopwatch.elapsed().toNanos(); } if (lastLoop) { - if (messageFrame.getExceptionalHaltReason().isPresent()) { - out.println(messageFrame.getExceptionalHaltReason().get()); - } - if (messageFrame.getRevertReason().isPresent()) { - out.println( - new String(messageFrame.getRevertReason().get().toArrayUnsafe(), UTF_8)); - } + messageFrame + .getExceptionalHaltReason() + .ifPresent(haltReason -> out.println(haltReason)); + messageFrame + .getRevertReason() + .ifPresent(bytes -> out.println(new String(bytes.toArrayUnsafe(), UTF_8))); } } } @@ -572,7 +578,7 @@ public class EvmToolCommand implements Runnable { out.println("{"); worldState .streamAccounts(Bytes32.ZERO, Integer.MAX_VALUE) - .sorted(Comparator.comparing(o -> o.getAddress().get().toHexString())) + .sorted(Comparator.comparing(o -> o.getAddress().orElse(Address.ZERO).toHexString())) .forEach( a -> { var account = worldState.get(a.getAddress().get()); @@ -585,7 +591,7 @@ public class EvmToolCommand implements Runnable { .map( e -> Map.entry( - e.getKey().get(), + e.getKey().orElse(UInt256.ZERO), account.getStorageValue(UInt256.fromBytes(e.getKey().get())))) .filter(e -> !e.getValue().isZero()) .sorted(Map.Entry.comparingByKey()) diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/GenesisFileModule.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/GenesisFileModule.java index 6eae387a64..8512b5537e 100644 --- a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/GenesisFileModule.java +++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/GenesisFileModule.java @@ -18,6 +18,7 @@ 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.GenesisConfigOptions; +import org.hyperledger.besu.datatypes.HardforkId.MainnetHardforkId; import org.hyperledger.besu.ethereum.chain.GenesisState; import org.hyperledger.besu.ethereum.core.Block; import org.hyperledger.besu.ethereum.core.BlockHeaderFunctions; @@ -28,6 +29,7 @@ import java.io.File; import java.io.IOException; import java.nio.charset.Charset; import java.nio.file.Files; +import java.util.Locale; import java.util.Optional; import javax.inject.Named; import javax.inject.Singleton; @@ -116,7 +118,7 @@ public class GenesisFileModule { final JsonObject config = new JsonObject(); genesis.put("config", config); config.put("chainId", 1337); - config.put("londonBlock", 0); + config.put(MainnetHardforkId.mostRecent().toString().toLowerCase(Locale.ROOT) + "Time", 0); genesis.put("baseFeePerGas", "0x3b9aca00"); genesis.put("gasLimit", "0x2540be400"); genesis.put("difficulty", "0x0"); 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 e36668f47c..0ce7bf98f5 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 @@ -27,7 +27,6 @@ import org.hyperledger.besu.ethereum.mainnet.MainnetProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolScheduleBuilder; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecAdapters; -import org.hyperledger.besu.evm.EvmSpecVersion; import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; @@ -71,13 +70,12 @@ class MainnetGenesisFileModule extends GenesisFileModule { } } - var schedules = createSchedules(configOptions.getChainId().orElse(BigInteger.valueOf(1337))); - var schedule = - schedules.get( - fork.orElse(EvmSpecVersion.defaultVersion().getName()) - .toLowerCase(Locale.getDefault())); - if (schedule != null) { - return schedule.get(); + if (fork.isPresent()) { + var schedules = createSchedules(configOptions.getChainId().orElse(BigInteger.valueOf(1337))); + var schedule = schedules.get(fork.get().toLowerCase(Locale.getDefault())); + if (schedule != null) { + return schedule.get(); + } } return MainnetProtocolSchedule.fromConfig( From 4f51d4d696e803b85a937b67d8d4d08750ae9af6 Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Sun, 25 Aug 2024 22:56:54 -0600 Subject: [PATCH 153/259] Fix fuzzing dependencies (#7519) The fuzzAll task depended on targets that didn't exist. Signed-off-by: Danno Ferrin Co-authored-by: Sally MacFarlane --- testfuzz/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testfuzz/build.gradle b/testfuzz/build.gradle index 1c96798155..e55cbe5983 100644 --- a/testfuzz/build.gradle +++ b/testfuzz/build.gradle @@ -105,7 +105,7 @@ tasks.register("fuzzReth") { } tasks.register("fuzzAll") { - dependsOn fuzzEvm1, fuzzEthJS, fuzzGeth, fuzzNethermind, fuzzReth + dependsOn fuzzEvmone, fuzzEthereumJS, fuzzGeth, fuzzNethermind, fuzzReth } jacoco { From 725dcf1c872326c5cfa19d17e113ef9cd214472a Mon Sep 17 00:00:00 2001 From: Chaminda Divitotawela Date: Mon, 26 Aug 2024 16:19:30 +1000 Subject: [PATCH 154/259] Release checklist update (#7494) * Release checklist update More details on homebrew and docs releases in release checklist issue template Co-authored-by: Simon Dudley Signed-off-by: Chaminda Divitotawela * Remove release creation for besu-docs from checklist It has been agreed there is no value creating releases in the hyperledger/besu-docs repo. Remove the related instruction from checklist Signed-off-by: Chaminda Divitotawela --------- Signed-off-by: Chaminda Divitotawela Signed-off-by: Chaminda Divitotawela Co-authored-by: Simon Dudley --- .github/ISSUE_TEMPLATE/release-checklist.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/release-checklist.md b/.github/ISSUE_TEMPLATE/release-checklist.md index 721c26edbd..413d68933f 100644 --- a/.github/ISSUE_TEMPLATE/release-checklist.md +++ b/.github/ISSUE_TEMPLATE/release-checklist.md @@ -29,9 +29,10 @@ assignees: '' - publishes the docker `latest` tag variants - [ ] Check binary SHAs are correct on the release page - [ ] Check "Container Verify" GitHub workflow has run successfully -- [ ] Create besu-docs release - https://github.com/hyperledger/besu-docs/releases/new - - Copy release notes from besu - - If publishing the release in github doesn't automatically trigger this workflow, then manually run https://github.com/hyperledger/besu-docs/actions/workflows/update-version.yml -- [ ] Create homebrew release - run GHA workflow directly https://github.com/hyperledger/homebrew-besu/actions/workflows/update-version.yml +- [ ] 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 - [ ] Delete the burn-in nodes (unless required for further analysis eg performance) - [ ] Social announcements From b57310ffac2565a12594e3aa45d77bca7f6d3b35 Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Mon, 26 Aug 2024 19:59:46 -0600 Subject: [PATCH 155/259] EOF testing error codes for layout (#7522) Update the eof layout error codes to match codes in reference tests. This includes support for multiple possible errors for a specific test. Signed-off-by: Danno Ferrin --- .../evmtool/CodeValidationSubCommandTest.java | 12 +- .../evmtool/pretty-print/dangling-data.json | 2 +- .../state-test/create-invalid-eof.json | 2 +- .../ethereum/eof/EOFReferenceTestTools.java | 92 ++++++---- .../hyperledger/besu/evm/code/EOFLayout.java | 75 ++++---- .../hyperledger/besu/evm/code/CodeV1Test.java | 8 +- .../besu/evm/code/EOFLayoutTest.java | 173 +++++++++++------- 7 files changed, 225 insertions(+), 139 deletions(-) diff --git a/ethereum/evmtool/src/test/java/org/hyperledger/besu/evmtool/CodeValidationSubCommandTest.java b/ethereum/evmtool/src/test/java/org/hyperledger/besu/evmtool/CodeValidationSubCommandTest.java index d6b7359413..9fe34b4836 100644 --- a/ethereum/evmtool/src/test/java/org/hyperledger/besu/evmtool/CodeValidationSubCommandTest.java +++ b/ethereum/evmtool/src/test/java/org/hyperledger/besu/evmtool/CodeValidationSubCommandTest.java @@ -57,7 +57,8 @@ class CodeValidationSubCommandTest { EvmToolCommand parentCommand = new EvmToolCommand(bais, new PrintWriter(baos, true, UTF_8)); final CodeValidateSubCommand codeValidateSubCommand = new CodeValidateSubCommand(parentCommand); codeValidateSubCommand.run(); - assertThat(baos.toString(UTF_8)).contains("err: layout - EOF header byte 1 incorrect\n"); + assertThat(baos.toString(UTF_8)) + .contains("err: layout - invalid_magic EOF header byte 1 incorrect\n"); } @Test @@ -71,7 +72,7 @@ class CodeValidationSubCommandTest { .contains( """ OK 1/0/0 - err: layout - EOF header byte 1 incorrect + err: layout - invalid_magic EOF header byte 1 incorrect OK 1/0/0 """); } @@ -97,7 +98,8 @@ class CodeValidationSubCommandTest { final CommandLine cmd = new CommandLine(codeValidateSubCommand); cmd.parseArgs(CODE_BAD_MAGIC); codeValidateSubCommand.run(); - assertThat(baos.toString(UTF_8)).contains("err: layout - EOF header byte 1 incorrect\n"); + assertThat(baos.toString(UTF_8)) + .contains("err: layout - invalid_magic EOF header byte 1 incorrect\n"); } @Test @@ -113,7 +115,7 @@ class CodeValidationSubCommandTest { .contains( """ OK 1/0/0 - err: layout - EOF header byte 1 incorrect + err: layout - invalid_magic EOF header byte 1 incorrect OK 1/0/0 """); } @@ -154,7 +156,7 @@ class CodeValidationSubCommandTest { .isEqualTo( """ OK 1/0/0 - err: layout - EOF header byte 1 incorrect + err: layout - invalid_magic EOF header byte 1 incorrect OK 1/0/0 """); } diff --git a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/pretty-print/dangling-data.json b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/pretty-print/dangling-data.json index 27833a1bb9..bdab829bbc 100644 --- a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/pretty-print/dangling-data.json +++ b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/pretty-print/dangling-data.json @@ -4,5 +4,5 @@ "ef00010100040200010001040000000080000000ff" ], "stdin": "", - "stdout": "EOF layout is invalid - Dangling data after end of all sections\n" + "stdout": "EOF layout is invalid - invalid_section_bodies_size data after end of all sections\n" } \ No newline at end of file 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 dc786d6136..e2eb67602e 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 @@ -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: Expected kind 1 but read kind 17"}, + {"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"}, {"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/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 8621b5d08a..3c0c2dbbb2 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 @@ -20,9 +20,11 @@ import java.nio.file.Path; import java.util.Arrays; import java.util.Collection; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Map.Entry; +import com.google.common.base.Splitter; import org.apache.tuweni.bytes.Bytes; import org.hyperledger.besu.ethereum.referencetests.EOFTestCaseSpec; @@ -31,9 +33,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.evm.code.EOFLayout.EOFContainerMode; import org.hyperledger.besu.testutil.JsonTestParameters; public class EOFReferenceTestTools { @@ -124,6 +124,25 @@ public class EOFReferenceTestTools { // hardwire in the magic byte transaction checks if (evm.getMaxEOFVersion() < 1) { assertThat(expected.exception()).isEqualTo("EOF_InvalidCode"); + } else if (code.size() > evm.getEvmVersion().getMaxInitcodeSize()) { + // this check is in EOFCREATE and Transaction validator, but unit tests sniff it out. + assertThat(false) + .withFailMessage( + () -> + "No Expected exception, actual exception - container_size_above_limit " + + code.size()) + .isEqualTo(expected.result()); + if (name.contains("eip7692")) { + // if the test is from EEST, validate the exception name. + assertThat("container_size_above_limit") + .withFailMessage( + () -> + "Expected exception: %s actual exception: %s %d" + .formatted( + expected.exception(), "container_size_above_limit ", code.size())) + .containsIgnoringCase(expected.exception().replace("EOFException.", "")); + } + } else { EOFLayout layout = EOFLayout.parseEOF(code); @@ -134,39 +153,27 @@ public class EOFReferenceTestTools { } else { parsedCode = evm.getCodeUncached(code); } - if ("EOF_IncompatibleContainerKind".equals(expected.exception()) && parsedCode.isValid()) { - EOFContainerMode expectedMode = - EOFContainerMode.valueOf(containerKind == null ? "RUNTIME" : containerKind); - EOFContainerMode containerMode = - ((CodeV1) parsedCode).getEofLayout().containerMode().get(); - EOFContainerMode actualMode = - containerMode == null ? EOFContainerMode.RUNTIME : containerMode; - assertThat(actualMode) - .withFailMessage("Code did not parse to valid containerKind of " + expectedMode) - .isNotEqualTo(expectedMode); - } else { - if (expected.result()) { + 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.", "")); - } + () -> "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 { @@ -178,6 +185,25 @@ public class EOFReferenceTestTools { + " actual exception - " + (layout.isValid() ? null : layout.invalidReason())) .isEqualTo(expected.result()); + if (name.contains("eip7692")) { + // if the test is from EEST, validate the exception name. + boolean exceptionMatched = false; + for (String e : Splitter.on('|').split(expected.exception())) { + if (layout + .invalidReason() + .toLowerCase(Locale.ROOT) + .contains(e.replace("EOFException.", "").toLowerCase(Locale.ROOT))) { + exceptionMatched = true; + break; + } + } + assertThat(exceptionMatched) + .withFailMessage( + () -> + "Expected exception :%s actual exception: %s" + .formatted(expected.exception(), layout.invalidReason())) + .isTrue(); + } } } } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/code/EOFLayout.java b/evm/src/main/java/org/hyperledger/besu/evm/code/EOFLayout.java index d5abb05f86..7883b70d80 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/code/EOFLayout.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/code/EOFLayout.java @@ -131,10 +131,10 @@ public record EOFLayout( private static String readKind(final ByteArrayInputStream inputStream, final int expectedKind) { int kind = inputStream.read(); if (kind == -1) { - return "Improper section headers"; + return "missing_headers_terminator Improper section headers"; } if (kind != expectedKind) { - return "Expected kind " + expectedKind + " but read kind " + kind; + return "unexpected_header_kind expected " + expectedKind + " actual " + kind; } return null; } @@ -217,7 +217,10 @@ public record EOFLayout( // This ReferenceEquality check is correct if ((strictSize || result != parsedContainer) && step.container.size() != parsedContainer.container.size()) { - return invalidLayout(container, parsedContainer.version, "subcontainer size mismatch"); + return invalidLayout( + container, + parsedContainer.version, + "invalid_section_bodies_size subcontainer size mismatch"); } if (step.index >= 0) { step.parentSubcontainers[step.index] = parsedContainer; @@ -233,18 +236,18 @@ public record EOFLayout( new ByteArrayInputStream(step.container.toArrayUnsafe()); if (inputStream.available() < 3) { - return invalidLayout(step.container, -1, "EOF Container too small"); + return invalidLayout(step.container, -1, "invalid_magic EOF Container too small"); } if (inputStream.read() != 0xEF) { - return invalidLayout(step.container, -1, "EOF header byte 0 incorrect"); + return invalidLayout(step.container, -1, "invalid_magic EOF header byte 0 incorrect"); } if (inputStream.read() != 0x0) { - return invalidLayout(step.container, -1, "EOF header byte 1 incorrect"); + return invalidLayout(step.container, -1, "invalid_magic EOF header byte 1 incorrect"); } final int version = inputStream.read(); if (version > MAX_SUPPORTED_VERSION || version < 1) { - return invalidLayout(step.container, version, "Unsupported EOF Version " + version); + return invalidLayout(step.container, version, "invalid_version " + version); } String error = readKind(inputStream, SECTION_TYPES); @@ -252,8 +255,11 @@ public record EOFLayout( return invalidLayout(step.container, version, error); } int typesLength = readUnsignedShort(inputStream); - if (typesLength <= 0 || typesLength % 4 != 0) { - return invalidLayout(step.container, version, "Invalid Types section size"); + if (typesLength % 4 != 0) { + return invalidLayout( + step.container, + version, + "invalid_type_section_size Invalid Types section size (mod 4 != 0)"); } error = readKind(inputStream, SECTION_CODE); @@ -262,28 +268,29 @@ public record EOFLayout( } int codeSectionCount = readUnsignedShort(inputStream); if (codeSectionCount <= 0) { - return invalidLayout(step.container, version, "Invalid Code section count"); + return invalidLayout( + step.container, version, "incomplete_section_number Too few code sections"); } - if (codeSectionCount * 4 != typesLength) { + if (codeSectionCount > 1024) { return invalidLayout( step.container, version, - "Type section length incompatible with code section count - 0x" - + Integer.toHexString(codeSectionCount) - + " * 4 != 0x" - + Integer.toHexString(typesLength)); + "too_many_code_sections - 0x" + Integer.toHexString(codeSectionCount)); } - if (codeSectionCount > 1024) { + if (codeSectionCount * 4 != typesLength) { return invalidLayout( step.container, version, - "Too many code sections - 0x" + Integer.toHexString(codeSectionCount)); + "invalid_section_bodies_size Type section - 0x" + + Integer.toHexString(codeSectionCount) + + " * 4 != 0x" + + Integer.toHexString(typesLength)); } int[] codeSectionSizes = new int[codeSectionCount]; for (int i = 0; i < codeSectionCount; i++) { int size = readUnsignedShort(inputStream); if (size <= 0) { - return invalidLayout(step.container, version, "Invalid Code section size for section " + i); + return invalidLayout(step.container, version, "zero_section_size code " + i); } codeSectionSizes[i] = size; } @@ -303,7 +310,7 @@ public record EOFLayout( return invalidLayout( step.container, version, - "Too many container sections - 0x" + Integer.toHexString(containerSectionCount)); + "too_many_containers sections - 0x" + Integer.toHexString(containerSectionCount)); } containerSectionSizes = new int[containerSectionCount]; for (int i = 0; i < containerSectionCount; i++) { @@ -325,7 +332,7 @@ public record EOFLayout( } int dataSize = readUnsignedShort(inputStream); if (dataSize < 0) { - return invalidLayout(step.container, version, "Invalid Data section size"); + return invalidLayout(step.container, version, "incomplete_data_header"); } error = readKind(inputStream, SECTION_TERMINATOR); @@ -340,11 +347,12 @@ public record EOFLayout( typeData[i][2] = readUnsignedShort(inputStream); } if (typeData[codeSectionCount - 1][2] == -1) { - return invalidLayout(step.container, version, "Incomplete type section"); + return invalidLayout( + step.container, version, "invalid_section_bodies_size Incomplete type section"); } if (typeData[0][0] != 0 || (typeData[0][1] & 0x7f) != 0) { return invalidLayout( - step.container, version, "Code section does not have zero inputs and outputs"); + step.container, version, "invalid_first_section_type must be zero input non-returning"); } CodeSection[] codeSections = new CodeSection[codeSectionCount]; int pos = // calculate pos in stream... @@ -364,25 +372,28 @@ public record EOFLayout( for (int i = 0; i < codeSectionCount; i++) { int codeSectionSize = codeSectionSizes[i]; if (inputStream.skip(codeSectionSize) != codeSectionSize) { - return invalidLayout(step.container, version, "Incomplete code section " + i); + return invalidLayout( + step.container, version, "invalid_section_bodies_size code section " + i); } if (typeData[i][0] > 0x7f) { return invalidLayout( step.container, version, - "Type data input stack too large - 0x" + Integer.toHexString(typeData[i][0])); + "inputs_outputs_num_above_limit Type data input stack too large - 0x" + + Integer.toHexString(typeData[i][0])); } if (typeData[i][1] > 0x80) { return invalidLayout( step.container, version, - "Type data output stack too large - 0x" + Integer.toHexString(typeData[i][1])); + "inputs_outputs_num_above_limit - 0x" + Integer.toHexString(typeData[i][1])); } if (typeData[i][2] > 0x3ff) { return invalidLayout( step.container, version, - "Type data max stack too large - 0x" + Integer.toHexString(typeData[i][2])); + "max_stack_height_above_limit Type data max stack too large - 0x" + + Integer.toHexString(typeData[i][2])); } codeSections[i] = new CodeSection(codeSectionSize, typeData[i][0], typeData[i][1], typeData[i][2], pos); @@ -390,8 +401,7 @@ public record EOFLayout( return invalidLayout( step.container, version, - "Code section at zero expected non-returning flag, but had return stack of " - + typeData[0][1]); + "invalid_first_section_type want 0x80 (non-returning flag) has " + typeData[0][1]); } pos += codeSectionSize; } @@ -400,7 +410,7 @@ public record EOFLayout( for (int i = 0; i < containerSectionCount; i++) { int subcontainerSize = containerSectionSizes[i]; if (subcontainerSize != inputStream.skip(subcontainerSize)) { - return invalidLayout(step.container, version, "incomplete subcontainer"); + return invalidLayout(step.container, version, "invalid_section_bodies_size"); } Bytes subcontainer = step.container.slice(pos, subcontainerSize); pos += subcontainerSize; @@ -413,7 +423,8 @@ public record EOFLayout( Bytes completeContainer; if (inputStream.read() != -1) { if (step.strictSize) { - return invalidLayout(step.container, version, "Dangling data after end of all sections"); + return invalidLayout( + step.container, version, "invalid_section_bodies_size data after end of all sections"); } else { completeContainer = step.container.slice(0, pos + dataSize); } @@ -422,7 +433,9 @@ public record EOFLayout( } if (step.strictSize && dataSize != data.size()) { return invalidLayout( - step.container, version, "Truncated data section when a complete section was required"); + step.container, + version, + "toplevel_container_truncated Truncated data section when a complete section was required"); } return new EOFLayout(completeContainer, version, codeSections, subContainers, dataSize, data); diff --git a/evm/src/test/java/org/hyperledger/besu/evm/code/CodeV1Test.java b/evm/src/test/java/org/hyperledger/besu/evm/code/CodeV1Test.java index 9b7edf80b4..5ae88a6cc7 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/code/CodeV1Test.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/code/CodeV1Test.java @@ -100,7 +100,7 @@ class CodeV1Test { assertThat(validationError) .isEqualTo( - "Invalid EOF container - Code section at zero expected non-returning flag, but had return stack of 0"); + "Invalid EOF container - invalid_first_section_type want 0x80 (non-returning flag) has 0"); } @ParameterizedTest @@ -751,7 +751,7 @@ class CodeV1Test { return Stream.of( Arguments.of( "0 outputs at section 0", - "EOF Layout invalid - Code section at zero expected non-returning flag, but had return stack of 0", + "EOF Layout invalid - invalid_first_section_type want 0x80 (non-returning flag) has 0", 0, List.of(List.of("e4", 0, 0, 0), List.of("e4", 0, 0, 0))), Arguments.of( @@ -766,12 +766,12 @@ class CodeV1Test { List.of(List.of("00", 0, 0x80, 0), List.of("e4", 1, 1, 1), List.of("e4", 0, 0, 0))), Arguments.of( "more than 0 outputs section 0", - "EOF Layout invalid - Code section at zero expected non-returning flag, but had return stack of 0", + "EOF Layout invalid - invalid_first_section_type want 0x80 (non-returning flag) has 0", 0, List.of(List.of("44 50 e4", 0, 0, 1), List.of("4400", 0, 1, 1))), Arguments.of( "more than 0 outputs section 0", - "EOF Layout invalid - Code section at zero expected non-returning flag, but had return stack of 0", + "EOF Layout invalid - invalid_first_section_type want 0x80 (non-returning flag) has 0", 1, List.of(List.of("00", 0, 0, 0), List.of("44 e4", 0, 1, 1))), Arguments.of( diff --git a/evm/src/test/java/org/hyperledger/besu/evm/code/EOFLayoutTest.java b/evm/src/test/java/org/hyperledger/besu/evm/code/EOFLayoutTest.java index 006fe1632b..2cce45830d 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/code/EOFLayoutTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/code/EOFLayoutTest.java @@ -29,162 +29,187 @@ public class EOFLayoutTest { public static Collection containersWithFormatErrors() { return Arrays.asList( new Object[][] { - {"EF", "No magic", "EOF Container too small", -1}, - {"FFFFFF", "Wrong magic", "EOF header byte 0 incorrect", -1}, - {"EFFF01010002020004006000AABBCCDD", "Invalid magic", "EOF header byte 1 incorrect", -1}, - {"EF00", "No version", "EOF Container too small", -1}, - {"EF0000010002020004006000AABBCCDD", "Invalid version", "Unsupported EOF Version 0", 0}, - {"EF0002010002020004006000AABBCCDD", "Invalid version", "Unsupported EOF Version 2", 2}, - { - "EF00FF010002020004006000AABBCCDD", - "Invalid version", - "Unsupported EOF Version 255", - 255 - }, - {"EF0001", "No header", "Improper section headers", 1}, - {"EF0001 00", "No code section", "Expected kind 1 but read kind 0", 1}, - {"EF0001 01", "No code section size", "Invalid Types section size", 1}, - {"EF0001 0100", "Code section size incomplete", "Invalid Types section size", 1}, - {"EF0001 010004", "No section terminator", "Improper section headers", 1}, - {"EF0001 010004 00", "No code section contents", "Expected kind 2 but read kind 0", 1}, - {"EF0001 010004 02", "No code section count", "Invalid Code section count", 1}, - {"EF0001 010004 0200", "Short code section count", "Invalid Code section count", 1}, - { - "EF0001 010004 020001", + {"EF", "No magic", "invalid_magic EOF Container too small", -1}, + {"FFFFFF", "Wrong magic", "invalid_magic EOF header byte 0 incorrect", -1}, + { + "EFFF01010002020004006000AABBCCDD", + "Invalid magic", + "invalid_magic EOF header byte 1 incorrect", + -1 + }, + {"EF00", "No version", "invalid_magic EOF Container too small", -1}, + {"EF0000010002020004006000AABBCCDD", "Invalid version", "invalid_version 0", 0}, + {"EF0002010002020004006000AABBCCDD", "Invalid version", "invalid_version 2", 2}, + {"EF00FF010002020004006000AABBCCDD", "Invalid version", "invalid_version 255", 255}, + {"EF0001", "No header", "missing_headers_terminator Improper section headers", 1}, + {"EF0001 00", "No code section", "unexpected_header_kind expected 1 actual 0", 1}, + { + "EF0001 01", "No code section size", - "Invalid Code section size for section 0", + "invalid_type_section_size Invalid Types section size (mod 4 != 0)", 1 }, { - "EF0001 010004 02000100", - "Short code section size", - "Invalid Code section size for section 0", + "EF0001 0100", + "Code section size incomplete", + "invalid_type_section_size Invalid Types section size (mod 4 != 0)", 1 }, + { + "EF0001 010004", + "No section terminator", + "missing_headers_terminator Improper section headers", + 1 + }, + { + "EF0001 010004 00", + "No code section contents", + "unexpected_header_kind expected 2 actual 0", + 1 + }, + { + "EF0001 010004 02", + "No code section count", + "incomplete_section_number Too few code sections", + 1 + }, + { + "EF0001 010004 0200", + "Short code section count", + "incomplete_section_number Too few code sections", + 1 + }, + {"EF0001 010004 020001", "No code section size", "zero_section_size code 0", 1}, + {"EF0001 010004 02000100", "Short code section size", "zero_section_size code 0", 1}, { "EF0001 010008 0200020001", "No code section size multiple codes", - "Invalid Code section size for section 1", + "zero_section_size code 1", 1 }, { "EF0001 010008 020002000100", "No code section size multiple codes", - "Invalid Code section size for section 1", + "zero_section_size code 1", 1 }, - {"EF0001 010004 0200010001 04", "No data section size", "Invalid Data section size", 1}, + {"EF0001 010004 0200010001 04", "No data section size", "incomplete_data_header", 1}, + {"EF0001 010004 0200010001 0400", "Short data section size", "incomplete_data_header", 1}, { - "EF0001 010004 0200010001 0400", - "Short data section size", - "Invalid Data section size", + "EF0001 010004 0200010001 040000", + "No Terminator", + "missing_headers_terminator Improper section headers", + 1 + }, + { + "EF0001 010004 0200010002 040000 00", + "No type section", + "invalid_section_bodies_size Incomplete type section", 1 }, - {"EF0001 010004 0200010001 040000", "No Terminator", "Improper section headers", 1}, - {"EF0001 010004 0200010002 040000 00", "No type section", "Incomplete type section", 1}, { "EF0001 010004 0200010002 040001 040001 00 DA DA", "Duplicate data sections", - "Expected kind 0 but read kind 4", + "unexpected_header_kind expected 0 actual 4", 1 }, { "EF0001 010004 0200010002 040000 00 00", "Incomplete type section", - "Incomplete type section", + "invalid_section_bodies_size Incomplete type section", 1 }, { "EF0001 010008 02000200020002 040000 00 00000000FE", "Incomplete type section", - "Incomplete type section", + "invalid_section_bodies_size Incomplete type section", 1 }, { "EF0001 010008 0200010001 040000 00 00000000 FE ", "Incorrect type section size", - "Type section length incompatible with code section count - 0x1 * 4 != 0x8", + "invalid_section_bodies_size Type section - 0x1 * 4 != 0x8", 1 }, { "EF0001 010008 02000200010001 040000 00 0100000000000000 FE FE", "Incorrect section zero type input", - "Code section does not have zero inputs and outputs", + "invalid_first_section_type must be zero input non-returning", 1 }, { "EF0001 010008 02000200010001 040000 00 0001000000000000 FE FE", "Incorrect section zero type output", - "Code section does not have zero inputs and outputs", + "invalid_first_section_type must be zero input non-returning", 1 }, { "EF0001 010004 0200010002 040000 00 00000000 ", "Incomplete code section", - "Incomplete code section 0", + "invalid_section_bodies_size code section 0", 1 }, { "EF0001 010004 0200010002 040000 00 00000000 FE", "Incomplete code section", - "Incomplete code section 0", + "invalid_section_bodies_size code section 0", 1 }, { "EF0001 010008 02000200020002 040000 00 00800000 00000000 FEFE ", "No code section multiple", - "Incomplete code section 1", + "invalid_section_bodies_size code section 1", 1 }, { "EF0001 010008 02000200020002 040000 00 00800000 00000000 FEFE FE", "Incomplete code section multiple", - "Incomplete code section 1", + "invalid_section_bodies_size code section 1", 1 }, { "EF0001 010004 0200010001 040003 00 00800000 FE DEADBEEF", "Excess data section", - "Dangling data after end of all sections", + "invalid_section_bodies_size data after end of all sections", 1 }, { "EF0001 0200010001 040001 00 FE DA", "type section missing", - "Expected kind 1 but read kind 2", + "unexpected_header_kind expected 1 actual 2", 1 }, { "EF0001 010004 040001 00 00000000 DA", "code section missing", - "Expected kind 2 but read kind 4", + "unexpected_header_kind expected 2 actual 4", 1 }, { "EF0001 010004 0200010001 00 00000000 FE", "data section missing", - "Expected kind 4 but read kind 0", + "unexpected_header_kind expected 4 actual 0", 1 }, { "EF0001 040001 00 DA", "type and code section missing", - "Expected kind 1 but read kind 4", + "unexpected_header_kind expected 1 actual 4", 1 }, { "EF0001 0200010001 00 FE", "type and data section missing", - "Expected kind 1 but read kind 2", + "unexpected_header_kind expected 1 actual 2", 1 }, { "EF0001 010004 00 00000000", "code and data sections missing", - "Expected kind 2 but read kind 0", + "unexpected_header_kind expected 2 actual 0", 1 }, - {"EF0001 00", "all sections missing", "Expected kind 1 but read kind 0", 1}, + {"EF0001 00", "all sections missing", "unexpected_header_kind expected 1 actual 0", 1}, { "EF0001 011004 020401" + " 0001".repeat(1025) @@ -192,18 +217,33 @@ public class EOFLayoutTest { + " 00000000".repeat(1025) + " FE".repeat(1025), "no data section, 1025 code sections", - "Too many code sections - 0x401", + "too_many_code_sections - 0x401", + 1 + }, + { + "ef000101000002000003000000", + "All kinds zero size", + "incomplete_section_number Too few code sections", + 1 + }, + { + "ef0001010000020001000103000000ef", + "Zero type size ", + "invalid_section_bodies_size Type section - 0x1 * 4 != 0x0", 1 }, - {"ef000101000002000003000000", "All kinds zero size", "Invalid Types section size", 1}, - {"ef0001010000020001000103000000ef", "Zero type size ", "Invalid Types section size", 1}, { "ef0001010004020001000003000000", "Zero code section length", - "Invalid Code section size for section 0", + "zero_section_size code 0", + 1 + }, + { + "ef000101000402000003000000", + "Zero code sections", + "incomplete_section_number Too few code sections", 1 }, - {"ef000101000402000003000000", "Zero code sections", "Invalid Code section count", 1}, }); } @@ -241,31 +281,31 @@ public class EOFLayoutTest { { "EF0001 010008 02000200020002 040000 00 0100000000000000", "Incorrect section zero type input", - "Code section does not have zero inputs and outputs", + "invalid_first_section_type must be zero input non-returning", 1 }, { "EF0001 010008 02000200020002 040000 00 0001000000000000", "Incorrect section zero type output", - "Code section does not have zero inputs and outputs", + "invalid_first_section_type must be zero input non-returning", 1 }, { "EF0001 010010 0200040001000200020002 040000 00 00800000 F0000000 00010000 02030000 FE 5000 3000 8000", "inputs too large", - "Type data input stack too large - 0xf0", + "inputs_outputs_num_above_limit Type data input stack too large - 0xf0", 1 }, { "EF0001 010010 0200040001000200020002 040000 00 00800000 01000000 00F00000 02030000 FE 5000 3000 8000", "outputs too large", - "Type data output stack too large - 0xf0", + "inputs_outputs_num_above_limit - 0xf0", 1 }, { "EF0001 010010 0200040001000200020002 040000 00 00000400 01000000 00010000 02030400 FE 5000 3000 8000", "stack too large", - "Type data max stack too large - 0x400", + "max_stack_height_above_limit Type data max stack too large - 0x400", 1 }, { @@ -336,13 +376,13 @@ public class EOFLayoutTest { { "EF00 01 010004 0200010001 0300010015 040000 00 00800000 00 (EF0001 010004 0200010001 040000 00 00800000 00ff)", "dangling data in subcontainer", - "subcontainer size mismatch", + "invalid_section_bodies_size subcontainer size mismatch", 1 }, { "EF00 01 010004 0200010001 0300010014 040000 00 00800000 00 (EF0001 010004 0200010001 040000 00 00800000 00ff)", "dangling data in container", - "Dangling data after end of all sections", + "invalid_section_bodies_size data after end of all sections", 1 }, }); @@ -363,6 +403,11 @@ public class EOFLayoutTest { final Bytes container = Bytes.fromHexString(containerString.replaceAll("[^a-fxA-F0-9]", "")); final EOFLayout layout = EOFLayout.parseEOF(container, true); + if (failureReason != null) { + assertThat(failureReason) + .withFailMessage("Error string should start with a reference test error code") + .matches("^[a-zA-Z]+_.*"); + } assertThat(layout.version()).isEqualTo(expectedVersion); assertThat(layout.invalidReason()).isEqualTo(failureReason); assertThat(layout.container()).isEqualTo(container); From e0aa4f6d4a8d5ba0cb79e286739d4d336247f2b3 Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Tue, 27 Aug 2024 14:49:12 +1000 Subject: [PATCH 156/259] add engine_getClientVersionV1 (#7512) * add engine_getClientVersionV1 Signed-off-by: Matilda Clerke --- CHANGELOG.md | 1 + .../java/org/hyperledger/besu/BesuInfo.java | 39 +++++++++- .../org/hyperledger/besu/RunnerBuilder.java | 2 + .../org/hyperledger/besu/BesuInfoTest.java | 7 +- build.gradle | 14 ++-- .../jsonrpc/JsonRpcTestMethodsFactory.java | 6 +- .../besu/ethereum/api/jsonrpc/RpcMethod.java | 1 + .../engine/EngineGetClientVersionV1.java | 57 +++++++++++++++ .../EngineGetClientVersionResultV1.java | 52 ++++++++++++++ .../ExecutionEngineJsonRpcMethods.java | 13 +++- .../methods/JsonRpcMethodsFactory.java | 10 ++- .../AbstractJsonRpcHttpServiceTest.java | 6 +- .../jsonrpc/AdminJsonRpcHttpServiceTest.java | 6 +- .../JsonRpcHttpServiceHostAllowlistTest.java | 6 +- .../jsonrpc/JsonRpcHttpServiceLoginTest.java | 6 +- .../JsonRpcHttpServiceRpcApisTest.java | 8 ++- .../api/jsonrpc/JsonRpcHttpServiceTest.java | 26 +++---- .../jsonrpc/JsonRpcHttpServiceTestBase.java | 6 +- .../JsonRpcHttpServiceTlsClientAuthTest.java | 6 +- ...RpcHttpServiceTlsMisconfigurationTest.java | 6 +- .../jsonrpc/JsonRpcHttpServiceTlsTest.java | 6 +- .../engine/EngineGetClientVersionV1Test.java | 72 +++++++++++++++++++ .../websocket/WebSocketServiceLoginTest.java | 6 +- 23 files changed, 316 insertions(+), 46 deletions(-) create mode 100644 ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetClientVersionV1.java create mode 100644 ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/EngineGetClientVersionResultV1.java create mode 100644 ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetClientVersionV1Test.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c31d55fb7..c00417cab6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ - Add 'inbound' field to admin_peers JSON-RPC Call [#7461](https://github.com/hyperledger/besu/pull/7461) - Add pending block header to `TransactionEvaluationContext` plugin API [#7483](https://github.com/hyperledger/besu/pull/7483) - Add bootnode to holesky config [#7500](https://github.com/hyperledger/besu/pull/7500) +- Implement engine_getClientVersionV1 ### Bug fixes - Fix tracing in precompiled contracts when halting for out of gas [#7318](https://github.com/hyperledger/besu/issues/7318) diff --git a/besu/src/main/java/org/hyperledger/besu/BesuInfo.java b/besu/src/main/java/org/hyperledger/besu/BesuInfo.java index 54447a5960..aa5163c2af 100644 --- a/besu/src/main/java/org/hyperledger/besu/BesuInfo.java +++ b/besu/src/main/java/org/hyperledger/besu/BesuInfo.java @@ -17,6 +17,8 @@ package org.hyperledger.besu; import org.hyperledger.besu.util.platform.PlatformDetector; import java.util.Optional; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * Represent Besu information such as version, OS etc. Used with --version option and during Besu @@ -24,9 +26,29 @@ import java.util.Optional; */ public final class BesuInfo { private static final String CLIENT = "besu"; - private static final String VERSION = BesuInfo.class.getPackage().getImplementationVersion(); private static final String OS = PlatformDetector.getOS(); private static final String VM = PlatformDetector.getVM(); + private static final String VERSION; + private static final String COMMIT; + + static { + String projectVersion = BesuInfo.class.getPackage().getImplementationVersion(); + if (projectVersion == null) { + // protect against unset project version (e.g. unit tests being run, etc) + VERSION = null; + COMMIT = null; + } else { + Pattern pattern = + Pattern.compile("(?\\d+\\.\\d+\\.?\\d?-?\\w*)-(?[0-9a-fA-F]{8})"); + Matcher matcher = pattern.matcher(projectVersion); + if (matcher.find()) { + VERSION = matcher.group("version"); + COMMIT = matcher.group("commit"); + } else { + throw new RuntimeException("Invalid project version: " + projectVersion); + } + } + } private BesuInfo() {} @@ -46,7 +68,7 @@ public final class BesuInfo { * or "besu/v23.1.0/osx-aarch_64/corretto-java-19" */ public static String version() { - return String.format("%s/v%s/%s/%s", CLIENT, VERSION, OS, VM); + return String.format("%s/v%s-%s/%s/%s", CLIENT, VERSION, COMMIT, OS, VM); } /** @@ -57,7 +79,18 @@ public final class BesuInfo { */ public static String nodeName(final Optional maybeIdentity) { return maybeIdentity - .map(identity -> String.format("%s/%s/v%s/%s/%s", CLIENT, identity, VERSION, OS, VM)) + .map( + identity -> + String.format("%s/%s/v%s-%s/%s/%s", CLIENT, identity, VERSION, COMMIT, OS, VM)) .orElse(version()); } + + /** + * Generate the commit hash for this besu version + * + * @return the commit hash for this besu version + */ + public static String commit() { + return COMMIT; + } } diff --git a/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java b/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java index e34c0115fe..9eaf254bbf 100644 --- a/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java @@ -1291,6 +1291,8 @@ public class RunnerBuilder { new JsonRpcMethodsFactory() .methods( BesuInfo.nodeName(identityString), + BesuInfo.shortVersion(), + BesuInfo.commit(), ethNetworkConfig.networkId(), besuController.getGenesisConfigOptions(), network, diff --git a/besu/src/test/java/org/hyperledger/besu/BesuInfoTest.java b/besu/src/test/java/org/hyperledger/besu/BesuInfoTest.java index 5a1cec440c..b7799f5ac3 100644 --- a/besu/src/test/java/org/hyperledger/besu/BesuInfoTest.java +++ b/besu/src/test/java/org/hyperledger/besu/BesuInfoTest.java @@ -33,7 +33,8 @@ public final class BesuInfoTest { */ @Test public void versionStringIsEthstatsFriendly() { - assertThat(BesuInfo.version()).matches("[^/]+/v(\\d+\\.\\d+\\.\\d+[^/]*|null)/[^/]+/[^/]+"); + assertThat(BesuInfo.version()) + .matches("[^/]+/v(\\d+\\.\\d+\\.\\d+[^/]*|null-null)/[^/]+/[^/]+"); } /** @@ -45,7 +46,7 @@ public final class BesuInfoTest { @Test public void noIdentityNodeNameIsEthstatsFriendly() { assertThat(BesuInfo.nodeName(Optional.empty())) - .matches("[^/]+/v(\\d+\\.\\d+\\.\\d+[^/]*|null)/[^/]+/[^/]+"); + .matches("[^/]+/v(\\d+\\.\\d+\\.\\d+[^/]*|null-null)/[^/]+/[^/]+"); } /** @@ -58,6 +59,6 @@ public final class BesuInfoTest { @Test public void userIdentityNodeNameIsEthstatsFriendly() { assertThat(BesuInfo.nodeName(Optional.of("TestUserIdentity"))) - .matches("[^/]+/[^/]+/v(\\d+\\.\\d+\\.\\d+[^/]*|null)/[^/]+/[^/]+"); + .matches("[^/]+/[^/]+/v(\\d+\\.\\d+\\.\\d+[^/]*|null-null)/[^/]+/[^/]+"); } } diff --git a/build.gradle b/build.gradle index 6a4f279666..003f6d63c6 100644 --- a/build.gradle +++ b/build.gradle @@ -820,7 +820,7 @@ task distDocker { dockerPlatform = "--platform ${project.getProperty('docker-platform')}" println "Building for platform ${project.getProperty('docker-platform')}" } - def gitDetails = getGitCommitDetails(7) + def gitDetails = getGitCommitDetails() executable shell workingDir dockerBuildDir args "-c", "docker build ${dockerPlatform} --build-arg BUILD_DATE=${buildTime()} --build-arg VERSION=${dockerBuildVersion} --build-arg VCS_REF=${gitDetails.hash} -t ${image} ." @@ -988,17 +988,13 @@ def buildTime() { def calculateVersion() { // Regex pattern for basic calendar versioning, with provision to omit patch rev def calVerPattern = ~/\d+\.\d+(\.\d+)?(-.*)?/ - + def gitDetails = getGitCommitDetails() // Adjust length as needed if (project.hasProperty('version') && (project.version =~ calVerPattern)) { - if (project.hasProperty('versionappendcommit') && project.versionappendcommit == "true") { - def gitDetails = getGitCommitDetails(7) // Adjust length as needed - return "${project.version}-${gitDetails.hash}" - } - return "${project.version}" + println("Generating project version using supplied version: ${project.version}-${gitDetails.hash}") + return "${project.version}-${gitDetails.hash}" } else { // If no version is supplied or it doesn't match the semantic versioning, calculate from git - println("Generating project version as supplied is version not semver: ${project.version}") - def gitDetails = getGitCommitDetails(7) // Adjust length as needed + println("Generating project version using date (${gitDetails.date}-develop-${gitDetails.hash}), as supplied version is not semver: ${project.version}") return "${gitDetails.date}-develop-${gitDetails.hash}" } } 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 a8226a6a69..b5f65e6d4b 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 @@ -64,7 +64,9 @@ import io.vertx.core.VertxOptions; /** Provides a facade to construct the JSON-RPC component. */ public class JsonRpcTestMethodsFactory { - private static final String CLIENT_VERSION = "TestClientVersion/0.1.0"; + 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; @@ -175,7 +177,9 @@ public class JsonRpcTestMethodsFactory { return new JsonRpcMethodsFactory() .methods( + CLIENT_NODE_NAME, CLIENT_VERSION, + CLIENT_COMMIT, NETWORK_ID, new StubGenesisConfigOptions(), peerDiscovery, diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcMethod.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcMethod.java index 63fa5b3ce5..75da090480 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcMethod.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcMethod.java @@ -63,6 +63,7 @@ public enum RpcMethod { ENGINE_FORKCHOICE_UPDATED_V2("engine_forkchoiceUpdatedV2"), ENGINE_FORKCHOICE_UPDATED_V3("engine_forkchoiceUpdatedV3"), ENGINE_EXCHANGE_TRANSITION_CONFIGURATION("engine_exchangeTransitionConfigurationV1"), + ENGINE_GET_CLIENT_VERSION_V1("engine_getClientVersionV1"), ENGINE_GET_PAYLOAD_BODIES_BY_HASH_V1("engine_getPayloadBodiesByHashV1"), ENGINE_GET_PAYLOAD_BODIES_BY_RANGE_V1("engine_getPayloadBodiesByRangeV1"), ENGINE_EXCHANGE_CAPABILITIES("engine_exchangeCapabilities"), 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 new file mode 100644 index 0000000000..5b1142eee0 --- /dev/null +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetClientVersionV1.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.api.jsonrpc.internal.methods.engine; + +import org.hyperledger.besu.ethereum.ProtocolContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod; +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.api.jsonrpc.internal.results.EngineGetClientVersionResultV1; + +import io.vertx.core.Vertx; + +public class EngineGetClientVersionV1 extends ExecutionEngineJsonRpcMethod { + private static final String ENGINE_CLIENT_CODE = "BU"; + private static final String ENGINE_CLIENT_NAME = "Besu"; + + private final String clientVersion; + private final String commit; + + public EngineGetClientVersionV1( + final Vertx vertx, + final ProtocolContext protocolContext, + final EngineCallListener engineCallListener, + final String clientVersion, + final String commit) { + super(vertx, protocolContext, engineCallListener); + this.clientVersion = clientVersion; + this.commit = commit; + } + + @Override + public String getName() { + return RpcMethod.ENGINE_GET_CLIENT_VERSION_V1.getMethodName(); + } + + @Override + public JsonRpcResponse syncResponse(final JsonRpcRequestContext request) { + return new JsonRpcSuccessResponse( + request.getRequest().getId(), + new EngineGetClientVersionResultV1( + ENGINE_CLIENT_CODE, ENGINE_CLIENT_NAME, clientVersion, commit)); + } +} diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/EngineGetClientVersionResultV1.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/EngineGetClientVersionResultV1.java new file mode 100644 index 0000000000..8251de6dc5 --- /dev/null +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/EngineGetClientVersionResultV1.java @@ -0,0 +1,52 @@ +/* + * 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.results; + +import com.fasterxml.jackson.annotation.JsonGetter; + +public class EngineGetClientVersionResultV1 { + private final String code; + private final String name; + private final String version; + private final String commit; + + public EngineGetClientVersionResultV1( + final String code, final String name, final String version, final String commit) { + this.code = code; + this.name = name; + this.version = version; + this.commit = commit; + } + + @JsonGetter(value = "code") + public String getCode() { + return code; + } + + @JsonGetter(value = "name") + public String getName() { + return name; + } + + @JsonGetter(value = "version") + public String getVersion() { + return version; + } + + @JsonGetter(value = "commit") + public String getCommit() { + return commit; + } +} 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 ca66926656..6dda09bce9 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 @@ -23,6 +23,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineE import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineForkchoiceUpdatedV1; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineForkchoiceUpdatedV2; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineForkchoiceUpdatedV3; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineGetClientVersionV1; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineGetPayloadBodiesByHashV1; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineGetPayloadBodiesByRangeV1; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineGetPayloadV1; @@ -57,13 +58,17 @@ public class ExecutionEngineJsonRpcMethods extends ApiGroupJsonRpcMethods { private final ProtocolContext protocolContext; private final EthPeers ethPeers; private final Vertx consensusEngineServer; + private final String clientVersion; + private final String commit; ExecutionEngineJsonRpcMethods( final MiningCoordinator miningCoordinator, final ProtocolSchedule protocolSchedule, final ProtocolContext protocolContext, final EthPeers ethPeers, - final Vertx consensusEngineServer) { + final Vertx consensusEngineServer, + final String clientVersion, + final String commit) { this.mergeCoordinator = Optional.ofNullable(miningCoordinator) .filter(mc -> mc.isCompatibleWithEngineApi()) @@ -72,6 +77,8 @@ public class ExecutionEngineJsonRpcMethods extends ApiGroupJsonRpcMethods { this.protocolContext = protocolContext; this.ethPeers = ethPeers; this.consensusEngineServer = consensusEngineServer; + this.clientVersion = clientVersion; + this.commit = commit; } @Override @@ -147,7 +154,9 @@ public class ExecutionEngineJsonRpcMethods extends ApiGroupJsonRpcMethods { new EngineExchangeCapabilities( consensusEngineServer, protocolContext, engineQosTimer), new EnginePreparePayloadDebug( - consensusEngineServer, protocolContext, engineQosTimer, mergeCoordinator.get()))); + consensusEngineServer, protocolContext, engineQosTimer, mergeCoordinator.get()), + new EngineGetClientVersionV1( + consensusEngineServer, protocolContext, engineQosTimer, clientVersion, commit))); if (protocolSchedule.anyMatch(p -> p.spec().getName().equalsIgnoreCase("cancun"))) { executionEngineApisSupported.add( diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/JsonRpcMethodsFactory.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/JsonRpcMethodsFactory.java index 924889ef47..41227c2ca8 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/JsonRpcMethodsFactory.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/JsonRpcMethodsFactory.java @@ -54,7 +54,9 @@ import io.vertx.core.Vertx; public class JsonRpcMethodsFactory { public Map methods( + final String clientNodeName, final String clientVersion, + final String commit, final BigInteger networkId, final GenesisConfigOptions genesisConfigOptions, final P2PNetwork p2pNetwork, @@ -89,7 +91,7 @@ public class JsonRpcMethodsFactory { final List availableApiGroups = List.of( new AdminJsonRpcMethods( - clientVersion, + clientNodeName, networkId, genesisConfigOptions, p2pNetwork, @@ -115,7 +117,9 @@ public class JsonRpcMethodsFactory { protocolSchedule, protocolContext, ethPeers, - consensusEngineServer), + consensusEngineServer, + clientVersion, + commit), new EthJsonRpcMethods( blockchainQueries, synchronizer, @@ -141,7 +145,7 @@ public class JsonRpcMethodsFactory { filterManager), new PrivxJsonRpcMethods( blockchainQueries, protocolSchedule, transactionPool, privacyParameters), - new Web3JsonRpcMethods(clientVersion), + new Web3JsonRpcMethods(clientNodeName), new TraceJsonRpcMethods( blockchainQueries, protocolSchedule, protocolContext, apiConfiguration), new TxPoolJsonRpcMethods(transactionPool), diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/AbstractJsonRpcHttpServiceTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/AbstractJsonRpcHttpServiceTest.java index 9193574c45..862e17b890 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/AbstractJsonRpcHttpServiceTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/AbstractJsonRpcHttpServiceTest.java @@ -75,7 +75,9 @@ public abstract class AbstractJsonRpcHttpServiceTest { protected BlockchainSetupUtil blockchainSetupUtil; - protected static String CLIENT_VERSION = "TestClientVersion/0.1.0"; + protected static final String CLIENT_NODE_NAME = "TestClientVersion/0.1.0"; + protected static final String CLIENT_VERSION = "0.1.0"; + protected static final String CLIENT_COMMIT = "12345678"; protected static final BigInteger NETWORK_ID = BigInteger.valueOf(123); protected static final Collection JSON_RPC_APIS = Arrays.asList( @@ -168,7 +170,9 @@ public abstract class AbstractJsonRpcHttpServiceTest { return new JsonRpcMethodsFactory() .methods( + CLIENT_NODE_NAME, CLIENT_VERSION, + CLIENT_COMMIT, NETWORK_ID, new StubGenesisConfigOptions(), peerDiscoveryMock, diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/AdminJsonRpcHttpServiceTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/AdminJsonRpcHttpServiceTest.java index 061d2a2d6a..4a03b2eb93 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/AdminJsonRpcHttpServiceTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/AdminJsonRpcHttpServiceTest.java @@ -58,13 +58,13 @@ public class AdminJsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { final List peerList = new ArrayList<>(); final PeerInfo info1 = new PeerInfo( - 4, CLIENT_VERSION, caps, 30302, Bytes.fromHexString(String.format("%0128x", 1))); + 4, CLIENT_NODE_NAME, caps, 30302, Bytes.fromHexString(String.format("%0128x", 1))); final PeerInfo info2 = new PeerInfo( - 4, CLIENT_VERSION, caps, 60302, Bytes.fromHexString(String.format("%0128x", 2))); + 4, CLIENT_NODE_NAME, caps, 60302, Bytes.fromHexString(String.format("%0128x", 2))); final PeerInfo info3 = new PeerInfo( - 4, CLIENT_VERSION, caps, 60303, Bytes.fromHexString(String.format("%0128x", 3))); + 4, CLIENT_NODE_NAME, caps, 60303, Bytes.fromHexString(String.format("%0128x", 3))); final InetSocketAddress addr30301 = new InetSocketAddress("localhost", 30301); final InetSocketAddress addr30302 = new InetSocketAddress("localhost", 30302); final InetSocketAddress addr60301 = new InetSocketAddress("localhost", 60301); diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceHostAllowlistTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceHostAllowlistTest.java index 80626ef2fc..25077bbf82 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceHostAllowlistTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceHostAllowlistTest.java @@ -79,7 +79,9 @@ public class JsonRpcHttpServiceHostAllowlistTest { private static OkHttpClient client; private static String baseUrl; private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); - private static final String CLIENT_VERSION = "TestClientVersion/0.1.0"; + 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 CHAIN_ID = BigInteger.valueOf(123); private final JsonRpcConfiguration jsonRpcConfig = createJsonRpcConfig(); @@ -100,7 +102,9 @@ public class JsonRpcHttpServiceHostAllowlistTest { rpcMethods = new JsonRpcMethodsFactory() .methods( + CLIENT_NODE_NAME, CLIENT_VERSION, + CLIENT_COMMIT, CHAIN_ID, new StubGenesisConfigOptions(), peerDiscoveryMock, diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceLoginTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceLoginTest.java index 0fb55fdf34..eb23b054d0 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceLoginTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceLoginTest.java @@ -100,7 +100,9 @@ public class JsonRpcHttpServiceLoginTest { protected static OkHttpClient client; protected static String baseUrl; protected static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); - protected static final String CLIENT_VERSION = "TestClientVersion/0.1.0"; + protected static final String CLIENT_NODE_NAME = "TestClientVersion/0.1.0"; + protected static final String CLIENT_VERSION = "0.1.0"; + protected static final String CLIENT_COMMIT = "12345678"; protected static final BigInteger CHAIN_ID = BigInteger.valueOf(123); protected static P2PNetwork peerDiscoveryMock; protected static BlockchainQueries blockchainQueries; @@ -131,7 +133,9 @@ public class JsonRpcHttpServiceLoginTest { rpcMethods = new JsonRpcMethodsFactory() .methods( + CLIENT_NODE_NAME, CLIENT_VERSION, + CLIENT_COMMIT, CHAIN_ID, genesisConfigOptions, peerDiscoveryMock, diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceRpcApisTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceRpcApisTest.java index 8323f61b2c..f35893490a 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceRpcApisTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceRpcApisTest.java @@ -94,7 +94,9 @@ public class JsonRpcHttpServiceRpcApisTest { private JsonRpcHttpService service; private static String baseUrl; private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); - private static final String CLIENT_VERSION = "TestClientVersion/0.1.0"; + 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 JsonRpcConfiguration configuration; private static final List netServices = @@ -202,7 +204,9 @@ public class JsonRpcHttpServiceRpcApisTest { final Map rpcMethods = new JsonRpcMethodsFactory() .methods( + CLIENT_NODE_NAME, CLIENT_VERSION, + CLIENT_COMMIT, NETWORK_ID, new StubGenesisConfigOptions(), mock(P2PNetwork.class), @@ -310,7 +314,9 @@ public class JsonRpcHttpServiceRpcApisTest { final Map rpcMethods = new JsonRpcMethodsFactory() .methods( + CLIENT_NODE_NAME, CLIENT_VERSION, + CLIENT_COMMIT, NETWORK_ID, new StubGenesisConfigOptions(), p2pNetwork, diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTest.java index bb5cb68a2a..52f2ee050c 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTest.java @@ -202,7 +202,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { testHelper.assertValidJsonRpcResult(json, id); // Check result final String result = json.getString("result"); - assertThat(result).isEqualTo(CLIENT_VERSION); + assertThat(result).isEqualTo(CLIENT_NODE_NAME); } } @@ -1127,7 +1127,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { testHelper.assertValidJsonRpcResult(json, id); // Check result final String result = json.getString("result"); - assertThat(result).isEqualTo(CLIENT_VERSION); + assertThat(result).isEqualTo(CLIENT_NODE_NAME); } } @@ -1143,7 +1143,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { final JsonObject json = new JsonObject(resp.body().string()); testHelper.assertValidJsonRpcResult(json, id); final String result = json.getString("result"); - assertThat(result).isEqualTo(CLIENT_VERSION); + assertThat(result).isEqualTo(CLIENT_NODE_NAME); } } @@ -1175,7 +1175,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { testHelper.assertValidJsonRpcResult(json, null); // Check result final String result = json.getString("result"); - assertThat(result).isEqualTo(CLIENT_VERSION); + assertThat(result).isEqualTo(CLIENT_NODE_NAME); } } @@ -1197,7 +1197,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { testHelper.assertValidJsonRpcResult(json, id); // Check result final String result = json.getString("result"); - assertThat(result).isEqualTo(CLIENT_VERSION); + assertThat(result).isEqualTo(CLIENT_NODE_NAME); } } @@ -1218,7 +1218,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { testHelper.assertValidJsonRpcResult(json, id); // Check result final String result = json.getString("result"); - assertThat(result).isEqualTo(CLIENT_VERSION); + assertThat(result).isEqualTo(CLIENT_NODE_NAME); } } @@ -1242,7 +1242,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { testHelper.assertValidJsonRpcResult(json, id); // Check result final String result = json.getString("result"); - assertThat(result).isEqualTo(CLIENT_VERSION); + assertThat(result).isEqualTo(CLIENT_NODE_NAME); } } @@ -1268,7 +1268,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { testHelper.assertValidJsonRpcResult(json, id); // Check result final String result = json.getString("result"); - assertThat(result).isEqualTo(CLIENT_VERSION); + assertThat(result).isEqualTo(CLIENT_NODE_NAME); } } @@ -1289,7 +1289,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { testHelper.assertValidJsonRpcResult(json, id); // Check result final String result = json.getString("result"); - assertThat(result).isEqualTo(CLIENT_VERSION); + assertThat(result).isEqualTo(CLIENT_NODE_NAME); } } @@ -1353,7 +1353,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { final JsonObject json = new JsonObject(resp.body().string()); testHelper.assertValidJsonRpcResult(json, id); final String result = json.getString("result"); - assertThat(result).isEqualTo(CLIENT_VERSION); + assertThat(result).isEqualTo(CLIENT_NODE_NAME); } } @@ -1485,7 +1485,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { // Check result web3_clientVersion final JsonObject jsonClientVersion = responses.get(clientVersionRequestId); testHelper.assertValidJsonRpcResult(jsonClientVersion, clientVersionRequestId); - assertThat(jsonClientVersion.getString("result")).isEqualTo(CLIENT_VERSION); + assertThat(jsonClientVersion.getString("result")).isEqualTo(CLIENT_NODE_NAME); // Check result unknown method final JsonObject jsonError = responses.get(brokenRequestId); @@ -1540,7 +1540,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { // Check result web3_clientVersion final JsonObject jsonClientVersion = responses.get(clientVersionRequestId); testHelper.assertValidJsonRpcResult(jsonClientVersion, clientVersionRequestId); - assertThat(jsonClientVersion.getString("result")).isEqualTo(CLIENT_VERSION); + assertThat(jsonClientVersion.getString("result")).isEqualTo(CLIENT_NODE_NAME); // Check invalid request final JsonObject jsonError = responses.get(invalidId); @@ -1605,7 +1605,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { // Check result web3_clientVersion final JsonObject jsonClientVersion = responses.get(clientVersionRequestId); testHelper.assertValidJsonRpcResult(jsonClientVersion, clientVersionRequestId); - assertThat(jsonClientVersion.getString("result")).isEqualTo(CLIENT_VERSION); + assertThat(jsonClientVersion.getString("result")).isEqualTo(CLIENT_NODE_NAME); // Check result net_version final JsonObject jsonNetVersion = responses.get(netVersionRequestId); diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTestBase.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTestBase.java index a2a856333e..5e5dc36bb0 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTestBase.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTestBase.java @@ -78,7 +78,9 @@ public class JsonRpcHttpServiceTestBase { protected static OkHttpClient client; protected static String baseUrl; protected static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); - protected static final String CLIENT_VERSION = "TestClientVersion/0.1.0"; + protected static final String CLIENT_NODE_NAME = "TestClientVersion/0.1.0"; + protected static final String CLIENT_VERSION = "0.1.0"; + protected static final String CLIENT_COMMIT = "12345678"; protected static final BigInteger CHAIN_ID = BigInteger.valueOf(123); protected static P2PNetwork peerDiscoveryMock; protected static EthPeers ethPeersMock; @@ -108,7 +110,9 @@ public class JsonRpcHttpServiceTestBase { rpcMethods = new JsonRpcMethodsFactory() .methods( + CLIENT_NODE_NAME, CLIENT_VERSION, + CLIENT_COMMIT, CHAIN_ID, new StubGenesisConfigOptions(), peerDiscoveryMock, diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsClientAuthTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsClientAuthTest.java index 1d3a3a087a..5cf13a4576 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsClientAuthTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsClientAuthTest.java @@ -85,7 +85,9 @@ public class JsonRpcHttpServiceTlsClientAuthTest { protected static final Vertx vertx = Vertx.vertx(); private static final String JSON_HEADER = "application/json; charset=utf-8"; - private static final String CLIENT_VERSION = "TestClientVersion/0.1.0"; + 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 CHAIN_ID = BigInteger.valueOf(123); private static final NatService natService = new NatService(Optional.empty()); @@ -114,7 +116,9 @@ public class JsonRpcHttpServiceTlsClientAuthTest { rpcMethods = new JsonRpcMethodsFactory() .methods( + CLIENT_NODE_NAME, CLIENT_VERSION, + CLIENT_COMMIT, CHAIN_ID, new StubGenesisConfigOptions(), peerDiscoveryMock, diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsMisconfigurationTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsMisconfigurationTest.java index 684f843d2f..c2661141a4 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsMisconfigurationTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsMisconfigurationTest.java @@ -75,7 +75,9 @@ class JsonRpcHttpServiceTlsMisconfigurationTest { protected static final Vertx vertx = Vertx.vertx(); - private static final String CLIENT_VERSION = "TestClientVersion/0.1.0"; + 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 CHAIN_ID = BigInteger.valueOf(123); private static final NatService natService = new NatService(Optional.empty()); private final SelfSignedP12Certificate besuCertificate = SelfSignedP12Certificate.create(); @@ -102,7 +104,9 @@ class JsonRpcHttpServiceTlsMisconfigurationTest { rpcMethods = new JsonRpcMethodsFactory() .methods( + CLIENT_NODE_NAME, CLIENT_VERSION, + CLIENT_COMMIT, CHAIN_ID, new StubGenesisConfigOptions(), peerDiscoveryMock, diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsTest.java index b6d7fa67f8..c0846ed9f2 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsTest.java @@ -81,7 +81,9 @@ public class JsonRpcHttpServiceTlsTest { protected static final Vertx vertx = Vertx.vertx(); private static final String JSON_HEADER = "application/json; charset=utf-8"; - private static final String CLIENT_VERSION = "TestClientVersion/0.1.0"; + 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 CHAIN_ID = BigInteger.valueOf(123); private static final NatService natService = new NatService(Optional.empty()); private JsonRpcHttpService service; @@ -103,7 +105,9 @@ public class JsonRpcHttpServiceTlsTest { rpcMethods = new JsonRpcMethodsFactory() .methods( + CLIENT_NODE_NAME, CLIENT_VERSION, + CLIENT_COMMIT, CHAIN_ID, new StubGenesisConfigOptions(), peerDiscoveryMock, 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 new file mode 100644 index 0000000000..1aa0def7e2 --- /dev/null +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetClientVersionV1Test.java @@ -0,0 +1,72 @@ +/* + * 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.methods.engine; + +import static org.assertj.core.api.Assertions.assertThat; + +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.response.JsonRpcResponse; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.EngineGetClientVersionResultV1; + +import io.vertx.core.Vertx; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +class EngineGetClientVersionV1Test { + + private static final String ENGINE_CLIENT_CODE = "BU"; + private static final String ENGINE_CLIENT_NAME = "Besu"; + + private static final String CLIENT_VERSION = "v25.6.7-dev-abcdef12"; + private static final String COMMIT = "abcdef12"; + + private EngineGetClientVersionV1 getClientVersion; + + @BeforeEach + void before() { + getClientVersion = + new EngineGetClientVersionV1( + Mockito.mock(Vertx.class), + Mockito.mock(ProtocolContext.class), + Mockito.mock(EngineCallListener.class), + CLIENT_VERSION, + COMMIT); + } + + @Test + void testGetName() { + assertThat(getClientVersion.getName()).isEqualTo("engine_getClientVersionV1"); + } + + @Test + void testSyncResponse() { + JsonRpcRequestContext request = new JsonRpcRequestContext(new JsonRpcRequest("v", "m", null)); + JsonRpcResponse actualResult = getClientVersion.syncResponse(request); + + assertThat(actualResult).isInstanceOf(JsonRpcSuccessResponse.class); + JsonRpcSuccessResponse successResponse = (JsonRpcSuccessResponse) actualResult; + assertThat(successResponse.getResult()).isInstanceOf(EngineGetClientVersionResultV1.class); + EngineGetClientVersionResultV1 actualEngineGetClientVersionResultV1 = + (EngineGetClientVersionResultV1) successResponse.getResult(); + assertThat(actualEngineGetClientVersionResultV1.getName()).isEqualTo(ENGINE_CLIENT_NAME); + assertThat(actualEngineGetClientVersionResultV1.getCode()).isEqualTo(ENGINE_CLIENT_CODE); + assertThat(actualEngineGetClientVersionResultV1.getVersion()).isEqualTo(CLIENT_VERSION); + assertThat(actualEngineGetClientVersionResultV1.getCommit()).isEqualTo(COMMIT); + } +} diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/WebSocketServiceLoginTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/WebSocketServiceLoginTest.java index 75927c4513..342941d0e9 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/WebSocketServiceLoginTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/WebSocketServiceLoginTest.java @@ -115,7 +115,9 @@ public class WebSocketServiceLoginTest { protected static OkHttpClient client; protected static String baseUrl; protected static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); - protected static final String CLIENT_VERSION = "TestClientVersion/0.1.0"; + protected static final String CLIENT_NODE_NAME = "TestClientVersion/0.1.0"; + protected static final String CLIENT_VERSION = "0.1.0"; + protected static final String CLIENT_COMMIT = "12345678"; protected static final BigInteger CHAIN_ID = BigInteger.valueOf(123); protected static P2PNetwork peerDiscoveryMock; protected static BlockchainQueries blockchainQueries; @@ -167,7 +169,9 @@ public class WebSocketServiceLoginTest { spy( new JsonRpcMethodsFactory() .methods( + CLIENT_NODE_NAME, CLIENT_VERSION, + CLIENT_COMMIT, CHAIN_ID, genesisConfigOptions, peerDiscoveryMock, From c656ece8fca77bb0acb15f578de86aac98dec7d2 Mon Sep 17 00:00:00 2001 From: Suyash Nayan <89125422+7suyash7@users.noreply.github.com> Date: Tue, 27 Aug 2024 15:47:47 +0530 Subject: [PATCH 157/259] build: Add Spotless Fail Fast to the build process (#7515) * Add Spotless Fail Fast to the build process --------- Signed-off-by: 7suyash7 Co-authored-by: Usman Saleem --- build.gradle | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 003f6d63c6..690c0fb39f 100644 --- a/build.gradle +++ b/build.gradle @@ -45,6 +45,10 @@ sonarqube { } } +tasks.register('spotlessCheckFast') { + dependsOn subprojects.collect { it.tasks.withType(com.diffplug.gradle.spotless.SpotlessCheck) } +} + project.tasks["sonarqube"].dependsOn "jacocoRootReport" if (!JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_21)) { @@ -432,6 +436,12 @@ allprojects { options.addStringOption('Xwerror', '-html5') options.encoding = 'UTF-8' } + + plugins.withType(JavaPlugin) { + tasks.withType(JavaCompile) { + it.dependsOn(rootProject.tasks.named('spotlessCheckFast')) + } + } } task deploy() {} @@ -455,7 +465,7 @@ task checkMavenCoordinateCollisions { tasks.register('checkPluginAPIChanges', DefaultTask) {} checkPluginAPIChanges.dependsOn(':plugin-api:checkAPIChanges') -check.dependsOn('checkPluginAPIChanges', 'checkMavenCoordinateCollisions') +check.dependsOn('checkPluginAPIChanges', 'checkMavenCoordinateCollisions', 'spotlessCheckFast') subprojects { From c0e0103b2b5778d1ce5b3750b1642852b96719f3 Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Tue, 27 Aug 2024 22:59:51 -0600 Subject: [PATCH 158/259] Add slow parsing detection to EOF layout fuzzing (#7516) * Add slow parsing validation Add CLI flags and fuzzing logic to enable "slow" parsing to be a loggable error. * picocli final field issue * fix some array boundary issues in pretty print and testing Signed-off-by: Danno Ferrin Signed-off-by: Sally MacFarlane --------- Signed-off-by: Danno Ferrin Signed-off-by: Sally MacFarlane Co-authored-by: Sally MacFarlane --- .../besu/evmtool/CodeValidateSubCommand.java | 21 ++-- .../besu/evmtool/PrettyPrintSubCommand.java | 8 +- .../hyperledger/besu/evm/code/EOFLayout.java | 74 +++++++---- testfuzz/build.gradle | 11 ++ .../besu/testfuzz/EofContainerSubCommand.java | 119 ++++++++++-------- ...ExternalClient.java => FuzzingClient.java} | 2 +- .../besu/testfuzz/InternalClient.java | 65 ++++++++++ .../besu/testfuzz/SingleQueryClient.java | 2 +- .../besu/testfuzz/StreamingClient.java | 2 +- 9 files changed, 220 insertions(+), 84 deletions(-) rename testfuzz/src/main/java/org/hyperledger/besu/testfuzz/{ExternalClient.java => FuzzingClient.java} (96%) create mode 100644 testfuzz/src/main/java/org/hyperledger/besu/testfuzz/InternalClient.java 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 a3fff8e5dc..d8be71cde1 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 @@ -126,9 +126,13 @@ public class CodeValidateSubCommand implements Runnable { private void checkCodeFromBufferedReader(final BufferedReader in) { try { for (String code = in.readLine(); code != null; code = in.readLine()) { - String validation = considerCode(code); - if (!Strings.isBlank(validation)) { - parentCommand.out.println(validation); + try { + String validation = considerCode(code); + if (!Strings.isBlank(validation)) { + parentCommand.out.println(validation); + } + } catch (RuntimeException e) { + parentCommand.out.println("fail: " + e.getMessage()); } } } catch (IOException e) { @@ -151,14 +155,17 @@ public class CodeValidateSubCommand implements Runnable { public String considerCode(final String hexCode) { Bytes codeBytes; try { - codeBytes = - Bytes.fromHexString( - hexCode.replaceAll("(^|\n)#[^\n]*($|\n)", "").replaceAll("[^0-9A-Za-z]", "")); + String strippedString = + hexCode.replaceAll("(^|\n)#[^\n]*($|\n)", "").replaceAll("[^0-9A-Za-z]", ""); + if (Strings.isEmpty(strippedString)) { + return ""; + } + codeBytes = Bytes.fromHexString(strippedString); } catch (RuntimeException re) { return "err: hex string -" + re; } if (codeBytes.isEmpty()) { - return ""; + return "err: empty container"; } EOFLayout layout = evm.get().parseEOF(codeBytes); 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 aeff4a96b5..e24c24a21e 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 @@ -89,7 +89,13 @@ public class PrettyPrintSubCommand implements Runnable { LogConfigurator.setLevel("", "OFF"); for (var hexCode : codeList) { - Bytes container = Bytes.fromHexString(hexCode); + Bytes container; + try { + container = Bytes.fromHexString(hexCode); + } catch (IllegalArgumentException e) { + parentCommand.out.println("Invalid hex string: " + e.getMessage()); + continue; + } if (container.get(0) != ((byte) 0xef) && container.get(1) != 0) { parentCommand.out.println( "Pretty printing of legacy EVM is not supported. Patches welcome!"); diff --git a/evm/src/main/java/org/hyperledger/besu/evm/code/EOFLayout.java b/evm/src/main/java/org/hyperledger/besu/evm/code/EOFLayout.java index 7883b70d80..8ff8c80158 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/code/EOFLayout.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/code/EOFLayout.java @@ -740,35 +740,59 @@ public record EOFLayout( OpcodeInfo ci = V1_OPCODES[byteCode[pc] & 0xff]; if (ci.opcode() == RelativeJumpVectorOperation.OPCODE) { - int tableSize = byteCode[pc + 1] & 0xff; - out.printf("%02x%02x", byteCode[pc], byteCode[pc + 1]); - for (int j = 0; j <= tableSize; j++) { - out.printf("%02x%02x", byteCode[pc + j * 2 + 2], byteCode[pc + j * 2 + 3]); - } - out.printf(" # [%d] %s(", pc, ci.name()); - for (int j = 0; j <= tableSize; j++) { - if (j != 0) { - out.print(','); + if (byteCode.length <= pc + 1) { + out.printf( + " %02x # [%d] %s()%n", byteCode[pc], pc, ci.name()); + pc++; + } else { + int tableSize = byteCode[pc + 1] & 0xff; + out.printf("%02x%02x", byteCode[pc], byteCode[pc + 1]); + int calculatedTableEnd = pc + tableSize * 2 + 4; + int lastTableEntry = Math.min(byteCode.length, calculatedTableEnd); + for (int j = pc + 2; j < lastTableEntry; j++) { + out.printf("%02x", byteCode[j]); + } + out.printf(" # [%d] %s(", pc, ci.name()); + for (int j = pc + 3; j < lastTableEntry; j += 2) { + // j indexes to the second byte of the word, to handle mid-word truncation + if (j != pc + 3) { + out.print(','); + } + int b0 = byteCode[j - 1]; // we want the sign extension, so no `& 0xff` + int b1 = byteCode[j] & 0xff; + out.print(b0 << 8 | b1); + } + if (byteCode.length < calculatedTableEnd) { + out.print(""); } - int b0 = byteCode[pc + j * 2 + 2]; // we want the sign extension, so no `& 0xff` - int b1 = byteCode[pc + j * 2 + 3] & 0xff; - out.print(b0 << 8 | b1); + pc += tableSize * 2 + 4; + out.print(")\n"); } - pc += tableSize * 2 + 4; - out.print(")\n"); } else if (ci.opcode() == RelativeJumpOperation.OPCODE || ci.opcode() == RelativeJumpIfOperation.OPCODE) { - int b0 = byteCode[pc + 1] & 0xff; - int b1 = byteCode[pc + 2] & 0xff; - short delta = (short) (b0 << 8 | b1); - out.printf("%02x%02x%02x # [%d] %s(%d)", byteCode[pc], b0, b1, pc, ci.name(), delta); + if (pc + 1 >= byteCode.length) { + out.printf(" %02x # [%d] %s()", byteCode[pc], pc, ci.name()); + } else if (pc + 2 >= byteCode.length) { + out.printf( + " %02x%02x # [%d] %s()", + byteCode[pc], byteCode[pc + 1], pc, ci.name()); + } else { + int b0 = byteCode[pc + 1] & 0xff; + int b1 = byteCode[pc + 2] & 0xff; + short delta = (short) (b0 << 8 | b1); + out.printf("%02x%02x%02x # [%d] %s(%d)", byteCode[pc], b0, b1, pc, ci.name(), delta); + } pc += 3; out.printf("%n"); } else if (ci.opcode() == ExchangeOperation.OPCODE) { - int imm = byteCode[pc + 1] & 0xff; - out.printf( - " %02x%02x # [%d] %s(%d, %d)", - byteCode[pc], imm, pc, ci.name(), imm >> 4, imm & 0x0F); + if (pc + 1 >= byteCode.length) { + out.printf(" %02x # [%d] %s()", byteCode[pc], pc, ci.name()); + } else { + int imm = byteCode[pc + 1] & 0xff; + out.printf( + " %02x%02x # [%d] %s(%d, %d)", + byteCode[pc], imm, pc, ci.name(), imm >> 4, imm & 0x0F); + } pc += 2; out.printf("%n"); } else { @@ -784,7 +808,11 @@ public record EOFLayout( } out.printf(" # [%d] %s", pc, ci.name()); if (advance == 2) { - out.printf("(%d)", byteCode[pc + 1] & 0xff); + if (byteCode.length <= pc + 1) { + out.print("()"); + } else { + out.printf("(%d)", byteCode[pc + 1] & 0xff); + } } else if (advance > 2) { out.print("(0x"); for (int j = 1; j < advance && (pc + j) < byteCode.length; j++) { diff --git a/testfuzz/build.gradle b/testfuzz/build.gradle index e55cbe5983..83bf621ac9 100644 --- a/testfuzz/build.gradle +++ b/testfuzz/build.gradle @@ -39,6 +39,7 @@ dependencies { implementation 'com.fasterxml.jackson.core:jackson-databind' implementation 'com.gitlab.javafuzz:core' + implementation 'com.google.guava:guava' implementation 'info.picocli:picocli' implementation 'io.tmio:tuweni-bytes' implementation 'org.jacoco:org.jacoco.agent' @@ -56,6 +57,7 @@ application { def corpusDir = "${buildDir}/generated/corpus" tasks.register("runFuzzer", JavaExec) { + doNotTrackState("Produces no artifacts") classpath = sourceSets.main.runtimeClasspath mainClass = 'org.hyperledger.besu.testfuzz.BesuFuzz' @@ -69,6 +71,15 @@ tasks.register("runFuzzer", JavaExec) { } } +// This fuzzes besu as an external client. Besu fuzzing as a local client is enabled by default. +tasks.register("fuzzBesu") { + dependsOn(":installDist") + doLast { + runFuzzer.args += "--client=besu=../build/install/besu/bin/evmtool code-validate" + } + finalizedBy("runFuzzer") +} + tasks.register("fuzzEvmone") { doLast { runFuzzer.args += "--client=evm1=evmone-eofparse" 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 efe84296cf..c2b518f182 100644 --- a/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/EofContainerSubCommand.java +++ b/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/EofContainerSubCommand.java @@ -17,14 +17,10 @@ package org.hyperledger.besu.testfuzz; import static org.hyperledger.besu.testfuzz.EofContainerSubCommand.COMMAND_NAME; import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.referencetests.EOFTestCaseSpec; -import org.hyperledger.besu.evm.Code; import org.hyperledger.besu.evm.EVM; import org.hyperledger.besu.evm.MainnetEVMs; -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.evm.code.EOFLayout.EOFContainerMode; import org.hyperledger.besu.evm.internal.EvmConfiguration; import java.io.File; @@ -39,6 +35,9 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.stream.Collectors; import com.fasterxml.jackson.core.JsonParser.Feature; import com.fasterxml.jackson.core.util.DefaultIndenter; @@ -50,6 +49,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import com.gitlab.javafuzz.core.AbstractFuzzTarget; +import com.google.common.base.Stopwatch; import org.apache.tuweni.bytes.Bytes; import picocli.CommandLine; import picocli.CommandLine.Option; @@ -83,6 +83,23 @@ public class EofContainerSubCommand extends AbstractFuzzTarget implements Runnab description = "Add a client for differential fuzzing") private final Map clients = new LinkedHashMap<>(); + @Option( + names = {"--no-local-client"}, + description = "Don't include built-in Besu with fuzzing") + private final Boolean noLocalClient = false; + + @Option( + names = {"--time-limit-ns"}, + defaultValue = "5000", + description = "Time threshold, in nanoseconds, that results in a fuzz error if exceeded") + private long timeThresholdMicros = 5_000; + + @Option( + names = {"--time-limit-warmup"}, + defaultValue = "2000", + description = "Minimum number of fuzz tests before a time limit fuzz error can occur") + private long timeThresholdIterations = 2_000; + @CommandLine.ParentCommand private final BesuFuzzCommand parentCommand; static final ObjectMapper eofTestMapper = createObjectMapper(); @@ -91,7 +108,7 @@ public class EofContainerSubCommand extends AbstractFuzzTarget implements Runnab .getTypeFactory() .constructParametricType(Map.class, String.class, EOFTestCaseSpec.class); - List externalClients = new ArrayList<>(); + List fuzzingClients = new ArrayList<>(); EVM evm = MainnetEVMs.pragueEOF(EvmConfiguration.DEFAULT); long validContainers; long totalContainers; @@ -150,7 +167,10 @@ public class EofContainerSubCommand extends AbstractFuzzTarget implements Runnab } } - clients.forEach((k, v) -> externalClients.add(new StreamingClient(k, v.split(" ")))); + if (!noLocalClient) { + fuzzingClients.add(new InternalClient("this")); + } + clients.forEach((k, v) -> fuzzingClients.add(new StreamingClient(k, v.split(" ")))); System.out.println("Fuzzing client set: " + clients.keySet()); try { @@ -196,55 +216,54 @@ public class EofContainerSubCommand extends AbstractFuzzTarget implements Runnab public void fuzz(final byte[] bytes) { Bytes eofUnderTest = Bytes.wrap(bytes); String eofUnderTestHexString = eofUnderTest.toHexString(); - Code code = evm.getCodeUncached(eofUnderTest); - Map results = new LinkedHashMap<>(); - boolean mismatch = false; - for (var client : externalClients) { - String value = client.differentialFuzz(eofUnderTestHexString); - results.put(client.getName(), value); - if (value == null || value.startsWith("fail: ")) { - mismatch = true; // if an external client fails, always report it as an error - } - } - boolean besuValid = false; - String besuReason; - if (!code.isValid()) { - besuReason = ((CodeInvalid) code).getInvalidReason(); - } else if (code.getEofVersion() != 1) { - EOFLayout layout = EOFLayout.parseEOF(eofUnderTest); - if (layout.isValid()) { - besuReason = "Besu Parsing Error"; - parentCommand.out.println(layout.version()); - parentCommand.out.println(layout.invalidReason()); - parentCommand.out.println(code.getEofVersion()); - parentCommand.out.println(code.getClass().getName()); - System.exit(1); - mismatch = true; - } else { - besuReason = layout.invalidReason(); - } - } else if (EOFContainerMode.INITCODE.equals( - ((CodeV1) code).getEofLayout().containerMode().get())) { - besuReason = "Code is initcode, not runtime"; - } else { - besuReason = "OK"; - besuValid = true; - } - for (var entry : results.entrySet()) { - mismatch = - mismatch - || besuValid != entry.getValue().toUpperCase(Locale.getDefault()).startsWith("OK"); - } - if (mismatch) { - parentCommand.out.println("besu: " + besuReason); - for (var entry : results.entrySet()) { + + AtomicBoolean passHappened = new AtomicBoolean(false); + AtomicBoolean failHappened = new AtomicBoolean(false); + + Map resultMap = + fuzzingClients.stream() + .parallel() + .map( + client -> { + Stopwatch stopwatch = Stopwatch.createStarted(); + String value = client.differentialFuzz(eofUnderTestHexString); + stopwatch.stop(); + long elapsedMicros = stopwatch.elapsed(TimeUnit.MICROSECONDS); + if (elapsedMicros > timeThresholdMicros + && totalContainers > timeThresholdIterations) { + Hash name = Hash.hash(eofUnderTest); + parentCommand.out.printf( + "%s: slow validation %d µs%n", client.getName(), elapsedMicros); + try { + Files.writeString( + Path.of("slow-" + client.getName() + "-" + name + ".hex"), + eofUnderTestHexString); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + if (value.toLowerCase(Locale.ROOT).startsWith("ok")) { + passHappened.set(true); + } else if (value.toLowerCase(Locale.ROOT).startsWith("err")) { + failHappened.set(true); + } else { + // unexpected output: trigger a mismatch + passHappened.set(true); + failHappened.set(true); + } + return Map.entry(client.getName(), value); + }) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + + if (passHappened.get() && failHappened.get()) { + for (var entry : resultMap.entrySet()) { parentCommand.out.println(entry.getKey() + ": " + entry.getValue()); } parentCommand.out.println("code: " + eofUnderTest.toUnprefixedHexString()); parentCommand.out.println("size: " + eofUnderTest.size()); parentCommand.out.println(); } else { - if (besuValid) { + if (passHappened.get()) { validContainers++; } totalContainers++; diff --git a/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/ExternalClient.java b/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/FuzzingClient.java similarity index 96% rename from testfuzz/src/main/java/org/hyperledger/besu/testfuzz/ExternalClient.java rename to testfuzz/src/main/java/org/hyperledger/besu/testfuzz/FuzzingClient.java index e5505239ab..441228baf9 100644 --- a/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/ExternalClient.java +++ b/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/FuzzingClient.java @@ -14,7 +14,7 @@ */ package org.hyperledger.besu.testfuzz; -interface ExternalClient { +interface FuzzingClient { String getName(); diff --git a/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/InternalClient.java b/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/InternalClient.java new file mode 100644 index 0000000000..a6d7035fe8 --- /dev/null +++ b/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/InternalClient.java @@ -0,0 +1,65 @@ +/* + * 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.testfuzz; + +import org.hyperledger.besu.evm.Code; +import org.hyperledger.besu.evm.EVM; +import org.hyperledger.besu.evm.MainnetEVMs; +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.evm.code.EOFLayout.EOFContainerMode; +import org.hyperledger.besu.evm.internal.EvmConfiguration; + +import org.apache.tuweni.bytes.Bytes; + +class InternalClient implements FuzzingClient { + String name; + final EVM evm; + + public InternalClient(final String clientName) { + this.name = clientName; + this.evm = MainnetEVMs.pragueEOF(EvmConfiguration.DEFAULT); + } + + @Override + public String getName() { + return name; + } + + @Override + @SuppressWarnings("java:S2142") + public String differentialFuzz(final String data) { + try { + Bytes clientData = Bytes.fromHexString(data); + Code code = evm.getCodeUncached(clientData); + if (code.getEofVersion() < 1) { + return "err: legacy EVM"; + } else if (!code.isValid()) { + return "err: " + ((CodeInvalid) code).getInvalidReason(); + } else { + EOFLayout layout = ((CodeV1) code).getEofLayout(); + if (EOFContainerMode.INITCODE.equals(layout.containerMode().get())) { + return "err: initcode container when runtime mode expected"; + } + return "OK %d/%d/%d" + .formatted( + layout.getCodeSectionCount(), layout.getSubcontainerCount(), layout.dataLength()); + } + } catch (RuntimeException e) { + return "fail: " + e.getMessage(); + } + } +} diff --git a/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/SingleQueryClient.java b/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/SingleQueryClient.java index 802a6011aa..716d9fe250 100644 --- a/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/SingleQueryClient.java +++ b/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/SingleQueryClient.java @@ -24,7 +24,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; @SuppressWarnings({"java:S106", "CallToPrintStackTrace"}) // we use lots the console, on purpose -class SingleQueryClient implements ExternalClient { +class SingleQueryClient implements FuzzingClient { final String name; String[] command; Pattern okRegexp; diff --git a/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/StreamingClient.java b/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/StreamingClient.java index a59cd9326f..feefc34ffb 100644 --- a/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/StreamingClient.java +++ b/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/StreamingClient.java @@ -19,7 +19,7 @@ import java.io.IOException; import java.io.PrintWriter; import java.nio.charset.StandardCharsets; -class StreamingClient implements ExternalClient { +class StreamingClient implements FuzzingClient { final String name; final BufferedReader reader; final PrintWriter writer; From 5eb670085ae8534027ec4e21f54add21dfece0e1 Mon Sep 17 00:00:00 2001 From: Cooper Mosawi Date: Wed, 28 Aug 2024 17:39:45 +1200 Subject: [PATCH 159/259] fix truffle site (#7526) Signed-off-by: Blue Co-authored-by: Sally MacFarlane --- .../tests/simple-permissioning-smart-contract/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acceptance-tests/tests/simple-permissioning-smart-contract/README.md b/acceptance-tests/tests/simple-permissioning-smart-contract/README.md index c6a92e2cff..bad7708880 100644 --- a/acceptance-tests/tests/simple-permissioning-smart-contract/README.md +++ b/acceptance-tests/tests/simple-permissioning-smart-contract/README.md @@ -1,5 +1,5 @@ ## Pre-requisites -* [Truffle](https://truffleframework.com/) installed +* [Truffle](https://archive.trufflesuite.com/truffle/) installed ``` npm install -g truffle ``` From 078523df6414b32fb316a43efeab64f2e66053fd Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Wed, 28 Aug 2024 00:41:33 -0600 Subject: [PATCH 160/259] Refactor max code size (#7523) * Refactor max code size Refactor the max code size to no longer be a part of the operation but instead is queried from the EVM version specification. Signed-off-by: Danno Ferrin --------- Signed-off-by: Danno Ferrin Co-authored-by: Sally MacFarlane --- .../org/hyperledger/besu/evm/ClassicEVMs.java | 5 ----- .../org/hyperledger/besu/evm/MainnetEVMs.java | 12 ++---------- .../evm/operation/AbstractCreateOperation.java | 8 +------- .../besu/evm/operation/Create2Operation.java | 5 ++--- .../besu/evm/operation/CreateOperation.java | 5 ++--- .../besu/evm/operation/EOFCreateOperation.java | 2 +- .../operation/AbstractCreateOperationTest.java | 7 +++---- .../evm/operation/Create2OperationTest.java | 10 +++------- .../besu/evm/operation/CreateOperationTest.java | 17 +++++++---------- 9 files changed, 21 insertions(+), 50 deletions(-) diff --git a/evm/src/main/java/org/hyperledger/besu/evm/ClassicEVMs.java b/evm/src/main/java/org/hyperledger/besu/evm/ClassicEVMs.java index 7cd02bbf65..07b0f2c87f 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/ClassicEVMs.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/ClassicEVMs.java @@ -14,13 +14,10 @@ */ package org.hyperledger.besu.evm; -import static org.hyperledger.besu.evm.MainnetEVMs.SHANGHAI_INIT_CODE_SIZE_LIMIT; import static org.hyperledger.besu.evm.MainnetEVMs.registerIstanbulOperations; import org.hyperledger.besu.evm.gascalculator.GasCalculator; import org.hyperledger.besu.evm.internal.EvmConfiguration; -import org.hyperledger.besu.evm.operation.Create2Operation; -import org.hyperledger.besu.evm.operation.CreateOperation; import org.hyperledger.besu.evm.operation.OperationRegistry; import org.hyperledger.besu.evm.operation.Push0Operation; @@ -62,8 +59,6 @@ public class ClassicEVMs { OperationRegistry registry = new OperationRegistry(); registerIstanbulOperations(registry, gasCalculator, chainId); registry.put(new Push0Operation(gasCalculator)); - registry.put(new CreateOperation(gasCalculator, SHANGHAI_INIT_CODE_SIZE_LIMIT)); - registry.put(new Create2Operation(gasCalculator, SHANGHAI_INIT_CODE_SIZE_LIMIT)); return registry; } } 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 06ef2da253..998776d714 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/MainnetEVMs.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/MainnetEVMs.java @@ -147,12 +147,6 @@ public class MainnetEVMs { /** The constant DEV_NET_CHAIN_ID. */ public static final BigInteger DEV_NET_CHAIN_ID = BigInteger.valueOf(1337); - /** The constant SPURIOUS_DRAGON_CONTRACT_SIZE_LIMIT. */ - public static final int SPURIOUS_DRAGON_CONTRACT_SIZE_LIMIT = 0x6000; - - /** The constant SHANGHAI_INIT_CODE_SIZE_LIMIT. */ - public static final int SHANGHAI_INIT_CODE_SIZE_LIMIT = 2 * SPURIOUS_DRAGON_CONTRACT_SIZE_LIMIT; - private MainnetEVMs() { // utility class } @@ -264,7 +258,7 @@ public class MainnetEVMs { registry.put(new InvalidOperation(gasCalculator)); registry.put(new StopOperation(gasCalculator)); registry.put(new SelfDestructOperation(gasCalculator)); - registry.put(new CreateOperation(gasCalculator, Integer.MAX_VALUE)); + registry.put(new CreateOperation(gasCalculator)); registry.put(new CallOperation(gasCalculator)); registry.put(new CallCodeOperation(gasCalculator)); @@ -474,7 +468,7 @@ public class MainnetEVMs { public static void registerConstantinopleOperations( final OperationRegistry registry, final GasCalculator gasCalculator) { registerByzantiumOperations(registry, gasCalculator); - registry.put(new Create2Operation(gasCalculator, Integer.MAX_VALUE)); + registry.put(new Create2Operation(gasCalculator)); registry.put(new SarOperation(gasCalculator)); registry.put(new ShlOperation(gasCalculator)); registry.put(new ShrOperation(gasCalculator)); @@ -809,8 +803,6 @@ public class MainnetEVMs { final BigInteger chainID) { registerParisOperations(registry, gasCalculator, chainID); registry.put(new Push0Operation(gasCalculator)); - registry.put(new CreateOperation(gasCalculator, SHANGHAI_INIT_CODE_SIZE_LIMIT)); - registry.put(new Create2Operation(gasCalculator, SHANGHAI_INIT_CODE_SIZE_LIMIT)); } /** diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCreateOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCreateOperation.java index 3bc712341b..3a78016f2d 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCreateOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCreateOperation.java @@ -45,9 +45,6 @@ public abstract class AbstractCreateOperation extends AbstractOperation { protected static final OperationResult INVALID_OPERATION = new OperationResult(0L, ExceptionalHaltReason.INVALID_OPERATION); - /** The maximum init code size */ - protected final int maxInitcodeSize; - /** The EOF Version this create operation requires initcode to be in */ protected final int eofVersion; @@ -59,7 +56,6 @@ public abstract class AbstractCreateOperation extends AbstractOperation { * @param stackItemsConsumed the stack items consumed * @param stackItemsProduced the stack items produced * @param gasCalculator the gas calculator - * @param maxInitcodeSize Maximum init code size * @param eofVersion the EOF version this create operation is valid in */ protected AbstractCreateOperation( @@ -68,10 +64,8 @@ public abstract class AbstractCreateOperation extends AbstractOperation { final int stackItemsConsumed, final int stackItemsProduced, final GasCalculator gasCalculator, - final int maxInitcodeSize, final int eofVersion) { super(opcode, name, stackItemsConsumed, stackItemsProduced, gasCalculator); - this.maxInitcodeSize = maxInitcodeSize; this.eofVersion = eofVersion; } @@ -103,7 +97,7 @@ public abstract class AbstractCreateOperation extends AbstractOperation { Code code = codeSupplier.get(); - if (code != null && code.getSize() > maxInitcodeSize) { + if (code != null && code.getSize() > evm.getEvmVersion().getMaxInitcodeSize()) { frame.popStackItems(getStackItemsConsumed()); return new OperationResult(cost, ExceptionalHaltReason.CODE_TOO_LARGE); } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/Create2Operation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/Create2Operation.java index 1fe3ef6469..3338a1e26a 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/Create2Operation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/Create2Operation.java @@ -39,10 +39,9 @@ public class Create2Operation extends AbstractCreateOperation { * Instantiates a new Create2 operation. * * @param gasCalculator the gas calculator - * @param maxInitcodeSize Maximum init code size */ - public Create2Operation(final GasCalculator gasCalculator, final int maxInitcodeSize) { - super(0xF5, "CREATE2", 4, 1, gasCalculator, maxInitcodeSize, 0); + public Create2Operation(final GasCalculator gasCalculator) { + super(0xF5, "CREATE2", 4, 1, gasCalculator, 0); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/CreateOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/CreateOperation.java index a82288fff7..9537c5012d 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/CreateOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/CreateOperation.java @@ -36,10 +36,9 @@ public class CreateOperation extends AbstractCreateOperation { * Instantiates a new Create operation. * * @param gasCalculator the gas calculator - * @param maxInitcodeSize Maximum init code size */ - public CreateOperation(final GasCalculator gasCalculator, final int maxInitcodeSize) { - super(0xF0, "CREATE", 3, 1, gasCalculator, maxInitcodeSize, 0); + public CreateOperation(final GasCalculator gasCalculator) { + super(0xF0, "CREATE", 3, 1, gasCalculator, 0); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/EOFCreateOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/EOFCreateOperation.java index 11d361e54c..3ea3ef1407 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/EOFCreateOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/EOFCreateOperation.java @@ -44,7 +44,7 @@ public class EOFCreateOperation extends AbstractCreateOperation { * @param gasCalculator the gas calculator */ public EOFCreateOperation(final GasCalculator gasCalculator) { - super(OPCODE, "EOFCREATE", 4, 1, gasCalculator, Integer.MAX_VALUE, 1); + super(OPCODE, "EOFCREATE", 4, 1, gasCalculator, 1); } @Override diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operation/AbstractCreateOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operation/AbstractCreateOperationTest.java index d066b4e9ab..4c5da84f31 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operation/AbstractCreateOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operation/AbstractCreateOperationTest.java @@ -57,7 +57,7 @@ class AbstractCreateOperationTest { private final MutableAccount account = mock(MutableAccount.class); private final MutableAccount newAccount = mock(MutableAccount.class); private final FakeCreateOperation operation = - new FakeCreateOperation(new ConstantinopleGasCalculator(), Integer.MAX_VALUE); + new FakeCreateOperation(new ConstantinopleGasCalculator()); private static final Bytes SIMPLE_CREATE = Bytes.fromHexString( @@ -100,10 +100,9 @@ class AbstractCreateOperationTest { * Instantiates a new Create operation. * * @param gasCalculator the gas calculator - * @param maxInitcodeSize Maximum init code size */ - public FakeCreateOperation(final GasCalculator gasCalculator, final int maxInitcodeSize) { - super(0xEF, "FAKECREATE", 3, 1, gasCalculator, maxInitcodeSize, 0); + public FakeCreateOperation(final GasCalculator gasCalculator) { + super(0xEF, "FAKECREATE", 3, 1, gasCalculator, 0); } @Override 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 a08fd2916f..4b2a5449ed 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 @@ -60,11 +60,7 @@ public class Create2OperationTest { private final MutableAccount newAccount = mock(MutableAccount.class); private final Create2Operation operation = - new Create2Operation(new ConstantinopleGasCalculator(), Integer.MAX_VALUE); - - private final Create2Operation maxInitCodeOperation = - new Create2Operation( - new ConstantinopleGasCalculator(), MainnetEVMs.SHANGHAI_INIT_CODE_SIZE_LIMIT); + new Create2Operation(new ConstantinopleGasCalculator()); private static final String TOPIC = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; // 32 FFs @@ -221,7 +217,7 @@ public class Create2OperationTest { when(worldUpdater.updater()).thenReturn(worldUpdater); final EVM myEVM = MainnetEVMs.shanghai(DEV_NET_CHAIN_ID, EvmConfiguration.DEFAULT); - var result = maxInitCodeOperation.execute(messageFrame, myEVM); + var result = operation.execute(messageFrame, myEVM); final MessageFrame createFrame = messageFrame.getMessageFrameStack().peek(); final ContractCreationProcessor ccp = new ContractCreationProcessor(myEVM, false, List.of(), 0, List.of()); @@ -250,7 +246,7 @@ public class Create2OperationTest { when(worldUpdater.updater()).thenReturn(worldUpdater); final EVM evm = MainnetEVMs.shanghai(DEV_NET_CHAIN_ID, EvmConfiguration.DEFAULT); - var result = maxInitCodeOperation.execute(messageFrame, evm); + var result = operation.execute(messageFrame, evm); assertThat(result.getHaltReason()).isEqualTo(CODE_TOO_LARGE); } 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 c10d8f3d6c..482df37fd6 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 @@ -52,12 +52,7 @@ class CreateOperationTest { private final WorldUpdater worldUpdater = mock(WorldUpdater.class); private final MutableAccount account = mock(MutableAccount.class); private final MutableAccount newAccount = mock(MutableAccount.class); - private final CreateOperation operation = - new CreateOperation(new ConstantinopleGasCalculator(), Integer.MAX_VALUE); - private final CreateOperation maxInitCodeOperation = - new CreateOperation( - new ConstantinopleGasCalculator(), MainnetEVMs.SHANGHAI_INIT_CODE_SIZE_LIMIT); - private final EVM evm = MainnetEVMs.pragueEOF(EvmConfiguration.DEFAULT); + private final CreateOperation operation = new CreateOperation(new ConstantinopleGasCalculator()); private static final String TOPIC = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; // 32 FFs @@ -82,7 +77,7 @@ class CreateOperationTest { @Test void createFromMemoryMutationSafe() { - // Given: Execute a CREATE operation with a contract that logs in the constructor + // Given: Execute a CREATE operation with a contract that logs in the constructor final UInt256 memoryOffset = UInt256.fromHexString("0xFF"); final UInt256 memoryLength = UInt256.valueOf(SIMPLE_CREATE.size()); final MessageFrame messageFrame = testMemoryFrame(memoryOffset, memoryLength, UInt256.ZERO, 1); @@ -190,7 +185,7 @@ class CreateOperationTest { when(worldUpdater.updater()).thenReturn(worldUpdater); final EVM evm = MainnetEVMs.shanghai(DEV_NET_CHAIN_ID, EvmConfiguration.DEFAULT); - var result = maxInitCodeOperation.execute(messageFrame, evm); + var result = operation.execute(messageFrame, evm); final MessageFrame createFrame = messageFrame.getMessageFrameStack().peek(); final ContractCreationProcessor ccp = new ContractCreationProcessor(evm, false, List.of(), 0, List.of()); @@ -218,17 +213,18 @@ class CreateOperationTest { when(worldUpdater.updater()).thenReturn(worldUpdater); final EVM evm = MainnetEVMs.shanghai(DEV_NET_CHAIN_ID, EvmConfiguration.DEFAULT); - var result = maxInitCodeOperation.execute(messageFrame, evm); + var result = operation.execute(messageFrame, evm); assertThat(result.getHaltReason()).isEqualTo(CODE_TOO_LARGE); } @Test void eofV1CannotCall() { + final EVM pragueEvm = MainnetEVMs.pragueEOF(EvmConfiguration.DEFAULT); final UInt256 memoryOffset = UInt256.fromHexString("0xFF"); final UInt256 memoryLength = UInt256.valueOf(SIMPLE_CREATE.size()); final MessageFrame messageFrame = new TestMessageFrameBuilder() - .code(evm.getCodeUncached(SIMPLE_EOF)) + .code(pragueEvm.getCodeUncached(SIMPLE_EOF)) .pushStackItem(memoryLength) .pushStackItem(memoryOffset) .pushStackItem(Bytes.EMPTY) @@ -252,6 +248,7 @@ class CreateOperationTest { final UInt256 memoryLength, final UInt256 value, final int depth) { + final EVM evm = MainnetEVMs.pragueEOF(EvmConfiguration.DEFAULT); final MessageFrame messageFrame = MessageFrame.builder() .type(MessageFrame.Type.CONTRACT_CREATION) From be8f4945b0772b035d10a2a07ada69c178acb7b6 Mon Sep 17 00:00:00 2001 From: Stefan Pingel <16143240+pinges@users.noreply.github.com> Date: Thu, 29 Aug 2024 00:30:56 +1000 Subject: [PATCH 161/259] Metrics for sync phases (#7390) * add metrics to measure the time for chain and world state sync Signed-off-by: stefan.pingel@consensys.net Signed-off-by: Stefan Pingel <16143240+pinges@users.noreply.github.com> Co-authored-by: Simon Dudley Co-authored-by: Sally MacFarlane --- .../WorldStateDownloaderBenchmark.java | 4 +- .../eth/sync/DefaultSynchronizer.java | 23 ++++- .../eth/sync/PipelineChainDownloader.java | 9 +- .../CheckpointDownloaderFactory.java | 10 +- .../checkpointsync/CheckpointSyncActions.java | 7 +- .../CheckpointSyncChainDownloader.java | 7 +- .../eth/sync/fastsync/FastSyncActions.java | 7 +- .../fastsync/FastSyncChainDownloader.java | 7 +- .../eth/sync/fastsync/FastSyncDownloader.java | 10 +- .../worldstate/FastDownloaderFactory.java | 10 +- .../worldstate/FastWorldDownloadState.java | 9 +- .../worldstate/FastWorldStateDownloader.java | 9 +- .../fullsync/FullSyncChainDownloader.java | 7 +- .../eth/sync/fullsync/FullSyncDownloader.java | 7 +- .../sync/snapsync/SnapDownloaderFactory.java | 15 +-- .../eth/sync/snapsync/SnapSyncDownloader.java | 7 +- .../sync/snapsync/SnapWorldDownloadState.java | 89 +++++++++--------- .../snapsync/SnapWorldStateDownloader.java | 9 +- .../sync/worldstate/WorldDownloadState.java | 6 +- .../eth/sync/PipelineChainDownloaderTest.java | 5 +- .../CheckPointSyncChainDownloaderTest.java | 4 +- .../fastsync/FastDownloaderFactoryTest.java | 16 +++- .../fastsync/FastSyncChainDownloaderTest.java | 4 +- .../sync/fastsync/FastSyncDownloaderTest.java | 83 ++++++++++++----- .../FastWorldDownloadStateTest.java | 4 +- .../FastWorldStateDownloaderTest.java | 4 +- .../FullSyncChainDownloaderForkTest.java | 4 +- .../fullsync/FullSyncChainDownloaderTest.java | 4 +- ...DownloaderTotalTerminalDifficultyTest.java | 4 +- .../sync/fullsync/FullSyncDownloaderTest.java | 4 +- .../snapsync/SnapWorldDownloadStateTest.java | 4 +- .../besu/metrics/SyncDurationMetrics.java | 91 +++++++++++++++++++ .../besu/metrics/noop/NoOpMetricsSystem.java | 9 ++ .../opentelemetry/OpenTelemetrySystem.java | 9 ++ .../prometheus/PrometheusMetricsSystem.java | 22 +++++ .../prometheus/PrometheusSimpleTimer.java | 35 +++++++ .../besu/metrics/StubMetricsSystem.java | 9 ++ plugin-api/build.gradle | 2 +- .../besu/plugin/services/MetricsSystem.java | 28 ++++++ 39 files changed, 473 insertions(+), 124 deletions(-) create mode 100644 metrics/core/src/main/java/org/hyperledger/besu/metrics/SyncDurationMetrics.java create mode 100644 metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusSimpleTimer.java diff --git a/ethereum/eth/src/jmh/java/org/hyperledger/besu/ethereum/eth/sync/worldstate/WorldStateDownloaderBenchmark.java b/ethereum/eth/src/jmh/java/org/hyperledger/besu/ethereum/eth/sync/worldstate/WorldStateDownloaderBenchmark.java index 04d4af81a9..079b6ba47f 100644 --- a/ethereum/eth/src/jmh/java/org/hyperledger/besu/ethereum/eth/sync/worldstate/WorldStateDownloaderBenchmark.java +++ b/ethereum/eth/src/jmh/java/org/hyperledger/besu/ethereum/eth/sync/worldstate/WorldStateDownloaderBenchmark.java @@ -43,6 +43,7 @@ import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; import org.hyperledger.besu.metrics.ObservableMetricsSystem; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import org.hyperledger.besu.plugin.services.storage.rocksdb.RocksDBKeyValueStorageFactory; import org.hyperledger.besu.plugin.services.storage.rocksdb.RocksDBMetricsFactory; @@ -120,7 +121,8 @@ public class WorldStateDownloaderBenchmark { syncConfig.getWorldStateMaxRequestsWithoutProgress(), syncConfig.getWorldStateMinMillisBeforeStalling(), Clock.fixed(Instant.ofEpochSecond(1000), ZoneOffset.UTC), - metricsSystem); + metricsSystem, + SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS); } private Hash createExistingWorldState() { 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 a41ad1812b..b7dc2adb16 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 @@ -38,6 +38,7 @@ import org.hyperledger.besu.ethereum.storage.StorageProvider; import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.BonsaiWorldStateProvider; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; import org.hyperledger.besu.metrics.BesuMetricCategory; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.plugin.data.SyncStatus; import org.hyperledger.besu.plugin.services.BesuEvents; import org.hyperledger.besu.plugin.services.BesuEvents.SyncStatusListener; @@ -67,6 +68,7 @@ public class DefaultSynchronizer implements Synchronizer, UnverifiedForkchoiceLi private final AtomicBoolean running = new AtomicBoolean(false); private final Optional blockPropagationManager; private final Supplier>> fastSyncFactory; + private final SyncDurationMetrics syncDurationMetrics; private Optional> fastSyncDownloader; private final Optional fullSyncDownloader; private final ProtocolContext protocolContext; @@ -118,6 +120,8 @@ public class DefaultSynchronizer implements Synchronizer, UnverifiedForkchoiceLi metricsSystem, blockBroadcaster)); + syncDurationMetrics = new SyncDurationMetrics(metricsSystem); + this.fullSyncDownloader = terminationCondition.shouldStopDownload() ? Optional.empty() @@ -129,7 +133,8 @@ public class DefaultSynchronizer implements Synchronizer, UnverifiedForkchoiceLi ethContext, syncState, metricsSystem, - terminationCondition)); + terminationCondition, + syncDurationMetrics)); if (SyncMode.FAST.equals(syncConfig.getSyncMode())) { this.fastSyncFactory = @@ -144,7 +149,8 @@ public class DefaultSynchronizer implements Synchronizer, UnverifiedForkchoiceLi ethContext, worldStateStorageCoordinator, syncState, - clock); + clock, + syncDurationMetrics); } else if (syncConfig.getSyncMode() == SyncMode.CHECKPOINT) { this.fastSyncFactory = () -> @@ -159,7 +165,8 @@ public class DefaultSynchronizer implements Synchronizer, UnverifiedForkchoiceLi ethContext, worldStateStorageCoordinator, syncState, - clock); + clock, + syncDurationMetrics); } else { this.fastSyncFactory = () -> @@ -174,7 +181,8 @@ public class DefaultSynchronizer implements Synchronizer, UnverifiedForkchoiceLi ethContext, worldStateStorageCoordinator, syncState, - clock); + clock, + syncDurationMetrics); } // create a non-resync fast sync downloader: @@ -205,6 +213,9 @@ public class DefaultSynchronizer implements Synchronizer, UnverifiedForkchoiceLi public CompletableFuture start() { if (running.compareAndSet(false, true)) { LOG.info("Starting synchronizer."); + + syncDurationMetrics.startTimer(SyncDurationMetrics.Labels.TOTAL_SYNC_DURATION); + blockPropagationManager.ifPresent( manager -> { if (!manager.isRunning()) { @@ -390,6 +401,10 @@ public class DefaultSynchronizer implements Synchronizer, UnverifiedForkchoiceLi blockPropagationManager.ifPresent(BlockPropagationManager::stop); LOG.info("Stopping the pruner."); running.set(false); + + syncDurationMetrics.stopTimer(SyncDurationMetrics.Labels.FLAT_DB_HEAL); + syncDurationMetrics.stopTimer(SyncDurationMetrics.Labels.TOTAL_SYNC_DURATION); + return null; } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/PipelineChainDownloader.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/PipelineChainDownloader.java index bfec1435ce..8f2ee1d48a 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/PipelineChainDownloader.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/PipelineChainDownloader.java @@ -24,6 +24,7 @@ import org.hyperledger.besu.ethereum.eth.sync.state.SyncTarget; import org.hyperledger.besu.ethereum.eth.sync.tasks.exceptions.InvalidBlockException; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.messages.DisconnectMessage.DisconnectReason; import org.hyperledger.besu.metrics.BesuMetricCategory; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.plugin.services.MetricsSystem; import org.hyperledger.besu.plugin.services.metrics.Counter; import org.hyperledger.besu.plugin.services.metrics.LabelledMetric; @@ -51,6 +52,7 @@ public class PipelineChainDownloader implements ChainDownloader { private final AtomicBoolean cancelled = new AtomicBoolean(false); private final Counter pipelineCompleteCounter; private final Counter pipelineErrorCounter; + private final SyncDurationMetrics syncDurationMetrics; private Pipeline currentDownloadPipeline; public PipelineChainDownloader( @@ -58,11 +60,13 @@ public class PipelineChainDownloader implements ChainDownloader { final AbstractSyncTargetManager syncTargetManager, final DownloadPipelineFactory downloadPipelineFactory, final EthScheduler scheduler, - final MetricsSystem metricsSystem) { + final MetricsSystem metricsSystem, + final SyncDurationMetrics syncDurationMetrics) { this.syncState = syncState; this.syncTargetManager = syncTargetManager; this.downloadPipelineFactory = downloadPipelineFactory; this.scheduler = scheduler; + this.syncDurationMetrics = syncDurationMetrics; final LabelledMetric labelledCounter = metricsSystem.createLabelledCounter( @@ -79,6 +83,9 @@ public class PipelineChainDownloader implements ChainDownloader { if (!started.compareAndSet(false, true)) { throw new IllegalStateException("Cannot start a chain download twice"); } + + syncDurationMetrics.startTimer(SyncDurationMetrics.Labels.CHAIN_DOWNLOAD_DURATION); + return performDownload(); } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/checkpointsync/CheckpointDownloaderFactory.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/checkpointsync/CheckpointDownloaderFactory.java index 8668f2beff..03df47e440 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/checkpointsync/CheckpointDownloaderFactory.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/checkpointsync/CheckpointDownloaderFactory.java @@ -36,6 +36,7 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ScheduleBasedBlockHeaderFunctions; import org.hyperledger.besu.ethereum.trie.CompactEncoding; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.plugin.services.MetricsSystem; import org.hyperledger.besu.services.tasks.InMemoryTasksPriorityQueues; @@ -62,7 +63,8 @@ public class CheckpointDownloaderFactory extends SnapDownloaderFactory { final EthContext ethContext, final WorldStateStorageCoordinator worldStateStorageCoordinator, final SyncState syncState, - final Clock clock) { + final Clock clock, + final SyncDurationMetrics syncDurationMetrics) { final Path fastSyncDataDirectory = dataDirectory.resolve(FAST_SYNC_FOLDER); final FastSyncStateStorage fastSyncStateStorage = @@ -149,7 +151,8 @@ public class CheckpointDownloaderFactory extends SnapDownloaderFactory { syncConfig.getWorldStateMaxRequestsWithoutProgress(), syncConfig.getWorldStateMinMillisBeforeStalling(), clock, - metricsSystem); + metricsSystem, + syncDurationMetrics); final FastSyncDownloader fastSyncDownloader = new SnapSyncDownloader( fastSyncActions, @@ -158,7 +161,8 @@ public class CheckpointDownloaderFactory extends SnapDownloaderFactory { fastSyncStateStorage, snapTaskCollection, fastSyncDataDirectory, - snapSyncState); + snapSyncState, + syncDurationMetrics); syncState.setWorldStateDownloadStatus(snapWorldStateDownloader); return Optional.of(fastSyncDownloader); } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/checkpointsync/CheckpointSyncActions.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/checkpointsync/CheckpointSyncActions.java index bfe6a308a2..5096b74e24 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/checkpointsync/CheckpointSyncActions.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/checkpointsync/CheckpointSyncActions.java @@ -24,6 +24,7 @@ import org.hyperledger.besu.ethereum.eth.sync.fastsync.FastSyncState; import org.hyperledger.besu.ethereum.eth.sync.state.SyncState; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.plugin.services.MetricsSystem; public class CheckpointSyncActions extends FastSyncActions { @@ -48,7 +49,8 @@ public class CheckpointSyncActions extends FastSyncActions { } @Override - public ChainDownloader createChainDownloader(final FastSyncState currentState) { + public ChainDownloader createChainDownloader( + final FastSyncState currentState, final SyncDurationMetrics syncDurationMetrics) { return CheckpointSyncChainDownloader.create( syncConfig, worldStateStorageCoordinator, @@ -57,6 +59,7 @@ public class CheckpointSyncActions extends FastSyncActions { ethContext, syncState, metricsSystem, - currentState); + currentState, + syncDurationMetrics); } } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/checkpointsync/CheckpointSyncChainDownloader.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/checkpointsync/CheckpointSyncChainDownloader.java index aaafac5ac9..5450b9e5a4 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/checkpointsync/CheckpointSyncChainDownloader.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/checkpointsync/CheckpointSyncChainDownloader.java @@ -25,6 +25,7 @@ import org.hyperledger.besu.ethereum.eth.sync.fastsync.SyncTargetManager; import org.hyperledger.besu.ethereum.eth.sync.state.SyncState; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.plugin.services.MetricsSystem; public class CheckpointSyncChainDownloader extends FastSyncChainDownloader { @@ -37,7 +38,8 @@ public class CheckpointSyncChainDownloader extends FastSyncChainDownloader { final EthContext ethContext, final SyncState syncState, final MetricsSystem metricsSystem, - final FastSyncState fastSyncState) { + final FastSyncState fastSyncState, + final SyncDurationMetrics syncDurationMetrics) { final SyncTargetManager syncTargetManager = new SyncTargetManager( @@ -55,6 +57,7 @@ public class CheckpointSyncChainDownloader extends FastSyncChainDownloader { new CheckpointSyncDownloadPipelineFactory( config, protocolSchedule, protocolContext, ethContext, fastSyncState, metricsSystem), ethContext.getScheduler(), - metricsSystem); + metricsSystem, + syncDurationMetrics); } } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncActions.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncActions.java index 06bf8aace6..7f6bbae3f3 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncActions.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncActions.java @@ -28,6 +28,7 @@ import org.hyperledger.besu.ethereum.eth.sync.tasks.RetryingGetHeaderFromPeerByH import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; import org.hyperledger.besu.metrics.BesuMetricCategory; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.plugin.services.MetricsSystem; import org.hyperledger.besu.plugin.services.metrics.Counter; @@ -155,7 +156,8 @@ public class FastSyncActions { return fastSyncState; } - public ChainDownloader createChainDownloader(final FastSyncState currentState) { + public ChainDownloader createChainDownloader( + final FastSyncState currentState, final SyncDurationMetrics syncDurationMetrics) { return FastSyncChainDownloader.create( syncConfig, worldStateStorageCoordinator, @@ -164,7 +166,8 @@ public class FastSyncActions { ethContext, syncState, metricsSystem, - currentState); + currentState, + syncDurationMetrics); } private CompletableFuture downloadPivotBlockHeader(final Hash hash) { diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncChainDownloader.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncChainDownloader.java index 36f56ccfd8..c36ff7cb48 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncChainDownloader.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncChainDownloader.java @@ -22,6 +22,7 @@ import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration; import org.hyperledger.besu.ethereum.eth.sync.state.SyncState; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.plugin.services.MetricsSystem; public class FastSyncChainDownloader { @@ -36,7 +37,8 @@ public class FastSyncChainDownloader { final EthContext ethContext, final SyncState syncState, final MetricsSystem metricsSystem, - final FastSyncState fastSyncState) { + final FastSyncState fastSyncState, + final SyncDurationMetrics syncDurationMetrics) { final SyncTargetManager syncTargetManager = new SyncTargetManager( @@ -53,6 +55,7 @@ public class FastSyncChainDownloader { new FastSyncDownloadPipelineFactory( config, protocolSchedule, protocolContext, ethContext, fastSyncState, metricsSystem), ethContext.getScheduler(), - metricsSystem); + metricsSystem, + syncDurationMetrics); } } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncDownloader.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncDownloader.java index 565824a780..0aaeefc6d6 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncDownloader.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncDownloader.java @@ -23,6 +23,7 @@ import org.hyperledger.besu.ethereum.eth.sync.worldstate.StalledDownloadExceptio import org.hyperledger.besu.ethereum.eth.sync.worldstate.WorldStateDownloader; import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.BonsaiWorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; import org.hyperledger.besu.services.tasks.TaskCollection; import org.hyperledger.besu.util.ExceptionUtils; @@ -52,6 +53,7 @@ public class FastSyncDownloader { private final WorldStateDownloader worldStateDownloader; private final TaskCollection taskCollection; private final Path fastSyncDataDirectory; + private final SyncDurationMetrics syncDurationMetrics; private volatile Optional trailingPeerRequirements = Optional.empty(); private final AtomicBoolean running = new AtomicBoolean(false); @@ -66,7 +68,8 @@ public class FastSyncDownloader { final FastSyncStateStorage fastSyncStateStorage, final TaskCollection taskCollection, final Path fastSyncDataDirectory, - final FastSyncState initialFastSyncState) { + final FastSyncState initialFastSyncState, + final SyncDurationMetrics syncDurationMetrics) { this.fastSyncActions = fastSyncActions; this.worldStateStorageCoordinator = worldStateStorageCoordinator; this.worldStateDownloader = worldStateDownloader; @@ -74,6 +77,7 @@ public class FastSyncDownloader { this.taskCollection = taskCollection; this.fastSyncDataDirectory = fastSyncDataDirectory; this.initialFastSyncState = initialFastSyncState; + this.syncDurationMetrics = syncDurationMetrics; } public CompletableFuture start() { @@ -81,6 +85,7 @@ public class FastSyncDownloader { throw new IllegalStateException("SyncDownloader already running"); } LOG.info("Starting pivot-based sync"); + return start(initialFastSyncState); } @@ -189,7 +194,8 @@ public class FastSyncDownloader { } final CompletableFuture worldStateFuture = worldStateDownloader.run(fastSyncActions, currentState); - final ChainDownloader chainDownloader = fastSyncActions.createChainDownloader(currentState); + final ChainDownloader chainDownloader = + fastSyncActions.createChainDownloader(currentState, syncDurationMetrics); final CompletableFuture chainFuture = chainDownloader.start(); // If either download fails, cancel the other one. diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/worldstate/FastDownloaderFactory.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/worldstate/FastDownloaderFactory.java index bf9f28db6c..8b71a57885 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/worldstate/FastDownloaderFactory.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/worldstate/FastDownloaderFactory.java @@ -30,6 +30,7 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ScheduleBasedBlockHeaderFunctions; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; import org.hyperledger.besu.metrics.BesuMetricCategory; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.plugin.services.MetricsSystem; import org.hyperledger.besu.services.tasks.InMemoryTasksPriorityQueues; @@ -60,7 +61,8 @@ public class FastDownloaderFactory { final EthContext ethContext, final WorldStateStorageCoordinator worldStateStorageCoordinator, final SyncState syncState, - final Clock clock) { + final Clock clock, + final SyncDurationMetrics syncDurationMetrics) { final Path fastSyncDataDirectory = dataDirectory.resolve(FAST_SYNC_FOLDER); final FastSyncStateStorage fastSyncStateStorage = @@ -114,7 +116,8 @@ public class FastDownloaderFactory { syncConfig.getWorldStateMaxRequestsWithoutProgress(), syncConfig.getWorldStateMinMillisBeforeStalling(), clock, - metricsSystem); + metricsSystem, + syncDurationMetrics); final FastSyncDownloader fastSyncDownloader = new FastSyncDownloader<>( new FastSyncActions( @@ -131,7 +134,8 @@ public class FastDownloaderFactory { fastSyncStateStorage, taskCollection, fastSyncDataDirectory, - fastSyncState); + fastSyncState, + syncDurationMetrics); syncState.setWorldStateDownloadStatus(worldStateDownloader); return Optional.of(fastSyncDownloader); } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/worldstate/FastWorldDownloadState.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/worldstate/FastWorldDownloadState.java index 3bd6a76c79..307f98e7f5 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/worldstate/FastWorldDownloadState.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/worldstate/FastWorldDownloadState.java @@ -20,6 +20,7 @@ import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.eth.sync.worldstate.WorldDownloadState; import org.hyperledger.besu.ethereum.worldstate.WorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.services.tasks.InMemoryTasksPriorityQueues; import java.time.Clock; @@ -37,13 +38,15 @@ public class FastWorldDownloadState extends WorldDownloadState final InMemoryTasksPriorityQueues pendingRequests, final int maxRequestsWithoutProgress, final long minMillisBeforeStalling, - final Clock clock) { + final Clock clock, + final SyncDurationMetrics syncDurationMetrics) { super( worldStateStorageCoordinator, pendingRequests, maxRequestsWithoutProgress, minMillisBeforeStalling, - clock); + clock, + syncDurationMetrics); } @Override @@ -70,7 +73,9 @@ public class FastWorldDownloadState extends WorldDownloadState // THere are no more inputs to process so make sure we wake up any threads waiting to dequeue // so they can give up waiting. notifyAll(); + LOG.info("Finished downloading world state from peers"); + return true; } else { return false; diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/worldstate/FastWorldStateDownloader.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/worldstate/FastWorldStateDownloader.java index 559ade5900..341f1f66ac 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/worldstate/FastWorldStateDownloader.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/worldstate/FastWorldStateDownloader.java @@ -22,6 +22,7 @@ import org.hyperledger.besu.ethereum.eth.sync.fastsync.FastSyncState; import org.hyperledger.besu.ethereum.eth.sync.worldstate.WorldStateDownloader; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; import org.hyperledger.besu.metrics.BesuMetricCategory; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.plugin.services.MetricsSystem; import org.hyperledger.besu.services.tasks.InMemoryTasksPriorityQueues; @@ -51,6 +52,7 @@ public class FastWorldStateDownloader implements WorldStateDownloader { private final WorldStateStorageCoordinator worldStateStorageCoordinator; private final AtomicReference downloadState = new AtomicReference<>(); + private final SyncDurationMetrics syncDurationMetrics; private Optional maybeCompleteTask = Optional.empty(); @@ -63,7 +65,8 @@ public class FastWorldStateDownloader implements WorldStateDownloader { final int maxNodeRequestsWithoutProgress, final long minMillisBeforeStalling, final Clock clock, - final MetricsSystem metricsSystem) { + final MetricsSystem metricsSystem, + final SyncDurationMetrics syncDurationMetrics) { this.ethContext = ethContext; this.worldStateStorageCoordinator = worldStateStorageCoordinator; this.taskCollection = taskCollection; @@ -73,6 +76,7 @@ public class FastWorldStateDownloader implements WorldStateDownloader { this.minMillisBeforeStalling = minMillisBeforeStalling; this.clock = clock; this.metricsSystem = metricsSystem; + this.syncDurationMetrics = syncDurationMetrics; metricsSystem.createIntegerGauge( BesuMetricCategory.SYNCHRONIZER, @@ -137,7 +141,8 @@ public class FastWorldStateDownloader implements WorldStateDownloader { taskCollection, maxNodeRequestsWithoutProgress, minMillisBeforeStalling, - clock); + clock, + syncDurationMetrics); this.downloadState.set(newDownloadState); if (!newDownloadState.downloadWasResumed()) { diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncChainDownloader.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncChainDownloader.java index f4a7011626..3a0f6edb08 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncChainDownloader.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncChainDownloader.java @@ -21,6 +21,7 @@ import org.hyperledger.besu.ethereum.eth.sync.PipelineChainDownloader; import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration; import org.hyperledger.besu.ethereum.eth.sync.state.SyncState; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.plugin.services.MetricsSystem; public class FullSyncChainDownloader { @@ -33,7 +34,8 @@ public class FullSyncChainDownloader { final EthContext ethContext, final SyncState syncState, final MetricsSystem metricsSystem, - final SyncTerminationCondition terminationCondition) { + final SyncTerminationCondition terminationCondition, + final SyncDurationMetrics syncDurationMetrics) { final FullSyncTargetManager syncTargetManager = new FullSyncTargetManager( @@ -55,6 +57,7 @@ public class FullSyncChainDownloader { metricsSystem, terminationCondition), ethContext.getScheduler(), - metricsSystem); + metricsSystem, + syncDurationMetrics); } } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncDownloader.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncDownloader.java index 4484c19446..8f1aca792c 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncDownloader.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncDownloader.java @@ -21,6 +21,7 @@ import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration; import org.hyperledger.besu.ethereum.eth.sync.TrailingPeerRequirements; import org.hyperledger.besu.ethereum.eth.sync.state.SyncState; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.plugin.services.MetricsSystem; import java.util.concurrent.CompletableFuture; @@ -43,7 +44,8 @@ public class FullSyncDownloader { final EthContext ethContext, final SyncState syncState, final MetricsSystem metricsSystem, - final SyncTerminationCondition terminationCondition) { + final SyncTerminationCondition terminationCondition, + final SyncDurationMetrics syncDurationMetrics) { this.syncConfig = syncConfig; this.protocolContext = protocolContext; this.syncState = syncState; @@ -56,7 +58,8 @@ public class FullSyncDownloader { ethContext, syncState, metricsSystem, - terminationCondition); + terminationCondition, + syncDurationMetrics); } public CompletableFuture start() { diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/SnapDownloaderFactory.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/SnapDownloaderFactory.java index 5b40fceb08..5de8ceb984 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/SnapDownloaderFactory.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/SnapDownloaderFactory.java @@ -33,6 +33,7 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ScheduleBasedBlockHeaderFunctions; import org.hyperledger.besu.ethereum.trie.CompactEncoding; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.plugin.services.MetricsSystem; import org.hyperledger.besu.services.tasks.InMemoryTasksPriorityQueues; @@ -58,7 +59,8 @@ public class SnapDownloaderFactory extends FastDownloaderFactory { final EthContext ethContext, final WorldStateStorageCoordinator worldStateStorageCoordinator, final SyncState syncState, - final Clock clock) { + final Clock clock, + final SyncDurationMetrics syncDurationMetrics) { final Path fastSyncDataDirectory = dataDirectory.resolve(FAST_SYNC_FOLDER); final FastSyncStateStorage fastSyncStateStorage = @@ -93,10 +95,7 @@ public class SnapDownloaderFactory extends FastDownloaderFactory { return Optional.empty(); } - final SnapSyncProcessState snapSyncState = - new SnapSyncProcessState( - fastSyncStateStorage.loadState( - ScheduleBasedBlockHeaderFunctions.create(protocolSchedule))); + final SnapSyncProcessState snapSyncState = new SnapSyncProcessState(fastSyncState); final InMemoryTasksPriorityQueues snapTaskCollection = createSnapWorldStateDownloaderTaskCollection(); @@ -112,7 +111,8 @@ public class SnapDownloaderFactory extends FastDownloaderFactory { syncConfig.getWorldStateMaxRequestsWithoutProgress(), syncConfig.getWorldStateMinMillisBeforeStalling(), clock, - metricsSystem); + metricsSystem, + syncDurationMetrics); final FastSyncDownloader fastSyncDownloader = new SnapSyncDownloader( new FastSyncActions( @@ -129,7 +129,8 @@ public class SnapDownloaderFactory extends FastDownloaderFactory { fastSyncStateStorage, snapTaskCollection, fastSyncDataDirectory, - snapSyncState); + snapSyncState, + syncDurationMetrics); syncState.setWorldStateDownloadStatus(snapWorldStateDownloader); return Optional.of(fastSyncDownloader); } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/SnapSyncDownloader.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/SnapSyncDownloader.java index 00c571f984..34fd4de5be 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/SnapSyncDownloader.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/SnapSyncDownloader.java @@ -21,6 +21,7 @@ import org.hyperledger.besu.ethereum.eth.sync.fastsync.FastSyncStateStorage; import org.hyperledger.besu.ethereum.eth.sync.snapsync.request.SnapDataRequest; import org.hyperledger.besu.ethereum.eth.sync.worldstate.WorldStateDownloader; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.services.tasks.TaskCollection; import java.nio.file.Path; @@ -35,7 +36,8 @@ public class SnapSyncDownloader extends FastSyncDownloader { final FastSyncStateStorage fastSyncStateStorage, final TaskCollection taskCollection, final Path fastSyncDataDirectory, - final FastSyncState initialFastSyncState) { + final FastSyncState initialFastSyncState, + final SyncDurationMetrics syncDurationMetrics) { super( fastSyncActions, worldStateStorageCoordinator, @@ -43,7 +45,8 @@ public class SnapSyncDownloader extends FastSyncDownloader { fastSyncStateStorage, taskCollection, fastSyncDataDirectory, - initialFastSyncState); + initialFastSyncState, + syncDurationMetrics); } @Override diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/SnapWorldDownloadState.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/SnapWorldDownloadState.java index b8c8a784ab..41beaafa6a 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/SnapWorldDownloadState.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/SnapWorldDownloadState.java @@ -36,6 +36,8 @@ import org.hyperledger.besu.ethereum.worldstate.FlatDbMode; import org.hyperledger.besu.ethereum.worldstate.WorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; import org.hyperledger.besu.metrics.BesuMetricCategory; +import org.hyperledger.besu.metrics.SyncDurationMetrics; +import org.hyperledger.besu.plugin.services.MetricsSystem; import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; import org.hyperledger.besu.services.tasks.InMemoryTaskQueue; import org.hyperledger.besu.services.tasks.InMemoryTasksPriorityQueues; @@ -92,6 +94,8 @@ public class SnapWorldDownloadState extends WorldDownloadState // metrics around the snapsync private final SnapSyncMetricsManager metricsManager; + private final AtomicBoolean trieHealStartedBefore = new AtomicBoolean(false); + public SnapWorldDownloadState( final WorldStateStorageCoordinator worldStateStorageCoordinator, final SnapSyncStatePersistenceManager snapContext, @@ -102,13 +106,15 @@ public class SnapWorldDownloadState extends WorldDownloadState final long minMillisBeforeStalling, final SnapSyncMetricsManager metricsManager, final Clock clock, - final EthContext ethContext) { + final EthContext ethContext, + final SyncDurationMetrics syncDurationMetrics) { super( worldStateStorageCoordinator, pendingRequests, maxRequestsWithoutProgress, minMillisBeforeStalling, - clock); + clock, + syncDurationMetrics); this.snapContext = snapContext; this.blockchain = blockchain; this.snapSyncState = snapSyncState; @@ -116,46 +122,34 @@ public class SnapWorldDownloadState extends WorldDownloadState this.blockObserverId = blockchain.observeBlockAdded(createBlockchainObserver()); this.ethContext = ethContext; - metricsManager - .getMetricsSystem() - .createLongGauge( - BesuMetricCategory.SYNCHRONIZER, - "snap_world_state_pending_account_requests_current", - "Number of account pending requests for snap sync world state download", - pendingAccountRequests::size); - metricsManager - .getMetricsSystem() - .createLongGauge( - BesuMetricCategory.SYNCHRONIZER, - "snap_world_state_pending_storage_requests_current", - "Number of storage pending requests for snap sync world state download", - pendingStorageRequests::size); - metricsManager - .getMetricsSystem() - .createLongGauge( - BesuMetricCategory.SYNCHRONIZER, - "snap_world_state_pending_big_storage_requests_current", - "Number of storage pending requests for snap sync world state download", - pendingLargeStorageRequests::size); - metricsManager - .getMetricsSystem() - .createLongGauge( - BesuMetricCategory.SYNCHRONIZER, - "snap_world_state_pending_code_requests_current", - "Number of code pending requests for snap sync world state download", - pendingCodeRequests::size); - metricsManager - .getMetricsSystem() - .createLongGauge( - BesuMetricCategory.SYNCHRONIZER, - "snap_world_state_pending_trie_node_requests_current", - "Number of trie node pending requests for snap sync world state download", - pendingTrieNodeRequests::size); - } - - @Override - public synchronized void notifyTaskAvailable() { - notifyAll(); + final MetricsSystem metricsSystem = metricsManager.getMetricsSystem(); + metricsSystem.createLongGauge( + BesuMetricCategory.SYNCHRONIZER, + "snap_world_state_pending_account_requests_current", + "Number of account pending requests for snap sync world state download", + pendingAccountRequests::size); + metricsSystem.createLongGauge( + BesuMetricCategory.SYNCHRONIZER, + "snap_world_state_pending_storage_requests_current", + "Number of storage pending requests for snap sync world state download", + pendingStorageRequests::size); + metricsSystem.createLongGauge( + BesuMetricCategory.SYNCHRONIZER, + "snap_world_state_pending_big_storage_requests_current", + "Number of storage pending requests for snap sync world state download", + pendingLargeStorageRequests::size); + metricsSystem.createLongGauge( + BesuMetricCategory.SYNCHRONIZER, + "snap_world_state_pending_code_requests_current", + "Number of code pending requests for snap sync world state download", + pendingCodeRequests::size); + metricsSystem.createLongGauge( + BesuMetricCategory.SYNCHRONIZER, + "snap_world_state_pending_trie_node_requests_current", + "Number of trie node pending requests for snap sync world state download", + pendingTrieNodeRequests::size); + syncDurationMetrics.startTimer( + SyncDurationMetrics.Labels.SNAP_INITIAL_WORLD_STATE_DOWNLOAD_DURATION); } @Override @@ -191,6 +185,9 @@ public class SnapWorldDownloadState extends WorldDownloadState // if all snapsync tasks are completed and the healing was running and the blockchain is not // behind the pivot block else { + syncDurationMetrics.stopTimer(SyncDurationMetrics.Labels.SNAP_WORLD_STATE_HEALING_DURATION); + syncDurationMetrics.stopTimer(SyncDurationMetrics.Labels.CHAIN_DOWNLOAD_DURATION); + // If the flat database healing process is not in progress and the flat database mode is // FULL if (!snapSyncState.isHealFlatDatabaseInProgress() @@ -217,6 +214,7 @@ public class SnapWorldDownloadState extends WorldDownloadState // Clear the snap context snapContext.clear(); internalFuture.complete(null); + return true; } } @@ -236,6 +234,12 @@ public class SnapWorldDownloadState extends WorldDownloadState /** Method to start the healing process of the trie */ public synchronized void startTrieHeal() { + if (trieHealStartedBefore.compareAndSet(false, true)) { + syncDurationMetrics.stopTimer( + SyncDurationMetrics.Labels.SNAP_INITIAL_WORLD_STATE_DOWNLOAD_DURATION); + + syncDurationMetrics.startTimer(SyncDurationMetrics.Labels.SNAP_WORLD_STATE_HEALING_DURATION); + } snapContext.clearAccountRangeTasks(); snapSyncState.setHealTrieStatus(true); // Try to find a new pivot block before starting the healing process @@ -272,6 +276,7 @@ public class SnapWorldDownloadState extends WorldDownloadState public synchronized void startFlatDatabaseHeal(final BlockHeader header) { LOG.info("Initiating the healing process for the flat database"); + syncDurationMetrics.startTimer(SyncDurationMetrics.Labels.FLAT_DB_HEAL); snapSyncState.setHealFlatDatabaseInProgress(true); final Map ranges = RangeManager.generateAllRanges(16); ranges.forEach( diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/SnapWorldStateDownloader.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/SnapWorldStateDownloader.java index 9ae49b93c7..fc9d0d8ef1 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/SnapWorldStateDownloader.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/SnapWorldStateDownloader.java @@ -31,6 +31,7 @@ import org.hyperledger.besu.ethereum.trie.RangeManager; import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.BonsaiWorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; import org.hyperledger.besu.metrics.BesuMetricCategory; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.plugin.services.MetricsSystem; import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; import org.hyperledger.besu.services.tasks.InMemoryTasksPriorityQueues; @@ -67,6 +68,7 @@ public class SnapWorldStateDownloader implements WorldStateDownloader { private final WorldStateStorageCoordinator worldStateStorageCoordinator; private final AtomicReference downloadState = new AtomicReference<>(); + private final SyncDurationMetrics syncDurationMetrics; public SnapWorldStateDownloader( final EthContext ethContext, @@ -79,7 +81,8 @@ public class SnapWorldStateDownloader implements WorldStateDownloader { final int maxNodeRequestsWithoutProgress, final long minMillisBeforeStalling, final Clock clock, - final MetricsSystem metricsSystem) { + final MetricsSystem metricsSystem, + final SyncDurationMetrics syncDurationMetrics) { this.ethContext = ethContext; this.protocolContext = protocolContext; this.worldStateStorageCoordinator = worldStateStorageCoordinator; @@ -91,6 +94,7 @@ public class SnapWorldStateDownloader implements WorldStateDownloader { this.minMillisBeforeStalling = minMillisBeforeStalling; this.clock = clock; this.metricsSystem = metricsSystem; + this.syncDurationMetrics = syncDurationMetrics; metricsSystem.createIntegerGauge( BesuMetricCategory.SYNCHRONIZER, @@ -148,7 +152,8 @@ public class SnapWorldStateDownloader implements WorldStateDownloader { minMillisBeforeStalling, snapsyncMetricsManager, clock, - ethContext); + ethContext, + syncDurationMetrics); final Map ranges = RangeManager.generateAllRanges(16); snapsyncMetricsManager.initRange(ranges); diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/worldstate/WorldDownloadState.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/worldstate/WorldDownloadState.java index fd3ae682da..4945713ae3 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/worldstate/WorldDownloadState.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/worldstate/WorldDownloadState.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.eth.manager.EthScheduler; import org.hyperledger.besu.ethereum.eth.manager.task.EthTask; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.services.tasks.InMemoryTasksPriorityQueues; import org.hyperledger.besu.services.tasks.Task; import org.hyperledger.besu.services.tasks.TasksPriorityProvider; @@ -37,6 +38,7 @@ import org.slf4j.LoggerFactory; public abstract class WorldDownloadState { private static final Logger LOG = LoggerFactory.getLogger(WorldDownloadState.class); + protected final SyncDurationMetrics syncDurationMetrics; private boolean downloadWasResumed; protected final InMemoryTasksPriorityQueues pendingRequests; @@ -61,7 +63,8 @@ public abstract class WorldDownloadState final InMemoryTasksPriorityQueues pendingRequests, final int maxRequestsWithoutProgress, final long minMillisBeforeStalling, - final Clock clock) { + final Clock clock, + final SyncDurationMetrics syncDurationMetrics) { this.worldStateStorageCoordinator = worldStateStorageCoordinator; this.minMillisBeforeStalling = minMillisBeforeStalling; this.timestampOfLastProgress = clock.millis(); @@ -69,6 +72,7 @@ public abstract class WorldDownloadState this.pendingRequests = pendingRequests; this.maxRequestsWithoutProgress = maxRequestsWithoutProgress; this.clock = clock; + this.syncDurationMetrics = syncDurationMetrics; this.internalFuture = new CompletableFuture<>(); this.downloadFuture = new CompletableFuture<>(); this.internalFuture.whenComplete(this::cleanup); diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/PipelineChainDownloaderTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/PipelineChainDownloaderTest.java index c8304f5b8d..f440234905 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/PipelineChainDownloaderTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/PipelineChainDownloaderTest.java @@ -34,6 +34,7 @@ import org.hyperledger.besu.ethereum.eth.sync.state.SyncState; import org.hyperledger.besu.ethereum.eth.sync.state.SyncTarget; import org.hyperledger.besu.ethereum.eth.sync.tasks.exceptions.InvalidBlockException; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.messages.DisconnectMessage.DisconnectReason; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import org.hyperledger.besu.services.pipeline.Pipeline; @@ -69,13 +70,15 @@ public class PipelineChainDownloaderTest { public void setUp() { syncTarget = new SyncTarget(peer1, commonAncestor); syncTarget2 = new SyncTarget(peer2, commonAncestor); + final NoOpMetricsSystem noOpMetricsSystem = new NoOpMetricsSystem(); chainDownloader = new PipelineChainDownloader( syncState, syncTargetManager, downloadPipelineFactory, scheduler, - new NoOpMetricsSystem()); + noOpMetricsSystem, + SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS); } @Test diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/checkpointsync/CheckPointSyncChainDownloaderTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/checkpointsync/CheckPointSyncChainDownloaderTest.java index c623b553f1..43f03100a7 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/checkpointsync/CheckPointSyncChainDownloaderTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/checkpointsync/CheckPointSyncChainDownloaderTest.java @@ -40,6 +40,7 @@ import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.BonsaiWorldSt import org.hyperledger.besu.ethereum.trie.forest.storage.ForestWorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.worldstate.WorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; @@ -141,7 +142,8 @@ public class CheckPointSyncChainDownloaderTest { ethContext, syncState, new NoOpMetricsSystem(), - new FastSyncState(otherBlockchain.getBlockHeader(pivotBlockNumber).get())); + new FastSyncState(otherBlockchain.getBlockHeader(pivotBlockNumber).get()), + SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS); } @ParameterizedTest diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastDownloaderFactoryTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastDownloaderFactoryTest.java index b5be361bf4..37ca5be2e9 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastDownloaderFactoryTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastDownloaderFactoryTest.java @@ -35,6 +35,7 @@ import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.BonsaiWorldSt import org.hyperledger.besu.ethereum.trie.forest.storage.ForestWorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.worldstate.WorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.plugin.services.MetricsSystem; import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; @@ -115,7 +116,8 @@ public class FastDownloaderFactoryTest { ethContext, worldStateStorageCoordinator, syncState, - clock)) + clock, + SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS)) .isInstanceOf(IllegalStateException.class); } @@ -139,7 +141,8 @@ public class FastDownloaderFactoryTest { ethContext, worldStateStorageCoordinator, syncState, - clock); + clock, + SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS); assertThat(result).isEmpty(); } @@ -166,7 +169,8 @@ public class FastDownloaderFactoryTest { ethContext, worldStateStorageCoordinator, syncState, - clock); + clock, + SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS); verify(mutableBlockchain).getChainHeadBlockNumber(); } @@ -200,7 +204,8 @@ public class FastDownloaderFactoryTest { ethContext, worldStateStorageCoordinator, syncState, - clock); + clock, + SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS); verify(worldStateKeyValueStorage).clear(); assertThat(Files.exists(stateQueueDir)).isFalse(); @@ -236,7 +241,8 @@ public class FastDownloaderFactoryTest { ethContext, worldStateStorageCoordinator, syncState, - clock)) + clock, + SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS)) .isInstanceOf(IllegalStateException.class); } diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncChainDownloaderTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncChainDownloaderTest.java index f7a8a9ee54..34014246d2 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncChainDownloaderTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncChainDownloaderTest.java @@ -36,6 +36,7 @@ import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration; import org.hyperledger.besu.ethereum.eth.sync.state.SyncState; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; @@ -111,7 +112,8 @@ public class FastSyncChainDownloaderTest { ethContext, syncState, new NoOpMetricsSystem(), - new FastSyncState(otherBlockchain.getBlockHeader(pivotBlockNumber).get())); + new FastSyncState(otherBlockchain.getBlockHeader(pivotBlockNumber).get()), + SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS); } @ParameterizedTest diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncDownloaderTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncDownloaderTest.java index e929b72ff9..13444a9127 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncDownloaderTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncDownloaderTest.java @@ -38,6 +38,7 @@ import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.BonsaiWorldSt import org.hyperledger.besu.ethereum.trie.forest.storage.ForestWorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.worldstate.WorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; import org.hyperledger.besu.services.tasks.TaskCollection; @@ -105,7 +106,8 @@ public class FastSyncDownloaderTest { storage, taskCollection, fastSyncDataDirectory, - FastSyncState.EMPTY_SYNC_STATE); + FastSyncState.EMPTY_SYNC_STATE, + SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS); } @ParameterizedTest @@ -119,7 +121,8 @@ public class FastSyncDownloaderTest { .thenReturn(completedFuture(selectPivotBlockState)); when(fastSyncActions.downloadPivotBlockHeader(selectPivotBlockState)) .thenReturn(completedFuture(downloadPivotBlockHeaderState)); - when(fastSyncActions.createChainDownloader(downloadPivotBlockHeaderState)) + when(fastSyncActions.createChainDownloader( + downloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS)) .thenReturn(chainDownloader); when(chainDownloader.start()).thenReturn(completedFuture(null)); when(worldStateDownloader.run( @@ -131,7 +134,9 @@ public class FastSyncDownloaderTest { verify(fastSyncActions).selectPivotBlock(FastSyncState.EMPTY_SYNC_STATE); verify(fastSyncActions).downloadPivotBlockHeader(selectPivotBlockState); verify(storage).storeState(downloadPivotBlockHeaderState); - verify(fastSyncActions).createChainDownloader(downloadPivotBlockHeaderState); + verify(fastSyncActions) + .createChainDownloader( + downloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS); verify(chainDownloader).start(); verify(worldStateDownloader) .run(any(FastSyncActions.class), eq(new FastSyncState(pivotBlockHeader))); @@ -148,7 +153,9 @@ public class FastSyncDownloaderTest { final CompletableFuture complete = completedFuture(fastSyncState); when(fastSyncActions.selectPivotBlock(fastSyncState)).thenReturn(complete); when(fastSyncActions.downloadPivotBlockHeader(fastSyncState)).thenReturn(complete); - when(fastSyncActions.createChainDownloader(fastSyncState)).thenReturn(chainDownloader); + when(fastSyncActions.createChainDownloader( + fastSyncState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS)) + .thenReturn(chainDownloader); when(chainDownloader.start()).thenReturn(completedFuture(null)); when(worldStateDownloader.run( any(FastSyncActions.class), eq(new FastSyncState(pivotBlockHeader)))) @@ -162,14 +169,16 @@ public class FastSyncDownloaderTest { storage, taskCollection, fastSyncDataDirectory, - fastSyncState); + fastSyncState, + SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS); final CompletableFuture result = resumedDownloader.start(); verify(fastSyncActions).selectPivotBlock(fastSyncState); verify(fastSyncActions).downloadPivotBlockHeader(fastSyncState); verify(storage).storeState(fastSyncState); - verify(fastSyncActions).createChainDownloader(fastSyncState); + verify(fastSyncActions) + .createChainDownloader(fastSyncState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS); verify(chainDownloader).start(); verify(worldStateDownloader) .run(any(FastSyncActions.class), eq(new FastSyncState(pivotBlockHeader))); @@ -206,7 +215,8 @@ public class FastSyncDownloaderTest { .thenReturn(completedFuture(selectPivotBlockState)); when(fastSyncActions.downloadPivotBlockHeader(selectPivotBlockState)) .thenReturn(completedFuture(downloadPivotBlockHeaderState)); - when(fastSyncActions.createChainDownloader(downloadPivotBlockHeaderState)) + when(fastSyncActions.createChainDownloader( + downloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS)) .thenReturn(chainDownloader); when(chainDownloader.start()).thenReturn(chainFuture); when(worldStateDownloader.run( @@ -218,7 +228,9 @@ public class FastSyncDownloaderTest { verify(fastSyncActions).selectPivotBlock(FastSyncState.EMPTY_SYNC_STATE); verify(fastSyncActions).downloadPivotBlockHeader(selectPivotBlockState); verify(storage).storeState(downloadPivotBlockHeaderState); - verify(fastSyncActions).createChainDownloader(downloadPivotBlockHeaderState); + verify(fastSyncActions) + .createChainDownloader( + downloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS); verify(worldStateDownloader) .run(any(FastSyncActions.class), eq(new FastSyncState(pivotBlockHeader))); verifyNoMoreInteractions(fastSyncActions, worldStateDownloader, storage); @@ -246,7 +258,8 @@ public class FastSyncDownloaderTest { .thenReturn(completedFuture(selectPivotBlockState)); when(fastSyncActions.downloadPivotBlockHeader(selectPivotBlockState)) .thenReturn(completedFuture(downloadPivotBlockHeaderState)); - when(fastSyncActions.createChainDownloader(downloadPivotBlockHeaderState)) + when(fastSyncActions.createChainDownloader( + downloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS)) .thenReturn(chainDownloader); when(chainDownloader.start()).thenReturn(chainFuture); when(worldStateDownloader.run( @@ -257,7 +270,9 @@ public class FastSyncDownloaderTest { verify(fastSyncActions).selectPivotBlock(FastSyncState.EMPTY_SYNC_STATE); verify(fastSyncActions).downloadPivotBlockHeader(selectPivotBlockState); - verify(fastSyncActions).createChainDownloader(downloadPivotBlockHeaderState); + verify(fastSyncActions) + .createChainDownloader( + downloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS); verify(worldStateDownloader) .run(any(FastSyncActions.class), eq(new FastSyncState(pivotBlockHeader))); verifyNoMoreInteractions(fastSyncActions); @@ -321,7 +336,8 @@ public class FastSyncDownloaderTest { .thenReturn(completedFuture(selectPivotBlockState)); when(fastSyncActions.downloadPivotBlockHeader(selectPivotBlockState)) .thenReturn(completedFuture(downloadPivotBlockHeaderState)); - when(fastSyncActions.createChainDownloader(downloadPivotBlockHeaderState)) + when(fastSyncActions.createChainDownloader( + downloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS)) .thenReturn(chainDownloader); when(chainDownloader.start()).thenReturn(chainFuture); when(worldStateDownloader.run( @@ -332,7 +348,9 @@ public class FastSyncDownloaderTest { verify(fastSyncActions).selectPivotBlock(FastSyncState.EMPTY_SYNC_STATE); verify(fastSyncActions).downloadPivotBlockHeader(selectPivotBlockState); - verify(fastSyncActions).createChainDownloader(downloadPivotBlockHeaderState); + verify(fastSyncActions) + .createChainDownloader( + downloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS); verify(worldStateDownloader) .run(any(FastSyncActions.class), eq(new FastSyncState(pivotBlockHeader))); verifyNoMoreInteractions(fastSyncActions); @@ -359,7 +377,8 @@ public class FastSyncDownloaderTest { .thenReturn(completedFuture(selectPivotBlockState)); when(fastSyncActions.downloadPivotBlockHeader(selectPivotBlockState)) .thenReturn(completedFuture(downloadPivotBlockHeaderState)); - when(fastSyncActions.createChainDownloader(downloadPivotBlockHeaderState)) + when(fastSyncActions.createChainDownloader( + downloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS)) .thenReturn(chainDownloader); when(chainDownloader.start()).thenReturn(chainFuture); when(worldStateDownloader.run( @@ -370,7 +389,9 @@ public class FastSyncDownloaderTest { verify(fastSyncActions).selectPivotBlock(FastSyncState.EMPTY_SYNC_STATE); verify(fastSyncActions).downloadPivotBlockHeader(selectPivotBlockState); - verify(fastSyncActions).createChainDownloader(downloadPivotBlockHeaderState); + verify(fastSyncActions) + .createChainDownloader( + downloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS); verify(worldStateDownloader) .run(any(FastSyncActions.class), eq(new FastSyncState(pivotBlockHeader))); verifyNoMoreInteractions(fastSyncActions); @@ -407,7 +428,8 @@ public class FastSyncDownloaderTest { completedFuture(selectPivotBlockState), completedFuture(secondSelectPivotBlockState)); when(fastSyncActions.downloadPivotBlockHeader(selectPivotBlockState)) .thenReturn(completedFuture(downloadPivotBlockHeaderState)); - when(fastSyncActions.createChainDownloader(downloadPivotBlockHeaderState)) + when(fastSyncActions.createChainDownloader( + downloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS)) .thenReturn(chainDownloader); when(chainDownloader.start()).thenReturn(chainFuture); when(worldStateDownloader.run( @@ -418,7 +440,8 @@ public class FastSyncDownloaderTest { when(fastSyncActions.downloadPivotBlockHeader(secondSelectPivotBlockState)) .thenReturn(completedFuture(secondDownloadPivotBlockHeaderState)); - when(fastSyncActions.createChainDownloader(secondDownloadPivotBlockHeaderState)) + when(fastSyncActions.createChainDownloader( + secondDownloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS)) .thenReturn(secondChainDownloader); when(secondChainDownloader.start()).thenReturn(completedFuture(null)); when(worldStateDownloader.run( @@ -430,7 +453,9 @@ public class FastSyncDownloaderTest { verify(fastSyncActions).selectPivotBlock(FastSyncState.EMPTY_SYNC_STATE); verify(fastSyncActions).downloadPivotBlockHeader(selectPivotBlockState); verify(storage).storeState(downloadPivotBlockHeaderState); - verify(fastSyncActions).createChainDownloader(downloadPivotBlockHeaderState); + verify(fastSyncActions) + .createChainDownloader( + downloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS); verify(worldStateDownloader) .run(any(FastSyncActions.class), eq(new FastSyncState(pivotBlockHeader))); verifyNoMoreInteractions(fastSyncActions, worldStateDownloader, storage); @@ -446,7 +471,9 @@ public class FastSyncDownloaderTest { verify(fastSyncActions, times(2)).selectPivotBlock(FastSyncState.EMPTY_SYNC_STATE); verify(fastSyncActions).downloadPivotBlockHeader(secondSelectPivotBlockState); verify(storage).storeState(secondDownloadPivotBlockHeaderState); - verify(fastSyncActions).createChainDownloader(secondDownloadPivotBlockHeaderState); + verify(fastSyncActions) + .createChainDownloader( + secondDownloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS); verify(worldStateDownloader) .run(any(FastSyncActions.class), eq(new FastSyncState(secondPivotBlockHeader))); verifyNoMoreInteractions(fastSyncActions, worldStateDownloader, storage); @@ -481,7 +508,8 @@ public class FastSyncDownloaderTest { completedFuture(selectPivotBlockState), completedFuture(secondSelectPivotBlockState)); when(fastSyncActions.downloadPivotBlockHeader(selectPivotBlockState)) .thenReturn(completedFuture(downloadPivotBlockHeaderState)); - when(fastSyncActions.createChainDownloader(downloadPivotBlockHeaderState)) + when(fastSyncActions.createChainDownloader( + downloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS)) .thenReturn(chainDownloader); when(chainDownloader.start()).thenReturn(chainFuture); when(worldStateDownloader.run( @@ -494,7 +522,8 @@ public class FastSyncDownloaderTest { when(fastSyncActions.downloadPivotBlockHeader(secondSelectPivotBlockState)) .thenReturn(completedFuture(secondDownloadPivotBlockHeaderState)); - when(fastSyncActions.createChainDownloader(secondDownloadPivotBlockHeaderState)) + when(fastSyncActions.createChainDownloader( + secondDownloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS)) .thenReturn(secondChainDownloader); when(secondChainDownloader.start()).thenReturn(completedFuture(null)); when(worldStateDownloader.run( @@ -506,7 +535,9 @@ public class FastSyncDownloaderTest { verify(fastSyncActions).selectPivotBlock(FastSyncState.EMPTY_SYNC_STATE); verify(fastSyncActions).downloadPivotBlockHeader(selectPivotBlockState); verify(storage).storeState(downloadPivotBlockHeaderState); - verify(fastSyncActions).createChainDownloader(downloadPivotBlockHeaderState); + verify(fastSyncActions) + .createChainDownloader( + downloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS); verify(worldStateDownloader) .run(any(FastSyncActions.class), eq(new FastSyncState(pivotBlockHeader))); verifyNoMoreInteractions(fastSyncActions, worldStateDownloader, storage); @@ -524,7 +555,9 @@ public class FastSyncDownloaderTest { verify(fastSyncActions, times(2)).selectPivotBlock(FastSyncState.EMPTY_SYNC_STATE); verify(fastSyncActions).downloadPivotBlockHeader(secondSelectPivotBlockState); verify(storage).storeState(secondDownloadPivotBlockHeaderState); - verify(fastSyncActions).createChainDownloader(secondDownloadPivotBlockHeaderState); + verify(fastSyncActions) + .createChainDownloader( + secondDownloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS); verify(worldStateDownloader) .run(any(FastSyncActions.class), eq(new FastSyncState(secondPivotBlockHeader))); verifyNoMoreInteractions(fastSyncActions, worldStateDownloader, storage); @@ -556,7 +589,8 @@ public class FastSyncDownloaderTest { .thenReturn(completedFuture(selectPivotBlockState)); when(fastSyncActions.downloadPivotBlockHeader(selectPivotBlockState)) .thenReturn(completedFuture(downloadPivotBlockHeaderState)); - when(fastSyncActions.createChainDownloader(downloadPivotBlockHeaderState)) + when(fastSyncActions.createChainDownloader( + downloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS)) .thenReturn(chainDownloader); when(chainDownloader.start()).thenReturn(new CompletableFuture<>()); when(worldStateDownloader.run( @@ -581,7 +615,8 @@ public class FastSyncDownloaderTest { .thenReturn(completedFuture(selectPivotBlockState)); when(fastSyncActions.downloadPivotBlockHeader(selectPivotBlockState)) .thenReturn(completedFuture(downloadPivotBlockHeaderState)); - when(fastSyncActions.createChainDownloader(downloadPivotBlockHeaderState)) + when(fastSyncActions.createChainDownloader( + downloadPivotBlockHeaderState, SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS)) .thenReturn(chainDownloader); when(chainDownloader.start()).thenReturn(completedFuture(null)); when(worldStateDownloader.run( diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/worldstate/FastWorldDownloadStateTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/worldstate/FastWorldDownloadStateTest.java index a808ac7078..e3d2a37cd0 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/worldstate/FastWorldDownloadStateTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/worldstate/FastWorldDownloadStateTest.java @@ -31,6 +31,7 @@ import org.hyperledger.besu.ethereum.trie.forest.storage.ForestWorldStateKeyValu 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.metrics.SyncDurationMetrics; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; import org.hyperledger.besu.services.kvstore.InMemoryKeyValueStorage; @@ -100,7 +101,8 @@ public class FastWorldDownloadStateTest { pendingRequests, MAX_REQUESTS_WITHOUT_PROGRESS, MIN_MILLIS_BEFORE_STALLING, - clock); + clock, + SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS); assertThat(downloadState.isDownloading()).isTrue(); downloadState.setRootNodeData(ROOT_NODE_DATA); future = downloadState.getDownloadFuture(); diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/worldstate/FastWorldStateDownloaderTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/worldstate/FastWorldStateDownloaderTest.java index 3a29a444a4..75fe892aeb 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/worldstate/FastWorldStateDownloaderTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/worldstate/FastWorldStateDownloaderTest.java @@ -64,6 +64,7 @@ import org.hyperledger.besu.evm.account.Account; import org.hyperledger.besu.evm.account.AccountStorageEntry; import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.evm.worldstate.WorldState; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import org.hyperledger.besu.services.kvstore.InMemoryKeyValueStorage; import org.hyperledger.besu.services.tasks.InMemoryTasksPriorityQueues; @@ -1051,7 +1052,8 @@ class FastWorldStateDownloaderTest { config.getWorldStateMaxRequestsWithoutProgress(), config.getWorldStateMinMillisBeforeStalling(), TestClock.fixed(), - new NoOpMetricsSystem()); + new NoOpMetricsSystem(), + SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS); } private WorldStatePreimageStorage createPreimageStorage() { diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncChainDownloaderForkTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncChainDownloaderForkTest.java index a46aff5670..d7b5970098 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncChainDownloaderForkTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncChainDownloaderForkTest.java @@ -32,6 +32,7 @@ import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration; import org.hyperledger.besu.ethereum.eth.sync.state.SyncState; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.messages.DisconnectMessage.DisconnectReason; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import org.hyperledger.besu.plugin.services.MetricsSystem; @@ -89,7 +90,8 @@ public class FullSyncChainDownloaderForkTest { ethContext, syncState, metricsSystem, - SyncTerminationCondition.never()); + SyncTerminationCondition.never(), + SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS); } private ChainDownloader downloader() { diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncChainDownloaderTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncChainDownloaderTest.java index ded65f6a12..ac7f0fb825 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncChainDownloaderTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncChainDownloaderTest.java @@ -42,6 +42,7 @@ import org.hyperledger.besu.ethereum.eth.sync.state.SyncState; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.MessageData; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.messages.DisconnectMessage.DisconnectReason; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import org.hyperledger.besu.plugin.services.MetricsSystem; import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; @@ -121,7 +122,8 @@ public class FullSyncChainDownloaderTest { ethContext, syncState, metricsSystem, - SyncTerminationCondition.never()); + SyncTerminationCondition.never(), + SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS); } private ChainDownloader downloader() { diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncChainDownloaderTotalTerminalDifficultyTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncChainDownloaderTotalTerminalDifficultyTest.java index 4eeb3bbc63..311ccf5de3 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncChainDownloaderTotalTerminalDifficultyTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncChainDownloaderTotalTerminalDifficultyTest.java @@ -31,6 +31,7 @@ import org.hyperledger.besu.ethereum.eth.sync.ChainDownloader; import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration; import org.hyperledger.besu.ethereum.eth.sync.state.SyncState; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import org.hyperledger.besu.plugin.services.MetricsSystem; import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; @@ -107,7 +108,8 @@ public class FullSyncChainDownloaderTotalTerminalDifficultyTest { ethContext, syncState, metricsSystem, - terminalCondition); + terminalCondition, + SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS); } private SynchronizerConfiguration.Builder syncConfigBuilder() { diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncDownloaderTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncDownloaderTest.java index a44ddc07bb..63e41f6d25 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncDownloaderTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncDownloaderTest.java @@ -29,6 +29,7 @@ import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration; import org.hyperledger.besu.ethereum.eth.sync.TrailingPeerRequirements; import org.hyperledger.besu.ethereum.eth.sync.state.SyncState; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; +import org.hyperledger.besu.metrics.SyncDurationMetrics; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import org.hyperledger.besu.plugin.services.MetricsSystem; import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; @@ -96,7 +97,8 @@ public class FullSyncDownloaderTest { ethContext, syncState, metricsSystem, - SyncTerminationCondition.never()); + SyncTerminationCondition.never(), + SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS); } @ParameterizedTest diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/SnapWorldDownloadStateTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/SnapWorldDownloadStateTest.java index d1e90b5eb6..24e4869960 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/SnapWorldDownloadStateTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/SnapWorldDownloadStateTest.java @@ -46,6 +46,7 @@ import org.hyperledger.besu.ethereum.trie.forest.storage.ForestWorldStateKeyValu 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.metrics.SyncDurationMetrics; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; import org.hyperledger.besu.services.kvstore.InMemoryKeyValueStorage; @@ -137,7 +138,8 @@ public class SnapWorldDownloadStateTest { MIN_MILLIS_BEFORE_STALLING, metricsManager, clock, - ethContext); + ethContext, + SyncDurationMetrics.NO_OP_SYNC_DURATION_METRICS); final DynamicPivotBlockSelector dynamicPivotBlockManager = mock(DynamicPivotBlockSelector.class); doAnswer( diff --git a/metrics/core/src/main/java/org/hyperledger/besu/metrics/SyncDurationMetrics.java b/metrics/core/src/main/java/org/hyperledger/besu/metrics/SyncDurationMetrics.java new file mode 100644 index 0000000000..d6fc937009 --- /dev/null +++ b/metrics/core/src/main/java/org/hyperledger/besu/metrics/SyncDurationMetrics.java @@ -0,0 +1,91 @@ +/* + * 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.metrics; + +import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; +import org.hyperledger.besu.plugin.services.MetricsSystem; +import org.hyperledger.besu.plugin.services.metrics.LabelledMetric; +import org.hyperledger.besu.plugin.services.metrics.OperationTimer; + +import java.util.HashMap; + +/** + * This class manages the synchronization duration metrics for the Hyperledger Besu project. It + * provides methods to start and stop timers for various synchronization phases. + */ +public class SyncDurationMetrics { + + /** A {@link SyncDurationMetrics} instance that does not record any metrics. */ + public static final SyncDurationMetrics NO_OP_SYNC_DURATION_METRICS = + new SyncDurationMetrics(new NoOpMetricsSystem()); + + private final LabelledMetric timer; + + private final HashMap timers = new HashMap<>(); + + /** + * Creates a new {@link SyncDurationMetrics} instance. + * + * @param metricsSystem The {@link MetricsSystem} to use to record metrics. + */ + public SyncDurationMetrics(final MetricsSystem metricsSystem) { + timer = + metricsSystem.createSimpleLabelledTimer( + BesuMetricCategory.SYNCHRONIZER, "sync_duration", "Time taken to sync", "name"); + } + + /** + * Starts a timer for the given synchronization phase. + * + * @param label The synchronization phase to start the timer for. + */ + public void startTimer(final Labels label) { + timers.computeIfAbsent(label.name(), k -> timer.labels(label.name()).startTimer()); + } + + /** + * Stops the timer for the given synchronization phase. + * + * @param label The synchronization phase to stop the timer for. + */ + public void stopTimer(final Labels label) { + OperationTimer.TimingContext context = timers.remove(label.name()); + if (context != null) { + context.stopTimer(); + } + } + + /** Enum representing the different synchronization phases. */ + public enum Labels { + /** + * Total time taken to get into sync. It is useful for SNAP and CHECKPOINT sync-modes only. + * + *

Total sync duration includes the separate stages mentioned below, some of which occur in + * parallel. + * + *

Total sync duration excludes the backwards sync stage due to implementation challenges. + * The backwards sync should be a very short duration following the other sync stages. + */ + TOTAL_SYNC_DURATION, + /** Time taken to download the chain data (headers, blocks, receipts). */ + CHAIN_DOWNLOAD_DURATION, + /** Time taken to download the initial world state, before the healing step. */ + SNAP_INITIAL_WORLD_STATE_DOWNLOAD_DURATION, + /** Time taken to heal the world state, after the initial download. */ + SNAP_WORLD_STATE_HEALING_DURATION, + /** Time taken to do the flat database heal. */ + FLAT_DB_HEAL; + } +} 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 2b3db497b3..2d1ee26cfd 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 @@ -104,6 +104,15 @@ public class NoOpMetricsSystem implements ObservableMetricsSystem { } } + @Override + public LabelledMetric createSimpleLabelledTimer( + final MetricCategory category, + final String name, + final String help, + final String... labelNames) { + return getOperationTimerLabelledMetric(labelNames.length); + } + @Override public LabelledMetric createLabelledTimer( final MetricCategory category, diff --git a/metrics/core/src/main/java/org/hyperledger/besu/metrics/opentelemetry/OpenTelemetrySystem.java b/metrics/core/src/main/java/org/hyperledger/besu/metrics/opentelemetry/OpenTelemetrySystem.java index c52dd037f7..ca1dc5dd3a 100644 --- a/metrics/core/src/main/java/org/hyperledger/besu/metrics/opentelemetry/OpenTelemetrySystem.java +++ b/metrics/core/src/main/java/org/hyperledger/besu/metrics/opentelemetry/OpenTelemetrySystem.java @@ -231,6 +231,15 @@ public class OpenTelemetrySystem implements ObservableMetricsSystem { }); } + @Override + public LabelledMetric createSimpleLabelledTimer( + final MetricCategory category, + final String name, + final String help, + final String... labelNames) { + return createLabelledTimer(category, name, help, labelNames); + } + @Override public LabelledMetric createLabelledTimer( final MetricCategory category, diff --git a/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusMetricsSystem.java b/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusMetricsSystem.java index 218f575510..653f448311 100644 --- a/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusMetricsSystem.java +++ b/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusMetricsSystem.java @@ -40,6 +40,7 @@ import io.prometheus.client.Collector.MetricFamilySamples; import io.prometheus.client.Collector.MetricFamilySamples.Sample; import io.prometheus.client.CollectorRegistry; import io.prometheus.client.Counter; +import io.prometheus.client.Histogram; import io.prometheus.client.Summary; import io.prometheus.client.hotspot.BufferPoolsExports; import io.prometheus.client.hotspot.ClassLoadingExports; @@ -139,6 +140,27 @@ public class PrometheusMetricsSystem implements ObservableMetricsSystem { }); } + @Override + public LabelledMetric createSimpleLabelledTimer( + final MetricCategory category, + final String name, + final String help, + final String... labelNames) { + final String metricName = convertToPrometheusName(category, name); + return cachedTimers.computeIfAbsent( + metricName, + (k) -> { + if (timersEnabled && isCategoryEnabled(category)) { + final Histogram histogram = + Histogram.build(metricName, help).labelNames(labelNames).buckets(1D).create(); + addCollectorUnchecked(category, histogram); + return new PrometheusSimpleTimer(histogram); + } else { + return NoOpMetricsSystem.getOperationTimerLabelledMetric(labelNames.length); + } + }); + } + @Override public void createGauge( final MetricCategory category, diff --git a/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusSimpleTimer.java b/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusSimpleTimer.java new file mode 100644 index 0000000000..24799cb33d --- /dev/null +++ b/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusSimpleTimer.java @@ -0,0 +1,35 @@ +/* + * 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.metrics.prometheus; + +import org.hyperledger.besu.plugin.services.metrics.LabelledMetric; +import org.hyperledger.besu.plugin.services.metrics.OperationTimer; + +import io.prometheus.client.Histogram; + +class PrometheusSimpleTimer implements LabelledMetric { + + private final Histogram histogram; + + public PrometheusSimpleTimer(final Histogram histogram) { + this.histogram = histogram; + } + + @Override + public OperationTimer labels(final String... labels) { + final Histogram.Child metric = histogram.labels(labels); + return () -> metric.startTimer()::observeDuration; + } +} diff --git a/metrics/core/src/test-support/java/org/hyperledger/besu/metrics/StubMetricsSystem.java b/metrics/core/src/test-support/java/org/hyperledger/besu/metrics/StubMetricsSystem.java index 9e4b9d1ef9..2e0ea006db 100644 --- a/metrics/core/src/test-support/java/org/hyperledger/besu/metrics/StubMetricsSystem.java +++ b/metrics/core/src/test-support/java/org/hyperledger/besu/metrics/StubMetricsSystem.java @@ -75,6 +75,15 @@ public class StubMetricsSystem implements ObservableMetricsSystem { return labelValues -> NoOpMetricsSystem.NO_OP_OPERATION_TIMER; } + @Override + public LabelledMetric createSimpleLabelledTimer( + final MetricCategory category, + final String name, + final String help, + final String... labelNames) { + return labelValues -> NoOpMetricsSystem.NO_OP_OPERATION_TIMER; + } + @Override public void createGauge( final MetricCategory category, diff --git a/plugin-api/build.gradle b/plugin-api/build.gradle index af8da71a7f..66c8e34837 100644 --- a/plugin-api/build.gradle +++ b/plugin-api/build.gradle @@ -70,7 +70,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 = '2tFIKwEd8T5I37ywbFnVcMwTR8HiiCC6gO1Chd3hZp8=' + knownHash = 'V/bdVbzJLjdwch266dHHuxIGwiCRhS4w3jDwHt4TWqg=' } check.dependsOn('checkAPIChanges') diff --git a/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/MetricsSystem.java b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/MetricsSystem.java index a72eb182b0..80e02a6dba 100644 --- a/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/MetricsSystem.java +++ b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/MetricsSystem.java @@ -89,6 +89,34 @@ public interface MetricsSystem extends BesuService { LabelledMetric createLabelledTimer( MetricCategory category, String name, String help, String... labelNames); + /** + * Creates a simple Timer. + * + * @param category The {@link MetricCategory} this timer is assigned to. + * @param name A name for this metric. + * @param help A human readable description of the metric. + * @return The created Timer instance. + */ + default OperationTimer createSimpleTimer( + final MetricCategory category, final String name, final String help) { + return createSimpleLabelledTimer(category, name, help).labels(); + } + + /** + * Creates a simple Timer with assigned labels. + * + * @param category The {@link MetricCategory} this timer is assigned to. + * @param name A name for this metric. + * @param help A human readable description of the metric. + * @param labelNames An array of labels to assign to the Timer. + * @return The created Timer instance. + */ + LabelledMetric createSimpleLabelledTimer( + final MetricCategory category, + final String name, + final String help, + final String... labelNames); + /** * Creates a gauge for displaying double vales. A gauge is a metric to report the current value. * The metric value may go up or down. From 8ae0db4b2405ce2f331128b56a470c943e19e909 Mon Sep 17 00:00:00 2001 From: garyschulte Date: Wed, 28 Aug 2024 12:43:23 -0700 Subject: [PATCH 162/259] Check for infinity in eip-196 ecmul (#7509) * check for infinity before calling out to jni for ecmul * some changelog clean-up Signed-off-by: garyschulte --- CHANGELOG.md | 32 ++++++++++++------- .../AltBN128MulPrecompiledContract.java | 7 ++++ 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c00417cab6..2b5276f589 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,15 +2,6 @@ ## [Unreleased] -### Fixed -- **DebugMetrics**: Fixed a `ClassCastException` occurring in `DebugMetrics` when handling nested metric structures. Previously, `Double` values within these structures were incorrectly cast to `Map` objects, leading to errors. This update allows for proper handling of both direct values and nested structures at the same level. Issue# [#7383](https://github.com/hyperledger/besu/pull/7383) -- `evmtool` was not respecting the `--genesis` setting, resulting in unexpected trace results. [#7433](https://github.com/hyperledger/besu/pull/7433) - -### Tests -- Added a comprehensive test case to reproduce the bug and verify the fix for the `ClassCastException` in `DebugMetrics`. This ensures that complex, dynamically nested metric structures can be handled without errors. - -## Next release - ### Upcoming Breaking Changes ### Breaking Changes @@ -20,12 +11,15 @@ - Add 'inbound' field to admin_peers JSON-RPC Call [#7461](https://github.com/hyperledger/besu/pull/7461) - Add pending block header to `TransactionEvaluationContext` plugin API [#7483](https://github.com/hyperledger/besu/pull/7483) - Add bootnode to holesky config [#7500](https://github.com/hyperledger/besu/pull/7500) -- Implement engine_getClientVersionV1 +- Implement engine_getClientVersionV1 [#7512](https://github.com/hyperledger/besu/pull/7512) +- Performance optimzation for ECMUL (1 of 2) [#7509](https://github.com/hyperledger/besu/pull/7509) ### Bug fixes - Fix tracing in precompiled contracts when halting for out of gas [#7318](https://github.com/hyperledger/besu/issues/7318) - Correctly release txpool save and restore lock in case of exceptions [#7473](https://github.com/hyperledger/besu/pull/7473) - Fix for `eth_gasPrice` could not retrieve block error [#7482](https://github.com/hyperledger/besu/pull/7482) +- **DebugMetrics**: Fixed a `ClassCastException` occurring in `DebugMetrics` when handling nested metric structures. Previously, `Double` values within these structures were incorrectly cast to `Map` objects, leading to errors. This update allows for proper handling of both direct values and nested structures at the same level. Issue# [#7383](https://github.com/hyperledger/besu/pull/7383) +- `evmtool` was not respecting the `--genesis` setting, resulting in unexpected trace results. [#7433](https://github.com/hyperledger/besu/pull/7433) ## 24.8.0 @@ -45,8 +39,7 @@ - In process RPC service [#7395](https://github.com/hyperledger/besu/pull/7395) - Added support for tracing private transactions using `priv_traceTransaction` API. [#6161](https://github.com/hyperledger/besu/pull/6161) - Wrap WorldUpdater into EVMWorldupdater [#7434](https://github.com/hyperledger/besu/pull/7434) -- Bump besu-native to 0.9.4 [#7456](https://github.com/hyperledger/besu/pull/7456) - +- Bump besu-native to 0.9.4 [#7456](https://github.com/hyperledger/besu/pull/7456)= ### Bug fixes - Correct entrypoint in Docker evmtool [#7430](https://github.com/hyperledger/besu/pull/7430) @@ -54,6 +47,11 @@ - Fix behaviour when starting in a pre-merge network [#7431](https://github.com/hyperledger/besu/pull/7431) - Fix Null pointer from DNS daemon [#7505](https://github.com/hyperledger/besu/issues/7505) +### Download Links +https://github.com/hyperledger/besu/releases/tag/24.8.0 +https://github.com/hyperledger/besu/releases/download/24.8.0/besu-24.8.0.tar.gz / sha256 9671157a623fb94005357bc409d1697a0d62bb6fd434b1733441bb301a9534a4 +https://github.com/hyperledger/besu/releases/download/24.8.0/besu-24.8.0.zip / sha256 9ee217d2188e8da89002c3f42e4f85f89aab782e9512bd03520296f0a4dcdd90 + ## 24.7.1 ### Breaking Changes @@ -89,6 +87,11 @@ - Add 30 second timeout to trie log pruner preload [#7365](https://github.com/hyperledger/besu/pull/7365) - Avoid executing pruner preload during trie log subcommands [#7366](https://github.com/hyperledger/besu/pull/7366) +### Download Links +https://github.com/hyperledger/besu/releases/tag/24.7.1 +https://github.com/hyperledger/besu/releases/download/24.7.1/besu-24.7.1.tar.gz / sha256 59ac352a86fd887225737a5fe4dad1742347edd3c3fbed98b079177e4ea8d544 +https://github.com/hyperledger/besu/releases/download/24.7.1/besu-24.7.1.zip / sha256 e616f8100f026a71a146a33847b40257c279b38085b17bb991df045cccb6f832 + ## 24.7.0 ### Upcoming Breaking Changes @@ -121,6 +124,11 @@ - Fix "Could not confirm best peer had pivot block" [#7109](https://github.com/hyperledger/besu/issues/7109) - Fix "Chain Download Halt" [#6884](https://github.com/hyperledger/besu/issues/6884) +### Download Links +https://github.com/hyperledger/besu/releases/tag/24.7.0 +https://github.com/hyperledger/besu/releases/download/24.7.0/besu-24.7.0.tar.gz / sha256 96cf47defd1d8c10bfc22634e53e3d640eaa81ef58cb0808e5f4265998979530 +https://github.com/hyperledger/besu/releases/download/24.7.0/besu-24.7.0.zip / sha256 7e92e2eb469be197af8c8ca7ac494e7a2e7ee91cbdb02d99ff87fb5209e0c2a0 + ## 24.6.0 diff --git a/evm/src/main/java/org/hyperledger/besu/evm/precompile/AltBN128MulPrecompiledContract.java b/evm/src/main/java/org/hyperledger/besu/evm/precompile/AltBN128MulPrecompiledContract.java index 25399d9e71..fe58faa68d 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/precompile/AltBN128MulPrecompiledContract.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/precompile/AltBN128MulPrecompiledContract.java @@ -38,6 +38,7 @@ public class AltBN128MulPrecompiledContract extends AbstractAltBnPrecompiledCont new BigInteger( "115792089237316195423570985008687907853269984665640564039457584007913129639935"); + private static final Bytes POINT_AT_INFINITY = Bytes.repeat((byte) 0, 64); private final long gasCost; private AltBN128MulPrecompiledContract(final GasCalculator gasCalculator, final long gasCost) { @@ -78,6 +79,12 @@ public class AltBN128MulPrecompiledContract extends AbstractAltBnPrecompiledCont @Override public PrecompileContractResult computePrecompile( final Bytes input, @Nonnull final MessageFrame messageFrame) { + + if (input.size() >= 64 && input.slice(0, 64).equals(POINT_AT_INFINITY)) { + return new PrecompileContractResult( + POINT_AT_INFINITY, false, MessageFrame.State.COMPLETED_SUCCESS, Optional.empty()); + } + if (useNative) { return computeNative(input, messageFrame); } else { From a8bbcd5d8b85141051cb6fba4f01ac35e0caddaf Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Thu, 29 Aug 2024 12:23:44 +1000 Subject: [PATCH 163/259] Check for commit hash before appending another in build.gradle caclulateVersion (#7537) Signed-off-by: Matilda Clerke --- build.gradle | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 690c0fb39f..6211183a7a 100644 --- a/build.gradle +++ b/build.gradle @@ -997,12 +997,16 @@ def buildTime() { @Memoized def calculateVersion() { // Regex pattern for basic calendar versioning, with provision to omit patch rev - def calVerPattern = ~/\d+\.\d+(\.\d+)?(-.*)?/ + def calVerPattern = ~/\d+\.\d+(\.\d+)?(-\w+)?$/ + def calVerWithCommitPattern = ~/\d+\.\d+(\.\d+)?(-\w+)?-[0-9a-fA-F]{7,8}$/ def gitDetails = getGitCommitDetails() // Adjust length as needed - if (project.hasProperty('version') && (project.version =~ calVerPattern)) { + if (project.hasProperty('version') && project.version =~ calVerWithCommitPattern) { + println("Utilising supplied version as it appears to already contain commit hash: ${project.version}") + return project.version + } else if (project.hasProperty('version') && project.version =~ calVerPattern) { println("Generating project version using supplied version: ${project.version}-${gitDetails.hash}") return "${project.version}-${gitDetails.hash}" - } else { + } else { // If no version is supplied or it doesn't match the semantic versioning, calculate from git println("Generating project version using date (${gitDetails.date}-develop-${gitDetails.hash}), as supplied version is not semver: ${project.version}") return "${gitDetails.date}-develop-${gitDetails.hash}" From 03cdd45916178c7c4cdd04f6ac2ce73dfebb544c Mon Sep 17 00:00:00 2001 From: Rodion Date: Thu, 29 Aug 2024 14:09:01 +0800 Subject: [PATCH 164/259] Drop messages that exceeds local message size limit (#7507) Signed-off-by: Rodion Lim Co-authored-by: Sally MacFarlane --- CHANGELOG.md | 2 +- .../besu/services/BesuEventsImplTest.java | 3 +- .../besu/ethereum/eth/manager/EthPeer.java | 3 +- .../eth/manager/EthProtocolManager.java | 3 +- .../eth/messages/NewBlockMessage.java | 13 ++++- .../ethereum/eth/sync/BlockBroadcaster.java | 12 ++++- .../eth/messages/NewBlockMessageTest.java | 15 +++++- .../AbstractBlockPropagationManagerTest.java | 51 ++++++++++++++----- .../eth/sync/BlockBroadcasterTest.java | 11 ++-- 9 files changed, 86 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b5276f589..81183f6514 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,10 +18,10 @@ - Fix tracing in precompiled contracts when halting for out of gas [#7318](https://github.com/hyperledger/besu/issues/7318) - Correctly release txpool save and restore lock in case of exceptions [#7473](https://github.com/hyperledger/besu/pull/7473) - Fix for `eth_gasPrice` could not retrieve block error [#7482](https://github.com/hyperledger/besu/pull/7482) +- Correctly drops messages that exceeds local message size limit [#5455](https://github.com/hyperledger/besu/pull/7507) - **DebugMetrics**: Fixed a `ClassCastException` occurring in `DebugMetrics` when handling nested metric structures. Previously, `Double` values within these structures were incorrectly cast to `Map` objects, leading to errors. This update allows for proper handling of both direct values and nested structures at the same level. Issue# [#7383](https://github.com/hyperledger/besu/pull/7383) - `evmtool` was not respecting the `--genesis` setting, resulting in unexpected trace results. [#7433](https://github.com/hyperledger/besu/pull/7433) - ## 24.8.0 ### Upcoming Breaking Changes diff --git a/besu/src/test/java/org/hyperledger/besu/services/BesuEventsImplTest.java b/besu/src/test/java/org/hyperledger/besu/services/BesuEventsImplTest.java index 3673e78e31..478ce4ebc4 100644 --- a/besu/src/test/java/org/hyperledger/besu/services/BesuEventsImplTest.java +++ b/besu/src/test/java/org/hyperledger/besu/services/BesuEventsImplTest.java @@ -68,6 +68,7 @@ import org.hyperledger.besu.plugin.data.SyncStatus; import org.hyperledger.besu.services.kvstore.InMemoryKeyValueStorage; import org.hyperledger.besu.testutil.DeterministicEthScheduler; import org.hyperledger.besu.testutil.TestClock; +import org.hyperledger.besu.util.number.ByteUnits; import java.math.BigInteger; import java.time.ZoneId; @@ -154,7 +155,7 @@ public class BesuEventsImplTest { .when(mockWorldStateArchive.getMutable(any(), anyBoolean())) .thenReturn(Optional.of(mockWorldState)); - blockBroadcaster = new BlockBroadcaster(mockEthContext); + blockBroadcaster = new BlockBroadcaster(mockEthContext, 10 * ByteUnits.MEGABYTE); syncState = new SyncState(blockchain, mockEthPeers); TransactionPoolConfiguration txPoolConfig = ImmutableTransactionPoolConfiguration.builder() diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/EthPeer.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/EthPeer.java index 755283b080..899e702724 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/EthPeer.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/EthPeer.java @@ -291,12 +291,13 @@ public class EthPeer implements Comparable { if (messageData.getSize() > maxMessageSize) { // This is a bug or else a misconfiguration of the max message size. LOG.error( - "Sending {} message to peer ({}) which exceeds local message size limit of {} bytes. Message code: {}, Message Size: {}", + "Dropping {} message to peer ({}) which exceeds local message size limit of {} bytes. Message code: {}, Message Size: {}", protocolName, this, maxMessageSize, messageData.getCode(), messageData.getSize()); + return null; } if (requestManagers.containsKey(protocolName)) { diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/EthProtocolManager.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/EthProtocolManager.java index 5532bed865..58318f9611 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/EthProtocolManager.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/EthProtocolManager.java @@ -107,7 +107,8 @@ public class EthProtocolManager implements ProtocolManager, MinedBlockObserver { this.ethMessages = ethMessages; this.ethContext = ethContext; - this.blockBroadcaster = new BlockBroadcaster(ethContext); + this.blockBroadcaster = + new BlockBroadcaster(ethContext, ethereumWireProtocolConfiguration.getMaxMessageSize()); this.supportedCapabilities = calculateCapabilities(synchronizerConfiguration, ethereumWireProtocolConfiguration); diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/messages/NewBlockMessage.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/messages/NewBlockMessage.java index 9227e57413..d198cacb36 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/messages/NewBlockMessage.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/messages/NewBlockMessage.java @@ -44,11 +44,20 @@ public class NewBlockMessage extends AbstractMessageData { return MESSAGE_CODE; } - public static NewBlockMessage create(final Block block, final Difficulty totalDifficulty) { + public static NewBlockMessage create( + final Block block, final Difficulty totalDifficulty, final int maxMessageSize) + throws IllegalArgumentException { final NewBlockMessageData msgData = new NewBlockMessageData(block, totalDifficulty); final BytesValueRLPOutput out = new BytesValueRLPOutput(); msgData.writeTo(out); - return new NewBlockMessage(out.encoded()); + final Bytes data = out.encoded(); + if (data.size() > maxMessageSize) { + throw new IllegalArgumentException( + String.format( + "Block message size %d bytes is larger than allowed message size %d bytes", + data.size(), maxMessageSize)); + } + return new NewBlockMessage(data); } public static NewBlockMessage readFrom(final MessageData message) { diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/BlockBroadcaster.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/BlockBroadcaster.java index 1bf55b01f8..b81c044832 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/BlockBroadcaster.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/BlockBroadcaster.java @@ -28,11 +28,13 @@ public class BlockBroadcaster { private static final Logger LOG = LoggerFactory.getLogger(BlockBroadcaster.class); private final EthContext ethContext; + private final int maxMessageSize; private final Subscribers blockPropagatedSubscribers = Subscribers.create(); - public BlockBroadcaster(final EthContext ethContext) { + public BlockBroadcaster(final EthContext ethContext, final int maxMessageSize) { this.ethContext = ethContext; + this.maxMessageSize = maxMessageSize; } public long subscribePropagateNewBlocks(final BlockPropagatedSubscriber callback) { @@ -45,7 +47,13 @@ public class BlockBroadcaster { public void propagate(final Block block, final Difficulty totalDifficulty) { blockPropagatedSubscribers.forEach(listener -> listener.accept(block, totalDifficulty)); - final NewBlockMessage newBlockMessage = NewBlockMessage.create(block, totalDifficulty); + final NewBlockMessage newBlockMessage; + try { + newBlockMessage = NewBlockMessage.create(block, totalDifficulty, this.maxMessageSize); + } catch (final IllegalArgumentException e) { + LOG.error("Failed to create block", e); + return; + } ethContext .getEthPeers() .streamAvailablePeers() diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/messages/NewBlockMessageTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/messages/NewBlockMessageTest.java index 2d7427bc2a..4d30e9e93a 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/messages/NewBlockMessageTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/messages/NewBlockMessageTest.java @@ -24,12 +24,14 @@ import org.hyperledger.besu.ethereum.core.ProtocolScheduleFixture; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.RawMessage; import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; +import org.hyperledger.besu.util.number.ByteUnits; import org.apache.tuweni.bytes.Bytes; import org.junit.jupiter.api.Test; public class NewBlockMessageTest { private static final ProtocolSchedule protocolSchedule = ProtocolScheduleFixture.MAINNET; + private static final int maxMessageSize = 10 * ByteUnits.MEGABYTE; @Test public void roundTripNewBlockMessage() { @@ -37,7 +39,8 @@ public class NewBlockMessageTest { final BlockDataGenerator blockGenerator = new BlockDataGenerator(); final Block blockForInsertion = blockGenerator.block(); - final NewBlockMessage msg = NewBlockMessage.create(blockForInsertion, totalDifficulty); + final NewBlockMessage msg = + NewBlockMessage.create(blockForInsertion, totalDifficulty, maxMessageSize); assertThat(msg.getCode()).isEqualTo(EthPV62.NEW_BLOCK); assertThat(msg.totalDifficulty(protocolSchedule)).isEqualTo(totalDifficulty); final Block extractedBlock = msg.block(protocolSchedule); @@ -73,4 +76,14 @@ public class NewBlockMessageTest { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> NewBlockMessage.readFrom(rawMsg)); } + + @Test + public void createBlockMessageLargerThanLimitThrows() { + final Difficulty totalDifficulty = Difficulty.of(98765); + final BlockDataGenerator blockGenerator = new BlockDataGenerator(); + final Block newBlock = blockGenerator.block(); + + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> NewBlockMessage.create(newBlock, totalDifficulty, 1)); + } } diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/AbstractBlockPropagationManagerTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/AbstractBlockPropagationManagerTest.java index dcc0239f61..c576b7f8e2 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/AbstractBlockPropagationManagerTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/AbstractBlockPropagationManagerTest.java @@ -63,6 +63,7 @@ import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import org.hyperledger.besu.plugin.services.MetricsSystem; import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; import org.hyperledger.besu.testutil.TestClock; +import org.hyperledger.besu.util.number.ByteUnits; import java.util.Collections; import java.util.List; @@ -95,6 +96,7 @@ public abstract class AbstractBlockPropagationManagerTest { protected SyncState syncState; protected final MetricsSystem metricsSystem = new NoOpMetricsSystem(); private final Hash finalizedHash = Hash.fromHexStringLenient("0x1337"); + private final int maxMessageSize = 10 * ByteUnits.MEGABYTE; protected void setup(final DataStorageFormat dataStorageFormat) { blockchainUtil = BlockchainSetupUtil.forTesting(dataStorageFormat); @@ -222,11 +224,14 @@ public abstract class AbstractBlockPropagationManagerTest { final RespondingEthPeer peer = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 0); final NewBlockMessage nextAnnouncement = NewBlockMessage.create( - nextBlock, getFullBlockchain().getTotalDifficultyByHash(nextBlock.getHash()).get()); + nextBlock, + getFullBlockchain().getTotalDifficultyByHash(nextBlock.getHash()).get(), + maxMessageSize); final NewBlockMessage nextNextAnnouncement = NewBlockMessage.create( nextNextBlock, - getFullBlockchain().getTotalDifficultyByHash(nextNextBlock.getHash()).get()); + getFullBlockchain().getTotalDifficultyByHash(nextNextBlock.getHash()).get(), + maxMessageSize); final Responder responder = RespondingEthPeer.blockchainResponder(getFullBlockchain()); // Broadcast first message @@ -256,11 +261,14 @@ public abstract class AbstractBlockPropagationManagerTest { final RespondingEthPeer peer = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 0); final NewBlockMessage nextAnnouncement = NewBlockMessage.create( - nextBlock, getFullBlockchain().getTotalDifficultyByHash(nextBlock.getHash()).get()); + nextBlock, + getFullBlockchain().getTotalDifficultyByHash(nextBlock.getHash()).get(), + maxMessageSize); final NewBlockMessage nextNextAnnouncement = NewBlockMessage.create( nextNextBlock, - getFullBlockchain().getTotalDifficultyByHash(nextNextBlock.getHash()).get()); + getFullBlockchain().getTotalDifficultyByHash(nextNextBlock.getHash()).get(), + maxMessageSize); final Responder responder = RespondingEthPeer.blockchainResponder(getFullBlockchain()); // Broadcast second message first @@ -299,7 +307,9 @@ public abstract class AbstractBlockPropagationManagerTest { block1.getHash(), block1.getHeader().getNumber()))); final NewBlockMessage block2Msg = NewBlockMessage.create( - block2, getFullBlockchain().getTotalDifficultyByHash(block2.getHash()).get()); + block2, + getFullBlockchain().getTotalDifficultyByHash(block2.getHash()).get(), + maxMessageSize); final NewBlockHashesMessage block3Msg = NewBlockHashesMessage.create( Collections.singletonList( @@ -307,7 +317,9 @@ public abstract class AbstractBlockPropagationManagerTest { block3.getHash(), block3.getHeader().getNumber()))); final NewBlockMessage block4Msg = NewBlockMessage.create( - block4, getFullBlockchain().getTotalDifficultyByHash(block4.getHash()).get()); + block4, + getFullBlockchain().getTotalDifficultyByHash(block4.getHash()).get(), + maxMessageSize); final Responder responder = RespondingEthPeer.blockchainResponder(getFullBlockchain()); // Broadcast older blocks @@ -362,7 +374,9 @@ public abstract class AbstractBlockPropagationManagerTest { nextBlock.getHash(), nextBlock.getHeader().getNumber()))); final NewBlockMessage newBlock = NewBlockMessage.create( - nextBlock, getFullBlockchain().getTotalDifficultyByHash(nextBlock.getHash()).get()); + nextBlock, + getFullBlockchain().getTotalDifficultyByHash(nextBlock.getHash()).get(), + maxMessageSize); final Responder responder = RespondingEthPeer.blockchainResponder(getFullBlockchain()); // Broadcast first message @@ -413,7 +427,9 @@ public abstract class AbstractBlockPropagationManagerTest { nextBlock.getHash(), nextBlock.getHeader().getNumber()))); final NewBlockMessage newBlock = NewBlockMessage.create( - nextBlock, getFullBlockchain().getTotalDifficultyByHash(nextBlock.getHash()).get()); + nextBlock, + getFullBlockchain().getTotalDifficultyByHash(nextBlock.getHash()).get(), + maxMessageSize); // Broadcast messages EthProtocolManagerTestUtil.broadcastMessage(ethProtocolManager, peer, newBlock); @@ -467,7 +483,9 @@ public abstract class AbstractBlockPropagationManagerTest { final RespondingEthPeer peer = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 0); final NewBlockMessage futureAnnouncement = NewBlockMessage.create( - futureBlock, getFullBlockchain().getTotalDifficultyByHash(futureBlock.getHash()).get()); + futureBlock, + getFullBlockchain().getTotalDifficultyByHash(futureBlock.getHash()).get(), + maxMessageSize); // Broadcast EthProtocolManagerTestUtil.broadcastMessage(ethProtocolManager, peer, futureAnnouncement); @@ -522,7 +540,8 @@ public abstract class AbstractBlockPropagationManagerTest { // Setup peer and messages final RespondingEthPeer peer = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 0); - final NewBlockMessage oldAnnouncement = NewBlockMessage.create(oldBlock, Difficulty.ZERO); + final NewBlockMessage oldAnnouncement = + NewBlockMessage.create(oldBlock, Difficulty.ZERO, maxMessageSize); // Broadcast EthProtocolManagerTestUtil.broadcastMessage(ethProtocolManager, peer, oldAnnouncement); @@ -559,7 +578,7 @@ public abstract class AbstractBlockPropagationManagerTest { blockPropagationManager.start(); final RespondingEthPeer peer = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 0); final NewBlockMessage blockAnnouncementMsg = - NewBlockMessage.create(blockToPurge, Difficulty.ZERO); + NewBlockMessage.create(blockToPurge, Difficulty.ZERO, maxMessageSize); // Broadcast EthProtocolManagerTestUtil.broadcastMessage(ethProtocolManager, peer, blockAnnouncementMsg); @@ -597,7 +616,8 @@ public abstract class AbstractBlockPropagationManagerTest { getFullBlockchain().getTotalDifficultyByHash(nextBlock.getHeader().getParentHash()).get(); final Difficulty totalDifficulty = getFullBlockchain().getTotalDifficultyByHash(nextBlock.getHash()).get(); - final NewBlockMessage nextAnnouncement = NewBlockMessage.create(nextBlock, totalDifficulty); + final NewBlockMessage nextAnnouncement = + NewBlockMessage.create(nextBlock, totalDifficulty, maxMessageSize); // Broadcast message EthProtocolManagerTestUtil.broadcastMessage(ethProtocolManager, peer, nextAnnouncement); @@ -735,7 +755,8 @@ public abstract class AbstractBlockPropagationManagerTest { final Difficulty totalDifficulty = getFullBlockchain().getTotalDifficultyByHash(block.getHash()).get(); - final NewBlockMessage newBlockMessage = NewBlockMessage.create(block, totalDifficulty); + final NewBlockMessage newBlockMessage = + NewBlockMessage.create(block, totalDifficulty, maxMessageSize); // Broadcast message EthProtocolManagerTestUtil.broadcastMessage(ethProtocolManager, peer, newBlockMessage); @@ -933,7 +954,9 @@ public abstract class AbstractBlockPropagationManagerTest { final RespondingEthPeer peer = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 0); final NewBlockMessage nextAnnouncement = NewBlockMessage.create( - nextBlock, getFullBlockchain().getTotalDifficultyByHash(nextBlock.getHash()).get()); + nextBlock, + getFullBlockchain().getTotalDifficultyByHash(nextBlock.getHash()).get(), + maxMessageSize); final Responder responder = RespondingEthPeer.blockchainResponder(getFullBlockchain()); syncState.setReachedTerminalDifficulty(true); diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/BlockBroadcasterTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/BlockBroadcasterTest.java index da8f269b89..ef1220fd55 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/BlockBroadcasterTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/BlockBroadcasterTest.java @@ -30,6 +30,7 @@ import org.hyperledger.besu.ethereum.eth.manager.EthPeer; import org.hyperledger.besu.ethereum.eth.manager.EthPeers; import org.hyperledger.besu.ethereum.eth.messages.NewBlockMessage; import org.hyperledger.besu.ethereum.p2p.rlpx.connections.PeerConnection; +import org.hyperledger.besu.util.number.ByteUnits; import java.util.Collections; import java.util.stream.Stream; @@ -38,6 +39,8 @@ import org.junit.jupiter.api.Test; public class BlockBroadcasterTest { + final int maxMessageSize = 10 * ByteUnits.MEGABYTE; + @Test public void blockPropagationUnitTest() throws PeerConnection.PeerNotConnected { final EthPeer ethPeer = mock(EthPeer.class); @@ -47,10 +50,10 @@ public class BlockBroadcasterTest { final EthContext ethContext = mock(EthContext.class); when(ethContext.getEthPeers()).thenReturn(ethPeers); - final BlockBroadcaster blockBroadcaster = new BlockBroadcaster(ethContext); + final BlockBroadcaster blockBroadcaster = new BlockBroadcaster(ethContext, maxMessageSize); final Block block = generateBlock(); final NewBlockMessage newBlockMessage = - NewBlockMessage.create(block, block.getHeader().getDifficulty()); + NewBlockMessage.create(block, block.getHeader().getDifficulty(), maxMessageSize); blockBroadcaster.propagate(block, Difficulty.ZERO); @@ -70,10 +73,10 @@ public class BlockBroadcasterTest { final EthContext ethContext = mock(EthContext.class); when(ethContext.getEthPeers()).thenReturn(ethPeers); - final BlockBroadcaster blockBroadcaster = new BlockBroadcaster(ethContext); + final BlockBroadcaster blockBroadcaster = new BlockBroadcaster(ethContext, maxMessageSize); final Block block = generateBlock(); final NewBlockMessage newBlockMessage = - NewBlockMessage.create(block, block.getHeader().getDifficulty()); + NewBlockMessage.create(block, block.getHeader().getDifficulty(), maxMessageSize); blockBroadcaster.propagate(block, Difficulty.ZERO); From 77743b22f2bad11cf711435dffa76f4c41fa8c8d Mon Sep 17 00:00:00 2001 From: garyschulte Date: Thu, 29 Aug 2024 15:06:05 -0700 Subject: [PATCH 165/259] Bump besu-native (#7543) * pull in latest besu native, addressing ecmul perf Signed-off-by: garyschulte --- CHANGELOG.md | 1 + gradle/verification-metadata.xml | 70 ++++++++++++++++---------------- gradle/versions.gradle | 2 +- 3 files changed, 37 insertions(+), 36 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 81183f6514..20bbb812af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ - Add bootnode to holesky config [#7500](https://github.com/hyperledger/besu/pull/7500) - Implement engine_getClientVersionV1 [#7512](https://github.com/hyperledger/besu/pull/7512) - Performance optimzation for ECMUL (1 of 2) [#7509](https://github.com/hyperledger/besu/pull/7509) +- Performance optimzation for ECMUL (2 of 2) [#7543](https://github.com/hyperledger/besu/pull/7543) ### Bug fixes - Fix tracing in precompiled contracts when halting for out of gas [#7318](https://github.com/hyperledger/besu/issues/7318) diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index 49c1e7f00c..bd4023f708 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -4661,12 +4661,12 @@ - - - + + + - - + + @@ -4677,52 +4677,52 @@ - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + diff --git a/gradle/versions.gradle b/gradle/versions.gradle index e0baf3bb46..587b464ee3 100644 --- a/gradle/versions.gradle +++ b/gradle/versions.gradle @@ -156,7 +156,7 @@ dependencyManagement { dependency 'org.fusesource.jansi:jansi:2.4.1' - dependencySet(group: 'org.hyperledger.besu', version: '0.9.4') { + dependencySet(group: 'org.hyperledger.besu', version: '0.9.5') { entry 'arithmetic' entry 'ipa-multipoint' entry 'bls12-381' From 039f0441c6aca634737f6a03993885d16fed8cf5 Mon Sep 17 00:00:00 2001 From: Fabio Di Fabio Date: Fri, 30 Aug 2024 02:14:49 +0200 Subject: [PATCH 166/259] Alternative solution to execute spotlessCheck first during a build (#7541) Signed-off-by: Fabio Di Fabio --- build.gradle | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/build.gradle b/build.gradle index 6211183a7a..41c309030c 100644 --- a/build.gradle +++ b/build.gradle @@ -45,10 +45,6 @@ sonarqube { } } -tasks.register('spotlessCheckFast') { - dependsOn subprojects.collect { it.tasks.withType(com.diffplug.gradle.spotless.SpotlessCheck) } -} - project.tasks["sonarqube"].dependsOn "jacocoRootReport" if (!JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_21)) { @@ -60,12 +56,15 @@ group = 'org.hyperledger.besu' defaultTasks 'build', 'checkLicense', 'javadoc' -def buildAliases = ['dev': [ +def buildAliases = [ + 'dev': [ 'spotlessApply', 'build', 'checkLicense', 'javadoc' - ]] + ], + 'build': ['spotlessCheck', 'build'] +] def expandedTaskList = [] gradle.startParameter.taskNames.each { @@ -436,12 +435,6 @@ allprojects { options.addStringOption('Xwerror', '-html5') options.encoding = 'UTF-8' } - - plugins.withType(JavaPlugin) { - tasks.withType(JavaCompile) { - it.dependsOn(rootProject.tasks.named('spotlessCheckFast')) - } - } } task deploy() {} @@ -465,7 +458,7 @@ task checkMavenCoordinateCollisions { tasks.register('checkPluginAPIChanges', DefaultTask) {} checkPluginAPIChanges.dependsOn(':plugin-api:checkAPIChanges') -check.dependsOn('checkPluginAPIChanges', 'checkMavenCoordinateCollisions', 'spotlessCheckFast') +check.dependsOn('checkPluginAPIChanges', 'checkMavenCoordinateCollisions') subprojects { From 892846aeab989d1ffeb5ccfc9ce1754ebde5e3c5 Mon Sep 17 00:00:00 2001 From: Suyash Nayan <89125422+7suyash7@users.noreply.github.com> Date: Fri, 30 Aug 2024 10:38:34 +0530 Subject: [PATCH 167/259] Add qbft_getRequestTimeoutSeconds RPC Method (#7521) * Add qbft_getRequestTimeoutSeconds RPC Method Signed-off-by: 7suyash7 --- .../controller/QbftBesuControllerBuilder.java | 6 +- .../qbft/jsonrpc/QbftJsonRpcMethods.java | 26 ++++--- .../methods/QbftGetRequestTimeoutSeconds.java | 51 ++++++++++++++ .../QbftGetRequestTimeoutSecondsTest.java | 68 +++++++++++++++++++ .../besu/ethereum/api/jsonrpc/RpcMethod.java | 1 + 5 files changed, 143 insertions(+), 9 deletions(-) create mode 100644 consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftGetRequestTimeoutSeconds.java create mode 100644 consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftGetRequestTimeoutSecondsTest.java 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 ab2dbce3f1..7961305c48 100644 --- a/besu/src/main/java/org/hyperledger/besu/controller/QbftBesuControllerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/controller/QbftBesuControllerBuilder.java @@ -16,6 +16,7 @@ package org.hyperledger.besu.controller; import static com.google.common.base.Preconditions.checkNotNull; +import org.hyperledger.besu.config.BftConfigOptions; import org.hyperledger.besu.config.BftFork; import org.hyperledger.besu.config.QbftConfigOptions; import org.hyperledger.besu.config.QbftFork; @@ -103,6 +104,7 @@ public class QbftBesuControllerBuilder extends BftBesuControllerBuilder { private ForksSchedule qbftForksSchedule; private ValidatorPeers peers; private TransactionValidatorProvider transactionValidatorProvider; + private BftConfigOptions bftConfigOptions; /** Default Constructor. */ public QbftBesuControllerBuilder() {} @@ -120,6 +122,7 @@ public class QbftBesuControllerBuilder extends BftBesuControllerBuilder { qbftConfig = genesisConfigOptions.getQbftConfigOptions(); bftEventQueue = new BftEventQueue(qbftConfig.getMessageQueueLimit()); qbftForksSchedule = QbftForksSchedulesFactory.create(genesisConfigOptions); + bftConfigOptions = qbftConfig; } @Override @@ -132,7 +135,8 @@ public class QbftBesuControllerBuilder extends BftBesuControllerBuilder { protocolContext, protocolSchedule, miningParameters, - createReadOnlyValidatorProvider(protocolContext.getBlockchain())); + createReadOnlyValidatorProvider(protocolContext.getBlockchain()), + bftConfigOptions); } private ValidatorProvider createReadOnlyValidatorProvider(final Blockchain blockchain) { diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/QbftJsonRpcMethods.java b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/QbftJsonRpcMethods.java index 366d1c560d..ce8ce388f2 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/QbftJsonRpcMethods.java +++ b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/QbftJsonRpcMethods.java @@ -14,11 +14,13 @@ */ package org.hyperledger.besu.consensus.qbft.jsonrpc; +import org.hyperledger.besu.config.BftConfigOptions; import org.hyperledger.besu.consensus.common.BlockInterface; import org.hyperledger.besu.consensus.common.bft.BftContext; import org.hyperledger.besu.consensus.common.validator.ValidatorProvider; import org.hyperledger.besu.consensus.qbft.jsonrpc.methods.QbftDiscardValidatorVote; import org.hyperledger.besu.consensus.qbft.jsonrpc.methods.QbftGetPendingVotes; +import org.hyperledger.besu.consensus.qbft.jsonrpc.methods.QbftGetRequestTimeoutSeconds; import org.hyperledger.besu.consensus.qbft.jsonrpc.methods.QbftGetSignerMetrics; import org.hyperledger.besu.consensus.qbft.jsonrpc.methods.QbftGetValidatorsByBlockHash; import org.hyperledger.besu.consensus.qbft.jsonrpc.methods.QbftGetValidatorsByBlockNumber; @@ -40,6 +42,7 @@ public class QbftJsonRpcMethods extends ApiGroupJsonRpcMethods { private final ValidatorProvider readOnlyValidatorProvider; private final ProtocolSchedule protocolSchedule; private final MiningParameters miningParameters; + private final BftConfigOptions bftConfig; /** * Instantiates a new Qbft json rpc methods. @@ -48,16 +51,19 @@ public class QbftJsonRpcMethods extends ApiGroupJsonRpcMethods { * @param protocolSchedule the protocol schedule * @param miningParameters the mining parameters * @param readOnlyValidatorProvider the read only validator provider + * @param bftConfig the BFT config options, containing QBFT-specific settings */ public QbftJsonRpcMethods( final ProtocolContext context, final ProtocolSchedule protocolSchedule, final MiningParameters miningParameters, - final ValidatorProvider readOnlyValidatorProvider) { + final ValidatorProvider readOnlyValidatorProvider, + final BftConfigOptions bftConfig) { this.context = context; this.readOnlyValidatorProvider = readOnlyValidatorProvider; this.protocolSchedule = protocolSchedule; this.miningParameters = miningParameters; + this.bftConfig = bftConfig; } @Override @@ -77,12 +83,16 @@ public class QbftJsonRpcMethods extends ApiGroupJsonRpcMethods { final BlockInterface blockInterface = bftContext.getBlockInterface(); final ValidatorProvider validatorProvider = bftContext.getValidatorProvider(); - return mapOf( - new QbftProposeValidatorVote(validatorProvider), - new QbftGetValidatorsByBlockNumber(blockchainQueries, readOnlyValidatorProvider), - new QbftDiscardValidatorVote(validatorProvider), - new QbftGetValidatorsByBlockHash(context.getBlockchain(), readOnlyValidatorProvider), - new QbftGetSignerMetrics(readOnlyValidatorProvider, blockInterface, blockchainQueries), - new QbftGetPendingVotes(validatorProvider)); + Map methods = + mapOf( + new QbftProposeValidatorVote(validatorProvider), + new QbftGetValidatorsByBlockNumber(blockchainQueries, readOnlyValidatorProvider), + new QbftDiscardValidatorVote(validatorProvider), + new QbftGetValidatorsByBlockHash(context.getBlockchain(), readOnlyValidatorProvider), + new QbftGetSignerMetrics(readOnlyValidatorProvider, blockInterface, blockchainQueries), + new QbftGetPendingVotes(validatorProvider), + new QbftGetRequestTimeoutSeconds(bftConfig)); + + return methods; } } diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftGetRequestTimeoutSeconds.java b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftGetRequestTimeoutSeconds.java new file mode 100644 index 0000000000..0cd12c95e7 --- /dev/null +++ b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftGetRequestTimeoutSeconds.java @@ -0,0 +1,51 @@ +/* + * 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.consensus.qbft.jsonrpc.methods; + +import org.hyperledger.besu.config.BftConfigOptions; +import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; + +/** + * Implements the qbft_getRequestTimeoutSeconds RPC method to retrieve the QBFT request timeout in + * seconds. + */ +public class QbftGetRequestTimeoutSeconds implements JsonRpcMethod { + + private final BftConfigOptions bftConfig; + + /** + * Constructs a new QbftGetRequestTimeoutSeconds instance. + * + * @param bftConfig The BFT configuration options + */ + public QbftGetRequestTimeoutSeconds(final BftConfigOptions bftConfig) { + this.bftConfig = bftConfig; + } + + @Override + public String getName() { + return RpcMethod.QBFT_GET_REQUEST_TIMEOUT_SECONDS.getMethodName(); + } + + @Override + public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { + return new JsonRpcSuccessResponse( + requestContext.getRequest().getId(), bftConfig.getRequestTimeoutSeconds()); + } +} diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftGetRequestTimeoutSecondsTest.java b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftGetRequestTimeoutSecondsTest.java new file mode 100644 index 0000000000..bc7e4b8e28 --- /dev/null +++ b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/jsonrpc/methods/QbftGetRequestTimeoutSecondsTest.java @@ -0,0 +1,68 @@ +/* + * 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.consensus.qbft.jsonrpc.methods; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.when; + +import org.hyperledger.besu.config.BftConfigOptions; +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.response.JsonRpcResponse; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; + +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) +public class QbftGetRequestTimeoutSecondsTest { + + private static final String JSON_RPC_VERSION = "2.0"; + private static final String METHOD_NAME = "qbft_getRequestTimeoutSeconds"; + + @Mock private BftConfigOptions bftConfigOptions; + + private QbftGetRequestTimeoutSeconds method; + + @BeforeEach + public void setUp() { + this.method = new QbftGetRequestTimeoutSeconds(bftConfigOptions); + } + + @Test + public void shouldReturnCorrectMethodName() { + assertThat(method.getName()).isEqualTo(METHOD_NAME); + } + + @Test + public void shouldReturnCorrectRequestTimeout() { + final int expectedTimeout = 5; + when(bftConfigOptions.getRequestTimeoutSeconds()).thenReturn(expectedTimeout); + JsonRpcRequestContext request = requestWithParams(); + + JsonRpcResponse response = method.response(request); + + assertThat(response).isInstanceOf(JsonRpcSuccessResponse.class); + JsonRpcSuccessResponse successResponse = (JsonRpcSuccessResponse) response; + assertThat(successResponse.getResult()).isEqualTo(expectedTimeout); + } + + private JsonRpcRequestContext requestWithParams(final Object... params) { + return new JsonRpcRequestContext(new JsonRpcRequest(JSON_RPC_VERSION, METHOD_NAME, params)); + } +} diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcMethod.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcMethod.java index 75da090480..79d33ffbac 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcMethod.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcMethod.java @@ -153,6 +153,7 @@ public enum RpcMethod { QBFT_GET_VALIDATORS_BY_BLOCK_NUMBER("qbft_getValidatorsByBlockNumber"), QBFT_PROPOSE_VALIDATOR_VOTE("qbft_proposeValidatorVote"), QBFT_GET_SIGNER_METRICS("qbft_getSignerMetrics"), + QBFT_GET_REQUEST_TIMEOUT_SECONDS("qbft_getRequestTimeoutSeconds"), MINER_CHANGE_TARGET_GAS_LIMIT("miner_changeTargetGasLimit"), MINER_SET_COINBASE("miner_setCoinbase"), MINER_SET_ETHERBASE("miner_setEtherbase"), From 1ea1d4cedef4a96a6dbc4f2fffc7e30a975bc215 Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Fri, 30 Aug 2024 16:01:43 +1000 Subject: [PATCH 168/259] Revert engine getclientversionv1 changes (#7546) * Revert "Check for commit hash before appending another in build.gradle caclulateVersion (#7537)" This reverts commit a8bbcd5d8b85141051cb6fba4f01ac35e0caddaf. Signed-off-by: Matilda Clerke * Revert engine_getClientVersionV1 changes Signed-off-by: Matilda Clerke --------- Signed-off-by: Matilda Clerke --- CHANGELOG.md | 1 - .../java/org/hyperledger/besu/BesuInfo.java | 39 +--------- .../org/hyperledger/besu/RunnerBuilder.java | 2 - .../org/hyperledger/besu/BesuInfoTest.java | 7 +- build.gradle | 24 +++---- .../jsonrpc/JsonRpcTestMethodsFactory.java | 6 +- .../besu/ethereum/api/jsonrpc/RpcMethod.java | 1 - .../engine/EngineGetClientVersionV1.java | 57 --------------- .../EngineGetClientVersionResultV1.java | 52 -------------- .../ExecutionEngineJsonRpcMethods.java | 13 +--- .../methods/JsonRpcMethodsFactory.java | 10 +-- .../AbstractJsonRpcHttpServiceTest.java | 6 +- .../jsonrpc/AdminJsonRpcHttpServiceTest.java | 6 +- .../JsonRpcHttpServiceHostAllowlistTest.java | 6 +- .../jsonrpc/JsonRpcHttpServiceLoginTest.java | 6 +- .../JsonRpcHttpServiceRpcApisTest.java | 8 +-- .../api/jsonrpc/JsonRpcHttpServiceTest.java | 26 +++---- .../jsonrpc/JsonRpcHttpServiceTestBase.java | 6 +- .../JsonRpcHttpServiceTlsClientAuthTest.java | 6 +- ...RpcHttpServiceTlsMisconfigurationTest.java | 6 +- .../jsonrpc/JsonRpcHttpServiceTlsTest.java | 6 +- .../engine/EngineGetClientVersionV1Test.java | 72 ------------------- .../websocket/WebSocketServiceLoginTest.java | 6 +- 23 files changed, 49 insertions(+), 323 deletions(-) delete mode 100644 ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetClientVersionV1.java delete mode 100644 ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/EngineGetClientVersionResultV1.java delete mode 100644 ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetClientVersionV1Test.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 20bbb812af..51494f46b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,6 @@ - Add 'inbound' field to admin_peers JSON-RPC Call [#7461](https://github.com/hyperledger/besu/pull/7461) - Add pending block header to `TransactionEvaluationContext` plugin API [#7483](https://github.com/hyperledger/besu/pull/7483) - Add bootnode to holesky config [#7500](https://github.com/hyperledger/besu/pull/7500) -- Implement engine_getClientVersionV1 [#7512](https://github.com/hyperledger/besu/pull/7512) - Performance optimzation for ECMUL (1 of 2) [#7509](https://github.com/hyperledger/besu/pull/7509) - Performance optimzation for ECMUL (2 of 2) [#7543](https://github.com/hyperledger/besu/pull/7543) diff --git a/besu/src/main/java/org/hyperledger/besu/BesuInfo.java b/besu/src/main/java/org/hyperledger/besu/BesuInfo.java index aa5163c2af..54447a5960 100644 --- a/besu/src/main/java/org/hyperledger/besu/BesuInfo.java +++ b/besu/src/main/java/org/hyperledger/besu/BesuInfo.java @@ -17,8 +17,6 @@ package org.hyperledger.besu; import org.hyperledger.besu.util.platform.PlatformDetector; import java.util.Optional; -import java.util.regex.Matcher; -import java.util.regex.Pattern; /** * Represent Besu information such as version, OS etc. Used with --version option and during Besu @@ -26,29 +24,9 @@ import java.util.regex.Pattern; */ public final class BesuInfo { private static final String CLIENT = "besu"; + private static final String VERSION = BesuInfo.class.getPackage().getImplementationVersion(); private static final String OS = PlatformDetector.getOS(); private static final String VM = PlatformDetector.getVM(); - private static final String VERSION; - private static final String COMMIT; - - static { - String projectVersion = BesuInfo.class.getPackage().getImplementationVersion(); - if (projectVersion == null) { - // protect against unset project version (e.g. unit tests being run, etc) - VERSION = null; - COMMIT = null; - } else { - Pattern pattern = - Pattern.compile("(?\\d+\\.\\d+\\.?\\d?-?\\w*)-(?[0-9a-fA-F]{8})"); - Matcher matcher = pattern.matcher(projectVersion); - if (matcher.find()) { - VERSION = matcher.group("version"); - COMMIT = matcher.group("commit"); - } else { - throw new RuntimeException("Invalid project version: " + projectVersion); - } - } - } private BesuInfo() {} @@ -68,7 +46,7 @@ public final class BesuInfo { * or "besu/v23.1.0/osx-aarch_64/corretto-java-19" */ public static String version() { - return String.format("%s/v%s-%s/%s/%s", CLIENT, VERSION, COMMIT, OS, VM); + return String.format("%s/v%s/%s/%s", CLIENT, VERSION, OS, VM); } /** @@ -79,18 +57,7 @@ public final class BesuInfo { */ public static String nodeName(final Optional maybeIdentity) { return maybeIdentity - .map( - identity -> - String.format("%s/%s/v%s-%s/%s/%s", CLIENT, identity, VERSION, COMMIT, OS, VM)) + .map(identity -> String.format("%s/%s/v%s/%s/%s", CLIENT, identity, VERSION, OS, VM)) .orElse(version()); } - - /** - * Generate the commit hash for this besu version - * - * @return the commit hash for this besu version - */ - public static String commit() { - return COMMIT; - } } diff --git a/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java b/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java index 9eaf254bbf..e34c0115fe 100644 --- a/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java @@ -1291,8 +1291,6 @@ public class RunnerBuilder { new JsonRpcMethodsFactory() .methods( BesuInfo.nodeName(identityString), - BesuInfo.shortVersion(), - BesuInfo.commit(), ethNetworkConfig.networkId(), besuController.getGenesisConfigOptions(), network, diff --git a/besu/src/test/java/org/hyperledger/besu/BesuInfoTest.java b/besu/src/test/java/org/hyperledger/besu/BesuInfoTest.java index b7799f5ac3..5a1cec440c 100644 --- a/besu/src/test/java/org/hyperledger/besu/BesuInfoTest.java +++ b/besu/src/test/java/org/hyperledger/besu/BesuInfoTest.java @@ -33,8 +33,7 @@ public final class BesuInfoTest { */ @Test public void versionStringIsEthstatsFriendly() { - assertThat(BesuInfo.version()) - .matches("[^/]+/v(\\d+\\.\\d+\\.\\d+[^/]*|null-null)/[^/]+/[^/]+"); + assertThat(BesuInfo.version()).matches("[^/]+/v(\\d+\\.\\d+\\.\\d+[^/]*|null)/[^/]+/[^/]+"); } /** @@ -46,7 +45,7 @@ public final class BesuInfoTest { @Test public void noIdentityNodeNameIsEthstatsFriendly() { assertThat(BesuInfo.nodeName(Optional.empty())) - .matches("[^/]+/v(\\d+\\.\\d+\\.\\d+[^/]*|null-null)/[^/]+/[^/]+"); + .matches("[^/]+/v(\\d+\\.\\d+\\.\\d+[^/]*|null)/[^/]+/[^/]+"); } /** @@ -59,6 +58,6 @@ public final class BesuInfoTest { @Test public void userIdentityNodeNameIsEthstatsFriendly() { assertThat(BesuInfo.nodeName(Optional.of("TestUserIdentity"))) - .matches("[^/]+/[^/]+/v(\\d+\\.\\d+\\.\\d+[^/]*|null-null)/[^/]+/[^/]+"); + .matches("[^/]+/[^/]+/v(\\d+\\.\\d+\\.\\d+[^/]*|null)/[^/]+/[^/]+"); } } diff --git a/build.gradle b/build.gradle index 41c309030c..1a41a05b2f 100644 --- a/build.gradle +++ b/build.gradle @@ -823,7 +823,7 @@ task distDocker { dockerPlatform = "--platform ${project.getProperty('docker-platform')}" println "Building for platform ${project.getProperty('docker-platform')}" } - def gitDetails = getGitCommitDetails() + def gitDetails = getGitCommitDetails(7) executable shell workingDir dockerBuildDir args "-c", "docker build ${dockerPlatform} --build-arg BUILD_DATE=${buildTime()} --build-arg VERSION=${dockerBuildVersion} --build-arg VCS_REF=${gitDetails.hash} -t ${image} ." @@ -990,18 +990,18 @@ def buildTime() { @Memoized def calculateVersion() { // Regex pattern for basic calendar versioning, with provision to omit patch rev - def calVerPattern = ~/\d+\.\d+(\.\d+)?(-\w+)?$/ - def calVerWithCommitPattern = ~/\d+\.\d+(\.\d+)?(-\w+)?-[0-9a-fA-F]{7,8}$/ - def gitDetails = getGitCommitDetails() // Adjust length as needed - if (project.hasProperty('version') && project.version =~ calVerWithCommitPattern) { - println("Utilising supplied version as it appears to already contain commit hash: ${project.version}") - return project.version - } else if (project.hasProperty('version') && project.version =~ calVerPattern) { - println("Generating project version using supplied version: ${project.version}-${gitDetails.hash}") - return "${project.version}-${gitDetails.hash}" - } else { + def calVerPattern = ~/\d+\.\d+(\.\d+)?(-.*)?/ + + if (project.hasProperty('version') && (project.version =~ calVerPattern)) { + if (project.hasProperty('versionappendcommit') && project.versionappendcommit == "true") { + def gitDetails = getGitCommitDetails(7) // Adjust length as needed + return "${project.version}-${gitDetails.hash}" + } + return "${project.version}" + } else { // If no version is supplied or it doesn't match the semantic versioning, calculate from git - println("Generating project version using date (${gitDetails.date}-develop-${gitDetails.hash}), as supplied version is not semver: ${project.version}") + println("Generating project version as supplied is version not semver: ${project.version}") + def gitDetails = getGitCommitDetails(7) // Adjust length as needed return "${gitDetails.date}-develop-${gitDetails.hash}" } } 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 b5f65e6d4b..a8226a6a69 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 @@ -64,9 +64,7 @@ import io.vertx.core.VertxOptions; /** Provides a facade to construct the JSON-RPC component. */ 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 String CLIENT_VERSION = "TestClientVersion/0.1.0"; private static final BigInteger NETWORK_ID = BigInteger.valueOf(123); private final BlockchainImporter importer; @@ -177,9 +175,7 @@ public class JsonRpcTestMethodsFactory { return new JsonRpcMethodsFactory() .methods( - CLIENT_NODE_NAME, CLIENT_VERSION, - CLIENT_COMMIT, NETWORK_ID, new StubGenesisConfigOptions(), peerDiscovery, diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcMethod.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcMethod.java index 79d33ffbac..5c9da63bc9 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcMethod.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcMethod.java @@ -63,7 +63,6 @@ public enum RpcMethod { ENGINE_FORKCHOICE_UPDATED_V2("engine_forkchoiceUpdatedV2"), ENGINE_FORKCHOICE_UPDATED_V3("engine_forkchoiceUpdatedV3"), ENGINE_EXCHANGE_TRANSITION_CONFIGURATION("engine_exchangeTransitionConfigurationV1"), - ENGINE_GET_CLIENT_VERSION_V1("engine_getClientVersionV1"), ENGINE_GET_PAYLOAD_BODIES_BY_HASH_V1("engine_getPayloadBodiesByHashV1"), ENGINE_GET_PAYLOAD_BODIES_BY_RANGE_V1("engine_getPayloadBodiesByRangeV1"), ENGINE_EXCHANGE_CAPABILITIES("engine_exchangeCapabilities"), 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 deleted file mode 100644 index 5b1142eee0..0000000000 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetClientVersionV1.java +++ /dev/null @@ -1,57 +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.methods.engine; - -import org.hyperledger.besu.ethereum.ProtocolContext; -import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod; -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.api.jsonrpc.internal.results.EngineGetClientVersionResultV1; - -import io.vertx.core.Vertx; - -public class EngineGetClientVersionV1 extends ExecutionEngineJsonRpcMethod { - private static final String ENGINE_CLIENT_CODE = "BU"; - private static final String ENGINE_CLIENT_NAME = "Besu"; - - private final String clientVersion; - private final String commit; - - public EngineGetClientVersionV1( - final Vertx vertx, - final ProtocolContext protocolContext, - final EngineCallListener engineCallListener, - final String clientVersion, - final String commit) { - super(vertx, protocolContext, engineCallListener); - this.clientVersion = clientVersion; - this.commit = commit; - } - - @Override - public String getName() { - return RpcMethod.ENGINE_GET_CLIENT_VERSION_V1.getMethodName(); - } - - @Override - public JsonRpcResponse syncResponse(final JsonRpcRequestContext request) { - return new JsonRpcSuccessResponse( - request.getRequest().getId(), - new EngineGetClientVersionResultV1( - ENGINE_CLIENT_CODE, ENGINE_CLIENT_NAME, clientVersion, commit)); - } -} diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/EngineGetClientVersionResultV1.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/EngineGetClientVersionResultV1.java deleted file mode 100644 index 8251de6dc5..0000000000 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/EngineGetClientVersionResultV1.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.results; - -import com.fasterxml.jackson.annotation.JsonGetter; - -public class EngineGetClientVersionResultV1 { - private final String code; - private final String name; - private final String version; - private final String commit; - - public EngineGetClientVersionResultV1( - final String code, final String name, final String version, final String commit) { - this.code = code; - this.name = name; - this.version = version; - this.commit = commit; - } - - @JsonGetter(value = "code") - public String getCode() { - return code; - } - - @JsonGetter(value = "name") - public String getName() { - return name; - } - - @JsonGetter(value = "version") - public String getVersion() { - return version; - } - - @JsonGetter(value = "commit") - public String getCommit() { - return commit; - } -} 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 6dda09bce9..ca66926656 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 @@ -23,7 +23,6 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineE import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineForkchoiceUpdatedV1; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineForkchoiceUpdatedV2; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineForkchoiceUpdatedV3; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineGetClientVersionV1; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineGetPayloadBodiesByHashV1; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineGetPayloadBodiesByRangeV1; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineGetPayloadV1; @@ -58,17 +57,13 @@ public class ExecutionEngineJsonRpcMethods extends ApiGroupJsonRpcMethods { private final ProtocolContext protocolContext; private final EthPeers ethPeers; private final Vertx consensusEngineServer; - private final String clientVersion; - private final String commit; ExecutionEngineJsonRpcMethods( final MiningCoordinator miningCoordinator, final ProtocolSchedule protocolSchedule, final ProtocolContext protocolContext, final EthPeers ethPeers, - final Vertx consensusEngineServer, - final String clientVersion, - final String commit) { + final Vertx consensusEngineServer) { this.mergeCoordinator = Optional.ofNullable(miningCoordinator) .filter(mc -> mc.isCompatibleWithEngineApi()) @@ -77,8 +72,6 @@ public class ExecutionEngineJsonRpcMethods extends ApiGroupJsonRpcMethods { this.protocolContext = protocolContext; this.ethPeers = ethPeers; this.consensusEngineServer = consensusEngineServer; - this.clientVersion = clientVersion; - this.commit = commit; } @Override @@ -154,9 +147,7 @@ public class ExecutionEngineJsonRpcMethods extends ApiGroupJsonRpcMethods { new EngineExchangeCapabilities( consensusEngineServer, protocolContext, engineQosTimer), new EnginePreparePayloadDebug( - consensusEngineServer, protocolContext, engineQosTimer, mergeCoordinator.get()), - new EngineGetClientVersionV1( - consensusEngineServer, protocolContext, engineQosTimer, clientVersion, commit))); + consensusEngineServer, protocolContext, engineQosTimer, mergeCoordinator.get()))); if (protocolSchedule.anyMatch(p -> p.spec().getName().equalsIgnoreCase("cancun"))) { executionEngineApisSupported.add( diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/JsonRpcMethodsFactory.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/JsonRpcMethodsFactory.java index 41227c2ca8..924889ef47 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/JsonRpcMethodsFactory.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/JsonRpcMethodsFactory.java @@ -54,9 +54,7 @@ import io.vertx.core.Vertx; public class JsonRpcMethodsFactory { public Map methods( - final String clientNodeName, final String clientVersion, - final String commit, final BigInteger networkId, final GenesisConfigOptions genesisConfigOptions, final P2PNetwork p2pNetwork, @@ -91,7 +89,7 @@ public class JsonRpcMethodsFactory { final List availableApiGroups = List.of( new AdminJsonRpcMethods( - clientNodeName, + clientVersion, networkId, genesisConfigOptions, p2pNetwork, @@ -117,9 +115,7 @@ public class JsonRpcMethodsFactory { protocolSchedule, protocolContext, ethPeers, - consensusEngineServer, - clientVersion, - commit), + consensusEngineServer), new EthJsonRpcMethods( blockchainQueries, synchronizer, @@ -145,7 +141,7 @@ public class JsonRpcMethodsFactory { filterManager), new PrivxJsonRpcMethods( blockchainQueries, protocolSchedule, transactionPool, privacyParameters), - new Web3JsonRpcMethods(clientNodeName), + new Web3JsonRpcMethods(clientVersion), new TraceJsonRpcMethods( blockchainQueries, protocolSchedule, protocolContext, apiConfiguration), new TxPoolJsonRpcMethods(transactionPool), diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/AbstractJsonRpcHttpServiceTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/AbstractJsonRpcHttpServiceTest.java index 862e17b890..9193574c45 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/AbstractJsonRpcHttpServiceTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/AbstractJsonRpcHttpServiceTest.java @@ -75,9 +75,7 @@ public abstract class AbstractJsonRpcHttpServiceTest { protected BlockchainSetupUtil blockchainSetupUtil; - protected static final String CLIENT_NODE_NAME = "TestClientVersion/0.1.0"; - protected static final String CLIENT_VERSION = "0.1.0"; - protected static final String CLIENT_COMMIT = "12345678"; + protected static String CLIENT_VERSION = "TestClientVersion/0.1.0"; protected static final BigInteger NETWORK_ID = BigInteger.valueOf(123); protected static final Collection JSON_RPC_APIS = Arrays.asList( @@ -170,9 +168,7 @@ public abstract class AbstractJsonRpcHttpServiceTest { return new JsonRpcMethodsFactory() .methods( - CLIENT_NODE_NAME, CLIENT_VERSION, - CLIENT_COMMIT, NETWORK_ID, new StubGenesisConfigOptions(), peerDiscoveryMock, diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/AdminJsonRpcHttpServiceTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/AdminJsonRpcHttpServiceTest.java index 4a03b2eb93..061d2a2d6a 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/AdminJsonRpcHttpServiceTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/AdminJsonRpcHttpServiceTest.java @@ -58,13 +58,13 @@ public class AdminJsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { final List peerList = new ArrayList<>(); final PeerInfo info1 = new PeerInfo( - 4, CLIENT_NODE_NAME, caps, 30302, Bytes.fromHexString(String.format("%0128x", 1))); + 4, CLIENT_VERSION, caps, 30302, Bytes.fromHexString(String.format("%0128x", 1))); final PeerInfo info2 = new PeerInfo( - 4, CLIENT_NODE_NAME, caps, 60302, Bytes.fromHexString(String.format("%0128x", 2))); + 4, CLIENT_VERSION, caps, 60302, Bytes.fromHexString(String.format("%0128x", 2))); final PeerInfo info3 = new PeerInfo( - 4, CLIENT_NODE_NAME, caps, 60303, Bytes.fromHexString(String.format("%0128x", 3))); + 4, CLIENT_VERSION, caps, 60303, Bytes.fromHexString(String.format("%0128x", 3))); final InetSocketAddress addr30301 = new InetSocketAddress("localhost", 30301); final InetSocketAddress addr30302 = new InetSocketAddress("localhost", 30302); final InetSocketAddress addr60301 = new InetSocketAddress("localhost", 60301); diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceHostAllowlistTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceHostAllowlistTest.java index 25077bbf82..80626ef2fc 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceHostAllowlistTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceHostAllowlistTest.java @@ -79,9 +79,7 @@ public class JsonRpcHttpServiceHostAllowlistTest { private static OkHttpClient client; private static String baseUrl; private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); - 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 String CLIENT_VERSION = "TestClientVersion/0.1.0"; private static final BigInteger CHAIN_ID = BigInteger.valueOf(123); private final JsonRpcConfiguration jsonRpcConfig = createJsonRpcConfig(); @@ -102,9 +100,7 @@ public class JsonRpcHttpServiceHostAllowlistTest { rpcMethods = new JsonRpcMethodsFactory() .methods( - CLIENT_NODE_NAME, CLIENT_VERSION, - CLIENT_COMMIT, CHAIN_ID, new StubGenesisConfigOptions(), peerDiscoveryMock, diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceLoginTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceLoginTest.java index eb23b054d0..0fb55fdf34 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceLoginTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceLoginTest.java @@ -100,9 +100,7 @@ public class JsonRpcHttpServiceLoginTest { protected static OkHttpClient client; protected static String baseUrl; protected static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); - protected static final String CLIENT_NODE_NAME = "TestClientVersion/0.1.0"; - protected static final String CLIENT_VERSION = "0.1.0"; - protected static final String CLIENT_COMMIT = "12345678"; + protected static final String CLIENT_VERSION = "TestClientVersion/0.1.0"; protected static final BigInteger CHAIN_ID = BigInteger.valueOf(123); protected static P2PNetwork peerDiscoveryMock; protected static BlockchainQueries blockchainQueries; @@ -133,9 +131,7 @@ public class JsonRpcHttpServiceLoginTest { rpcMethods = new JsonRpcMethodsFactory() .methods( - CLIENT_NODE_NAME, CLIENT_VERSION, - CLIENT_COMMIT, CHAIN_ID, genesisConfigOptions, peerDiscoveryMock, diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceRpcApisTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceRpcApisTest.java index f35893490a..8323f61b2c 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceRpcApisTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceRpcApisTest.java @@ -94,9 +94,7 @@ public class JsonRpcHttpServiceRpcApisTest { private JsonRpcHttpService service; private static String baseUrl; private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); - 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 String CLIENT_VERSION = "TestClientVersion/0.1.0"; private static final BigInteger NETWORK_ID = BigInteger.valueOf(123); private JsonRpcConfiguration configuration; private static final List netServices = @@ -204,9 +202,7 @@ public class JsonRpcHttpServiceRpcApisTest { final Map rpcMethods = new JsonRpcMethodsFactory() .methods( - CLIENT_NODE_NAME, CLIENT_VERSION, - CLIENT_COMMIT, NETWORK_ID, new StubGenesisConfigOptions(), mock(P2PNetwork.class), @@ -314,9 +310,7 @@ public class JsonRpcHttpServiceRpcApisTest { final Map rpcMethods = new JsonRpcMethodsFactory() .methods( - CLIENT_NODE_NAME, CLIENT_VERSION, - CLIENT_COMMIT, NETWORK_ID, new StubGenesisConfigOptions(), p2pNetwork, diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTest.java index 52f2ee050c..bb5cb68a2a 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTest.java @@ -202,7 +202,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { testHelper.assertValidJsonRpcResult(json, id); // Check result final String result = json.getString("result"); - assertThat(result).isEqualTo(CLIENT_NODE_NAME); + assertThat(result).isEqualTo(CLIENT_VERSION); } } @@ -1127,7 +1127,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { testHelper.assertValidJsonRpcResult(json, id); // Check result final String result = json.getString("result"); - assertThat(result).isEqualTo(CLIENT_NODE_NAME); + assertThat(result).isEqualTo(CLIENT_VERSION); } } @@ -1143,7 +1143,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { final JsonObject json = new JsonObject(resp.body().string()); testHelper.assertValidJsonRpcResult(json, id); final String result = json.getString("result"); - assertThat(result).isEqualTo(CLIENT_NODE_NAME); + assertThat(result).isEqualTo(CLIENT_VERSION); } } @@ -1175,7 +1175,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { testHelper.assertValidJsonRpcResult(json, null); // Check result final String result = json.getString("result"); - assertThat(result).isEqualTo(CLIENT_NODE_NAME); + assertThat(result).isEqualTo(CLIENT_VERSION); } } @@ -1197,7 +1197,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { testHelper.assertValidJsonRpcResult(json, id); // Check result final String result = json.getString("result"); - assertThat(result).isEqualTo(CLIENT_NODE_NAME); + assertThat(result).isEqualTo(CLIENT_VERSION); } } @@ -1218,7 +1218,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { testHelper.assertValidJsonRpcResult(json, id); // Check result final String result = json.getString("result"); - assertThat(result).isEqualTo(CLIENT_NODE_NAME); + assertThat(result).isEqualTo(CLIENT_VERSION); } } @@ -1242,7 +1242,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { testHelper.assertValidJsonRpcResult(json, id); // Check result final String result = json.getString("result"); - assertThat(result).isEqualTo(CLIENT_NODE_NAME); + assertThat(result).isEqualTo(CLIENT_VERSION); } } @@ -1268,7 +1268,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { testHelper.assertValidJsonRpcResult(json, id); // Check result final String result = json.getString("result"); - assertThat(result).isEqualTo(CLIENT_NODE_NAME); + assertThat(result).isEqualTo(CLIENT_VERSION); } } @@ -1289,7 +1289,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { testHelper.assertValidJsonRpcResult(json, id); // Check result final String result = json.getString("result"); - assertThat(result).isEqualTo(CLIENT_NODE_NAME); + assertThat(result).isEqualTo(CLIENT_VERSION); } } @@ -1353,7 +1353,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { final JsonObject json = new JsonObject(resp.body().string()); testHelper.assertValidJsonRpcResult(json, id); final String result = json.getString("result"); - assertThat(result).isEqualTo(CLIENT_NODE_NAME); + assertThat(result).isEqualTo(CLIENT_VERSION); } } @@ -1485,7 +1485,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { // Check result web3_clientVersion final JsonObject jsonClientVersion = responses.get(clientVersionRequestId); testHelper.assertValidJsonRpcResult(jsonClientVersion, clientVersionRequestId); - assertThat(jsonClientVersion.getString("result")).isEqualTo(CLIENT_NODE_NAME); + assertThat(jsonClientVersion.getString("result")).isEqualTo(CLIENT_VERSION); // Check result unknown method final JsonObject jsonError = responses.get(brokenRequestId); @@ -1540,7 +1540,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { // Check result web3_clientVersion final JsonObject jsonClientVersion = responses.get(clientVersionRequestId); testHelper.assertValidJsonRpcResult(jsonClientVersion, clientVersionRequestId); - assertThat(jsonClientVersion.getString("result")).isEqualTo(CLIENT_NODE_NAME); + assertThat(jsonClientVersion.getString("result")).isEqualTo(CLIENT_VERSION); // Check invalid request final JsonObject jsonError = responses.get(invalidId); @@ -1605,7 +1605,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { // Check result web3_clientVersion final JsonObject jsonClientVersion = responses.get(clientVersionRequestId); testHelper.assertValidJsonRpcResult(jsonClientVersion, clientVersionRequestId); - assertThat(jsonClientVersion.getString("result")).isEqualTo(CLIENT_NODE_NAME); + assertThat(jsonClientVersion.getString("result")).isEqualTo(CLIENT_VERSION); // Check result net_version final JsonObject jsonNetVersion = responses.get(netVersionRequestId); diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTestBase.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTestBase.java index 5e5dc36bb0..a2a856333e 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTestBase.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTestBase.java @@ -78,9 +78,7 @@ public class JsonRpcHttpServiceTestBase { protected static OkHttpClient client; protected static String baseUrl; protected static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); - protected static final String CLIENT_NODE_NAME = "TestClientVersion/0.1.0"; - protected static final String CLIENT_VERSION = "0.1.0"; - protected static final String CLIENT_COMMIT = "12345678"; + protected static final String CLIENT_VERSION = "TestClientVersion/0.1.0"; protected static final BigInteger CHAIN_ID = BigInteger.valueOf(123); protected static P2PNetwork peerDiscoveryMock; protected static EthPeers ethPeersMock; @@ -110,9 +108,7 @@ public class JsonRpcHttpServiceTestBase { rpcMethods = new JsonRpcMethodsFactory() .methods( - CLIENT_NODE_NAME, CLIENT_VERSION, - CLIENT_COMMIT, CHAIN_ID, new StubGenesisConfigOptions(), peerDiscoveryMock, diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsClientAuthTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsClientAuthTest.java index 5cf13a4576..1d3a3a087a 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsClientAuthTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsClientAuthTest.java @@ -85,9 +85,7 @@ public class JsonRpcHttpServiceTlsClientAuthTest { protected static final Vertx vertx = Vertx.vertx(); private static final String JSON_HEADER = "application/json; charset=utf-8"; - 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 String CLIENT_VERSION = "TestClientVersion/0.1.0"; private static final BigInteger CHAIN_ID = BigInteger.valueOf(123); private static final NatService natService = new NatService(Optional.empty()); @@ -116,9 +114,7 @@ public class JsonRpcHttpServiceTlsClientAuthTest { rpcMethods = new JsonRpcMethodsFactory() .methods( - CLIENT_NODE_NAME, CLIENT_VERSION, - CLIENT_COMMIT, CHAIN_ID, new StubGenesisConfigOptions(), peerDiscoveryMock, diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsMisconfigurationTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsMisconfigurationTest.java index c2661141a4..684f843d2f 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsMisconfigurationTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsMisconfigurationTest.java @@ -75,9 +75,7 @@ class JsonRpcHttpServiceTlsMisconfigurationTest { protected static final Vertx vertx = Vertx.vertx(); - 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 String CLIENT_VERSION = "TestClientVersion/0.1.0"; private static final BigInteger CHAIN_ID = BigInteger.valueOf(123); private static final NatService natService = new NatService(Optional.empty()); private final SelfSignedP12Certificate besuCertificate = SelfSignedP12Certificate.create(); @@ -104,9 +102,7 @@ class JsonRpcHttpServiceTlsMisconfigurationTest { rpcMethods = new JsonRpcMethodsFactory() .methods( - CLIENT_NODE_NAME, CLIENT_VERSION, - CLIENT_COMMIT, CHAIN_ID, new StubGenesisConfigOptions(), peerDiscoveryMock, diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsTest.java index c0846ed9f2..b6d7fa67f8 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsTest.java @@ -81,9 +81,7 @@ public class JsonRpcHttpServiceTlsTest { protected static final Vertx vertx = Vertx.vertx(); private static final String JSON_HEADER = "application/json; charset=utf-8"; - 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 String CLIENT_VERSION = "TestClientVersion/0.1.0"; private static final BigInteger CHAIN_ID = BigInteger.valueOf(123); private static final NatService natService = new NatService(Optional.empty()); private JsonRpcHttpService service; @@ -105,9 +103,7 @@ public class JsonRpcHttpServiceTlsTest { rpcMethods = new JsonRpcMethodsFactory() .methods( - CLIENT_NODE_NAME, CLIENT_VERSION, - CLIENT_COMMIT, CHAIN_ID, new StubGenesisConfigOptions(), peerDiscoveryMock, 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 deleted file mode 100644 index 1aa0def7e2..0000000000 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetClientVersionV1Test.java +++ /dev/null @@ -1,72 +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.methods.engine; - -import static org.assertj.core.api.Assertions.assertThat; - -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.response.JsonRpcResponse; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.EngineGetClientVersionResultV1; - -import io.vertx.core.Vertx; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.Mockito; - -class EngineGetClientVersionV1Test { - - private static final String ENGINE_CLIENT_CODE = "BU"; - private static final String ENGINE_CLIENT_NAME = "Besu"; - - private static final String CLIENT_VERSION = "v25.6.7-dev-abcdef12"; - private static final String COMMIT = "abcdef12"; - - private EngineGetClientVersionV1 getClientVersion; - - @BeforeEach - void before() { - getClientVersion = - new EngineGetClientVersionV1( - Mockito.mock(Vertx.class), - Mockito.mock(ProtocolContext.class), - Mockito.mock(EngineCallListener.class), - CLIENT_VERSION, - COMMIT); - } - - @Test - void testGetName() { - assertThat(getClientVersion.getName()).isEqualTo("engine_getClientVersionV1"); - } - - @Test - void testSyncResponse() { - JsonRpcRequestContext request = new JsonRpcRequestContext(new JsonRpcRequest("v", "m", null)); - JsonRpcResponse actualResult = getClientVersion.syncResponse(request); - - assertThat(actualResult).isInstanceOf(JsonRpcSuccessResponse.class); - JsonRpcSuccessResponse successResponse = (JsonRpcSuccessResponse) actualResult; - assertThat(successResponse.getResult()).isInstanceOf(EngineGetClientVersionResultV1.class); - EngineGetClientVersionResultV1 actualEngineGetClientVersionResultV1 = - (EngineGetClientVersionResultV1) successResponse.getResult(); - assertThat(actualEngineGetClientVersionResultV1.getName()).isEqualTo(ENGINE_CLIENT_NAME); - assertThat(actualEngineGetClientVersionResultV1.getCode()).isEqualTo(ENGINE_CLIENT_CODE); - assertThat(actualEngineGetClientVersionResultV1.getVersion()).isEqualTo(CLIENT_VERSION); - assertThat(actualEngineGetClientVersionResultV1.getCommit()).isEqualTo(COMMIT); - } -} diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/WebSocketServiceLoginTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/WebSocketServiceLoginTest.java index 342941d0e9..75927c4513 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/WebSocketServiceLoginTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/WebSocketServiceLoginTest.java @@ -115,9 +115,7 @@ public class WebSocketServiceLoginTest { protected static OkHttpClient client; protected static String baseUrl; protected static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); - protected static final String CLIENT_NODE_NAME = "TestClientVersion/0.1.0"; - protected static final String CLIENT_VERSION = "0.1.0"; - protected static final String CLIENT_COMMIT = "12345678"; + protected static final String CLIENT_VERSION = "TestClientVersion/0.1.0"; protected static final BigInteger CHAIN_ID = BigInteger.valueOf(123); protected static P2PNetwork peerDiscoveryMock; protected static BlockchainQueries blockchainQueries; @@ -169,9 +167,7 @@ public class WebSocketServiceLoginTest { spy( new JsonRpcMethodsFactory() .methods( - CLIENT_NODE_NAME, CLIENT_VERSION, - CLIENT_COMMIT, CHAIN_ID, genesisConfigOptions, peerDiscoveryMock, From da98fa5541b4b077937fa12fa83a0982b0658b1d Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Sat, 31 Aug 2024 04:13:53 +1000 Subject: [PATCH 169/259] Reintroduce engine get client version v1 with commit in manifest (#7548) * Include Commit-Hash in manifests * Add commit method in BesuInfo * Use 8 character hash in EngineGetClientVersionV1 and revert calculateVersion back to original spec Signed-off-by: Matilda Clerke Co-authored-by: garyschulte --- CHANGELOG.md | 1 + acceptance-tests/test-plugins/build.gradle | 3 +- besu/build.gradle | 3 +- .../java/org/hyperledger/besu/BesuInfo.java | 31 ++++++++ .../org/hyperledger/besu/RunnerBuilder.java | 2 + build.gradle | 2 +- config/build.gradle | 3 +- consensus/clique/build.gradle | 3 +- consensus/common/build.gradle | 3 +- consensus/ibft/build.gradle | 3 +- consensus/merge/build.gradle | 3 +- consensus/qbft/build.gradle | 3 +- crypto/algorithms/build.gradle | 1 + crypto/services/build.gradle | 1 + datatypes/build.gradle | 1 + ethereum/api/build.gradle | 3 +- .../jsonrpc/JsonRpcTestMethodsFactory.java | 6 +- .../besu/ethereum/api/jsonrpc/RpcMethod.java | 1 + .../engine/EngineGetClientVersionV1.java | 57 +++++++++++++++ .../EngineGetClientVersionResultV1.java | 52 ++++++++++++++ .../ExecutionEngineJsonRpcMethods.java | 13 +++- .../methods/JsonRpcMethodsFactory.java | 10 ++- .../AbstractJsonRpcHttpServiceTest.java | 6 +- .../jsonrpc/AdminJsonRpcHttpServiceTest.java | 6 +- .../JsonRpcHttpServiceHostAllowlistTest.java | 6 +- .../jsonrpc/JsonRpcHttpServiceLoginTest.java | 6 +- .../JsonRpcHttpServiceRpcApisTest.java | 8 ++- .../api/jsonrpc/JsonRpcHttpServiceTest.java | 26 +++---- .../jsonrpc/JsonRpcHttpServiceTestBase.java | 6 +- .../JsonRpcHttpServiceTlsClientAuthTest.java | 6 +- ...RpcHttpServiceTlsMisconfigurationTest.java | 6 +- .../jsonrpc/JsonRpcHttpServiceTlsTest.java | 6 +- .../engine/EngineGetClientVersionV1Test.java | 72 +++++++++++++++++++ .../websocket/WebSocketServiceLoginTest.java | 6 +- ethereum/blockcreation/build.gradle | 3 +- ethereum/core/build.gradle | 3 +- ethereum/eth/build.gradle | 3 +- ethereum/ethstats/build.gradle | 3 +- ethereum/evmtool/build.gradle | 3 +- ethereum/mock-p2p/build.gradle | 3 +- ethereum/p2p/build.gradle | 3 +- ethereum/permissioning/build.gradle | 3 +- ethereum/retesteth/build.gradle | 3 +- ethereum/rlp/build.gradle | 1 + ethereum/stratum/build.gradle | 3 +- ethereum/trie/build.gradle | 3 +- ethereum/verkletrie/build.gradle | 3 +- evm/build.gradle | 1 + metrics/core/build.gradle | 3 +- metrics/rocksdb/build.gradle | 3 +- nat/build.gradle | 3 +- pki/build.gradle | 3 +- plugin-api/build.gradle | 1 + plugins/rocksdb/build.gradle | 3 +- services/kvstore/build.gradle | 3 +- services/pipeline/build.gradle | 3 +- services/tasks/build.gradle | 3 +- testfuzz/build.gradle | 3 +- testutil/build.gradle | 3 +- util/build.gradle | 1 + 60 files changed, 372 insertions(+), 63 deletions(-) create mode 100644 ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetClientVersionV1.java create mode 100644 ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/EngineGetClientVersionResultV1.java create mode 100644 ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetClientVersionV1Test.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 51494f46b3..20bbb812af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ - Add 'inbound' field to admin_peers JSON-RPC Call [#7461](https://github.com/hyperledger/besu/pull/7461) - Add pending block header to `TransactionEvaluationContext` plugin API [#7483](https://github.com/hyperledger/besu/pull/7483) - Add bootnode to holesky config [#7500](https://github.com/hyperledger/besu/pull/7500) +- Implement engine_getClientVersionV1 [#7512](https://github.com/hyperledger/besu/pull/7512) - Performance optimzation for ECMUL (1 of 2) [#7509](https://github.com/hyperledger/besu/pull/7509) - Performance optimzation for ECMUL (2 of 2) [#7543](https://github.com/hyperledger/besu/pull/7543) diff --git a/acceptance-tests/test-plugins/build.gradle b/acceptance-tests/test-plugins/build.gradle index 19a45d218a..65a3dc64dc 100644 --- a/acceptance-tests/test-plugins/build.gradle +++ b/acceptance-tests/test-plugins/build.gradle @@ -25,7 +25,8 @@ task testPluginsJar(type: Jar) { 'Specification-Title': archiveBaseName, 'Specification-Version': project.version, 'Implementation-Title': archiveBaseName, - 'Implementation-Version': calculateVersion() + 'Implementation-Version': calculateVersion(), + 'Commit-Hash': getGitCommitDetails(40).hash ) } from sourceSets.main.output diff --git a/besu/build.gradle b/besu/build.gradle index 286ca7a30f..a0e6c7843f 100644 --- a/besu/build.gradle +++ b/besu/build.gradle @@ -22,7 +22,8 @@ jar { 'Specification-Title': archiveBaseName, 'Specification-Version': project.version, 'Implementation-Title': archiveBaseName, - 'Implementation-Version': calculateVersion() + 'Implementation-Version': calculateVersion(), + 'Commit-Hash': getGitCommitDetails(40).hash ) } } diff --git a/besu/src/main/java/org/hyperledger/besu/BesuInfo.java b/besu/src/main/java/org/hyperledger/besu/BesuInfo.java index 54447a5960..94414ee5f7 100644 --- a/besu/src/main/java/org/hyperledger/besu/BesuInfo.java +++ b/besu/src/main/java/org/hyperledger/besu/BesuInfo.java @@ -16,7 +16,11 @@ package org.hyperledger.besu; import org.hyperledger.besu.util.platform.PlatformDetector; +import java.net.JarURLConnection; +import java.net.URL; import java.util.Optional; +import java.util.jar.Attributes; +import java.util.jar.Manifest; /** * Represent Besu information such as version, OS etc. Used with --version option and during Besu @@ -27,6 +31,24 @@ public final class BesuInfo { private static final String VERSION = BesuInfo.class.getPackage().getImplementationVersion(); private static final String OS = PlatformDetector.getOS(); private static final String VM = PlatformDetector.getVM(); + private static final String COMMIT; + + static { + String className = BesuInfo.class.getSimpleName() + ".class"; + String classPath = BesuInfo.class.getResource(className).toString(); + + String commit; + try { + URL url = new URL(classPath); + JarURLConnection jarConnection = (JarURLConnection) url.openConnection(); + Manifest manifest = jarConnection.getManifest(); + Attributes attributes = manifest.getMainAttributes(); + commit = attributes.getValue("Commit-Hash"); + } catch (Exception e) { + commit = null; + } + COMMIT = commit; + } private BesuInfo() {} @@ -60,4 +82,13 @@ public final class BesuInfo { .map(identity -> String.format("%s/%s/v%s/%s/%s", CLIENT, identity, VERSION, OS, VM)) .orElse(version()); } + + /** + * Generate the commit hash for this besu version + * + * @return the commit hash for this besu version + */ + public static String commit() { + return COMMIT; + } } diff --git a/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java b/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java index e34c0115fe..9eaf254bbf 100644 --- a/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java @@ -1291,6 +1291,8 @@ public class RunnerBuilder { new JsonRpcMethodsFactory() .methods( BesuInfo.nodeName(identityString), + BesuInfo.shortVersion(), + BesuInfo.commit(), ethNetworkConfig.networkId(), besuController.getGenesisConfigOptions(), network, diff --git a/build.gradle b/build.gradle index 1a41a05b2f..6898086294 100644 --- a/build.gradle +++ b/build.gradle @@ -823,7 +823,7 @@ task distDocker { dockerPlatform = "--platform ${project.getProperty('docker-platform')}" println "Building for platform ${project.getProperty('docker-platform')}" } - def gitDetails = getGitCommitDetails(7) + def gitDetails = getGitCommitDetails() executable shell workingDir dockerBuildDir args "-c", "docker build ${dockerPlatform} --build-arg BUILD_DATE=${buildTime()} --build-arg VERSION=${dockerBuildVersion} --build-arg VCS_REF=${gitDetails.hash} -t ${image} ." diff --git a/config/build.gradle b/config/build.gradle index ae6b2ff4c4..a78b9a7105 100644 --- a/config/build.gradle +++ b/config/build.gradle @@ -22,7 +22,8 @@ jar { 'Specification-Title': archiveBaseName, 'Specification-Version': project.version, 'Implementation-Title': archiveBaseName, - 'Implementation-Version': calculateVersion() + 'Implementation-Version': calculateVersion(), + 'Commit-Hash': getGitCommitDetails(40).hash ) } } diff --git a/consensus/clique/build.gradle b/consensus/clique/build.gradle index f09e583777..d2fb44c6ef 100644 --- a/consensus/clique/build.gradle +++ b/consensus/clique/build.gradle @@ -22,7 +22,8 @@ jar { 'Specification-Title': archiveBaseName, 'Specification-Version': project.version, 'Implementation-Title': archiveBaseName, - 'Implementation-Version': calculateVersion() + 'Implementation-Version': calculateVersion(), + 'Commit-Hash': getGitCommitDetails(40).hash ) } } diff --git a/consensus/common/build.gradle b/consensus/common/build.gradle index 0043fe0711..7a937f7573 100644 --- a/consensus/common/build.gradle +++ b/consensus/common/build.gradle @@ -22,7 +22,8 @@ jar { 'Specification-Title': archiveBaseName, 'Specification-Version': project.version, 'Implementation-Title': archiveBaseName, - 'Implementation-Version': calculateVersion() + 'Implementation-Version': calculateVersion(), + 'Commit-Hash': getGitCommitDetails(40).hash ) } } diff --git a/consensus/ibft/build.gradle b/consensus/ibft/build.gradle index dd05944803..da6304c4e5 100644 --- a/consensus/ibft/build.gradle +++ b/consensus/ibft/build.gradle @@ -22,7 +22,8 @@ jar { 'Specification-Title': archiveBaseName, 'Specification-Version': project.version, 'Implementation-Title': archiveBaseName, - 'Implementation-Version': calculateVersion() + 'Implementation-Version': calculateVersion(), + 'Commit-Hash': getGitCommitDetails(40).hash ) } } diff --git a/consensus/merge/build.gradle b/consensus/merge/build.gradle index 9476f09d9d..e1b98e21e2 100644 --- a/consensus/merge/build.gradle +++ b/consensus/merge/build.gradle @@ -22,7 +22,8 @@ jar { 'Specification-Title': archiveBaseName, 'Specification-Version': project.version, 'Implementation-Title': archiveBaseName, - 'Implementation-Version': calculateVersion() + 'Implementation-Version': calculateVersion(), + 'Commit-Hash': getGitCommitDetails(40).hash ) } } diff --git a/consensus/qbft/build.gradle b/consensus/qbft/build.gradle index bb3d9a3f89..9675c4df89 100644 --- a/consensus/qbft/build.gradle +++ b/consensus/qbft/build.gradle @@ -22,7 +22,8 @@ jar { 'Specification-Title': archiveBaseName, 'Specification-Version': project.version, 'Implementation-Title': archiveBaseName, - 'Implementation-Version': calculateVersion() + 'Implementation-Version': calculateVersion(), + 'Commit-Hash': getGitCommitDetails(40).hash ) } } diff --git a/crypto/algorithms/build.gradle b/crypto/algorithms/build.gradle index 446a52c371..97b05bd71e 100644 --- a/crypto/algorithms/build.gradle +++ b/crypto/algorithms/build.gradle @@ -23,6 +23,7 @@ jar { 'Specification-Version': project.version, 'Implementation-Title': archiveBaseName, 'Implementation-Version': calculateVersion(), + 'Commit-Hash': getGitCommitDetails(40).hash, 'Automatic-Module-Name': 'org.hyperledger.besu.internal.crypto' ) } diff --git a/crypto/services/build.gradle b/crypto/services/build.gradle index 53b46d5747..be527e8c52 100644 --- a/crypto/services/build.gradle +++ b/crypto/services/build.gradle @@ -23,6 +23,7 @@ jar { 'Specification-Version': project.version, 'Implementation-Title': archiveBaseName, 'Implementation-Version': calculateVersion(), + 'Commit-Hash': getGitCommitDetails(40).hash, 'Automatic-Module-Name': 'org.hyperledger.besu.internal.crypto' ) } diff --git a/datatypes/build.gradle b/datatypes/build.gradle index 920e187c02..b1581b6c4b 100644 --- a/datatypes/build.gradle +++ b/datatypes/build.gradle @@ -23,6 +23,7 @@ jar { 'Specification-Version': project.version, 'Implementation-Title': archiveBaseName, 'Implementation-Version': calculateVersion(), + 'Commit-Hash': getGitCommitDetails(40).hash, 'Automatic-Module-Name': 'org.hyperledger.besu.datatypes' ) } diff --git a/ethereum/api/build.gradle b/ethereum/api/build.gradle index ed395df8c5..3269812fec 100644 --- a/ethereum/api/build.gradle +++ b/ethereum/api/build.gradle @@ -22,7 +22,8 @@ jar { 'Specification-Title': archiveBaseName, 'Specification-Version': project.version, 'Implementation-Title': archiveBaseName, - 'Implementation-Version': calculateVersion() + 'Implementation-Version': calculateVersion(), + 'Commit-Hash': getGitCommitDetails(40).hash ) } } 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 a8226a6a69..b5f65e6d4b 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 @@ -64,7 +64,9 @@ import io.vertx.core.VertxOptions; /** Provides a facade to construct the JSON-RPC component. */ public class JsonRpcTestMethodsFactory { - private static final String CLIENT_VERSION = "TestClientVersion/0.1.0"; + 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; @@ -175,7 +177,9 @@ public class JsonRpcTestMethodsFactory { return new JsonRpcMethodsFactory() .methods( + CLIENT_NODE_NAME, CLIENT_VERSION, + CLIENT_COMMIT, NETWORK_ID, new StubGenesisConfigOptions(), peerDiscovery, diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcMethod.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcMethod.java index 5c9da63bc9..79d33ffbac 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcMethod.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcMethod.java @@ -63,6 +63,7 @@ public enum RpcMethod { ENGINE_FORKCHOICE_UPDATED_V2("engine_forkchoiceUpdatedV2"), ENGINE_FORKCHOICE_UPDATED_V3("engine_forkchoiceUpdatedV3"), ENGINE_EXCHANGE_TRANSITION_CONFIGURATION("engine_exchangeTransitionConfigurationV1"), + ENGINE_GET_CLIENT_VERSION_V1("engine_getClientVersionV1"), ENGINE_GET_PAYLOAD_BODIES_BY_HASH_V1("engine_getPayloadBodiesByHashV1"), ENGINE_GET_PAYLOAD_BODIES_BY_RANGE_V1("engine_getPayloadBodiesByRangeV1"), ENGINE_EXCHANGE_CAPABILITIES("engine_exchangeCapabilities"), 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 new file mode 100644 index 0000000000..689cb44e6a --- /dev/null +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetClientVersionV1.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.api.jsonrpc.internal.methods.engine; + +import org.hyperledger.besu.ethereum.ProtocolContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod; +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.api.jsonrpc.internal.results.EngineGetClientVersionResultV1; + +import io.vertx.core.Vertx; + +public class EngineGetClientVersionV1 extends ExecutionEngineJsonRpcMethod { + private static final String ENGINE_CLIENT_CODE = "BU"; + private static final String ENGINE_CLIENT_NAME = "Besu"; + + private final String clientVersion; + private final String commit; + + public EngineGetClientVersionV1( + final Vertx vertx, + final ProtocolContext protocolContext, + final EngineCallListener engineCallListener, + final String clientVersion, + final String commit) { + super(vertx, protocolContext, engineCallListener); + this.clientVersion = clientVersion; + this.commit = commit; + } + + @Override + public String getName() { + return RpcMethod.ENGINE_GET_CLIENT_VERSION_V1.getMethodName(); + } + + @Override + public JsonRpcResponse syncResponse(final JsonRpcRequestContext request) { + return new JsonRpcSuccessResponse( + request.getRequest().getId(), + new EngineGetClientVersionResultV1( + ENGINE_CLIENT_CODE, ENGINE_CLIENT_NAME, clientVersion, commit.substring(0, 8))); + } +} diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/EngineGetClientVersionResultV1.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/EngineGetClientVersionResultV1.java new file mode 100644 index 0000000000..8251de6dc5 --- /dev/null +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/EngineGetClientVersionResultV1.java @@ -0,0 +1,52 @@ +/* + * 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.results; + +import com.fasterxml.jackson.annotation.JsonGetter; + +public class EngineGetClientVersionResultV1 { + private final String code; + private final String name; + private final String version; + private final String commit; + + public EngineGetClientVersionResultV1( + final String code, final String name, final String version, final String commit) { + this.code = code; + this.name = name; + this.version = version; + this.commit = commit; + } + + @JsonGetter(value = "code") + public String getCode() { + return code; + } + + @JsonGetter(value = "name") + public String getName() { + return name; + } + + @JsonGetter(value = "version") + public String getVersion() { + return version; + } + + @JsonGetter(value = "commit") + public String getCommit() { + return commit; + } +} 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 ca66926656..6dda09bce9 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 @@ -23,6 +23,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineE import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineForkchoiceUpdatedV1; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineForkchoiceUpdatedV2; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineForkchoiceUpdatedV3; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineGetClientVersionV1; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineGetPayloadBodiesByHashV1; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineGetPayloadBodiesByRangeV1; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineGetPayloadV1; @@ -57,13 +58,17 @@ public class ExecutionEngineJsonRpcMethods extends ApiGroupJsonRpcMethods { private final ProtocolContext protocolContext; private final EthPeers ethPeers; private final Vertx consensusEngineServer; + private final String clientVersion; + private final String commit; ExecutionEngineJsonRpcMethods( final MiningCoordinator miningCoordinator, final ProtocolSchedule protocolSchedule, final ProtocolContext protocolContext, final EthPeers ethPeers, - final Vertx consensusEngineServer) { + final Vertx consensusEngineServer, + final String clientVersion, + final String commit) { this.mergeCoordinator = Optional.ofNullable(miningCoordinator) .filter(mc -> mc.isCompatibleWithEngineApi()) @@ -72,6 +77,8 @@ public class ExecutionEngineJsonRpcMethods extends ApiGroupJsonRpcMethods { this.protocolContext = protocolContext; this.ethPeers = ethPeers; this.consensusEngineServer = consensusEngineServer; + this.clientVersion = clientVersion; + this.commit = commit; } @Override @@ -147,7 +154,9 @@ public class ExecutionEngineJsonRpcMethods extends ApiGroupJsonRpcMethods { new EngineExchangeCapabilities( consensusEngineServer, protocolContext, engineQosTimer), new EnginePreparePayloadDebug( - consensusEngineServer, protocolContext, engineQosTimer, mergeCoordinator.get()))); + consensusEngineServer, protocolContext, engineQosTimer, mergeCoordinator.get()), + new EngineGetClientVersionV1( + consensusEngineServer, protocolContext, engineQosTimer, clientVersion, commit))); if (protocolSchedule.anyMatch(p -> p.spec().getName().equalsIgnoreCase("cancun"))) { executionEngineApisSupported.add( diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/JsonRpcMethodsFactory.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/JsonRpcMethodsFactory.java index 924889ef47..41227c2ca8 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/JsonRpcMethodsFactory.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/JsonRpcMethodsFactory.java @@ -54,7 +54,9 @@ import io.vertx.core.Vertx; public class JsonRpcMethodsFactory { public Map methods( + final String clientNodeName, final String clientVersion, + final String commit, final BigInteger networkId, final GenesisConfigOptions genesisConfigOptions, final P2PNetwork p2pNetwork, @@ -89,7 +91,7 @@ public class JsonRpcMethodsFactory { final List availableApiGroups = List.of( new AdminJsonRpcMethods( - clientVersion, + clientNodeName, networkId, genesisConfigOptions, p2pNetwork, @@ -115,7 +117,9 @@ public class JsonRpcMethodsFactory { protocolSchedule, protocolContext, ethPeers, - consensusEngineServer), + consensusEngineServer, + clientVersion, + commit), new EthJsonRpcMethods( blockchainQueries, synchronizer, @@ -141,7 +145,7 @@ public class JsonRpcMethodsFactory { filterManager), new PrivxJsonRpcMethods( blockchainQueries, protocolSchedule, transactionPool, privacyParameters), - new Web3JsonRpcMethods(clientVersion), + new Web3JsonRpcMethods(clientNodeName), new TraceJsonRpcMethods( blockchainQueries, protocolSchedule, protocolContext, apiConfiguration), new TxPoolJsonRpcMethods(transactionPool), diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/AbstractJsonRpcHttpServiceTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/AbstractJsonRpcHttpServiceTest.java index 9193574c45..862e17b890 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/AbstractJsonRpcHttpServiceTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/AbstractJsonRpcHttpServiceTest.java @@ -75,7 +75,9 @@ public abstract class AbstractJsonRpcHttpServiceTest { protected BlockchainSetupUtil blockchainSetupUtil; - protected static String CLIENT_VERSION = "TestClientVersion/0.1.0"; + protected static final String CLIENT_NODE_NAME = "TestClientVersion/0.1.0"; + protected static final String CLIENT_VERSION = "0.1.0"; + protected static final String CLIENT_COMMIT = "12345678"; protected static final BigInteger NETWORK_ID = BigInteger.valueOf(123); protected static final Collection JSON_RPC_APIS = Arrays.asList( @@ -168,7 +170,9 @@ public abstract class AbstractJsonRpcHttpServiceTest { return new JsonRpcMethodsFactory() .methods( + CLIENT_NODE_NAME, CLIENT_VERSION, + CLIENT_COMMIT, NETWORK_ID, new StubGenesisConfigOptions(), peerDiscoveryMock, diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/AdminJsonRpcHttpServiceTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/AdminJsonRpcHttpServiceTest.java index 061d2a2d6a..4a03b2eb93 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/AdminJsonRpcHttpServiceTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/AdminJsonRpcHttpServiceTest.java @@ -58,13 +58,13 @@ public class AdminJsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { final List peerList = new ArrayList<>(); final PeerInfo info1 = new PeerInfo( - 4, CLIENT_VERSION, caps, 30302, Bytes.fromHexString(String.format("%0128x", 1))); + 4, CLIENT_NODE_NAME, caps, 30302, Bytes.fromHexString(String.format("%0128x", 1))); final PeerInfo info2 = new PeerInfo( - 4, CLIENT_VERSION, caps, 60302, Bytes.fromHexString(String.format("%0128x", 2))); + 4, CLIENT_NODE_NAME, caps, 60302, Bytes.fromHexString(String.format("%0128x", 2))); final PeerInfo info3 = new PeerInfo( - 4, CLIENT_VERSION, caps, 60303, Bytes.fromHexString(String.format("%0128x", 3))); + 4, CLIENT_NODE_NAME, caps, 60303, Bytes.fromHexString(String.format("%0128x", 3))); final InetSocketAddress addr30301 = new InetSocketAddress("localhost", 30301); final InetSocketAddress addr30302 = new InetSocketAddress("localhost", 30302); final InetSocketAddress addr60301 = new InetSocketAddress("localhost", 60301); diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceHostAllowlistTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceHostAllowlistTest.java index 80626ef2fc..25077bbf82 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceHostAllowlistTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceHostAllowlistTest.java @@ -79,7 +79,9 @@ public class JsonRpcHttpServiceHostAllowlistTest { private static OkHttpClient client; private static String baseUrl; private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); - private static final String CLIENT_VERSION = "TestClientVersion/0.1.0"; + 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 CHAIN_ID = BigInteger.valueOf(123); private final JsonRpcConfiguration jsonRpcConfig = createJsonRpcConfig(); @@ -100,7 +102,9 @@ public class JsonRpcHttpServiceHostAllowlistTest { rpcMethods = new JsonRpcMethodsFactory() .methods( + CLIENT_NODE_NAME, CLIENT_VERSION, + CLIENT_COMMIT, CHAIN_ID, new StubGenesisConfigOptions(), peerDiscoveryMock, diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceLoginTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceLoginTest.java index 0fb55fdf34..eb23b054d0 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceLoginTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceLoginTest.java @@ -100,7 +100,9 @@ public class JsonRpcHttpServiceLoginTest { protected static OkHttpClient client; protected static String baseUrl; protected static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); - protected static final String CLIENT_VERSION = "TestClientVersion/0.1.0"; + protected static final String CLIENT_NODE_NAME = "TestClientVersion/0.1.0"; + protected static final String CLIENT_VERSION = "0.1.0"; + protected static final String CLIENT_COMMIT = "12345678"; protected static final BigInteger CHAIN_ID = BigInteger.valueOf(123); protected static P2PNetwork peerDiscoveryMock; protected static BlockchainQueries blockchainQueries; @@ -131,7 +133,9 @@ public class JsonRpcHttpServiceLoginTest { rpcMethods = new JsonRpcMethodsFactory() .methods( + CLIENT_NODE_NAME, CLIENT_VERSION, + CLIENT_COMMIT, CHAIN_ID, genesisConfigOptions, peerDiscoveryMock, diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceRpcApisTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceRpcApisTest.java index 8323f61b2c..f35893490a 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceRpcApisTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceRpcApisTest.java @@ -94,7 +94,9 @@ public class JsonRpcHttpServiceRpcApisTest { private JsonRpcHttpService service; private static String baseUrl; private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); - private static final String CLIENT_VERSION = "TestClientVersion/0.1.0"; + 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 JsonRpcConfiguration configuration; private static final List netServices = @@ -202,7 +204,9 @@ public class JsonRpcHttpServiceRpcApisTest { final Map rpcMethods = new JsonRpcMethodsFactory() .methods( + CLIENT_NODE_NAME, CLIENT_VERSION, + CLIENT_COMMIT, NETWORK_ID, new StubGenesisConfigOptions(), mock(P2PNetwork.class), @@ -310,7 +314,9 @@ public class JsonRpcHttpServiceRpcApisTest { final Map rpcMethods = new JsonRpcMethodsFactory() .methods( + CLIENT_NODE_NAME, CLIENT_VERSION, + CLIENT_COMMIT, NETWORK_ID, new StubGenesisConfigOptions(), p2pNetwork, diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTest.java index bb5cb68a2a..52f2ee050c 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTest.java @@ -202,7 +202,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { testHelper.assertValidJsonRpcResult(json, id); // Check result final String result = json.getString("result"); - assertThat(result).isEqualTo(CLIENT_VERSION); + assertThat(result).isEqualTo(CLIENT_NODE_NAME); } } @@ -1127,7 +1127,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { testHelper.assertValidJsonRpcResult(json, id); // Check result final String result = json.getString("result"); - assertThat(result).isEqualTo(CLIENT_VERSION); + assertThat(result).isEqualTo(CLIENT_NODE_NAME); } } @@ -1143,7 +1143,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { final JsonObject json = new JsonObject(resp.body().string()); testHelper.assertValidJsonRpcResult(json, id); final String result = json.getString("result"); - assertThat(result).isEqualTo(CLIENT_VERSION); + assertThat(result).isEqualTo(CLIENT_NODE_NAME); } } @@ -1175,7 +1175,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { testHelper.assertValidJsonRpcResult(json, null); // Check result final String result = json.getString("result"); - assertThat(result).isEqualTo(CLIENT_VERSION); + assertThat(result).isEqualTo(CLIENT_NODE_NAME); } } @@ -1197,7 +1197,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { testHelper.assertValidJsonRpcResult(json, id); // Check result final String result = json.getString("result"); - assertThat(result).isEqualTo(CLIENT_VERSION); + assertThat(result).isEqualTo(CLIENT_NODE_NAME); } } @@ -1218,7 +1218,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { testHelper.assertValidJsonRpcResult(json, id); // Check result final String result = json.getString("result"); - assertThat(result).isEqualTo(CLIENT_VERSION); + assertThat(result).isEqualTo(CLIENT_NODE_NAME); } } @@ -1242,7 +1242,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { testHelper.assertValidJsonRpcResult(json, id); // Check result final String result = json.getString("result"); - assertThat(result).isEqualTo(CLIENT_VERSION); + assertThat(result).isEqualTo(CLIENT_NODE_NAME); } } @@ -1268,7 +1268,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { testHelper.assertValidJsonRpcResult(json, id); // Check result final String result = json.getString("result"); - assertThat(result).isEqualTo(CLIENT_VERSION); + assertThat(result).isEqualTo(CLIENT_NODE_NAME); } } @@ -1289,7 +1289,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { testHelper.assertValidJsonRpcResult(json, id); // Check result final String result = json.getString("result"); - assertThat(result).isEqualTo(CLIENT_VERSION); + assertThat(result).isEqualTo(CLIENT_NODE_NAME); } } @@ -1353,7 +1353,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { final JsonObject json = new JsonObject(resp.body().string()); testHelper.assertValidJsonRpcResult(json, id); final String result = json.getString("result"); - assertThat(result).isEqualTo(CLIENT_VERSION); + assertThat(result).isEqualTo(CLIENT_NODE_NAME); } } @@ -1485,7 +1485,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { // Check result web3_clientVersion final JsonObject jsonClientVersion = responses.get(clientVersionRequestId); testHelper.assertValidJsonRpcResult(jsonClientVersion, clientVersionRequestId); - assertThat(jsonClientVersion.getString("result")).isEqualTo(CLIENT_VERSION); + assertThat(jsonClientVersion.getString("result")).isEqualTo(CLIENT_NODE_NAME); // Check result unknown method final JsonObject jsonError = responses.get(brokenRequestId); @@ -1540,7 +1540,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { // Check result web3_clientVersion final JsonObject jsonClientVersion = responses.get(clientVersionRequestId); testHelper.assertValidJsonRpcResult(jsonClientVersion, clientVersionRequestId); - assertThat(jsonClientVersion.getString("result")).isEqualTo(CLIENT_VERSION); + assertThat(jsonClientVersion.getString("result")).isEqualTo(CLIENT_NODE_NAME); // Check invalid request final JsonObject jsonError = responses.get(invalidId); @@ -1605,7 +1605,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase { // Check result web3_clientVersion final JsonObject jsonClientVersion = responses.get(clientVersionRequestId); testHelper.assertValidJsonRpcResult(jsonClientVersion, clientVersionRequestId); - assertThat(jsonClientVersion.getString("result")).isEqualTo(CLIENT_VERSION); + assertThat(jsonClientVersion.getString("result")).isEqualTo(CLIENT_NODE_NAME); // Check result net_version final JsonObject jsonNetVersion = responses.get(netVersionRequestId); diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTestBase.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTestBase.java index a2a856333e..5e5dc36bb0 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTestBase.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTestBase.java @@ -78,7 +78,9 @@ public class JsonRpcHttpServiceTestBase { protected static OkHttpClient client; protected static String baseUrl; protected static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); - protected static final String CLIENT_VERSION = "TestClientVersion/0.1.0"; + protected static final String CLIENT_NODE_NAME = "TestClientVersion/0.1.0"; + protected static final String CLIENT_VERSION = "0.1.0"; + protected static final String CLIENT_COMMIT = "12345678"; protected static final BigInteger CHAIN_ID = BigInteger.valueOf(123); protected static P2PNetwork peerDiscoveryMock; protected static EthPeers ethPeersMock; @@ -108,7 +110,9 @@ public class JsonRpcHttpServiceTestBase { rpcMethods = new JsonRpcMethodsFactory() .methods( + CLIENT_NODE_NAME, CLIENT_VERSION, + CLIENT_COMMIT, CHAIN_ID, new StubGenesisConfigOptions(), peerDiscoveryMock, diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsClientAuthTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsClientAuthTest.java index 1d3a3a087a..5cf13a4576 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsClientAuthTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsClientAuthTest.java @@ -85,7 +85,9 @@ public class JsonRpcHttpServiceTlsClientAuthTest { protected static final Vertx vertx = Vertx.vertx(); private static final String JSON_HEADER = "application/json; charset=utf-8"; - private static final String CLIENT_VERSION = "TestClientVersion/0.1.0"; + 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 CHAIN_ID = BigInteger.valueOf(123); private static final NatService natService = new NatService(Optional.empty()); @@ -114,7 +116,9 @@ public class JsonRpcHttpServiceTlsClientAuthTest { rpcMethods = new JsonRpcMethodsFactory() .methods( + CLIENT_NODE_NAME, CLIENT_VERSION, + CLIENT_COMMIT, CHAIN_ID, new StubGenesisConfigOptions(), peerDiscoveryMock, diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsMisconfigurationTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsMisconfigurationTest.java index 684f843d2f..c2661141a4 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsMisconfigurationTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsMisconfigurationTest.java @@ -75,7 +75,9 @@ class JsonRpcHttpServiceTlsMisconfigurationTest { protected static final Vertx vertx = Vertx.vertx(); - private static final String CLIENT_VERSION = "TestClientVersion/0.1.0"; + 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 CHAIN_ID = BigInteger.valueOf(123); private static final NatService natService = new NatService(Optional.empty()); private final SelfSignedP12Certificate besuCertificate = SelfSignedP12Certificate.create(); @@ -102,7 +104,9 @@ class JsonRpcHttpServiceTlsMisconfigurationTest { rpcMethods = new JsonRpcMethodsFactory() .methods( + CLIENT_NODE_NAME, CLIENT_VERSION, + CLIENT_COMMIT, CHAIN_ID, new StubGenesisConfigOptions(), peerDiscoveryMock, diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsTest.java index b6d7fa67f8..c0846ed9f2 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsTest.java @@ -81,7 +81,9 @@ public class JsonRpcHttpServiceTlsTest { protected static final Vertx vertx = Vertx.vertx(); private static final String JSON_HEADER = "application/json; charset=utf-8"; - private static final String CLIENT_VERSION = "TestClientVersion/0.1.0"; + 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 CHAIN_ID = BigInteger.valueOf(123); private static final NatService natService = new NatService(Optional.empty()); private JsonRpcHttpService service; @@ -103,7 +105,9 @@ public class JsonRpcHttpServiceTlsTest { rpcMethods = new JsonRpcMethodsFactory() .methods( + CLIENT_NODE_NAME, CLIENT_VERSION, + CLIENT_COMMIT, CHAIN_ID, new StubGenesisConfigOptions(), peerDiscoveryMock, 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 new file mode 100644 index 0000000000..1aa0def7e2 --- /dev/null +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetClientVersionV1Test.java @@ -0,0 +1,72 @@ +/* + * 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.methods.engine; + +import static org.assertj.core.api.Assertions.assertThat; + +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.response.JsonRpcResponse; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.EngineGetClientVersionResultV1; + +import io.vertx.core.Vertx; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +class EngineGetClientVersionV1Test { + + private static final String ENGINE_CLIENT_CODE = "BU"; + private static final String ENGINE_CLIENT_NAME = "Besu"; + + private static final String CLIENT_VERSION = "v25.6.7-dev-abcdef12"; + private static final String COMMIT = "abcdef12"; + + private EngineGetClientVersionV1 getClientVersion; + + @BeforeEach + void before() { + getClientVersion = + new EngineGetClientVersionV1( + Mockito.mock(Vertx.class), + Mockito.mock(ProtocolContext.class), + Mockito.mock(EngineCallListener.class), + CLIENT_VERSION, + COMMIT); + } + + @Test + void testGetName() { + assertThat(getClientVersion.getName()).isEqualTo("engine_getClientVersionV1"); + } + + @Test + void testSyncResponse() { + JsonRpcRequestContext request = new JsonRpcRequestContext(new JsonRpcRequest("v", "m", null)); + JsonRpcResponse actualResult = getClientVersion.syncResponse(request); + + assertThat(actualResult).isInstanceOf(JsonRpcSuccessResponse.class); + JsonRpcSuccessResponse successResponse = (JsonRpcSuccessResponse) actualResult; + assertThat(successResponse.getResult()).isInstanceOf(EngineGetClientVersionResultV1.class); + EngineGetClientVersionResultV1 actualEngineGetClientVersionResultV1 = + (EngineGetClientVersionResultV1) successResponse.getResult(); + assertThat(actualEngineGetClientVersionResultV1.getName()).isEqualTo(ENGINE_CLIENT_NAME); + assertThat(actualEngineGetClientVersionResultV1.getCode()).isEqualTo(ENGINE_CLIENT_CODE); + assertThat(actualEngineGetClientVersionResultV1.getVersion()).isEqualTo(CLIENT_VERSION); + assertThat(actualEngineGetClientVersionResultV1.getCommit()).isEqualTo(COMMIT); + } +} diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/WebSocketServiceLoginTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/WebSocketServiceLoginTest.java index 75927c4513..342941d0e9 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/WebSocketServiceLoginTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/WebSocketServiceLoginTest.java @@ -115,7 +115,9 @@ public class WebSocketServiceLoginTest { protected static OkHttpClient client; protected static String baseUrl; protected static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); - protected static final String CLIENT_VERSION = "TestClientVersion/0.1.0"; + protected static final String CLIENT_NODE_NAME = "TestClientVersion/0.1.0"; + protected static final String CLIENT_VERSION = "0.1.0"; + protected static final String CLIENT_COMMIT = "12345678"; protected static final BigInteger CHAIN_ID = BigInteger.valueOf(123); protected static P2PNetwork peerDiscoveryMock; protected static BlockchainQueries blockchainQueries; @@ -167,7 +169,9 @@ public class WebSocketServiceLoginTest { spy( new JsonRpcMethodsFactory() .methods( + CLIENT_NODE_NAME, CLIENT_VERSION, + CLIENT_COMMIT, CHAIN_ID, genesisConfigOptions, peerDiscoveryMock, diff --git a/ethereum/blockcreation/build.gradle b/ethereum/blockcreation/build.gradle index 5f426fd932..753cc12d18 100644 --- a/ethereum/blockcreation/build.gradle +++ b/ethereum/blockcreation/build.gradle @@ -7,7 +7,8 @@ jar { 'Specification-Title': archiveBaseName, 'Specification-Version': project.version, 'Implementation-Title': archiveBaseName, - 'Implementation-Version': calculateVersion() + 'Implementation-Version': calculateVersion(), + 'Commit-Hash': getGitCommitDetails(40).hash ) } } diff --git a/ethereum/core/build.gradle b/ethereum/core/build.gradle index 0a25fa1a42..24c794e298 100644 --- a/ethereum/core/build.gradle +++ b/ethereum/core/build.gradle @@ -22,7 +22,8 @@ jar { 'Specification-Title': archiveBaseName, 'Specification-Version': project.version, 'Implementation-Title': archiveBaseName, - 'Implementation-Version': calculateVersion() + 'Implementation-Version': calculateVersion(), + 'Commit-Hash': getGitCommitDetails(40).hash ) } } diff --git a/ethereum/eth/build.gradle b/ethereum/eth/build.gradle index b51088f4cf..677783dfdf 100644 --- a/ethereum/eth/build.gradle +++ b/ethereum/eth/build.gradle @@ -22,7 +22,8 @@ jar { 'Specification-Title': archiveBaseName, 'Specification-Version': project.version, 'Implementation-Title': archiveBaseName, - 'Implementation-Version': calculateVersion() + 'Implementation-Version': calculateVersion(), + 'Commit-Hash': getGitCommitDetails(40).hash ) } } diff --git a/ethereum/ethstats/build.gradle b/ethereum/ethstats/build.gradle index 2097f0f1bb..8f10b73b36 100644 --- a/ethereum/ethstats/build.gradle +++ b/ethereum/ethstats/build.gradle @@ -22,7 +22,8 @@ jar { 'Specification-Title': archiveBaseName, 'Specification-Version': project.version, 'Implementation-Title': archiveBaseName, - 'Implementation-Version': calculateVersion() + 'Implementation-Version': calculateVersion(), + 'Commit-Hash': getGitCommitDetails(40).hash ) } } diff --git a/ethereum/evmtool/build.gradle b/ethereum/evmtool/build.gradle index 5712e7174a..c4c83883b5 100644 --- a/ethereum/evmtool/build.gradle +++ b/ethereum/evmtool/build.gradle @@ -29,7 +29,8 @@ jar { 'Specification-Title': archiveBaseName, 'Specification-Version': project.version, 'Implementation-Title': archiveBaseName, - 'Implementation-Version': calculateVersion() + 'Implementation-Version': calculateVersion(), + 'Commit-Hash': getGitCommitDetails(40).hash ) } } diff --git a/ethereum/mock-p2p/build.gradle b/ethereum/mock-p2p/build.gradle index 373e25be3c..a548d0cde7 100644 --- a/ethereum/mock-p2p/build.gradle +++ b/ethereum/mock-p2p/build.gradle @@ -22,7 +22,8 @@ jar { 'Specification-Title': archiveBaseName, 'Specification-Version': project.version, 'Implementation-Title': archiveBaseName, - 'Implementation-Version': calculateVersion() + 'Implementation-Version': calculateVersion(), + 'Commit-Hash': getGitCommitDetails(40).hash ) } } diff --git a/ethereum/p2p/build.gradle b/ethereum/p2p/build.gradle index 2d0331503f..971504a25a 100644 --- a/ethereum/p2p/build.gradle +++ b/ethereum/p2p/build.gradle @@ -22,7 +22,8 @@ jar { 'Specification-Title': archiveBaseName, 'Specification-Version': project.version, 'Implementation-Title': archiveBaseName, - 'Implementation-Version': calculateVersion() + 'Implementation-Version': calculateVersion(), + 'Commit-Hash': getGitCommitDetails(40).hash ) } } diff --git a/ethereum/permissioning/build.gradle b/ethereum/permissioning/build.gradle index eaf36c8fda..f404d70ede 100644 --- a/ethereum/permissioning/build.gradle +++ b/ethereum/permissioning/build.gradle @@ -22,7 +22,8 @@ jar { 'Specification-Title': archiveBaseName, 'Specification-Version': project.version, 'Implementation-Title': archiveBaseName, - 'Implementation-Version': calculateVersion() + 'Implementation-Version': calculateVersion(), + 'Commit-Hash': getGitCommitDetails(40).hash ) } } diff --git a/ethereum/retesteth/build.gradle b/ethereum/retesteth/build.gradle index 10b978b153..2fe2def439 100644 --- a/ethereum/retesteth/build.gradle +++ b/ethereum/retesteth/build.gradle @@ -20,7 +20,8 @@ jar { 'Specification-Title': archiveBaseName, 'Specification-Version': project.version, 'Implementation-Title': archiveBaseName, - 'Implementation-Version': calculateVersion() + 'Implementation-Version': calculateVersion(), + 'Commit-Hash': getGitCommitDetails(40).hash ) } } diff --git a/ethereum/rlp/build.gradle b/ethereum/rlp/build.gradle index 682d26761b..b95243e2ea 100644 --- a/ethereum/rlp/build.gradle +++ b/ethereum/rlp/build.gradle @@ -23,6 +23,7 @@ jar { 'Specification-Version': project.version, 'Implementation-Title': archiveBaseName, 'Implementation-Version': calculateVersion(), + 'Commit-Hash': getGitCommitDetails(40).hash, 'Automatic-Module-Name': 'org.hyperledger.besu.internal.rlp' ) } diff --git a/ethereum/stratum/build.gradle b/ethereum/stratum/build.gradle index 5c7dfaed20..83de6a8a5f 100644 --- a/ethereum/stratum/build.gradle +++ b/ethereum/stratum/build.gradle @@ -22,7 +22,8 @@ jar { 'Specification-Title': archiveBaseName, 'Specification-Version': project.version, 'Implementation-Title': archiveBaseName, - 'Implementation-Version': calculateVersion() + 'Implementation-Version': calculateVersion(), + 'Commit-Hash': getGitCommitDetails(40).hash ) } } diff --git a/ethereum/trie/build.gradle b/ethereum/trie/build.gradle index e8ce5cb9b7..080b9e8f51 100644 --- a/ethereum/trie/build.gradle +++ b/ethereum/trie/build.gradle @@ -22,7 +22,8 @@ jar { 'Specification-Title': archiveBaseName, 'Specification-Version': project.version, 'Implementation-Title': archiveBaseName, - 'Implementation-Version': calculateVersion() + 'Implementation-Version': calculateVersion(), + 'Commit-Hash': getGitCommitDetails(40).hash ) } } diff --git a/ethereum/verkletrie/build.gradle b/ethereum/verkletrie/build.gradle index 166b02efe1..00c7016fb6 100644 --- a/ethereum/verkletrie/build.gradle +++ b/ethereum/verkletrie/build.gradle @@ -22,7 +22,8 @@ jar { 'Specification-Title': archiveBaseName, 'Specification-Version': project.version, 'Implementation-Title': archiveBaseName, - 'Implementation-Version': calculateVersion() + 'Implementation-Version': calculateVersion(), + 'Commit-Hash': getGitCommitDetails(40).hash ) } } diff --git a/evm/build.gradle b/evm/build.gradle index b6f8ea3618..a48cb91649 100644 --- a/evm/build.gradle +++ b/evm/build.gradle @@ -25,6 +25,7 @@ jar { 'Specification-Version': project.version, 'Implementation-Title': archiveBaseName, 'Implementation-Version': calculateVersion(), + 'Commit-Hash': getGitCommitDetails(40).hash, 'Automatic-Module-Name': 'org.hyperledger.besu.evm' ) } diff --git a/metrics/core/build.gradle b/metrics/core/build.gradle index bc92cb6b5f..1438a198ae 100644 --- a/metrics/core/build.gradle +++ b/metrics/core/build.gradle @@ -22,7 +22,8 @@ jar { 'Specification-Title': archiveBaseName, 'Specification-Version': project.version, 'Implementation-Title': archiveBaseName, - 'Implementation-Version': calculateVersion() + 'Implementation-Version': calculateVersion(), + 'Commit-Hash': getGitCommitDetails(40).hash ) } } diff --git a/metrics/rocksdb/build.gradle b/metrics/rocksdb/build.gradle index 292909565d..d46488daf8 100644 --- a/metrics/rocksdb/build.gradle +++ b/metrics/rocksdb/build.gradle @@ -22,7 +22,8 @@ jar { 'Specification-Title': archiveBaseName, 'Specification-Version': project.version, 'Implementation-Title': archiveBaseName, - 'Implementation-Version': calculateVersion() + 'Implementation-Version': calculateVersion(), + 'Commit-Hash': getGitCommitDetails(40).hash ) } } diff --git a/nat/build.gradle b/nat/build.gradle index ec2fd3a3f0..b0a8597174 100644 --- a/nat/build.gradle +++ b/nat/build.gradle @@ -22,7 +22,8 @@ jar { 'Specification-Title': archiveBaseName, 'Specification-Version': project.version, 'Implementation-Title': archiveBaseName, - 'Implementation-Version': calculateVersion() + 'Implementation-Version': calculateVersion(), + 'Commit-Hash': getGitCommitDetails(40).hash ) } } diff --git a/pki/build.gradle b/pki/build.gradle index cb6aaf8b86..15f1e8c7d6 100644 --- a/pki/build.gradle +++ b/pki/build.gradle @@ -22,7 +22,8 @@ jar { 'Specification-Title': archiveBaseName, 'Specification-Version': project.version, 'Implementation-Title': archiveBaseName, - 'Implementation-Version': calculateVersion() + 'Implementation-Version': calculateVersion(), + 'Commit-Hash': getGitCommitDetails(40).hash ) } } diff --git a/plugin-api/build.gradle b/plugin-api/build.gradle index 66c8e34837..bee57ab5ae 100644 --- a/plugin-api/build.gradle +++ b/plugin-api/build.gradle @@ -22,6 +22,7 @@ jar { 'Specification-Version': project.version, 'Implementation-Title': archiveBaseName, 'Implementation-Version': calculateVersion(), + 'Commit-Hash': getGitCommitDetails(40).hash, 'Automatic-Module-Name': 'org.hyperledger.besu.plugin.api' ) } diff --git a/plugins/rocksdb/build.gradle b/plugins/rocksdb/build.gradle index 6af582bf3b..e5ca782504 100644 --- a/plugins/rocksdb/build.gradle +++ b/plugins/rocksdb/build.gradle @@ -20,7 +20,8 @@ jar { 'Specification-Title': archiveBaseName, 'Specification-Version': project.version, 'Implementation-Title': archiveBaseName, - 'Implementation-Version': calculateVersion() + 'Implementation-Version': calculateVersion(), + 'Commit-Hash': getGitCommitDetails(40).hash ) } } diff --git a/services/kvstore/build.gradle b/services/kvstore/build.gradle index 0415f6702b..5f379b60a5 100644 --- a/services/kvstore/build.gradle +++ b/services/kvstore/build.gradle @@ -22,7 +22,8 @@ jar { 'Specification-Title': archiveBaseName, 'Specification-Version': project.version, 'Implementation-Title': archiveBaseName, - 'Implementation-Version': calculateVersion() + 'Implementation-Version': calculateVersion(), + 'Commit-Hash': getGitCommitDetails(40).hash ) } } diff --git a/services/pipeline/build.gradle b/services/pipeline/build.gradle index b86edbf344..af9f065fed 100644 --- a/services/pipeline/build.gradle +++ b/services/pipeline/build.gradle @@ -22,7 +22,8 @@ jar { 'Specification-Title': archiveBaseName, 'Specification-Version': project.version, 'Implementation-Title': archiveBaseName, - 'Implementation-Version': calculateVersion() + 'Implementation-Version': calculateVersion(), + 'Commit-Hash': getGitCommitDetails(40).hash ) } } diff --git a/services/tasks/build.gradle b/services/tasks/build.gradle index 5cfa2411f3..c584c6987b 100644 --- a/services/tasks/build.gradle +++ b/services/tasks/build.gradle @@ -22,7 +22,8 @@ jar { 'Specification-Title': archiveBaseName, 'Specification-Version': project.version, 'Implementation-Title': archiveBaseName, - 'Implementation-Version': calculateVersion() + 'Implementation-Version': calculateVersion(), + 'Commit-Hash': getGitCommitDetails(40).hash ) } } diff --git a/testfuzz/build.gradle b/testfuzz/build.gradle index 83bf621ac9..fe869209ee 100644 --- a/testfuzz/build.gradle +++ b/testfuzz/build.gradle @@ -24,7 +24,8 @@ jar { 'Specification-Title': archiveBaseName, 'Specification-Version': project.version, 'Implementation-Title': archiveBaseName, - 'Implementation-Version': calculateVersion() + 'Implementation-Version': calculateVersion(), + 'Commit-Hash': getGitCommitDetails(40).hash ) } } diff --git a/testutil/build.gradle b/testutil/build.gradle index 491c213207..5b4f06e7ac 100644 --- a/testutil/build.gradle +++ b/testutil/build.gradle @@ -22,7 +22,8 @@ jar { 'Specification-Title': archiveBaseName, 'Specification-Version': project.version, 'Implementation-Title': archiveBaseName, - 'Implementation-Version': calculateVersion() + 'Implementation-Version': calculateVersion(), + 'Commit-Hash': getGitCommitDetails(40).hash ) } } diff --git a/util/build.gradle b/util/build.gradle index 41e4badb33..c0d32361e0 100644 --- a/util/build.gradle +++ b/util/build.gradle @@ -23,6 +23,7 @@ jar { 'Specification-Version': project.version, 'Implementation-Title': archiveBaseName, 'Implementation-Version': calculateVersion(), + 'Commit-Hash': getGitCommitDetails(40).hash, 'Automatic-Module-Name': 'org.hyperledger.besu.internal.util' ) } From ca8563ce2bad759398f668a59695b7e984dff408 Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Fri, 30 Aug 2024 12:49:56 -0600 Subject: [PATCH 170/259] Disable EOF CALL opcodes in legacy (#7544) When the EOF call opcodes are added to the EVM, ensure legacy cannot execute it. Signed-off-by: Danno Ferrin --- .../operation/AbstractExtCallOperation.java | 7 +++- .../besu/evm/operation/ExtCallOperation.java | 5 ++- .../operation/ExtDelegateCallOperation.java | 5 ++- .../evm/operation/ExtStaticCallOperation.java | 5 ++- .../evm/operation/ExtCallOperationTest.java | 34 +++++++++++++++++++ .../ExtDelegateCallOperationTest.java | 33 ++++++++++++++++++ .../operation/ExtStaticCallOperationTest.java | 34 +++++++++++++++++++ 7 files changed, 119 insertions(+), 4 deletions(-) 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 e44c0e7f9c..7b58e956f5 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 @@ -95,6 +95,11 @@ public abstract class AbstractExtCallOperation extends AbstractCallOperation { @Override public OperationResult execute(final MessageFrame frame, final EVM evm) { + Code callingCode = frame.getCode(); + if (callingCode.getEofVersion() == 0) { + return InvalidOperation.INVALID_RESULT; + } + final Bytes toBytes = frame.getStackItem(STACK_TO).trimLeadingZeros(); final Wei value = value(frame); final boolean zeroValue = value.isZero(); @@ -141,7 +146,7 @@ public abstract class AbstractExtCallOperation extends AbstractCallOperation { frame.clearReturnData(); // delegate calls to prior EOF versions are prohibited - if (isDelegate() && frame.getCode().getEofVersion() != code.getEofVersion()) { + if (isDelegate() && callingCode.getEofVersion() != code.getEofVersion()) { return softFailure(frame, cost); } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtCallOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtCallOperation.java index 5914f0e966..7fc41ac85c 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtCallOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtCallOperation.java @@ -24,6 +24,9 @@ import org.hyperledger.besu.evm.gascalculator.GasCalculator; /** The Call operation. */ public class ExtCallOperation extends AbstractExtCallOperation { + /** The constant OPCODE. */ + public static final int OPCODE = 0xF8; + static final int STACK_VALUE = 3; /** @@ -32,7 +35,7 @@ public class ExtCallOperation extends AbstractExtCallOperation { * @param gasCalculator the gas calculator */ public ExtCallOperation(final GasCalculator gasCalculator) { - super(0xF8, "EXTCALL", 4, 1, gasCalculator); + super(OPCODE, "EXTCALL", 4, 1, gasCalculator); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtDelegateCallOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtDelegateCallOperation.java index db851ee5a0..49b0a2a54a 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtDelegateCallOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtDelegateCallOperation.java @@ -24,13 +24,16 @@ import org.hyperledger.besu.evm.gascalculator.GasCalculator; /** The Delegate call operation. */ public class ExtDelegateCallOperation extends AbstractExtCallOperation { + /** The constant OPCODE. */ + public static final int OPCODE = 0xF9; + /** * Instantiates a new Delegate call operation. * * @param gasCalculator the gas calculator */ public ExtDelegateCallOperation(final GasCalculator gasCalculator) { - super(0xF9, "EXTDELEGATECALL", 3, 1, gasCalculator); + super(OPCODE, "EXTDELEGATECALL", 3, 1, gasCalculator); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtStaticCallOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtStaticCallOperation.java index ef3dc042d9..7413213779 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtStaticCallOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtStaticCallOperation.java @@ -24,13 +24,16 @@ import org.hyperledger.besu.evm.gascalculator.GasCalculator; /** The Static call operation. */ public class ExtStaticCallOperation extends AbstractExtCallOperation { + /** The constant OPCODE. */ + public static final int OPCODE = 0xFB; + /** * Instantiates a new Static call operation. * * @param gasCalculator the gas calculator */ public ExtStaticCallOperation(final GasCalculator gasCalculator) { - super(0xFB, "EXTSTATICCALL", 3, 1, gasCalculator); + super(OPCODE, "EXTSTATICCALL", 3, 1, gasCalculator); } @Override 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 c43893a543..93b1011501 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 @@ -45,6 +45,8 @@ 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); + public static final Code LEGACY_CODE = + EOF_EVM.getCodeUncached(Bytes.of(ExtCallOperation.OPCODE, 1)); public static final Code SIMPLE_EOF = EOF_EVM.getCodeUncached(Bytes.fromHexString("0xEF00010100040200010001040000000080000000")); public static final Code INVALID_EOF = @@ -118,6 +120,7 @@ public class ExtCallOperationTest { final var messageFrame = new TestMessageFrameBuilder() .initialGas(parentGas) + .code(SIMPLE_EOF) .pushStackItem(CONTRACT_ADDRESS) // canary for non-returning .pushStackItem(Bytes.EMPTY) .pushStackItem(Bytes.EMPTY) @@ -208,6 +211,7 @@ public class ExtCallOperationTest { final var messageFrame = new TestMessageFrameBuilder() .initialGas(parentGas) + .code(SIMPLE_EOF) .pushStackItem(CONTRACT_ADDRESS) // canary for non-returning .pushStackItem(valueSent) .pushStackItem(Bytes.EMPTY) @@ -243,6 +247,7 @@ public class ExtCallOperationTest { final var messageFrame = new TestMessageFrameBuilder() .initialGas(400000) + .code(SIMPLE_EOF) .pushStackItem(CONTRACT_ADDRESS) // canary for non-returning .pushStackItem(Bytes.EMPTY) .pushStackItem(Bytes.EMPTY) @@ -273,4 +278,33 @@ public class ExtCallOperationTest { assertThat(parentFrame.getStackItem(0)) .isEqualTo(AbstractExtCallOperation.EOF1_EXCEPTION_STACK_ITEM); } + + @Test + void legacyTest() { + final ExtCallOperation operation = new ExtCallOperation(new PragueEOFGasCalculator()); + + final var messageFrame = + new TestMessageFrameBuilder() + .initialGas(400000) + .code(LEGACY_CODE) + .pushStackItem(CONTRACT_ADDRESS) // canary for non-returning + .pushStackItem(Bytes.EMPTY) + .pushStackItem(Bytes.EMPTY) + .pushStackItem(Bytes.EMPTY) + .pushStackItem(CONTRACT_ADDRESS) + .worldUpdater(worldUpdater) + .build(); + messageFrame.warmUpAddress(CONTRACT_ADDRESS); + when(account.getBalance()).thenReturn(Wei.ZERO); + when(account.getCodeHash()).thenReturn(SIMPLE_EOF.getCodeHash()); + when(account.getCode()).thenReturn(SIMPLE_EOF.getBytes()); + when(worldUpdater.get(any())).thenReturn(account); + when(worldUpdater.getAccount(any())).thenReturn(account); + when(worldUpdater.updater()).thenReturn(worldUpdater); + + var result = operation.execute(messageFrame, EOF_EVM); + + assertThat(result.getGasCost()).isZero(); + assertThat(result.getHaltReason()).isEqualTo(ExceptionalHaltReason.INVALID_OPERATION); + } } 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 e1881892d5..62a10dcc2d 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 @@ -46,6 +46,8 @@ public class ExtDelegateCallOperationTest { private final MutableAccount account = mock(MutableAccount.class); // private final MutableAccount targetAccount = mock(MutableAccount.class); private static final EVM EOF_EVM = MainnetEVMs.pragueEOF(EvmConfiguration.DEFAULT); + public static final Code LEGACY_CODE = + EOF_EVM.getCodeUncached(Bytes.of(ExtDelegateCallOperation.OPCODE, 1)); public static final Code SIMPLE_EOF = EOF_EVM.getCodeUncached(Bytes.fromHexString("0xEF00010100040200010001040000000080000000")); public static final Code SIMPLE_LEGACY = EOF_EVM.getCodeUncached(Bytes.fromHexString("0x00")); @@ -229,6 +231,7 @@ public class ExtDelegateCallOperationTest { final var messageFrame = new TestMessageFrameBuilder() .initialGas(400000) + .code(SIMPLE_EOF) .pushStackItem(CONTRACT_ADDRESS) // canary for non-returning .pushStackItem(Bytes.EMPTY) .pushStackItem(Bytes.EMPTY) @@ -258,4 +261,34 @@ public class ExtDelegateCallOperationTest { assertThat(parentFrame.getStackItem(0)) .isEqualTo(AbstractExtCallOperation.EOF1_EXCEPTION_STACK_ITEM); } + + @Test + void legacyTest() { + final ExtDelegateCallOperation operation = + new ExtDelegateCallOperation(new PragueEOFGasCalculator()); + + final var messageFrame = + new TestMessageFrameBuilder() + .initialGas(400000) + .code(LEGACY_CODE) + .pushStackItem(CONTRACT_ADDRESS) // canary for non-returning + .pushStackItem(Bytes.EMPTY) + .pushStackItem(Bytes.EMPTY) + .pushStackItem(Bytes.EMPTY) + .pushStackItem(CONTRACT_ADDRESS) + .worldUpdater(worldUpdater) + .build(); + messageFrame.warmUpAddress(CONTRACT_ADDRESS); + when(account.getBalance()).thenReturn(Wei.ZERO); + when(account.getCodeHash()).thenReturn(SIMPLE_EOF.getCodeHash()); + when(account.getCode()).thenReturn(SIMPLE_EOF.getBytes()); + when(worldUpdater.get(any())).thenReturn(account); + when(worldUpdater.getAccount(any())).thenReturn(account); + when(worldUpdater.updater()).thenReturn(worldUpdater); + + var result = operation.execute(messageFrame, EOF_EVM); + + assertThat(result.getGasCost()).isZero(); + assertThat(result.getHaltReason()).isEqualTo(ExceptionalHaltReason.INVALID_OPERATION); + } } 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 90f2d30088..ed306e89c7 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 @@ -45,6 +45,8 @@ 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); + public static final Code LEGACY_CODE = + EOF_EVM.getCodeUncached(Bytes.of(ExtStaticCallOperation.OPCODE, 1)); public static final Code SIMPLE_EOF = EOF_EVM.getCodeUncached(Bytes.fromHexString("0xEF00010100040200010001040000000080000000")); public static final Code INVALID_EOF = @@ -119,6 +121,7 @@ public class ExtStaticCallOperationTest { final var messageFrame = new TestMessageFrameBuilder() .initialGas(parentGas) + .code(SIMPLE_EOF) .pushStackItem(CONTRACT_ADDRESS) // canary for non-returning .pushStackItem(Bytes.EMPTY) .pushStackItem(Bytes.EMPTY) @@ -154,6 +157,7 @@ public class ExtStaticCallOperationTest { final var messageFrame = new TestMessageFrameBuilder() .initialGas(400000) + .code(SIMPLE_EOF) .pushStackItem(CONTRACT_ADDRESS) // canary for non-returning .pushStackItem(Bytes.EMPTY) .pushStackItem(Bytes.EMPTY) @@ -183,4 +187,34 @@ public class ExtStaticCallOperationTest { assertThat(parentFrame.getStackItem(0)) .isEqualTo(AbstractExtCallOperation.EOF1_EXCEPTION_STACK_ITEM); } + + @Test + void legacyTest() { + final ExtStaticCallOperation operation = + new ExtStaticCallOperation(new PragueEOFGasCalculator()); + + final var messageFrame = + new TestMessageFrameBuilder() + .initialGas(400000) + .code(LEGACY_CODE) + .pushStackItem(CONTRACT_ADDRESS) // canary for non-returning + .pushStackItem(Bytes.EMPTY) + .pushStackItem(Bytes.EMPTY) + .pushStackItem(Bytes.EMPTY) + .pushStackItem(CONTRACT_ADDRESS) + .worldUpdater(worldUpdater) + .build(); + messageFrame.warmUpAddress(CONTRACT_ADDRESS); + when(account.getBalance()).thenReturn(Wei.ZERO); + when(account.getCodeHash()).thenReturn(SIMPLE_EOF.getCodeHash()); + when(account.getCode()).thenReturn(SIMPLE_EOF.getBytes()); + when(worldUpdater.get(any())).thenReturn(account); + when(worldUpdater.getAccount(any())).thenReturn(account); + when(worldUpdater.updater()).thenReturn(worldUpdater); + + var result = operation.execute(messageFrame, EOF_EVM); + + assertThat(result.getGasCost()).isZero(); + assertThat(result.getHaltReason()).isEqualTo(ExceptionalHaltReason.INVALID_OPERATION); + } } From 2339c1df20b81c30b446b612f7688cc589eb35b6 Mon Sep 17 00:00:00 2001 From: garyschulte Date: Fri, 30 Aug 2024 15:33:06 -0700 Subject: [PATCH 171/259] changelog for 24.9.0 (#7550) Signed-off-by: garyschulte --- CHANGELOG.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 20bbb812af..f118aa503b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,16 @@ ### Upcoming Breaking Changes +### Breaking Changes + +### Additions and Improvements + +### Bug fixes + +## 24.9.0 + +### Upcoming Breaking Changes + ### Breaking Changes - Receipt compaction is enabled by default. It will no longer be possible to downgrade Besu to versions prior to 24.5.1. From fa731020971f1a728b4b0e6667ddee9fe6caf239 Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Sun, 1 Sep 2024 17:01:04 -0600 Subject: [PATCH 172/259] Performance improvements to EOF layout fuzzing (#7545) * Performance improvements to fuzzing Turning off guidance speeds the rate of testing up by 10%. Also, add other options to store new guided-discovered tests. Signed-off-by: Danno Ferrin * bring in the whole javafuzz lib so we can tweak it. Signed-off-by: Danno Ferrin --------- Signed-off-by: Danno Ferrin Co-authored-by: Sally MacFarlane --- build.gradle | 4 - gradle/verification-metadata.xml | 13 - gradle/versions.gradle | 2 - testfuzz/build.gradle | 12 +- .../besu/testfuzz/EofContainerSubCommand.java | 27 +- .../besu/testfuzz/javafuzz/Corpus.java | 449 ++++++++++++++++++ .../besu/testfuzz/javafuzz/FuzzTarget.java | 31 ++ .../besu/testfuzz/{ => javafuzz}/Fuzzer.java | 103 ++-- .../besu/testfuzz/javafuzz/README.md | 14 + 9 files changed, 599 insertions(+), 56 deletions(-) create mode 100644 testfuzz/src/main/java/org/hyperledger/besu/testfuzz/javafuzz/Corpus.java create mode 100644 testfuzz/src/main/java/org/hyperledger/besu/testfuzz/javafuzz/FuzzTarget.java rename testfuzz/src/main/java/org/hyperledger/besu/testfuzz/{ => javafuzz}/Fuzzer.java (71%) create mode 100644 testfuzz/src/main/java/org/hyperledger/besu/testfuzz/javafuzz/README.md diff --git a/build.gradle b/build.gradle index 6898086294..75471c17de 100644 --- a/build.gradle +++ b/build.gradle @@ -163,10 +163,6 @@ allprojects { url 'https://splunk.jfrog.io/splunk/ext-releases-local' content { includeGroupByRegex('com\\.splunk\\..*') } } - maven { - url 'https://gitlab.com/api/v4/projects/19871573/packages/maven' - content { includeGroupByRegex('com\\.gitlab\\.javafuzz(\\..*)?') } - } mavenCentral() diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index bd4023f708..f9304c9f8e 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -546,19 +546,6 @@ - - - - - - - - - - - - - diff --git a/gradle/versions.gradle b/gradle/versions.gradle index 587b464ee3..f7599a8498 100644 --- a/gradle/versions.gradle +++ b/gradle/versions.gradle @@ -41,8 +41,6 @@ dependencyManagement { dependency 'org.hyperledger.besu:besu-errorprone-checks:1.0.0' - dependency 'com.gitlab.javafuzz:core:1.26' - dependency 'com.google.guava:guava:33.0.0-jre' dependency 'com.graphql-java:graphql-java:21.5' diff --git a/testfuzz/build.gradle b/testfuzz/build.gradle index fe869209ee..3346f3e56d 100644 --- a/testfuzz/build.gradle +++ b/testfuzz/build.gradle @@ -39,7 +39,6 @@ dependencies { implementation project(':util') implementation 'com.fasterxml.jackson.core:jackson-databind' - implementation 'com.gitlab.javafuzz:core' implementation 'com.google.guava:guava' implementation 'info.picocli:picocli' implementation 'io.tmio:tuweni-bytes' @@ -72,6 +71,15 @@ tasks.register("runFuzzer", JavaExec) { } } +// Adds guidance to the fuzzer but with a 90% performance drop. +tasks.register("fuzzGuided") { + doLast { + runFuzzer.args += "--guidance-regexp=org/(hyperledger/besu|apache/tuweni)" + runFuzzer.args += "--new-corpus-dir=${corpusDir}/.." + } + finalizedBy("runFuzzer") +} + // This fuzzes besu as an external client. Besu fuzzing as a local client is enabled by default. tasks.register("fuzzBesu") { dependsOn(":installDist") @@ -111,7 +119,7 @@ tasks.register("fuzzNethermind") { tasks.register("fuzzReth") { doLast { - runFuzzer.args += "--client=revm=revme bytecode" + runFuzzer.args += "--client=revm=revme bytecode --eof-runtime" } finalizedBy("runFuzzer") } 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 c2b518f182..27c4547d26 100644 --- a/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/EofContainerSubCommand.java +++ b/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/EofContainerSubCommand.java @@ -22,6 +22,7 @@ import org.hyperledger.besu.ethereum.referencetests.EOFTestCaseSpec; import org.hyperledger.besu.evm.EVM; import org.hyperledger.besu.evm.MainnetEVMs; import org.hyperledger.besu.evm.internal.EvmConfiguration; +import org.hyperledger.besu.testfuzz.javafuzz.Fuzzer; import java.io.File; import java.io.FileOutputStream; @@ -48,7 +49,6 @@ import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; -import com.gitlab.javafuzz.core.AbstractFuzzTarget; import com.google.common.base.Stopwatch; import org.apache.tuweni.bytes.Bytes; import picocli.CommandLine; @@ -61,7 +61,7 @@ import picocli.CommandLine.Option; description = "Fuzzes EOF container parsing and validation", mixinStandardHelpOptions = true, versionProvider = VersionProvider.class) -public class EofContainerSubCommand extends AbstractFuzzTarget implements Runnable { +public class EofContainerSubCommand implements Runnable { static final String COMMAND_NAME = "eof-container"; @@ -100,6 +100,16 @@ public class EofContainerSubCommand extends AbstractFuzzTarget implements Runnab description = "Minimum number of fuzz tests before a time limit fuzz error can occur") private long timeThresholdIterations = 2_000; + @Option( + names = {"--guidance-regexp"}, + description = "Regexp for classes that matter for guidance metric") + private String guidanceRegexp; + + @Option( + names = {"--new-corpus-dir"}, + description = "Directory to write hex versions of guidance added contracts") + private File newCorpusDir = null; + @CommandLine.ParentCommand private final BesuFuzzCommand parentCommand; static final ObjectMapper eofTestMapper = createObjectMapper(); @@ -174,7 +184,13 @@ public class EofContainerSubCommand extends AbstractFuzzTarget implements Runnab System.out.println("Fuzzing client set: " + clients.keySet()); try { - new Fuzzer(this, corpusDir.toString(), this::fuzzStats).start(); + new Fuzzer( + this::parseEOFContainers, + corpusDir.toString(), + this::fuzzStats, + guidanceRegexp, + newCorpusDir) + .start(); } catch (NoSuchAlgorithmException | ClassNotFoundException | InvocationTargetException @@ -212,8 +228,7 @@ public class EofContainerSubCommand extends AbstractFuzzTarget implements Runnab } } - @Override - public void fuzz(final byte[] bytes) { + void parseEOFContainers(final byte[] bytes) { Bytes eofUnderTest = Bytes.wrap(bytes); String eofUnderTestHexString = eofUnderTest.toHexString(); @@ -236,7 +251,7 @@ public class EofContainerSubCommand extends AbstractFuzzTarget implements Runnab "%s: slow validation %d µs%n", client.getName(), elapsedMicros); try { Files.writeString( - Path.of("slow-" + client.getName() + "-" + name + ".hex"), + Path.of("slow-" + name + "-" + client.getName() + ".hex"), eofUnderTestHexString); } catch (IOException e) { throw new RuntimeException(e); diff --git a/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/javafuzz/Corpus.java b/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/javafuzz/Corpus.java new file mode 100644 index 0000000000..56eba76d37 --- /dev/null +++ b/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/javafuzz/Corpus.java @@ -0,0 +1,449 @@ +/* + * 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.testfuzz.javafuzz; + +import org.hyperledger.besu.crypto.MessageDigestFactory; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.math.BigInteger; +import java.nio.file.Files; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.ThreadLocalRandom; + +/** + * Ported from ... because + * fields like max input size were not configurable. + */ +@SuppressWarnings("CatchAndPrintStackTrace") +public class Corpus { + private final ArrayList inputs; + private final int maxInputSize; + private static final int[] INTERESTING8 = {-128, -1, 0, 1, 16, 32, 64, 100, 127}; + private static final int[] INTERESTING16 = { + -32768, -129, 128, 255, 256, 512, 1000, 1024, 4096, 32767, -128, -1, 0, 1, 16, 32, 64, 100, 127 + }; + private static final int[] INTERESTING32 = { + -2147483648, + -100663046, + -32769, + 32768, + 65535, + 65536, + 100663045, + 2147483647, + -32768, + -129, + 128, + 255, + 256, + 512, + 1000, + 1024, + 4096, + 32767, + -128, + -1, + 0, + 1, + 16, + 32, + 64, + 100, + 127 + }; + private String corpusPath; + private int seedLength; + + /** + * Create a corpus + * + * @param dirs The directory to store the corpus files + */ + public Corpus(final String dirs) { + this.maxInputSize = 0xc001; // 48k+1 + this.corpusPath = null; + this.inputs = new ArrayList<>(); + if (dirs != null) { + String[] arr = dirs.split(",", -1); + for (String s : arr) { + File f = new File(s); + if (!f.exists()) { + f.mkdirs(); + } + if (f.isDirectory()) { + if (this.corpusPath == null) { + this.corpusPath = f.getPath(); + } + this.loadDir(f); + } else { + try { + this.inputs.add(Files.readAllBytes(f.toPath())); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + this.seedLength = this.inputs.size(); + } + + int getLength() { + return this.inputs.size(); + } + + private boolean randBool() { + return ThreadLocalRandom.current().nextBoolean(); + } + + private int rand(final int max) { + return ThreadLocalRandom.current().nextInt(0, max); + } + + private void loadDir(final File dir) { + for (final File f : dir.listFiles()) { + if (f.isFile()) { + try { + this.inputs.add(Files.readAllBytes(f.toPath())); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + + byte[] generateInput() throws NoSuchAlgorithmException { + if (this.seedLength != 0) { + this.seedLength--; + return this.inputs.get(this.seedLength); + } + if (this.inputs.isEmpty()) { + byte[] buf = new byte[] {}; + this.putBuffer(buf); + return buf; + } + byte[] buf = this.inputs.get(this.rand(this.inputs.size())); + return this.mutate(buf); + } + + void putBuffer(final byte[] buf) throws NoSuchAlgorithmException { + if (this.inputs.contains(buf)) { + return; + } + + this.inputs.add(buf); + + writeCorpusFile(buf); + } + + private void writeCorpusFile(final byte[] buf) throws NoSuchAlgorithmException { + if (this.corpusPath != null) { + MessageDigest md = MessageDigestFactory.create("SHA-256"); + md.update(buf); + byte[] digest = md.digest(); + String hex = String.format("%064x", new BigInteger(1, digest)); + try (FileOutputStream fos = new FileOutputStream(this.corpusPath + "/" + hex)) { + fos.write(buf); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + private String dec2bin(final int dec) { + String bin = Integer.toBinaryString(dec); + String padding = new String(new char[32 - bin.length()]).replace("\0", "0"); + return padding + bin; + } + + private int exp2() { + String bin = dec2bin(this.rand((int) Math.pow(2, 32))); + int count = 0; + for (int i = 0; i < 32; i++) { + if (bin.charAt(i) == '0') { + count++; + } else { + break; + } + } + return count; + } + + int chooseLen(final int n) { + int x = this.rand(100); + if (x < 90) { + return this.rand(Math.min(8, n)) + 1; + } else if (x < 99) { + return this.rand(Math.min(32, n)) + 1; + } else { + return this.rand(n) + 1; + } + } + + static void copy( + final byte[] src, final int srcPos, final byte[] dst, final int dstPos, final int length) { + System.arraycopy(src, srcPos, dst, dstPos, Math.min(length, src.length - srcPos)); + } + + static void copy(final byte[] src, final int srcPos, final byte[] dst, final int dstPos) { + System.arraycopy(src, srcPos, dst, dstPos, Math.min(src.length - srcPos, dst.length - dstPos)); + } + + static byte[] concatZeros(final byte[] a, final int n) { + byte[] c = new byte[a.length + n]; + Arrays.fill(c, (byte) 0); + System.arraycopy(a, 0, c, 0, a.length); + return c; + } + + byte[] mutate(final byte[] buf) { + byte[] res = buf.clone(); + int nm = 1 + this.exp2(); + for (int i = 0; i < nm; i++) { + int x = this.rand(16); + if (x == 0) { + // Remove a range of bytes. + if (res.length <= 1) { + i--; + continue; + } + int pos0 = this.rand(res.length); + int pos1 = pos0 + this.chooseLen(res.length - pos0); + copy(res, pos1, res, pos0, res.length - pos0); + res = Arrays.copyOfRange(res, 0, res.length - (pos1 - pos0)); + } else if (x == 1) { + // Insert a range of random bytes. + int pos = this.rand(res.length + 1); + int n = this.chooseLen(10); + res = concatZeros(res, n); + copy(res, pos, res, pos + n); + for (int k = 0; k < n; k++) { + res[pos + k] = (byte) this.rand(256); + } + } else if (x == 2) { + // Duplicate a range of bytes. + if (res.length <= 1) { + i--; + continue; + } + int src = this.rand(res.length); + int dst = this.rand(res.length); + while (src == dst) { + dst = this.rand(res.length); + } + int n = this.chooseLen(res.length - src); + byte[] tmp = new byte[n]; + Arrays.fill(tmp, (byte) 0); + copy(res, src, tmp, 0); + res = concatZeros(res, n); + copy(res, dst, res, dst + n); + System.arraycopy(tmp, 0, res, dst, n); + } else if (x == 3) { + // Copy a range of bytes. + if (res.length <= 1) { + i--; + continue; + } + int src = this.rand(res.length); + int dst = this.rand(res.length); + while (src == dst) { + dst = this.rand(res.length); + } + int n = this.chooseLen(res.length - src); + copy(res, src + n, res, dst); + } else if (x == 4) { + // Bit flip. Spooky! + if (res.length <= 1) { + i--; + continue; + } + int pos = this.rand(res.length); + res[pos] ^= (byte) (1 << (byte) this.rand(8)); + } else if (x == 5) { + // Set a byte to a random value. + if (res.length <= 1) { + i--; + continue; + } + int pos = this.rand(res.length); + res[pos] ^= (byte) (this.rand(255) + 1); + } else if (x == 6) { + // Swap 2 bytes. + if (res.length <= 1) { + i--; + continue; + } + int src = this.rand(res.length); + int dst = this.rand(res.length); + while (src == dst) { + dst = this.rand(res.length); + } + byte tmp1 = res[src]; + res[src] = res[dst]; + res[dst] = tmp1; + } else if (x == 7) { + // Add/subtract from a byte. + if (res.length == 0) { + i--; + continue; + } + int pos = this.rand(res.length); + int v = this.rand(35) + 1; + if (this.randBool()) { + res[pos] += (byte) v; + } else { + res[pos] -= (byte) v; + } + } else if (x == 8) { + // Add/subtract from a uint16. + i--; + // if (res.length < 2) { + // i--; + // continue; + // } + // int pos = this.rand(res.length - 1); + // int v = this.rand(35) + 1; + // if (this.randBool()) { + // v = 0 - v; + // } + // + // if (this.randBool()) { + // res[pos] = + // } else { + // + // } + + } else if (x == 9) { + i--; + // Add/subtract from a uint32. + } else if (x == 10) { + // Replace a byte with an interesting value. + if (res.length == 0) { + i--; + continue; + } + int pos = this.rand(res.length); + res[pos] = (byte) INTERESTING8[this.rand(INTERESTING8.length)]; + } else if (x == 11) { + // Replace an uint16 with an interesting value. + if (res.length < 2) { + i--; + continue; + } + int pos = this.rand(res.length - 1); + if (this.randBool()) { + res[pos] = (byte) (INTERESTING16[this.rand(INTERESTING16.length)] & 0xFF); + res[pos + 1] = (byte) ((INTERESTING16[this.rand(INTERESTING16.length)] >> 8) & 0xFF); + } else { + res[pos + 1] = (byte) (INTERESTING16[this.rand(INTERESTING16.length)] & 0xFF); + res[pos] = (byte) ((INTERESTING16[this.rand(INTERESTING16.length)] >> 8) & 0xFF); + } + } else if (x == 12) { + // Replace an uint32 with an interesting value. + if (res.length < 4) { + i--; + continue; + } + int pos = this.rand(res.length - 3); + if (this.randBool()) { + res[pos] = (byte) (INTERESTING32[this.rand(INTERESTING32.length)] & 0xFF); + res[pos + 1] = (byte) ((INTERESTING32[this.rand(INTERESTING32.length)] >> 8) & 0xFF); + res[pos + 2] = (byte) ((INTERESTING32[this.rand(INTERESTING32.length)] >> 16) & 0xFF); + res[pos + 3] = (byte) ((INTERESTING32[this.rand(INTERESTING32.length)] >> 24) & 0xFF); + } else { + res[pos + 3] = (byte) (INTERESTING32[this.rand(INTERESTING32.length)] & 0xFF); + res[pos + 2] = (byte) ((INTERESTING32[this.rand(INTERESTING32.length)] >> 8) & 0xFF); + res[pos + 1] = (byte) ((INTERESTING32[this.rand(INTERESTING32.length)] >> 16) & 0xFF); + res[pos] = (byte) ((INTERESTING32[this.rand(INTERESTING32.length)] >> 24) & 0xFF); + } + } else if (x == 13) { + // Replace an ascii digit with another digit. + List digits = new ArrayList<>(); + for (int k = 0; k < res.length; k++) { + if (res[k] >= 48 && res[k] <= 57) { + digits.add(k); + } + } + if (digits.isEmpty()) { + i--; + continue; + } + int pos = this.rand(digits.size()); + int was = res[digits.get(pos)]; + int now = was; + while (now == was) { + now = this.rand(10) + 48; + } + res[digits.get(pos)] = (byte) now; + } else if (x == 14) { + // Splice another input. + if (res.length < 4 || this.inputs.size() < 2) { + i--; + continue; + } + byte[] other = this.inputs.get(this.rand(this.inputs.size())); + if (other.length < 4) { + i--; + continue; + } + // Find common prefix and suffix. + int idx0 = 0; + while (idx0 < res.length && idx0 < other.length && res[idx0] == other[idx0]) { + idx0++; + } + int idx1 = 0; + while (idx1 < res.length + && idx1 < other.length + && res[res.length - idx1 - 1] == other[other.length - idx1 - 1]) { + idx1++; + } + int diff = Math.min(res.length - idx0 - idx1, other.length - idx0 - idx1); + if (diff < 4) { + i--; + continue; + } + copy(other, idx0, res, idx0, Math.min(other.length, idx0 + this.rand(diff - 2) + 1) - idx0); + } else if (x == 15) { + // Insert a part of another input. + if (res.length < 4 || this.inputs.size() < 2) { + i--; + continue; + } + byte[] other = this.inputs.get(this.rand(this.inputs.size())); + if (other.length < 4) { + i--; + continue; + } + int pos0 = this.rand(res.length + 1); + int pos1 = this.rand(other.length - 2); + int n = this.chooseLen(other.length - pos1 - 2) + 2; + res = concatZeros(res, n); + copy(res, pos0, res, pos0 + n); + if (n >= 0) System.arraycopy(other, pos1, res, pos0, n); + } + } + + if (res.length > this.maxInputSize) { + res = Arrays.copyOfRange(res, 0, this.maxInputSize); + } + return res; + } +} diff --git a/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/javafuzz/FuzzTarget.java b/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/javafuzz/FuzzTarget.java new file mode 100644 index 0000000000..26f3522e11 --- /dev/null +++ b/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/javafuzz/FuzzTarget.java @@ -0,0 +1,31 @@ +/* + * 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.testfuzz.javafuzz; + +/** + * Adapted from ... because + * I wanted it to be a functional interface + */ +@FunctionalInterface +public interface FuzzTarget { + + /** + * The target to fuzz + * + * @param data data proviced by the fuzzer + */ + void fuzz(byte[] data); +} diff --git a/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/Fuzzer.java b/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/javafuzz/Fuzzer.java similarity index 71% rename from testfuzz/src/main/java/org/hyperledger/besu/testfuzz/Fuzzer.java rename to testfuzz/src/main/java/org/hyperledger/besu/testfuzz/javafuzz/Fuzzer.java index e4ebb68cc8..f5d7f537a2 100644 --- a/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/Fuzzer.java +++ b/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/javafuzz/Fuzzer.java @@ -12,14 +12,20 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.testfuzz; +package org.hyperledger.besu.testfuzz.javafuzz; + +import static java.nio.charset.StandardCharsets.UTF_8; import org.hyperledger.besu.crypto.Hash; import org.hyperledger.besu.crypto.MessageDigestFactory; +import java.io.BufferedWriter; import java.io.ByteArrayInputStream; +import java.io.File; import java.io.FileOutputStream; import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.math.BigInteger; @@ -28,9 +34,9 @@ import java.security.NoSuchAlgorithmException; import java.util.HashMap; import java.util.Map; import java.util.function.Supplier; +import java.util.regex.Matcher; +import java.util.regex.Pattern; -import com.gitlab.javafuzz.core.AbstractFuzzTarget; -import com.gitlab.javafuzz.core.Corpus; import org.apache.tuweni.bytes.Bytes; import org.jacoco.core.data.ExecutionData; import org.jacoco.core.data.ExecutionDataReader; @@ -38,13 +44,19 @@ import org.jacoco.core.data.IExecutionDataVisitor; import org.jacoco.core.data.ISessionInfoVisitor; import org.jacoco.core.data.SessionInfo; -/** Ported from javafuzz because JaCoCo APIs changed. */ +/** + * Ported from ... because + * JaCoCo APIs changed. + */ @SuppressWarnings({"java:S106", "CallToPrintStackTrace"}) // we use lots the console, on purpose public class Fuzzer { - private final AbstractFuzzTarget target; + private final FuzzTarget target; private final Corpus corpus; private final Object agent; private final Method getExecutionDataMethod; + private final Pattern guidanceRegexp; + private final File newCorpusDir; private long executionsInSample; private long lastSampleTime; private long totalExecutions; @@ -58,6 +70,8 @@ public class Fuzzer { * @param target The target to fuzz * @param dirs the list of corpus dirs and files, comma separated. * @param fuzzStats additional fuzzing data from the client + * @param guidanceRegexp Regexp of (slash delimited) class names to check for guidance. + * @param newCorpusDir Direcroty to dump hex encoded versions of guidance discovered tests. * @throws ClassNotFoundException If Jacoco RT is not found (because jacocoagent.jar is not * loaded) * @throws NoSuchMethodException If the wrong version of Jacoco is loaded @@ -66,7 +80,11 @@ public class Fuzzer { * @throws NoSuchAlgorithmException If the SHA-256 crypto algo cannot be loaded. */ public Fuzzer( - final AbstractFuzzTarget target, final String dirs, final Supplier fuzzStats) + final FuzzTarget target, + final String dirs, + final Supplier fuzzStats, + final String guidanceRegexp, + final File newCorpusDir) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, @@ -75,6 +93,15 @@ public class Fuzzer { this.target = target; this.corpus = new Corpus(dirs); this.fuzzStats = fuzzStats; + this.newCorpusDir = newCorpusDir; + if (newCorpusDir != null) { + if (newCorpusDir.exists() && newCorpusDir.isFile()) { + throw new IllegalArgumentException("New corpus directory already exists as a file"); + } + newCorpusDir.mkdirs(); + } + this.guidanceRegexp = + guidanceRegexp == null || guidanceRegexp.isBlank() ? null : Pattern.compile(guidanceRegexp); Class c = Class.forName("org.jacoco.agent.rt.RT"); Method getAgentMethod = c.getMethod("getAgent"); this.agent = getAgentMethod.invoke(null); @@ -132,6 +159,11 @@ public class Fuzzer { this.lastSampleTime = System.currentTimeMillis(); Map hitMap = new HashMap<>(); + // preload some values so we don't get false hits in coverage we don't care about. + hitMap.put("org/hyperledger/besu/testfuzz/EofContainerSubCommand", 100); + hitMap.put("org/hyperledger/besu/testfuzz/Fuzzer", 100); + hitMap.put("org/hyperledger/besu/testfuzz/Fuzzer$HitCounter", 100); + hitMap.put("org/hyperledger/besu/testfuzz/InternalClient", 100); while (true) { byte[] buf = this.corpus.generateInput(); @@ -152,19 +184,22 @@ public class Fuzzer { if (newCoverage > this.totalCoverage) { this.totalCoverage = newCoverage; this.corpus.putBuffer(buf); - this.logStats("NEW"); - - // If you want hex strings of new hits, uncomment the following. - // String filename = fileNameForBuffer(buf); - // try (var pw = - // new PrintWriter( - // new BufferedWriter( - // new OutputStreamWriter(new FileOutputStream(filename), UTF_8)))) { - // pw.println(Bytes.wrap(buf).toHexString()); - // System.out.println(filename); - // } catch (IOException e) { - // e.printStackTrace(System.out); - // } + if (totalExecutions > corpus.getLength()) { + this.logStats("NEW"); + if (newCorpusDir != null) { + + String filename = fileNameForBuffer(buf); + try (var pw = + new PrintWriter( + new BufferedWriter( + new OutputStreamWriter( + new FileOutputStream(new File(newCorpusDir, filename)), UTF_8)))) { + pw.println(Bytes.wrap(buf).toHexString()); + } catch (IOException e) { + e.printStackTrace(System.out); + } + } + } } else if ((System.currentTimeMillis() - this.lastSampleTime) > 30000) { this.logStats("PULSE"); } @@ -175,14 +210,17 @@ public class Fuzzer { MessageDigest md = MessageDigestFactory.create(MessageDigestFactory.SHA256_ALG); md.update(buf); byte[] digest = md.digest(); - return String.format("./new-%064x.hex", new BigInteger(1, digest)); + return String.format("new-%064x.hex", new BigInteger(1, digest)); } private long getHitCount(final Map hitMap) throws IllegalAccessException, InvocationTargetException { + if (guidanceRegexp == null) { + return 1; + } byte[] dumpData = (byte[]) this.getExecutionDataMethod.invoke(this.agent, false); ExecutionDataReader edr = new ExecutionDataReader(new ByteArrayInputStream(dumpData)); - HitCounter hc = new HitCounter(hitMap); + HitCounter hc = new HitCounter(hitMap, guidanceRegexp); edr.setExecutionDataVisitor(hc); edr.setSessionInfoVisitor(hc); try { @@ -198,28 +236,35 @@ public class Fuzzer { static class HitCounter implements IExecutionDataVisitor, ISessionInfoVisitor { long hits = 0; Map hitMap; + Pattern guidanceRegexp; - public HitCounter(final Map hitMap) { + public HitCounter(final Map hitMap, final Pattern guidanceRegexp) { this.hitMap = hitMap; + this.guidanceRegexp = guidanceRegexp; } @Override public void visitClassExecution(final ExecutionData executionData) { + String name = executionData.getName(); + Matcher matcher = guidanceRegexp.matcher(name); int hit = 0; + if (!matcher.find()) { + return; + } + if (matcher.start() != 0) { + return; + } for (boolean b : executionData.getProbes()) { - if (executionData.getName().startsWith("org/hyperledger/besu/testfuzz/") - || executionData.getName().startsWith("org/bouncycastle/") - || executionData.getName().startsWith("com/gitlab/javafuzz/")) { - continue; - } if (b) { hit++; } } - String name = executionData.getName(); if (hitMap.containsKey(name)) { - if (hitMap.get(name) < hit) { + int theHits = hitMap.get(name); + if (theHits < hit) { hitMap.put(name, hit); + } else { + hit = theHits; } } else { hitMap.put(name, hit); diff --git a/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/javafuzz/README.md b/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/javafuzz/README.md new file mode 100644 index 0000000000..276e404fa0 --- /dev/null +++ b/testfuzz/src/main/java/org/hyperledger/besu/testfuzz/javafuzz/README.md @@ -0,0 +1,14 @@ +## Credits & Acknowledgments + +These classes were ported from [Javafuzz](https://gitlab.com/gitlab-org/security-products/analyzers/fuzzers/javafuzz/). +Javafuzz is a port of [fuzzitdev/jsfuzz](https://gitlab.com/gitlab-org/security-products/analyzers/fuzzers/jsfuzz). + +Which in turn based based on [go-fuzz](https://github.com/dvyukov/go-fuzz) originally developed by [Dmitry Vyukov's](https://twitter.com/dvyukov). +Which is in turn heavily based on [Michal Zalewski](https://twitter.com/lcamtuf) [AFL](http://lcamtuf.coredump.cx/afl/). + +## Changes + +* Increased max binary size to 48k+1 +* ported AbstractFuzzTarget to a functional interface FuzzTarget +* Fixed some incompatibilities with JaCoCo +* Besu style required changes (formatting, final params, etc.) \ No newline at end of file From c915e057cf11d6f84f6f50d8779bfade234b2809 Mon Sep 17 00:00:00 2001 From: Preeti <35308865+pr9t@users.noreply.github.com> Date: Mon, 2 Sep 2024 04:56:11 +0530 Subject: [PATCH 173/259] chore: Removed Privacy ATs (#7530) * chore: Removed privacy acceptance classes Signed-off-by: Preeti <35308865+pr9t@users.noreply.github.com> * Chore: removed classes that extends PrivateLogFilterAcceptanceTest and FlexiblePrivacyAcceptanceTestBase Signed-off-by: Preeti <35308865+pr9t@users.noreply.github.com> --------- Signed-off-by: Preeti <35308865+pr9t@users.noreply.github.com> Co-authored-by: Sally MacFarlane --- .../privacy/ParameterizedEnclaveTestBase.java | 74 -- .../privacy/PrivacyAcceptanceTestBase.java | 85 --- .../BftPrivacyClusterAcceptanceTest.java | 318 --------- ...loyPrivateSmartContractAcceptanceTest.java | 77 --- .../privacy/EnclaveErrorAcceptanceTest.java | 240 ------- .../FlexiblePrivacyAcceptanceTest.java | 642 ------------------ .../FlexiblePrivacyAcceptanceTestBase.java | 186 ----- .../PluginPrivacySigningAcceptanceTest.java | 137 ---- .../privacy/PrivCallAcceptanceTest.java | 295 -------- ...tStateRootFlexibleGroupAcceptanceTest.java | 181 ----- ...tStateRootOffchainGroupAcceptanceTest.java | 113 --- .../privacy/PrivGetCodeAcceptanceTest.java | 102 --- .../privacy/PrivGetLogsAcceptanceTest.java | 171 ----- ...ivGetPrivateTransactionAcceptanceTest.java | 153 ----- .../PrivTraceTransactionAcceptanceTest.java | 174 ----- .../privacy/PrivacyClusterAcceptanceTest.java | 407 ----------- .../privacy/PrivacyGroupAcceptanceTest.java | 255 ------- .../privacy/PrivacyReceiptAcceptanceTest.java | 165 ----- ...vateContractPublicStateAcceptanceTest.java | 225 ------ .../privacy/PrivateGenesisAcceptanceTest.java | 100 --- .../PrivateLogFilterAcceptanceTest.java | 162 ----- .../FlexibleMultiTenancyAcceptanceTest.java | 491 -------------- 22 files changed, 4753 deletions(-) delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/ParameterizedEnclaveTestBase.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/PrivacyAcceptanceTestBase.java delete mode 100644 acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/BftPrivacyClusterAcceptanceTest.java delete mode 100644 acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/DeployPrivateSmartContractAcceptanceTest.java delete mode 100644 acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/EnclaveErrorAcceptanceTest.java delete mode 100644 acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/FlexiblePrivacyAcceptanceTest.java delete mode 100644 acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/FlexiblePrivacyAcceptanceTestBase.java delete mode 100644 acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PluginPrivacySigningAcceptanceTest.java delete mode 100644 acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivCallAcceptanceTest.java delete mode 100644 acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivDebugGetStateRootFlexibleGroupAcceptanceTest.java delete mode 100644 acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivDebugGetStateRootOffchainGroupAcceptanceTest.java delete mode 100644 acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivGetCodeAcceptanceTest.java delete mode 100644 acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivGetLogsAcceptanceTest.java delete mode 100644 acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivGetPrivateTransactionAcceptanceTest.java delete mode 100644 acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivTraceTransactionAcceptanceTest.java delete mode 100644 acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivacyClusterAcceptanceTest.java delete mode 100644 acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivacyGroupAcceptanceTest.java delete mode 100644 acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivacyReceiptAcceptanceTest.java delete mode 100644 acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivateContractPublicStateAcceptanceTest.java delete mode 100644 acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivateGenesisAcceptanceTest.java delete mode 100644 acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivateLogFilterAcceptanceTest.java delete mode 100644 acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/multitenancy/FlexibleMultiTenancyAcceptanceTest.java diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/ParameterizedEnclaveTestBase.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/ParameterizedEnclaveTestBase.java deleted file mode 100644 index 581fd71722..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/ParameterizedEnclaveTestBase.java +++ /dev/null @@ -1,74 +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.tests.acceptance.dsl.privacy; - -import static org.hyperledger.enclave.testutil.EnclaveEncryptorType.EC; -import static org.hyperledger.enclave.testutil.EnclaveEncryptorType.NACL; -import static org.hyperledger.enclave.testutil.EnclaveType.NOOP; -import static org.hyperledger.enclave.testutil.EnclaveType.TESSERA; -import static org.web3j.utils.Restriction.RESTRICTED; -import static org.web3j.utils.Restriction.UNRESTRICTED; - -import org.hyperledger.besu.tests.acceptance.dsl.privacy.transaction.PluginCreateRandomPrivacyGroupIdTransaction; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.transaction.RestrictedCreatePrivacyGroupTransaction; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; -import org.hyperledger.enclave.testutil.EnclaveEncryptorType; -import org.hyperledger.enclave.testutil.EnclaveType; - -import java.util.Arrays; -import java.util.Collection; - -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.junit.runners.Parameterized.Parameters; -import org.web3j.utils.Restriction; - -@RunWith(Parameterized.class) -public abstract class ParameterizedEnclaveTestBase extends PrivacyAcceptanceTestBase { - protected final Restriction restriction; - protected final EnclaveType enclaveType; - protected final EnclaveEncryptorType enclaveEncryptorType; - - protected ParameterizedEnclaveTestBase( - final Restriction restriction, - final EnclaveType enclaveType, - final EnclaveEncryptorType enclaveEncryptorType) { - this.restriction = restriction; - this.enclaveType = enclaveType; - this.enclaveEncryptorType = enclaveEncryptorType; - } - - @Parameters(name = "{0} tx with {1} enclave and {2} encryptor type") - public static Collection params() { - return Arrays.asList( - new Object[][] { - {RESTRICTED, TESSERA, NACL}, - {RESTRICTED, TESSERA, EC}, - {UNRESTRICTED, NOOP, EnclaveEncryptorType.NOOP} - }); - } - - public Transaction createPrivacyGroup( - final String name, final String description, final PrivacyNode... nodes) { - - if (restriction == RESTRICTED) { - return new RestrictedCreatePrivacyGroupTransaction(name, description, nodes); - } else if (restriction == UNRESTRICTED) { - return new PluginCreateRandomPrivacyGroupIdTransaction(); - } else { - throw new RuntimeException("Do not know how to handle " + restriction); - } - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/PrivacyAcceptanceTestBase.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/PrivacyAcceptanceTestBase.java deleted file mode 100644 index 8e12cbc7a8..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/PrivacyAcceptanceTestBase.java +++ /dev/null @@ -1,85 +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.tests.acceptance.dsl.privacy; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.hyperledger.besu.tests.acceptance.dsl.WaitUtils; -import org.hyperledger.besu.tests.acceptance.dsl.condition.eth.EthConditions; -import org.hyperledger.besu.tests.acceptance.dsl.condition.net.NetConditions; -import org.hyperledger.besu.tests.acceptance.dsl.condition.priv.PrivConditions; -import org.hyperledger.besu.tests.acceptance.dsl.node.configuration.privacy.PrivacyNodeFactory; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.condition.PrivateContractVerifier; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.condition.PrivateTransactionVerifier; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.contract.PrivateContractTransactions; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.transaction.PrivacyTransactions; -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.net.NetTransactions; - -import java.math.BigInteger; - -import io.vertx.core.Vertx; -import org.junit.After; -import org.junit.ClassRule; -import org.junit.rules.TemporaryFolder; - -public class PrivacyAcceptanceTestBase { - @ClassRule public static final TemporaryFolder privacy = new TemporaryFolder(); - - protected final PrivacyTransactions privacyTransactions; - protected final PrivateContractVerifier privateContractVerifier; - protected final PrivateTransactionVerifier privateTransactionVerifier; - protected final PrivacyNodeFactory privacyBesu; - protected final PrivateContractTransactions privateContractTransactions; - protected final PrivConditions priv; - protected final PrivacyCluster privacyCluster; - protected final ContractTransactions contractTransactions; - protected final NetConditions net; - protected final EthTransactions ethTransactions; - protected final EthConditions eth; - private final Vertx vertx = Vertx.vertx(); - - public PrivacyAcceptanceTestBase() { - ethTransactions = new EthTransactions(); - net = new NetConditions(new NetTransactions()); - privacyTransactions = new PrivacyTransactions(); - privateContractVerifier = new PrivateContractVerifier(); - privateTransactionVerifier = new PrivateTransactionVerifier(privacyTransactions); - privacyBesu = new PrivacyNodeFactory(vertx); - privateContractTransactions = new PrivateContractTransactions(); - privacyCluster = new PrivacyCluster(net); - priv = - new PrivConditions( - new org.hyperledger.besu.tests.acceptance.dsl.transaction.privacy - .PrivacyTransactions()); - contractTransactions = new ContractTransactions(); - eth = new EthConditions(ethTransactions); - } - - protected void waitForBlockHeight(final PrivacyNode node, final long blockchainHeight) { - WaitUtils.waitFor( - 120, - () -> - assertThat(node.execute(ethTransactions.blockNumber())) - .isGreaterThanOrEqualTo(BigInteger.valueOf(blockchainHeight))); - } - - @After - public void tearDownAcceptanceTestBase() { - privacyCluster.close(); - vertx.close(); - } -} diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/BftPrivacyClusterAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/BftPrivacyClusterAcceptanceTest.java deleted file mode 100644 index 4475627fd1..0000000000 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/BftPrivacyClusterAcceptanceTest.java +++ /dev/null @@ -1,318 +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.tests.acceptance.privacy; - -import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyAcceptanceTestBase; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.account.PrivacyAccountResolver; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.bft.ConsensusType; -import org.hyperledger.besu.tests.web3j.generated.EventEmitter; -import org.hyperledger.enclave.testutil.EnclaveEncryptorType; -import org.hyperledger.enclave.testutil.EnclaveType; - -import java.io.IOException; -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Optional; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.testcontainers.containers.Network; -import org.web3j.protocol.besu.response.privacy.PrivateTransactionReceipt; -import org.web3j.utils.Restriction; - -@RunWith(Parameterized.class) -public class BftPrivacyClusterAcceptanceTest extends PrivacyAcceptanceTestBase { - private final BftPrivacyType bftPrivacyType; - - public static class BftPrivacyType { - private final EnclaveType enclaveType; - private final EnclaveEncryptorType enclaveEncryptorType; - private final ConsensusType consensusType; - private final Restriction restriction; - - public BftPrivacyType( - final EnclaveType enclaveType, - final EnclaveEncryptorType enclaveEncryptorType, - final ConsensusType consensusType, - final Restriction restriction) { - this.enclaveType = enclaveType; - this.enclaveEncryptorType = enclaveEncryptorType; - this.consensusType = consensusType; - this.restriction = restriction; - } - - @Override - public String toString() { - return String.join( - ",", - enclaveType.toString(), - enclaveEncryptorType.toString(), - consensusType.toString(), - restriction.toString()); - } - } - - public BftPrivacyClusterAcceptanceTest(final BftPrivacyType bftPrivacyType) { - this.bftPrivacyType = bftPrivacyType; - } - - @Parameterized.Parameters(name = "{0}") - public static Collection bftPrivacyTypes() { - final List bftPrivacyTypes = new ArrayList<>(); - for (EnclaveType x : EnclaveType.valuesForTests()) { - for (ConsensusType consensusType : ConsensusType.values()) { - bftPrivacyTypes.add( - new BftPrivacyType( - x, EnclaveEncryptorType.NACL, consensusType, Restriction.RESTRICTED)); - bftPrivacyTypes.add( - new BftPrivacyType(x, EnclaveEncryptorType.EC, consensusType, Restriction.RESTRICTED)); - } - } - - for (ConsensusType consensusType : ConsensusType.values()) { - bftPrivacyTypes.add( - new BftPrivacyType( - EnclaveType.NOOP, - EnclaveEncryptorType.NOOP, - consensusType, - Restriction.UNRESTRICTED)); - } - - return bftPrivacyTypes; - } - - private PrivacyNode alice; - private PrivacyNode bob; - private PrivacyNode charlie; - - @Before - public void setUp() throws Exception { - final Network containerNetwork = Network.newNetwork(); - - alice = createNode(containerNetwork, "node1", 0); - bob = createNode(containerNetwork, "node2", 1); - charlie = createNode(containerNetwork, "node3", 2); - - privacyCluster.start(alice, bob, charlie); - alice.verify(priv.syncingStatus(false)); - bob.verify(priv.syncingStatus(false)); - charlie.verify(priv.syncingStatus(false)); - } - - private PrivacyNode createNode( - final Network containerNetwork, final String nodeName, final int privacyAccount) - throws IOException { - if (bftPrivacyType.consensusType == ConsensusType.IBFT2) { - return privacyBesu.createIbft2NodePrivacyEnabled( - nodeName, - PrivacyAccountResolver.values()[privacyAccount].resolve( - bftPrivacyType.enclaveEncryptorType), - true, - bftPrivacyType.enclaveType, - Optional.of(containerNetwork), - false, - false, - bftPrivacyType.restriction == Restriction.UNRESTRICTED, - "0xAA"); - } else if (bftPrivacyType.consensusType == ConsensusType.QBFT) { - return privacyBesu.createQbftNodePrivacyEnabled( - nodeName, - PrivacyAccountResolver.values()[privacyAccount].resolve( - bftPrivacyType.enclaveEncryptorType), - bftPrivacyType.enclaveType, - Optional.of(containerNetwork), - false, - false, - bftPrivacyType.restriction == Restriction.UNRESTRICTED, - "0xAA"); - } else { - throw new IllegalStateException("Unknown consensus type " + bftPrivacyType.consensusType); - } - } - - @Test - public void onlyAliceAndBobCanExecuteContract() { - // Contract address is generated from sender address and transaction nonce - final String contractAddress = - EnclaveEncryptorType.EC.equals(bftPrivacyType.enclaveEncryptorType) - ? "0x3e5d325a03ad3ce5640502219833d30b89ce3ce1" - : "0xebf56429e6500e84442467292183d4d621359838"; - - final EventEmitter eventEmitter = - alice.execute( - privateContractTransactions.createSmartContract( - EventEmitter.class, - alice.getTransactionSigningKey(), - alice.getEnclaveKey(), - bob.getEnclaveKey())); - - privateContractVerifier - .validPrivateContractDeployed(contractAddress, alice.getAddress().toString()) - .verify(eventEmitter); - - final String transactionHash = - alice.execute( - privateContractTransactions.callSmartContract( - eventEmitter.getContractAddress(), - eventEmitter.store(BigInteger.ONE).encodeFunctionCall(), - alice.getTransactionSigningKey(), - bftPrivacyType.restriction, - alice.getEnclaveKey(), - bob.getEnclaveKey())); - - final PrivateTransactionReceipt expectedReceipt = - alice.execute(privacyTransactions.getPrivateTransactionReceipt(transactionHash)); - - bob.verify( - privateTransactionVerifier.validPrivateTransactionReceipt( - transactionHash, expectedReceipt)); - - if (bftPrivacyType.restriction != Restriction.UNRESTRICTED) { - charlie.verify(privateTransactionVerifier.noPrivateTransactionReceipt(transactionHash)); - } - } - - @Test - public void aliceCanDeployMultipleTimesInSingleGroup() { - final String firstDeployedAddress = - EnclaveEncryptorType.EC.equals(bftPrivacyType.enclaveEncryptorType) - ? "0x3e5d325a03ad3ce5640502219833d30b89ce3ce1" - : "0xebf56429e6500e84442467292183d4d621359838"; - - privacyCluster.stopNode(charlie); - - final EventEmitter firstEventEmitter = - alice.execute( - privateContractTransactions.createSmartContract( - EventEmitter.class, - alice.getTransactionSigningKey(), - alice.getEnclaveKey(), - bob.getEnclaveKey())); - - privateContractVerifier - .validPrivateContractDeployed(firstDeployedAddress, alice.getAddress().toString()) - .verify(firstEventEmitter); - - final String secondDeployedAddress = - EnclaveEncryptorType.EC.equals(bftPrivacyType.enclaveEncryptorType) - ? "0x5194e214fae257530710d18c868df7a295d9d53b" - : "0x10f807f8a905da5bd319196da7523c6bd768690f"; - - final EventEmitter secondEventEmitter = - alice.execute( - privateContractTransactions.createSmartContract( - EventEmitter.class, - alice.getTransactionSigningKey(), - alice.getEnclaveKey(), - bob.getEnclaveKey())); - - privateContractVerifier - .validPrivateContractDeployed(secondDeployedAddress, alice.getAddress().toString()) - .verify(secondEventEmitter); - } - - @Test - public void canInteractWithMultiplePrivacyGroups() { - // alice deploys contract - final String firstDeployedAddress = - EnclaveEncryptorType.EC.equals(bftPrivacyType.enclaveEncryptorType) - ? "0x760359bc605b3848f5199829bde6b382d90fb8eb" - : "0xff206d21150a8da5b83629d8a722f3135ed532b1"; - - final EventEmitter firstEventEmitter = - alice.execute( - privateContractTransactions.createSmartContract( - EventEmitter.class, - alice.getTransactionSigningKey(), - alice.getEnclaveKey(), - bob.getEnclaveKey(), - charlie.getEnclaveKey())); - - privateContractVerifier - .validPrivateContractDeployed(firstDeployedAddress, alice.getAddress().toString()) - .verify(firstEventEmitter); - - // charlie interacts with contract - final String firstTransactionHash = - charlie.execute( - privateContractTransactions.callSmartContract( - firstEventEmitter.getContractAddress(), - firstEventEmitter.store(BigInteger.ONE).encodeFunctionCall(), - charlie.getTransactionSigningKey(), - bftPrivacyType.restriction, - charlie.getEnclaveKey(), - alice.getEnclaveKey(), - bob.getEnclaveKey())); - - // alice gets receipt from charlie's interaction - final PrivateTransactionReceipt aliceReceipt = - alice.execute(privacyTransactions.getPrivateTransactionReceipt(firstTransactionHash)); - - // verify bob and charlie have access to the same receipt - bob.verify( - privateTransactionVerifier.validPrivateTransactionReceipt( - firstTransactionHash, aliceReceipt)); - charlie.verify( - privateTransactionVerifier.validPrivateTransactionReceipt( - firstTransactionHash, aliceReceipt)); - - // alice deploys second contract - final String secondDeployedAddress = - EnclaveEncryptorType.EC.equals(bftPrivacyType.enclaveEncryptorType) - ? "0x3e5d325a03ad3ce5640502219833d30b89ce3ce1" - : "0xebf56429e6500e84442467292183d4d621359838"; - - final EventEmitter secondEventEmitter = - alice.execute( - privateContractTransactions.createSmartContract( - EventEmitter.class, - alice.getTransactionSigningKey(), - alice.getEnclaveKey(), - bob.getEnclaveKey())); - - privateContractVerifier - .validPrivateContractDeployed(secondDeployedAddress, alice.getAddress().toString()) - .verify(secondEventEmitter); - - // bob interacts with contract - final String secondTransactionHash = - bob.execute( - privateContractTransactions.callSmartContract( - secondEventEmitter.getContractAddress(), - secondEventEmitter.store(BigInteger.ONE).encodeFunctionCall(), - bob.getTransactionSigningKey(), - bftPrivacyType.restriction, - bob.getEnclaveKey(), - alice.getEnclaveKey())); - - // alice gets receipt from bob's interaction - final PrivateTransactionReceipt secondExpectedReceipt = - alice.execute(privacyTransactions.getPrivateTransactionReceipt(secondTransactionHash)); - - bob.verify( - privateTransactionVerifier.validPrivateTransactionReceipt( - secondTransactionHash, secondExpectedReceipt)); - - // charlie cannot see the receipt - if (bftPrivacyType.restriction != Restriction.UNRESTRICTED) { - charlie.verify(privateTransactionVerifier.noPrivateTransactionReceipt(secondTransactionHash)); - } - } -} diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/DeployPrivateSmartContractAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/DeployPrivateSmartContractAcceptanceTest.java deleted file mode 100644 index 65786988c9..0000000000 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/DeployPrivateSmartContractAcceptanceTest.java +++ /dev/null @@ -1,77 +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.tests.acceptance.privacy; - -import static org.web3j.utils.Restriction.UNRESTRICTED; - -import org.hyperledger.besu.tests.acceptance.dsl.privacy.ParameterizedEnclaveTestBase; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.account.PrivacyAccountResolver; -import org.hyperledger.besu.tests.web3j.generated.EventEmitter; -import org.hyperledger.enclave.testutil.EnclaveEncryptorType; -import org.hyperledger.enclave.testutil.EnclaveType; - -import java.io.IOException; -import java.util.Optional; - -import org.junit.Test; -import org.web3j.utils.Restriction; - -public class DeployPrivateSmartContractAcceptanceTest extends ParameterizedEnclaveTestBase { - - private final PrivacyNode minerNode; - - public DeployPrivateSmartContractAcceptanceTest( - final Restriction restriction, - final EnclaveType enclaveType, - final EnclaveEncryptorType enclaveEncryptorType) - throws IOException { - super(restriction, enclaveType, enclaveEncryptorType); - - minerNode = - privacyBesu.createPrivateTransactionEnabledMinerNode( - restriction + "-node", - PrivacyAccountResolver.ALICE.resolve(enclaveEncryptorType), - enclaveType, - Optional.empty(), - false, - false, - restriction == UNRESTRICTED); - - privacyCluster.start(minerNode); - minerNode.verify(priv.syncingStatus(false)); - } - - @Test - public void deployingMustGiveValidReceiptAndCode() throws Exception { - final String contractAddress = - EnclaveEncryptorType.EC.equals(enclaveEncryptorType) - ? "0xfeeb2367e77e28f75fc3bcc55b70a535752db058" - : "0x89ce396d0f9f937ddfa71113e29b2081c4869555"; - - final EventEmitter eventEmitter = - minerNode.execute( - privateContractTransactions.createSmartContract( - EventEmitter.class, - minerNode.getTransactionSigningKey(), - minerNode.getEnclaveKey())); - - privateContractVerifier - .validPrivateContractDeployed(contractAddress, minerNode.getAddress().toString()) - .verify(eventEmitter); - - privateContractVerifier.validContractCodeProvided().verify(eventEmitter); - } -} diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/EnclaveErrorAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/EnclaveErrorAcceptanceTest.java deleted file mode 100644 index 3eab2b7243..0000000000 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/EnclaveErrorAcceptanceTest.java +++ /dev/null @@ -1,240 +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.tests.acceptance.privacy; - -import static org.assertj.core.api.Assertions.catchThrowable; -import static org.assertj.core.api.AssertionsForClassTypes.assertThat; -import static org.hyperledger.enclave.testutil.EnclaveEncryptorType.EC; -import static org.hyperledger.enclave.testutil.EnclaveEncryptorType.NACL; -import static org.hyperledger.enclave.testutil.EnclaveType.TESSERA; - -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyAcceptanceTestBase; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.account.PrivacyAccountResolver; -import org.hyperledger.besu.tests.web3j.generated.EventEmitter; -import org.hyperledger.enclave.testutil.EnclaveEncryptorType; -import org.hyperledger.enclave.testutil.EnclaveType; - -import java.io.IOException; -import java.math.BigInteger; -import java.security.KeyPairGenerator; -import java.security.spec.ECGenParameterSpec; -import java.util.Arrays; -import java.util.Base64; -import java.util.Collection; -import java.util.Optional; - -import org.apache.tuweni.crypto.sodium.Box; -import org.assertj.core.api.Condition; -import org.junit.Ignore; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.junit.runners.Parameterized.Parameters; -import org.testcontainers.containers.Network; -import org.web3j.protocol.besu.response.privacy.PrivateTransactionReceipt; -import org.web3j.utils.Restriction; - -@RunWith(Parameterized.class) -public class EnclaveErrorAcceptanceTest extends PrivacyAcceptanceTestBase { - - private final PrivacyNode alice; - private final PrivacyNode bob; - private final String wrongPublicKey; - - @Parameters(name = "{0} enclave type with {1} encryptor") - public static Collection enclaveParameters() { - return Arrays.asList( - new Object[][] { - {TESSERA, NACL}, - {TESSERA, EC} - }); - } - - public EnclaveErrorAcceptanceTest( - final EnclaveType enclaveType, final EnclaveEncryptorType enclaveEncryptorType) - throws IOException { - - final Network containerNetwork = Network.newNetwork(); - - alice = - privacyBesu.createIbft2NodePrivacyEnabled( - "node1", - PrivacyAccountResolver.ALICE.resolve(enclaveEncryptorType), - false, - enclaveType, - Optional.of(containerNetwork), - false, - false, - false, - "0xAA"); - bob = - privacyBesu.createIbft2NodePrivacyEnabled( - "node2", - PrivacyAccountResolver.BOB.resolve(enclaveEncryptorType), - false, - enclaveType, - Optional.of(containerNetwork), - false, - false, - false, - "0xBB"); - privacyCluster.start(alice, bob); - - alice.verify(priv.syncingStatus(false)); - bob.verify(priv.syncingStatus(false)); - - final byte[] wrongPublicKeyBytes = - EnclaveEncryptorType.EC.equals(enclaveEncryptorType) - ? getSECP256r1PublicKeyByteArray() - : Box.KeyPair.random().publicKey().bytesArray(); - - wrongPublicKey = Base64.getEncoder().encodeToString(wrongPublicKeyBytes); - } - - @Test - public void aliceCannotSendTransactionFromBobNode() { - final Throwable throwable = - catchThrowable( - () -> - alice.execute( - privateContractTransactions.createSmartContract( - EventEmitter.class, - alice.getTransactionSigningKey(), - wrongPublicKey, - bob.getEnclaveKey()))); - - assertThat(throwable) - .hasMessageContaining( - RpcErrorType.PRIVATE_FROM_DOES_NOT_MATCH_ENCLAVE_PUBLIC_KEY.getMessage()); - } - - @Test - public void enclaveNoPeerUrlError() { - final Throwable throwable = - catchThrowable( - () -> - alice.execute( - privateContractTransactions.createSmartContract( - EventEmitter.class, - alice.getTransactionSigningKey(), - alice.getEnclaveKey(), - wrongPublicKey))); - - final String tesseraMessage = RpcErrorType.TESSERA_NODE_MISSING_PEER_URL.getMessage(); - - assertThat(throwable.getMessage()).has(matchTesseraEnclaveMessage(tesseraMessage)); - } - - @Test - public void whenEnclaveIsDisconnectedGetReceiptReturnsInternalError() { - final EventEmitter eventEmitter = - alice.execute( - privateContractTransactions.createSmartContract( - EventEmitter.class, - alice.getTransactionSigningKey(), - alice.getEnclaveKey(), - bob.getEnclaveKey())); - - privateContractVerifier - .validPrivateContractDeployed( - eventEmitter.getContractAddress(), alice.getAddress().toString()) - .verify(eventEmitter); - - final String transactionHash = - alice.execute( - privateContractTransactions.callSmartContract( - eventEmitter.getContractAddress(), - eventEmitter.store(BigInteger.ONE).encodeFunctionCall(), - alice.getTransactionSigningKey(), - Restriction.RESTRICTED, - alice.getEnclaveKey(), - bob.getEnclaveKey())); - - final PrivateTransactionReceipt receiptBeforeEnclaveLosesConnection = - alice.execute(privacyTransactions.getPrivateTransactionReceipt(transactionHash)); - - alice.verify( - privateTransactionVerifier.validPrivateTransactionReceipt( - transactionHash, receiptBeforeEnclaveLosesConnection)); - - alice.getEnclave().stop(); - - alice.verify( - privateTransactionVerifier.internalErrorPrivateTransactionReceipt(transactionHash)); - } - - @Test - @Ignore("Web3J is broken by PR #1426") - public void transactionFailsIfPartyIsOffline() { - // Contract address is generated from sender address and transaction nonce - final String contractAddress = "0xebf56429e6500e84442467292183d4d621359838"; - - final EventEmitter eventEmitter = - alice.execute( - privateContractTransactions.createSmartContract( - EventEmitter.class, - alice.getTransactionSigningKey(), - alice.getEnclaveKey(), - bob.getEnclaveKey())); - - privateContractVerifier - .validPrivateContractDeployed(contractAddress, alice.getAddress().toString()) - .verify(eventEmitter); - - bob.getEnclave().stop(); - - final Throwable throwable = - catchThrowable( - () -> - alice.execute( - privateContractTransactions.callSmartContract( - eventEmitter.getContractAddress(), - eventEmitter.store(BigInteger.ONE).encodeFunctionCall(), - alice.getTransactionSigningKey(), - Restriction.RESTRICTED, - alice.getEnclaveKey(), - bob.getEnclaveKey()))); - - assertThat(throwable).hasMessageContaining("NodePropagatingToAllPeers"); - } - - @Test - public void createPrivacyGroupReturnsCorrectError() { - final Throwable throwable = - catchThrowable(() -> alice.execute(privacyTransactions.createPrivacyGroup(null, null))); - final String tesseraMessage = RpcErrorType.TESSERA_CREATE_GROUP_INCLUDE_SELF.getMessage(); - - assertThat(throwable.getMessage()).has(matchTesseraEnclaveMessage(tesseraMessage)); - } - - private Condition matchTesseraEnclaveMessage(final String enclaveMessage) { - return new Condition<>( - message -> message.contains(enclaveMessage), - "Message did not match Tessera expected output"); - } - - private byte[] getSECP256r1PublicKeyByteArray() { - try { - final KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC"); - final ECGenParameterSpec spec = new ECGenParameterSpec("secp256r1"); - keyGen.initialize(spec); - return keyGen.generateKeyPair().getPublic().getEncoded(); - } catch (Exception exception) { - return new byte[0]; - } - } -} diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/FlexiblePrivacyAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/FlexiblePrivacyAcceptanceTest.java deleted file mode 100644 index fb0a128b86..0000000000 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/FlexiblePrivacyAcceptanceTest.java +++ /dev/null @@ -1,642 +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.tests.acceptance.privacy; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.hyperledger.besu.ethereum.core.PrivacyParameters.FLEXIBLE_PRIVACY_PROXY; -import static org.hyperledger.enclave.testutil.EnclaveEncryptorType.EC; -import static org.hyperledger.enclave.testutil.EnclaveEncryptorType.NACL; -import static org.hyperledger.enclave.testutil.EnclaveType.TESSERA; -import static org.junit.runners.Parameterized.Parameters; - -import org.hyperledger.besu.tests.acceptance.dsl.condition.eth.EthConditions; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.account.PrivacyAccountResolver; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.miner.MinerTransactions; -import org.hyperledger.besu.tests.web3j.generated.EventEmitter; -import org.hyperledger.enclave.testutil.EnclaveEncryptorType; -import org.hyperledger.enclave.testutil.EnclaveType; - -import java.math.BigInteger; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import java.util.function.BiConsumer; -import java.util.function.Supplier; - -import com.google.common.collect.Lists; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.testcontainers.containers.Network; -import org.web3j.crypto.Credentials; -import org.web3j.protocol.besu.response.privacy.PrivateTransactionReceipt; -import org.web3j.protocol.core.methods.response.EthCall; -import org.web3j.protocol.core.methods.response.Log; -import org.web3j.protocol.core.methods.response.TransactionReceipt; -import org.web3j.tx.Contract; - -@RunWith(Parameterized.class) -public class FlexiblePrivacyAcceptanceTest extends FlexiblePrivacyAcceptanceTestBase { - - private final EnclaveType enclaveType; - private final EnclaveEncryptorType enclaveEncryptorType; - - public FlexiblePrivacyAcceptanceTest( - final EnclaveType enclaveType, final EnclaveEncryptorType enclaveEncryptorType) { - this.enclaveType = enclaveType; - this.enclaveEncryptorType = enclaveEncryptorType; - } - - @Parameters(name = "{0} enclave type with {1} encryptor") - public static Collection enclaveParameters() { - return Arrays.asList( - new Object[][] { - {TESSERA, NACL}, - {TESSERA, EC} - }); - } - - private PrivacyNode alice; - private PrivacyNode bob; - private PrivacyNode charlie; - - private final MinerTransactions minerTransactions = new MinerTransactions(); - private final EthConditions ethConditions = new EthConditions(ethTransactions); - - private static final String EXPECTED_STORE_OUTPUT_DATA = - "0x000000000000000000000000f17f52151ebef6c7334fad080c5704d77216b7320000000000000000000000000000000000000000000000000000000000000539"; - private static final String EXPECTED_STORE_EVENT_TOPIC = - "0xc9db20adedc6cf2b5d25252b101ab03e124902a73fcb12b753f3d1aaa2d8f9f5"; - - @Before - public void setUp() throws Exception { - final Network containerNetwork = Network.newNetwork(); - - alice = - privacyBesu.createFlexiblePrivacyGroupEnabledMinerNode( - "node1", - PrivacyAccountResolver.ALICE.resolve(enclaveEncryptorType), - false, - enclaveType, - Optional.of(containerNetwork)); - bob = - privacyBesu.createFlexiblePrivacyGroupEnabledNode( - "node2", - PrivacyAccountResolver.BOB.resolve(enclaveEncryptorType), - false, - enclaveType, - Optional.of(containerNetwork)); - charlie = - privacyBesu.createFlexiblePrivacyGroupEnabledNode( - "node3", - PrivacyAccountResolver.CHARLIE.resolve(enclaveEncryptorType), - false, - enclaveType, - Optional.of(containerNetwork)); - privacyCluster.start(alice, bob, charlie); - - alice.verify(priv.syncingStatus(false)); - bob.verify(priv.syncingStatus(false)); - charlie.verify(priv.syncingStatus(false)); - } - - @Test - public void nodeCanCreatePrivacyGroup() { - final String privacyGroupId = createFlexiblePrivacyGroup(alice); - checkFlexiblePrivacyGroupExists(privacyGroupId, alice); - } - - @Test - public void deployingMustGiveValidReceipt() { - final String privacyGroupId = createFlexiblePrivacyGroup(alice, bob); - final Contract eventEmitter = deployPrivateContract(EventEmitter.class, privacyGroupId, alice); - final String commitmentHash = getContractDeploymentCommitmentHash(eventEmitter); - - alice.verify(privateTransactionVerifier.existingPrivateTransactionReceipt(commitmentHash)); - bob.verify(privateTransactionVerifier.existingPrivateTransactionReceipt(commitmentHash)); - } - - @Test - public void canAddParticipantToGroup() { - final String privacyGroupId = createFlexiblePrivacyGroup(alice, bob); - final Contract eventEmitter = deployPrivateContract(EventEmitter.class, privacyGroupId, alice); - final String commitmentHash = getContractDeploymentCommitmentHash(eventEmitter); - - charlie.verify(privateTransactionVerifier.noPrivateTransactionReceipt(commitmentHash)); - - final Credentials aliceCredentials = Credentials.create(alice.getTransactionSigningKey()); - lockPrivacyGroup(privacyGroupId, alice, aliceCredentials); - addMembersToPrivacyGroup(privacyGroupId, alice, aliceCredentials, charlie); - checkFlexiblePrivacyGroupExists(privacyGroupId, alice, bob, charlie); - - charlie.verify(privateTransactionVerifier.existingPrivateTransactionReceipt(commitmentHash)); - } - - @Test - public void removedMemberCannotSendTransactionToGroup() { - final String privacyGroupId = createFlexiblePrivacyGroup(alice, bob); - - final String removeHash = - removeFromPrivacyGroup( - privacyGroupId, alice, Credentials.create(alice.getTransactionSigningKey()), bob); - - bob.verify(privateTransactionVerifier.existingPrivateTransactionReceipt(removeHash)); - - assertThatThrownBy(() -> deployPrivateContract(EventEmitter.class, privacyGroupId, bob)) - .isInstanceOf(RuntimeException.class) - .hasMessageContaining("Flexible Privacy group does not exist."); - } - - @Test - public void canInteractWithPrivateGenesisPreCompile() throws Exception { - final String privacyGroupId = createFlexiblePrivacyGroup(alice, bob); - - final EventEmitter eventEmitter = - alice.execute( - privateContractTransactions.loadSmartContractWithPrivacyGroupId( - "0x1000000000000000000000000000000000000001", - EventEmitter.class, - alice.getTransactionSigningKey(), - alice.getEnclaveKey(), - privacyGroupId)); - - privateTransactionVerifier.existingPrivateTransactionReceipt( - eventEmitter.store(BigInteger.valueOf(42)).send().getTransactionHash()); - - final String aliceResponse = - alice - .execute( - privacyTransactions.privCall( - privacyGroupId, eventEmitter, eventEmitter.value().encodeFunctionCall())) - .getValue(); - - assertThat(new BigInteger(aliceResponse.substring(2), 16)) - .isEqualByComparingTo(BigInteger.valueOf(42)); - - final String bobResponse = - bob.execute( - privacyTransactions.privCall( - privacyGroupId, eventEmitter, eventEmitter.value().encodeFunctionCall())) - .getValue(); - - assertThat(new BigInteger(bobResponse.substring(2), 16)) - .isEqualByComparingTo(BigInteger.valueOf(42)); - - final String charlieResponse = - charlie - .execute( - privacyTransactions.privCall( - privacyGroupId, eventEmitter, eventEmitter.value().encodeFunctionCall())) - .getValue(); - - assertThat(charlieResponse).isEqualTo("0x"); - } - - @Test - public void memberCanBeAddedAfterBeingRemoved() { - final String privacyGroupId = createFlexiblePrivacyGroup(alice); - - checkFlexiblePrivacyGroupExists(privacyGroupId, alice); - - lockPrivacyGroup(privacyGroupId, alice, Credentials.create(alice.getTransactionSigningKey())); - addMembersToPrivacyGroup( - privacyGroupId, alice, Credentials.create(alice.getTransactionSigningKey()), bob); - - checkFlexiblePrivacyGroupExists(privacyGroupId, alice, bob); - - final EventEmitter eventEmitter = - deployPrivateContract(EventEmitter.class, privacyGroupId, alice); - - final int valueSetWhileBobWasMember = 17; - final PrivateTransactionReceipt receiptWhileBobMember = - setEventEmitterValueAndCheck( - Lists.newArrayList(alice, bob), - privacyGroupId, - eventEmitter, - valueSetWhileBobWasMember); - - removeFromPrivacyGroup( - privacyGroupId, alice, Credentials.create(alice.getTransactionSigningKey()), bob); - - checkFlexiblePrivacyGroupExists(privacyGroupId, alice); - - final int valueSetWhileBobWas_NOT_aMember = 1337; - final PrivateTransactionReceipt receiptWhileBobRemoved = - setEventEmitterValueAndCheck( - Lists.newArrayList(alice), - privacyGroupId, - eventEmitter, - valueSetWhileBobWas_NOT_aMember); - checkEmitterValue( - Lists.newArrayList(bob), - privacyGroupId, - eventEmitter, - valueSetWhileBobWasMember); // bob did not get the last transaction - - lockPrivacyGroup(privacyGroupId, alice, Credentials.create(alice.getTransactionSigningKey())); - addMembersToPrivacyGroup( - privacyGroupId, alice, Credentials.create(alice.getTransactionSigningKey()), bob); - - checkFlexiblePrivacyGroupExists(privacyGroupId, alice, bob); - - checkEmitterValue( - Lists.newArrayList(alice, bob), - privacyGroupId, - eventEmitter, - valueSetWhileBobWas_NOT_aMember); - - PrivateTransactionReceipt receipt = - bob.execute( - privacyTransactions.getPrivateTransactionReceipt( - receiptWhileBobRemoved.getcommitmentHash())); - assertThat(receipt.getStatus()).isEqualTo("0x1"); - - receipt = - bob.execute( - privacyTransactions.getPrivateTransactionReceipt( - receiptWhileBobMember.getcommitmentHash())); - assertThat(receipt.getStatus()).isEqualTo("0x1"); - } - - PrivateTransactionReceipt setEventEmitterValueAndCheck( - final List nodes, - final String privacyGroupId, - final EventEmitter eventEmitter, - final int value) { - final PrivateTransactionReceipt receiptWhileBobMember = - setEventEmitterValue(nodes, privacyGroupId, eventEmitter, value); - - checkEmitterValue(nodes, privacyGroupId, eventEmitter, value); - return receiptWhileBobMember; - } - - private PrivateTransactionReceipt setEventEmitterValue( - final List nodes, - final String privacyGroupId, - final EventEmitter eventEmitter, - final int value) { - final PrivacyNode firstNode = nodes.get(0); - final String txHash = - firstNode.execute( - privateContractTransactions.callOnchainPermissioningSmartContract( - eventEmitter.getContractAddress(), - eventEmitter.store(BigInteger.valueOf(value)).encodeFunctionCall(), - firstNode.getTransactionSigningKey(), - firstNode.getEnclaveKey(), - privacyGroupId)); - PrivateTransactionReceipt receipt = null; - for (final PrivacyNode node : nodes) { - receipt = node.execute(privacyTransactions.getPrivateTransactionReceipt(txHash)); - assertThat(receipt.getStatus()).isEqualTo("0x1"); - } - return receipt; - } - - private void checkEmitterValue( - final List nodes, - final String privacyGroupId, - final EventEmitter eventEmitter, - final int expectedValue) { - for (final PrivacyNode node : nodes) { - final EthCall response = - node.execute( - privacyTransactions.privCall( - privacyGroupId, eventEmitter, eventEmitter.value().encodeFunctionCall())); - - assertThat(new BigInteger(response.getValue().substring(2), 16)) - .isEqualByComparingTo(BigInteger.valueOf(expectedValue)); - } - } - - @Test - public void bobCanAddCharlieAfterBeingAddedByAlice() { - final String privacyGroupId = createFlexiblePrivacyGroup(alice); - checkFlexiblePrivacyGroupExists(privacyGroupId, alice); - final EventEmitter eventEmitter = - alice.execute( - privateContractTransactions.createSmartContractWithPrivacyGroupId( - EventEmitter.class, - alice.getTransactionSigningKey(), - alice.getEnclaveKey(), - privacyGroupId)); - - privateContractVerifier - .validPrivateContractDeployed( - eventEmitter.getContractAddress(), alice.getAddress().toString()) - .verify(eventEmitter); - - final Credentials aliceCredentials = Credentials.create(alice.getTransactionSigningKey()); - final String aliceLockHash = - alice.execute( - privacyTransactions.privxLockPrivacyGroupAndCheck( - privacyGroupId, alice, aliceCredentials)); - - alice.execute( - privacyTransactions.addToPrivacyGroup(privacyGroupId, alice, aliceCredentials, bob)); - - checkFlexiblePrivacyGroupExists(privacyGroupId, alice, bob); - - bob.execute( - privacyTransactions.privxLockPrivacyGroupAndCheck(privacyGroupId, bob, aliceCredentials)); - - alice.execute(minerTransactions.minerStop()); - - alice.getBesu().verify(ethConditions.miningStatus(false)); - - final BigInteger pendingTransactionFilterId = - alice.execute(ethTransactions.newPendingTransactionsFilter()); - - final String callHash = - alice.execute( - privateContractTransactions.callOnchainPermissioningSmartContract( - eventEmitter.getContractAddress(), - eventEmitter.value().encodeFunctionCall(), - alice.getTransactionSigningKey(), - alice.getEnclaveKey(), - privacyGroupId)); - - final String bobAddHash = - addMembersToPrivacyGroup(privacyGroupId, bob, aliceCredentials, charlie); - - alice - .getBesu() - .verify( - ethConditions.expectNewPendingTransactions( - pendingTransactionFilterId, Arrays.asList(callHash, bobAddHash))); - - alice.execute(minerTransactions.minerStart()); - - alice.getBesu().verify(ethConditions.miningStatus(true)); - - checkFlexiblePrivacyGroupExists(privacyGroupId, alice, bob, charlie); - - final Optional aliceAddReceipt = - alice.execute(ethTransactions.getTransactionReceipt(bobAddHash)); - assertThat(aliceAddReceipt.get().getStatus()) - .isEqualTo("0x1"); // this means the PMT for the "add" succeeded which is what we expect - - final Optional alicePublicReceipt = - alice.execute(ethTransactions.getTransactionReceipt(callHash)); - if (alicePublicReceipt.isPresent()) { - assertThat(alicePublicReceipt.get().getBlockHash()) - .isEqualTo( - aliceAddReceipt - .get() - .getBlockHash()); // ensure that "add" and "call" are in the same block - assertThat(alicePublicReceipt.get().getStatus()) - .isEqualTo( - "0x1"); // this means the PMT for the "call" succeeded which is what we expect because - // it is in the same block as the "add" and there is no way to tell that this - // will happen before the block is mined - } - - final PrivateTransactionReceipt aliceReceipt = - alice.execute(privacyTransactions.getPrivateTransactionReceipt(callHash)); - assertThat(aliceReceipt.getStatus()) - .isEqualTo( - "0x0"); // this means the "call" failed which is what we expect because the group was - // locked! - final PrivateTransactionReceipt bobReceipt = - alice.execute(privacyTransactions.getPrivateTransactionReceipt(callHash)); - assertThat(bobReceipt.getStatus()) - .isEqualTo( - "0x0"); // this means the "call" failed which is what we expect because the group was - // locked! - - // assert charlie can access private transaction information from before he was added - final PrivateTransactionReceipt expectedAliceLockReceipt = - new PrivateTransactionReceipt( - null, - alice.getAddress().toHexString(), - FLEXIBLE_PRIVACY_PROXY.toHexString(), - "0x", - Collections.emptyList(), - null, - null, - alice.getEnclaveKey(), - null, - privacyGroupId, - "0x1", - null); - charlie.verify( - privateTransactionVerifier.validPrivateTransactionReceipt( - aliceLockHash, expectedAliceLockReceipt)); - - final String aliceStoreHash = - charlie.execute( - privateContractTransactions.callOnchainPermissioningSmartContract( - eventEmitter.getContractAddress(), - eventEmitter.store(BigInteger.valueOf(1337)).encodeFunctionCall(), - charlie.getTransactionSigningKey(), - charlie.getEnclaveKey(), - privacyGroupId)); - - final PrivateTransactionReceipt expectedStoreReceipt = - new PrivateTransactionReceipt( - null, - charlie.getAddress().toHexString(), - eventEmitter.getContractAddress(), - "0x", - Collections.singletonList( - new Log( - false, - "0x0", - "0x0", - aliceStoreHash, - null, - null, - eventEmitter.getContractAddress(), - EXPECTED_STORE_OUTPUT_DATA, - null, - Collections.singletonList(EXPECTED_STORE_EVENT_TOPIC))), - null, - null, - charlie.getEnclaveKey(), - null, - privacyGroupId, - "0x1", - null); - - alice.verify( - privateTransactionVerifier.validPrivateTransactionReceipt( - aliceStoreHash, expectedStoreReceipt)); - - bob.verify( - privateTransactionVerifier.validPrivateTransactionReceipt( - aliceStoreHash, expectedStoreReceipt)); - - charlie.verify( - privateTransactionVerifier.validPrivateTransactionReceipt( - aliceStoreHash, expectedStoreReceipt)); - - removeFromPrivacyGroup(privacyGroupId, bob, aliceCredentials, charlie); - - checkFlexiblePrivacyGroupExists(privacyGroupId, alice, bob); - } - - @Test - public void canOnlyCallProxyContractWhenGroupLocked() { - final String privacyGroupId = createFlexiblePrivacyGroup(alice); - checkFlexiblePrivacyGroupExists(privacyGroupId, alice); - - final EventEmitter eventEmitter = - alice.execute( - privateContractTransactions.createSmartContractWithPrivacyGroupId( - EventEmitter.class, - alice.getTransactionSigningKey(), - alice.getEnclaveKey(), - privacyGroupId)); - - privateContractVerifier - .validPrivateContractDeployed( - eventEmitter.getContractAddress(), alice.getAddress().toString()) - .verify(eventEmitter); - - final Credentials aliceCredentials = Credentials.create(alice.getTransactionSigningKey()); - - final Supplier callContract = - () -> { - return alice.execute( - privateContractTransactions.callOnchainPermissioningSmartContract( - eventEmitter.getContractAddress(), - eventEmitter.value().encodeFunctionCall(), - alice.getTransactionSigningKey(), - alice.getEnclaveKey(), - privacyGroupId)); - }; - - final String lockHash = - alice.execute( - privacyTransactions.privxLockPrivacyGroupAndCheck( - privacyGroupId, alice, aliceCredentials)); - - final String callWhileLockedHash = callContract.get(); - - final String unlockHash = - alice.execute( - privacyTransactions.privxUnlockPrivacyGroupAndCheck( - privacyGroupId, alice, aliceCredentials)); - - final String callAfterUnlockedHash = callContract.get(); - - alice.execute(minerTransactions.minerStart()); - alice.getBesu().verify(ethConditions.miningStatus(true)); - - final BiConsumer assertThatTransactionReceiptIs = - (String hash, String expectedResult) -> { - final PrivateTransactionReceipt receipt = - alice.execute(privacyTransactions.getPrivateTransactionReceipt(hash)); - assertThat(receipt.getStatus()).isEqualTo(expectedResult); - }; - - // when locking a group succeeds ... - assertThatTransactionReceiptIs.accept(lockHash, "0x1"); - // ... calls to contracts fail ... - assertThatTransactionReceiptIs.accept(callWhileLockedHash, "0x0"); - // ... but unlock the group works ... - assertThatTransactionReceiptIs.accept(unlockHash, "0x1"); - // ... and afterwards we can call contracts again - assertThatTransactionReceiptIs.accept(callAfterUnlockedHash, "0x1"); - } - - @Test - public void addMembersToTwoGroupsInTheSameBlock() { - final String privacyGroupId1 = createFlexiblePrivacyGroup(alice); - final String privacyGroupId2 = createFlexiblePrivacyGroup(bob); - checkFlexiblePrivacyGroupExists(privacyGroupId1, alice); - checkFlexiblePrivacyGroupExists(privacyGroupId2, bob); - - lockPrivacyGroup(privacyGroupId1, alice, Credentials.create(alice.getTransactionSigningKey())); - lockPrivacyGroup(privacyGroupId2, bob, Credentials.create(bob.getTransactionSigningKey())); - - final BigInteger pendingTransactionFilterId = - alice.execute(ethTransactions.newPendingTransactionsFilter()); - - alice.execute(minerTransactions.minerStop()); - alice.getBesu().verify(ethConditions.miningStatus(false)); - - final String aliceAddHash = - addMembersToPrivacyGroup( - privacyGroupId1, alice, Credentials.create(alice.getTransactionSigningKey()), charlie); - final String bobAddHash = - addMembersToPrivacyGroup( - privacyGroupId2, bob, Credentials.create(bob.getTransactionSigningKey()), alice); - - alice - .getBesu() - .verify( - ethConditions.expectNewPendingTransactions( - pendingTransactionFilterId, Arrays.asList(aliceAddHash, bobAddHash))); - - alice.execute(minerTransactions.minerStart()); - - checkFlexiblePrivacyGroupExists(privacyGroupId1, alice, charlie); - checkFlexiblePrivacyGroupExists(privacyGroupId2, bob, alice); - } - - private T deployPrivateContract( - final Class clazz, final String privacyGroupId, final PrivacyNode sender) { - final T contract = - sender.execute( - privateContractTransactions.createSmartContractWithPrivacyGroupId( - clazz, sender.getTransactionSigningKey(), sender.getEnclaveKey(), privacyGroupId)); - - privateContractVerifier - .validPrivateContractDeployed(contract.getContractAddress(), sender.getAddress().toString()) - .verify(contract); - - return contract; - } - - private String addMembersToPrivacyGroup( - final String privacyGroupId, - final PrivacyNode nodeAddingMember, - final Credentials signer, - final PrivacyNode... newMembers) { - return nodeAddingMember.execute( - privacyTransactions.addToPrivacyGroup( - privacyGroupId, nodeAddingMember, signer, newMembers)); - } - - private String removeFromPrivacyGroup( - final String privacyGroupId, - final PrivacyNode nodeRemovingMember, - final Credentials signer, - final PrivacyNode memberBeingRemoved) { - return nodeRemovingMember.execute( - privacyTransactions.removeFromPrivacyGroup( - privacyGroupId, - nodeRemovingMember.getEnclaveKey(), - signer, - memberBeingRemoved.getEnclaveKey())); - } - - /** - * This method will send a transaction to lock the privacy group identified by the specified id. - * This also checks if the lock transaction was successful. - * - * @return the hash of the lock privacy group transaction - */ - private String lockPrivacyGroup( - final String privacyGroupId, final PrivacyNode member, final Credentials signer) { - return member.execute( - privacyTransactions.privxLockPrivacyGroupAndCheck(privacyGroupId, member, signer)); - } -} diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/FlexiblePrivacyAcceptanceTestBase.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/FlexiblePrivacyAcceptanceTestBase.java deleted file mode 100644 index 9e4f1638da..0000000000 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/FlexiblePrivacyAcceptanceTestBase.java +++ /dev/null @@ -1,186 +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.tests.acceptance.privacy; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.hyperledger.besu.ethereum.core.PrivacyParameters.FLEXIBLE_PRIVACY_PROXY; -import static org.hyperledger.besu.ethereum.privacy.group.FlexibleGroupManagement.GET_PARTICIPANTS_METHOD_SIGNATURE; - -import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyAcceptanceTestBase; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.condition.ExpectValidFlexiblePrivacyGroupCreated; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.transaction.CreateFlexiblePrivacyGroupTransaction; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.privacy.PrivacyRequestFactory; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; - -import org.apache.tuweni.bytes.Bytes; -import org.web3j.abi.FunctionEncoder; -import org.web3j.abi.Utils; -import org.web3j.abi.datatypes.DynamicArray; -import org.web3j.abi.datatypes.DynamicBytes; -import org.web3j.protocol.besu.response.privacy.PrivateTransactionReceipt; -import org.web3j.protocol.core.methods.response.TransactionReceipt; -import org.web3j.tx.Contract; -import org.web3j.utils.Base64String; - -public class FlexiblePrivacyAcceptanceTestBase extends PrivacyAcceptanceTestBase { - - protected String createFlexiblePrivacyGroup(final PrivacyNode... members) { - final List addresses = - Arrays.stream(members).map(PrivacyNode::getEnclaveKey).collect(Collectors.toList()); - return createFlexiblePrivacyGroup(members[0].getEnclaveKey(), addresses, members); - } - - /** - * Create an flexible privacy group. The privacy group id will be randomly generated. - * - *

This method also checks that each node member has successfully processed the transaction and - * has the expected list of member for the group. - * - * @param members the list of members of the privacy group. The first member of the list will be - * the creator of the group. - * @return the id of the privacy group - */ - protected String createFlexiblePrivacyGroup( - final String privateFrom, final List addresses, final PrivacyNode... members) { - - final PrivacyNode groupCreator = members[0]; - - final CreateFlexiblePrivacyGroupTransaction createTx = - privacyTransactions.createFlexiblePrivacyGroup(groupCreator, privateFrom, addresses); - - final PrivacyRequestFactory.PrivxCreatePrivacyGroupResponse createResponse = - groupCreator.execute(createTx); - final String privacyGroupId = createResponse.getPrivacyGroupId(); - - final List membersEnclaveKeys = - Arrays.stream(members) - .map(m -> Base64String.wrap(m.getEnclaveKey())) - .collect(Collectors.toList()); - - for (final PrivacyNode member : members) { - member.verify(flexiblePrivacyGroupExists(privacyGroupId, membersEnclaveKeys)); - } - - final String commitmentHash = - callGetParticipantsMethodAndReturnCommitmentHash(privacyGroupId, groupCreator, privateFrom); - final PrivateTransactionReceipt expectedReceipt = - buildExpectedAddMemberTransactionReceipt(privacyGroupId, groupCreator, addresses); - - for (final PrivacyNode member : members) { - member.verify( - privateTransactionVerifier.validPrivateTransactionReceipt( - commitmentHash, expectedReceipt)); - } - - return privacyGroupId; - } - - protected String callGetParticipantsMethodAndReturnCommitmentHash( - final String privacyGroupId, final PrivacyNode groupCreator, final String privateFrom) { - return groupCreator.execute( - privateContractTransactions.callOnchainPermissioningSmartContract( - FLEXIBLE_PRIVACY_PROXY.toHexString(), - GET_PARTICIPANTS_METHOD_SIGNATURE.toString(), - groupCreator.getTransactionSigningKey(), - privateFrom, - privacyGroupId)); - } - - protected PrivateTransactionReceipt buildExpectedAddMemberTransactionReceipt( - final String privacyGroupId, final PrivacyNode groupCreator, final List members) { - return buildExpectedAddMemberTransactionReceipt( - privacyGroupId, groupCreator, groupCreator.getEnclaveKey(), members); - } - - protected PrivateTransactionReceipt buildExpectedAddMemberTransactionReceipt( - final String privacyGroupId, - final PrivacyNode groupCreator, - final String privateFrom, - final List members) { - - final StringBuilder output = new StringBuilder(); - // hex prefix - output.append("0x"); - - final String encodedParameters = - FunctionEncoder.encode( - "", - Arrays.asList( - new DynamicArray<>( - DynamicBytes.class, - Utils.typeMap( - members.stream() - .map(Bytes::fromBase64String) - .map(Bytes::toArrayUnsafe) - .collect(Collectors.toList()), - DynamicBytes.class)))); - - output.append(encodedParameters); - - return new PrivateTransactionReceipt( - null, - groupCreator.getAddress().toHexString(), - FLEXIBLE_PRIVACY_PROXY.toHexString(), - output.toString(), - Collections.emptyList(), - null, - null, - privateFrom, - null, - privacyGroupId, - "0x1", - null); - } - - protected ExpectValidFlexiblePrivacyGroupCreated flexiblePrivacyGroupExists( - final String privacyGroupId, final List members) { - return privateTransactionVerifier.flexiblePrivacyGroupExists(privacyGroupId, members); - } - - protected String getContractDeploymentCommitmentHash(final Contract contract) { - final Optional transactionReceipt = contract.getTransactionReceipt(); - assertThat(transactionReceipt).isPresent(); - final PrivateTransactionReceipt privateTransactionReceipt = - (PrivateTransactionReceipt) transactionReceipt.get(); - return privateTransactionReceipt.getcommitmentHash(); - } - - /** - * This method will check if a privacy group with the specified id and list of members exists. - * Each one of the members node will be queried to ensure that they all have the same privacy - * group in their private state. - * - * @param privacyGroupId the id of the privacy group - * @param members the list of member in the privacy group - */ - protected void checkFlexiblePrivacyGroupExists( - final String privacyGroupId, final PrivacyNode... members) { - final List membersEnclaveKeys = - Arrays.stream(members) - .map(PrivacyNode::getEnclaveKey) - .map(Base64String::wrap) - .collect(Collectors.toList()); - - for (final PrivacyNode member : members) { - member.verify(flexiblePrivacyGroupExists(privacyGroupId, membersEnclaveKeys)); - } - } -} diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PluginPrivacySigningAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PluginPrivacySigningAcceptanceTest.java deleted file mode 100644 index 330f00554d..0000000000 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PluginPrivacySigningAcceptanceTest.java +++ /dev/null @@ -1,137 +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.tests.acceptance.privacy; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.hyperledger.besu.tests.acceptance.dsl.node.configuration.BesuNodeConfigurationBuilder; -import org.hyperledger.besu.tests.acceptance.dsl.node.configuration.privacy.PrivacyNodeConfiguration; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyAcceptanceTestBase; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.account.PrivacyAccount; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.account.PrivacyAccountResolver; -import org.hyperledger.besu.tests.web3j.generated.EventEmitter; -import org.hyperledger.enclave.testutil.EnclaveEncryptorType; -import org.hyperledger.enclave.testutil.EnclaveKeyConfiguration; -import org.hyperledger.enclave.testutil.EnclaveType; - -import java.io.IOException; -import java.math.BigInteger; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.web3j.protocol.core.DefaultBlockParameter; -import org.web3j.protocol.core.methods.response.EthBlock.Block; -import org.web3j.protocol.core.methods.response.TransactionReceipt; - -@RunWith(Parameterized.class) -public class PluginPrivacySigningAcceptanceTest extends PrivacyAcceptanceTestBase { - private PrivacyNode minerNode; - - private final EnclaveEncryptorType enclaveEncryptorType; - - public PluginPrivacySigningAcceptanceTest(final EnclaveEncryptorType enclaveEncryptorType) { - this.enclaveEncryptorType = enclaveEncryptorType; - } - - @Parameterized.Parameters(name = "{0}") - public static Collection enclaveEncryptorTypes() { - return Arrays.stream(EnclaveEncryptorType.values()) - .filter(encryptorType -> !EnclaveEncryptorType.NOOP.equals(encryptorType)) - .collect(Collectors.toList()); - } - - @Before - public void setup() throws IOException { - final PrivacyAccount BOB = PrivacyAccountResolver.BOB.resolve(enclaveEncryptorType); - - minerNode = - privacyBesu.create( - new PrivacyNodeConfiguration( - false, - false, - true, - new BesuNodeConfigurationBuilder() - .name("miner") - .miningEnabled() - .jsonRpcEnabled() - .webSocketEnabled() - .enablePrivateTransactions() - .keyFilePath(BOB.getPrivateKeyPath()) - .plugins(Collections.singletonList("testPlugins")) - .extraCLIOptions( - List.of( - "--plugin-privacy-service-encryption-prefix=0xAA", - "--plugin-privacy-service-signing-enabled=true", - "--plugin-privacy-service-signing-key=8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63")) - .build(), - new EnclaveKeyConfiguration( - BOB.getEnclaveKeyPaths(), - BOB.getEnclavePrivateKeyPaths(), - BOB.getEnclaveEncryptorType())), - EnclaveType.NOOP, - Optional.empty()); - - privacyCluster.start(minerNode); - - minerNode.verify(priv.syncingStatus(false)); - } - - @Test - public void canDeployContractSignedByPlugin() throws Exception { - final String contractAddress = - EnclaveEncryptorType.EC.equals(enclaveEncryptorType) - ? "0xf01ec73d91fdeb8bb9388ec74e6a3981da86e021" - : "0xd0152772c54cecfa7684f09f7616dcc825545dff"; - - final EventEmitter eventEmitter = - minerNode.execute( - privateContractTransactions.createSmartContract( - EventEmitter.class, - minerNode.getTransactionSigningKey(), - minerNode.getEnclaveKey())); - - privateContractVerifier - .validPrivateContractDeployed(contractAddress, minerNode.getAddress().toString()) - .verify(eventEmitter); - privateContractVerifier.validContractCodeProvided().verify(eventEmitter); - - final BigInteger blockNumberContractDeployed = - eventEmitter.getTransactionReceipt().get().getBlockNumber(); - final Block blockContractDeployed = - minerNode.execute( - ethTransactions.block(DefaultBlockParameter.valueOf(blockNumberContractDeployed))); - - assertThat(blockContractDeployed.getTransactions().size()).isEqualTo(1); - - final String transactionHashContractDeployed = - (String) blockContractDeployed.getTransactions().get(0).get(); - final TransactionReceipt pmtReceipt = - minerNode - .execute(ethTransactions.getTransactionReceipt(transactionHashContractDeployed)) - .get(); - - assertThat(pmtReceipt.getStatus()).isEqualTo("0x1"); - assertThat(pmtReceipt.getFrom()).isEqualTo("0xfe3b557e8fb62b89f4916b721be55ceb828dbd73"); - } -} diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivCallAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivCallAcceptanceTest.java deleted file mode 100644 index 9d8a325903..0000000000 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivCallAcceptanceTest.java +++ /dev/null @@ -1,295 +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.tests.acceptance.privacy; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.hyperledger.besu.tests.web3j.generated.RevertReason.FUNC_REVERTWITHREVERTREASON; -import static org.web3j.utils.Restriction.UNRESTRICTED; - -import org.hyperledger.besu.tests.acceptance.dsl.privacy.ParameterizedEnclaveTestBase; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.account.PrivacyAccountResolver; -import org.hyperledger.besu.tests.web3j.generated.EventEmitter; -import org.hyperledger.besu.tests.web3j.generated.RevertReason; -import org.hyperledger.enclave.testutil.EnclaveEncryptorType; -import org.hyperledger.enclave.testutil.EnclaveType; - -import java.io.IOException; -import java.math.BigInteger; -import java.nio.charset.Charset; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import javax.annotation.Nonnull; - -import org.bouncycastle.util.encoders.Hex; -import org.junit.Test; -import org.web3j.abi.FunctionEncoder; -import org.web3j.abi.TypeReference; -import org.web3j.abi.datatypes.Bool; -import org.web3j.abi.datatypes.Function; -import org.web3j.abi.datatypes.Type; -import org.web3j.abi.datatypes.generated.Uint256; -import org.web3j.protocol.core.Request; -import org.web3j.protocol.core.methods.request.Transaction; -import org.web3j.protocol.core.methods.response.EthCall; -import org.web3j.protocol.core.methods.response.TransactionReceipt; -import org.web3j.protocol.http.HttpService; -import org.web3j.tx.Contract; -import org.web3j.utils.Restriction; - -public class PrivCallAcceptanceTest extends ParameterizedEnclaveTestBase { - - private static final int VALUE = 1024; - - private final PrivacyNode minerNode; - - public PrivCallAcceptanceTest( - final Restriction restriction, - final EnclaveType enclaveType, - final EnclaveEncryptorType enclaveEncryptorType) - throws IOException { - - super(restriction, enclaveType, enclaveEncryptorType); - - minerNode = - privacyBesu.createPrivateTransactionEnabledMinerNode( - restriction + "-node", - PrivacyAccountResolver.ALICE.resolve(enclaveEncryptorType), - enclaveType, - Optional.empty(), - false, - false, - restriction == UNRESTRICTED); - - privacyCluster.start(minerNode); - minerNode.verify(priv.syncingStatus(false)); - } - - @Test - public void mustReturnCorrectValue() throws Exception { - - final String privacyGroupId = - minerNode.execute(createPrivacyGroup("myGroupName", "my group description", minerNode)); - - final EventEmitter eventEmitter = - minerNode.execute( - privateContractTransactions.createSmartContractWithPrivacyGroupId( - EventEmitter.class, - minerNode.getTransactionSigningKey(), - restriction, - minerNode.getEnclaveKey(), - privacyGroupId)); - - privateContractVerifier - .validPrivateContractDeployed( - eventEmitter.getContractAddress(), minerNode.getAddress().toString()) - .verify(eventEmitter); - - final Request priv_call = - privCall(privacyGroupId, eventEmitter, false, false, false); - - EthCall resp = priv_call.send(); - - String value = resp.getValue(); - assertThat(new BigInteger(value.substring(2), 16)).isEqualByComparingTo(BigInteger.ZERO); - - final TransactionReceipt receipt = eventEmitter.store(BigInteger.valueOf(VALUE)).send(); - assertThat(receipt).isNotNull(); - - resp = priv_call.send(); - value = resp.getValue(); - assertThat(new BigInteger(value.substring(2), 16)) - .isEqualByComparingTo(BigInteger.valueOf(VALUE)); - } - - @Test - public void mustRevertWithRevertReason() throws Exception { - - final String privacyGroupId = - minerNode.execute(createPrivacyGroup("myGroupName", "my group description", minerNode)); - - final RevertReason revertReasonContract = - minerNode.execute( - privateContractTransactions.createSmartContractWithPrivacyGroupId( - RevertReason.class, - minerNode.getTransactionSigningKey(), - restriction, - minerNode.getEnclaveKey(), - privacyGroupId)); - - privateContractVerifier - .validPrivateContractDeployed( - revertReasonContract.getContractAddress(), minerNode.getAddress().toString()) - .verify(revertReasonContract); - - final Request priv_call = - privCall(privacyGroupId, revertReasonContract, false, false, true); - - EthCall resp = priv_call.send(); - assertThat(resp.getRevertReason()).isEqualTo("Execution reverted: RevertReason"); - - byte[] bytes = Hex.decode(resp.getError().getData().substring(3, 203)); - String revertMessage = - new String(Arrays.copyOfRange(bytes, 4, bytes.length), Charset.defaultCharset()).trim(); - assertThat(revertMessage).isEqualTo("RevertReason"); - } - - @Test - public void shouldReturnEmptyResultWithNonExistingPrivacyGroup() throws IOException { - - final String privacyGroupId = - minerNode.execute(createPrivacyGroup("myGroupName", "my group description", minerNode)); - - final EventEmitter eventEmitter = - minerNode.execute( - privateContractTransactions.createSmartContractWithPrivacyGroupId( - EventEmitter.class, - minerNode.getTransactionSigningKey(), - restriction, - minerNode.getEnclaveKey(), - privacyGroupId)); - - privateContractVerifier - .validPrivateContractDeployed( - eventEmitter.getContractAddress(), minerNode.getAddress().toString()) - .verify(eventEmitter); - - final String invalidPrivacyGroup = constructInvalidString(privacyGroupId); - final Request privCall = - privCall(invalidPrivacyGroup, eventEmitter, false, false, false); - - final EthCall result = privCall.send(); - - assertThat(result.getResult()).isEqualTo("0x"); - } - - @Test - public void mustNotSucceedWithWronglyEncodedFunction() throws IOException { - - final String privacyGroupId = - minerNode.execute(createPrivacyGroup("myGroupName", "my group description", minerNode)); - - final EventEmitter eventEmitter = - minerNode.execute( - privateContractTransactions.createSmartContractWithPrivacyGroupId( - EventEmitter.class, - minerNode.getTransactionSigningKey(), - restriction, - minerNode.getEnclaveKey(), - privacyGroupId)); - - privateContractVerifier - .validPrivateContractDeployed( - eventEmitter.getContractAddress(), minerNode.getAddress().toString()) - .verify(eventEmitter); - - final Request priv_call = - privCall(privacyGroupId, eventEmitter, true, false, false); - - final String errorMessage = priv_call.send().getError().getMessage(); - assertThat(errorMessage).isEqualTo("Private transaction failed"); - } - - @Test - public void mustReturn0xUsingInvalidContractAddress() throws IOException { - - final String privacyGroupId = - minerNode.execute(createPrivacyGroup("myGroupName", "my group description", minerNode)); - - final EventEmitter eventEmitter = - minerNode.execute( - privateContractTransactions.createSmartContractWithPrivacyGroupId( - EventEmitter.class, - minerNode.getTransactionSigningKey(), - restriction, - minerNode.getEnclaveKey(), - privacyGroupId)); - - privateContractVerifier - .validPrivateContractDeployed( - eventEmitter.getContractAddress(), minerNode.getAddress().toString()) - .verify(eventEmitter); - - final Request priv_call = - privCall(privacyGroupId, eventEmitter, false, true, false); - - final EthCall result = priv_call.send(); - - assertThat(result).isNotNull(); - assertThat(result.getResult()).isEqualTo("0x"); - } - - @Nonnull - private String constructInvalidString(final String privacyGroupId) { - final char[] chars = privacyGroupId.toCharArray(); - if (chars[3] == '0') { - chars[3] = '1'; - } else { - chars[3] = '0'; - } - return String.valueOf(chars); - } - - @Nonnull - private Request privCall( - final String privacyGroupId, - final Contract contract, - final boolean useInvalidParameters, - final boolean useInvalidContractAddress, - final boolean useRevertFunction) { - - final Uint256 invalid = new Uint256(BigInteger.TEN); - - @SuppressWarnings("rawtypes") - final List inputParameters = - useInvalidParameters ? Arrays.asList(invalid) : Collections.emptyList(); - - final Function function = - useRevertFunction - ? new Function( - FUNC_REVERTWITHREVERTREASON, - inputParameters, - Arrays.>asList(new TypeReference() {})) - : new Function( - "value", - inputParameters, - Arrays.>asList(new TypeReference() {})); - - final String encoded = FunctionEncoder.encode(function); - - final HttpService httpService = - new HttpService( - "http://" - + minerNode.getBesu().getHostName() - + ":" - + minerNode.getBesu().getJsonRpcPort().get()); - - final String validContractAddress = contract.getContractAddress(); - final String invalidContractAddress = constructInvalidString(validContractAddress); - final String contractAddress = - useInvalidContractAddress ? invalidContractAddress : validContractAddress; - - final Transaction transaction = - Transaction.createEthCallTransaction(null, contractAddress, encoded); - - return new Request<>( - "priv_call", - Arrays.asList(privacyGroupId, transaction, "latest"), - httpService, - EthCall.class); - } -} diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivDebugGetStateRootFlexibleGroupAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivDebugGetStateRootFlexibleGroupAcceptanceTest.java deleted file mode 100644 index b2e0d92dd7..0000000000 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivDebugGetStateRootFlexibleGroupAcceptanceTest.java +++ /dev/null @@ -1,181 +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.tests.acceptance.privacy; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.account.PrivacyAccountResolver; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.privacy.PrivacyRequestFactory; -import org.hyperledger.besu.tests.web3j.generated.EventEmitter; -import org.hyperledger.enclave.testutil.EnclaveEncryptorType; -import org.hyperledger.enclave.testutil.EnclaveType; - -import java.io.IOException; -import java.math.BigInteger; -import java.net.URISyntaxException; -import java.util.Collection; -import java.util.Optional; - -import org.apache.tuweni.bytes.Bytes32; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.junit.runners.Parameterized.Parameters; -import org.testcontainers.containers.Network; - -@RunWith(Parameterized.class) -public class PrivDebugGetStateRootFlexibleGroupAcceptanceTest - extends FlexiblePrivacyAcceptanceTestBase { - - private final EnclaveType enclaveType; - - public PrivDebugGetStateRootFlexibleGroupAcceptanceTest(final EnclaveType enclaveType) { - this.enclaveType = enclaveType; - } - - @Parameters(name = "{0}") - public static Collection enclaveTypes() { - return EnclaveType.valuesForTests(); - } - - private PrivacyNode aliceNode; - private PrivacyNode bobNode; - - @Before - public void setUp() throws IOException, URISyntaxException { - final Network containerNetwork = Network.newNetwork(); - - aliceNode = - privacyBesu.createFlexiblePrivacyGroupEnabledMinerNode( - "alice-node", - PrivacyAccountResolver.ALICE.resolve(EnclaveEncryptorType.NACL), - false, - enclaveType, - Optional.of(containerNetwork)); - bobNode = - privacyBesu.createFlexiblePrivacyGroupEnabledNode( - "bob-node", - PrivacyAccountResolver.BOB.resolve(EnclaveEncryptorType.NACL), - false, - enclaveType, - Optional.of(containerNetwork)); - - privacyCluster.start(aliceNode, bobNode); - - aliceNode.verify(priv.syncingStatus(false)); - bobNode.verify(priv.syncingStatus(false)); - } - - @Test - public void nodesInGroupShouldHaveSameStateRoot() { - final String privacyGroupId = createFlexiblePrivacyGroup(aliceNode, bobNode); - - final Hash aliceStateRootId = - aliceNode - .execute(privacyTransactions.debugGetStateRoot(privacyGroupId, "latest")) - .getResult(); - - final Hash bobStateRootId = - bobNode - .execute(privacyTransactions.debugGetStateRoot(privacyGroupId, "latest")) - .getResult(); - - assertThat(aliceStateRootId).isEqualTo(bobStateRootId); - } - - @Test - public void unknownGroupShouldReturnError() { - final PrivacyRequestFactory.DebugGetStateRoot aliceResult = - aliceNode.execute( - privacyTransactions.debugGetStateRoot( - Hash.wrap(Bytes32.random()).toBase64String(), "latest")); - - assertThat(aliceResult.getResult()).isNull(); - assertThat(aliceResult.hasError()).isTrue(); - assertThat(aliceResult.getError()).isNotNull(); - assertThat(aliceResult.getError().getMessage()).contains("Error finding privacy group"); - } - - @Test - public void blockParamShouldBeApplied() { - waitForBlockHeight(aliceNode, 2); - waitForBlockHeight(bobNode, 2); - - final String privacyGroupId = createFlexiblePrivacyGroup(aliceNode, bobNode); - - waitForBlockHeight(aliceNode, 10); - waitForBlockHeight(bobNode, 10); - - final Hash aliceResult1 = - aliceNode.execute(privacyTransactions.debugGetStateRoot(privacyGroupId, "1")).getResult(); - final Hash bobResultInt1 = - bobNode.execute(privacyTransactions.debugGetStateRoot(privacyGroupId, "1")).getResult(); - - assertThat(aliceResult1).isEqualTo(bobResultInt1); - - final Hash aliceResultLatest = - aliceNode - .execute(privacyTransactions.debugGetStateRoot(privacyGroupId, "latest")) - .getResult(); - - final Hash bobResultLatest = - bobNode - .execute(privacyTransactions.debugGetStateRoot(privacyGroupId, "latest")) - .getResult(); - - assertThat(aliceResultLatest).isEqualTo(bobResultLatest); - assertThat(aliceResult1).isNotEqualTo(aliceResultLatest); - } - - @Test - public void canInteractWithPrivateGenesisPreCompile() throws Exception { - final String privacyGroupId = createFlexiblePrivacyGroup(aliceNode, bobNode); - - final EventEmitter eventEmitter = - aliceNode.execute( - privateContractTransactions.loadSmartContractWithPrivacyGroupId( - "0x1000000000000000000000000000000000000001", - EventEmitter.class, - aliceNode.getTransactionSigningKey(), - aliceNode.getEnclaveKey(), - privacyGroupId)); - - privateTransactionVerifier.existingPrivateTransactionReceipt( - eventEmitter.store(BigInteger.valueOf(42)).send().getTransactionHash()); - - final String aliceResponse = - aliceNode - .execute( - privacyTransactions.privCall( - privacyGroupId, eventEmitter, eventEmitter.value().encodeFunctionCall())) - .getValue(); - - assertThat(new BigInteger(aliceResponse.substring(2), 16)) - .isEqualByComparingTo(BigInteger.valueOf(42)); - - final String bobResponse = - bobNode - .execute( - privacyTransactions.privCall( - privacyGroupId, eventEmitter, eventEmitter.value().encodeFunctionCall())) - .getValue(); - - assertThat(new BigInteger(bobResponse.substring(2), 16)) - .isEqualByComparingTo(BigInteger.valueOf(42)); - } -} diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivDebugGetStateRootOffchainGroupAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivDebugGetStateRootOffchainGroupAcceptanceTest.java deleted file mode 100644 index 6921da147e..0000000000 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivDebugGetStateRootOffchainGroupAcceptanceTest.java +++ /dev/null @@ -1,113 +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.tests.acceptance.privacy; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.web3j.utils.Restriction.UNRESTRICTED; - -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.ParameterizedEnclaveTestBase; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.account.PrivacyAccountResolver; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.privacy.PrivacyRequestFactory; -import org.hyperledger.enclave.testutil.EnclaveEncryptorType; -import org.hyperledger.enclave.testutil.EnclaveType; - -import java.io.IOException; -import java.util.Optional; - -import org.apache.tuweni.bytes.Bytes32; -import org.junit.Test; -import org.testcontainers.containers.Network; -import org.web3j.utils.Restriction; - -public class PrivDebugGetStateRootOffchainGroupAcceptanceTest extends ParameterizedEnclaveTestBase { - - private final PrivacyNode aliceNode; - private final PrivacyNode bobNode; - - public PrivDebugGetStateRootOffchainGroupAcceptanceTest( - final Restriction restriction, - final EnclaveType enclaveType, - final EnclaveEncryptorType enclaveEncryptorType) - throws IOException { - - super(restriction, enclaveType, enclaveEncryptorType); - - final Network containerNetwork = Network.newNetwork(); - - aliceNode = - privacyBesu.createIbft2NodePrivacyEnabled( - "alice-node", - PrivacyAccountResolver.ALICE.resolve(enclaveEncryptorType), - false, - enclaveType, - Optional.of(containerNetwork), - false, - false, - restriction == UNRESTRICTED, - "0xAA"); - bobNode = - privacyBesu.createIbft2NodePrivacyEnabled( - "bob-node", - PrivacyAccountResolver.BOB.resolve(enclaveEncryptorType), - false, - enclaveType, - Optional.of(containerNetwork), - false, - false, - restriction == UNRESTRICTED, - "0xBB"); - - privacyCluster.start(aliceNode, bobNode); - - aliceNode.verify(priv.syncingStatus(false)); - bobNode.verify(priv.syncingStatus(false)); - } - - @Test - public void nodesInGroupShouldHaveSameStateRoot() { - final String privacyGroupId = - aliceNode.execute( - createPrivacyGroup("testGroup", "A group for everyone", aliceNode, bobNode)); - - final Hash aliceStateRootId = - aliceNode - .execute(privacyTransactions.debugGetStateRoot(privacyGroupId, "latest")) - .getResult(); - - final Hash bobStateRootId = - bobNode - .execute(privacyTransactions.debugGetStateRoot(privacyGroupId, "latest")) - .getResult(); - - assertThat(aliceStateRootId).isEqualTo(bobStateRootId); - } - - @Test - public void unknownGroupShouldReturnError() { - if (restriction != UNRESTRICTED) { - final PrivacyRequestFactory.DebugGetStateRoot aliceResult = - aliceNode.execute( - privacyTransactions.debugGetStateRoot( - Hash.wrap(Bytes32.random()).toBase64String(), "latest")); - - assertThat(aliceResult.getResult()).isNull(); - assertThat(aliceResult.hasError()).isTrue(); - assertThat(aliceResult.getError()).isNotNull(); - assertThat(aliceResult.getError().getMessage()).contains("Error finding privacy group"); - } - } -} diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivGetCodeAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivGetCodeAcceptanceTest.java deleted file mode 100644 index 6ca47035dc..0000000000 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivGetCodeAcceptanceTest.java +++ /dev/null @@ -1,102 +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.tests.acceptance.privacy; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.web3j.utils.Restriction.UNRESTRICTED; - -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.ParameterizedEnclaveTestBase; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.account.PrivacyAccountResolver; -import org.hyperledger.besu.tests.web3j.generated.EventEmitter; -import org.hyperledger.enclave.testutil.EnclaveEncryptorType; -import org.hyperledger.enclave.testutil.EnclaveType; - -import java.io.IOException; -import java.util.Optional; - -import org.apache.tuweni.bytes.Bytes; -import org.junit.Test; -import org.web3j.utils.Restriction; - -public class PrivGetCodeAcceptanceTest extends ParameterizedEnclaveTestBase { - - private final PrivacyNode alice; - - public PrivGetCodeAcceptanceTest( - final Restriction restriction, - final EnclaveType enclaveType, - final EnclaveEncryptorType enclaveEncryptorType) - throws IOException { - - super(restriction, enclaveType, enclaveEncryptorType); - - alice = - privacyBesu.createPrivateTransactionEnabledMinerNode( - restriction + "-node", - PrivacyAccountResolver.ALICE.resolve(enclaveEncryptorType), - enclaveType, - Optional.empty(), - false, - false, - restriction == UNRESTRICTED); - - privacyCluster.start(alice); - alice.verify(priv.syncingStatus(false)); - } - - @Test - public void privGetCodeReturnsDeployedContractBytecode() { - final String privacyGroupId = createPrivacyGroup(); - final EventEmitter eventEmitterContract = deployPrivateContract(privacyGroupId); - - final Bytes deployedContractCode = - alice.execute( - privacyTransactions.privGetCode( - privacyGroupId, - Address.fromHexString(eventEmitterContract.getContractAddress()), - "latest")); - - assertThat(eventEmitterContract.getContractBinary()) - .contains(deployedContractCode.toUnprefixedHexString()); - } - - private EventEmitter deployPrivateContract(final String privacyGroupId) { - final EventEmitter eventEmitter = - alice.execute( - privateContractTransactions.createSmartContractWithPrivacyGroupId( - EventEmitter.class, - alice.getTransactionSigningKey(), - restriction, - alice.getEnclaveKey(), - privacyGroupId)); - - privateContractVerifier - .validPrivateContractDeployed( - eventEmitter.getContractAddress(), alice.getAddress().toString()) - .verify(eventEmitter); - return eventEmitter; - } - - private String createPrivacyGroup() { - final String privacyGroupId = - alice.execute(createPrivacyGroup("myGroupName", "my group description", alice)); - - assertThat(privacyGroupId).isNotNull(); - - return privacyGroupId; - } -} diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivGetLogsAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivGetLogsAcceptanceTest.java deleted file mode 100644 index 7ebdcea826..0000000000 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivGetLogsAcceptanceTest.java +++ /dev/null @@ -1,171 +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.tests.acceptance.privacy; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.web3j.utils.Restriction.UNRESTRICTED; - -import org.hyperledger.besu.tests.acceptance.dsl.privacy.ParameterizedEnclaveTestBase; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.account.PrivacyAccountResolver; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.util.LogFilterJsonParameter; -import org.hyperledger.besu.tests.web3j.generated.EventEmitter; -import org.hyperledger.enclave.testutil.EnclaveEncryptorType; -import org.hyperledger.enclave.testutil.EnclaveType; - -import java.io.IOException; -import java.math.BigInteger; -import java.util.List; -import java.util.Optional; - -import org.junit.Test; -import org.web3j.protocol.besu.response.privacy.PrivateTransactionReceipt; -import org.web3j.protocol.core.methods.response.EthLog.LogResult; -import org.web3j.utils.Restriction; - -@SuppressWarnings("rawtypes") -public class PrivGetLogsAcceptanceTest extends ParameterizedEnclaveTestBase { - - /* - This value is derived from the contract event signature - */ - private static final String EVENT_EMITTER_EVENT_TOPIC = - "0xc9db20adedc6cf2b5d25252b101ab03e124902a73fcb12b753f3d1aaa2d8f9f5"; - - private final PrivacyNode node; - - public PrivGetLogsAcceptanceTest( - final Restriction restriction, - final EnclaveType enclaveType, - final EnclaveEncryptorType enclaveEncryptorType) - throws IOException { - - super(restriction, enclaveType, enclaveEncryptorType); - - node = - privacyBesu.createPrivateTransactionEnabledMinerNode( - restriction + "-node", - PrivacyAccountResolver.ALICE.resolve(enclaveEncryptorType), - enclaveType, - Optional.empty(), - false, - false, - restriction == UNRESTRICTED); - - privacyCluster.start(node); - node.verify(priv.syncingStatus(false)); - } - - @Test - public void getLogsUsingBlockRangeFilter() { - final String privacyGroupId = createPrivacyGroup(); - final EventEmitter eventEmitterContract = deployEventEmitterContract(privacyGroupId); - - /* - Updating the contract value 2 times - */ - updateContractValue(privacyGroupId, eventEmitterContract, 1); - updateContractValue(privacyGroupId, eventEmitterContract, 2); - - final LogFilterJsonParameter filter = - blockRangeLogFilter("earliest", "latest", eventEmitterContract.getContractAddress()); - - final List logs = - node.execute(privacyTransactions.privGetLogs(privacyGroupId, filter)); - - /* - We expect one log entry per tx changing the contract value - */ - assertThat(logs).hasSize(2); - } - - @Test - public void getLogsUsingBlockHashFilter() { - final String privacyGroupId = createPrivacyGroup(); - final EventEmitter eventEmitterContract = deployEventEmitterContract(privacyGroupId); - - /* - Updating the contract value 1 times - */ - final PrivateTransactionReceipt updateValueReceipt = - updateContractValue(privacyGroupId, eventEmitterContract, 1); - final String blockHash = updateValueReceipt.getBlockHash(); - - final LogFilterJsonParameter filter = - blockHashLogFilter(blockHash, eventEmitterContract.getContractAddress()); - - final List logs = - node.execute(privacyTransactions.privGetLogs(privacyGroupId, filter)); - - assertThat(logs).hasSize(1); - } - - private LogFilterJsonParameter blockRangeLogFilter( - final String fromBlock, final String toBlock, final String contractAddress) { - return new LogFilterJsonParameter( - fromBlock, - toBlock, - List.of(contractAddress), - List.of(List.of(EVENT_EMITTER_EVENT_TOPIC)), - null); - } - - private LogFilterJsonParameter blockHashLogFilter( - final String blockHash, final String contractAddress) { - return new LogFilterJsonParameter( - null, - null, - List.of(contractAddress), - List.of(List.of(EVENT_EMITTER_EVENT_TOPIC)), - blockHash); - } - - private String createPrivacyGroup() { - return node.execute(createPrivacyGroup("myGroupName", "my group description", node)); - } - - private EventEmitter deployEventEmitterContract(final String privacyGroupId) { - final EventEmitter eventEmitter = - node.execute( - privateContractTransactions.createSmartContractWithPrivacyGroupId( - EventEmitter.class, - node.getTransactionSigningKey(), - restriction, - node.getEnclaveKey(), - privacyGroupId)); - - privateContractVerifier - .validPrivateContractDeployed( - eventEmitter.getContractAddress(), node.getAddress().toString()) - .verify(eventEmitter); - - return eventEmitter; - } - - private PrivateTransactionReceipt updateContractValue( - final String privacyGroupId, final EventEmitter eventEmitterContract, final int value) { - final String transactionHash = - node.execute( - privateContractTransactions.callSmartContractWithPrivacyGroupId( - eventEmitterContract.getContractAddress(), - eventEmitterContract.store(BigInteger.valueOf(value)).encodeFunctionCall(), - node.getTransactionSigningKey(), - restriction, - node.getEnclaveKey(), - privacyGroupId)); - - return node.execute(privacyTransactions.getPrivateTransactionReceipt(transactionHash)); - } -} diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivGetPrivateTransactionAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivGetPrivateTransactionAcceptanceTest.java deleted file mode 100644 index 59c5b8f71f..0000000000 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivGetPrivateTransactionAcceptanceTest.java +++ /dev/null @@ -1,153 +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.tests.acceptance.privacy; - -import static org.web3j.utils.Restriction.RESTRICTED; -import static org.web3j.utils.Restriction.UNRESTRICTED; - -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.datatypes.Wei; -import org.hyperledger.besu.ethereum.privacy.PrivateTransaction; -import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.ParameterizedEnclaveTestBase; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.account.PrivacyAccountResolver; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; -import org.hyperledger.enclave.testutil.EnclaveEncryptorType; -import org.hyperledger.enclave.testutil.EnclaveType; - -import java.io.IOException; -import java.util.Optional; - -import org.apache.tuweni.bytes.Bytes; -import org.junit.Test; -import org.testcontainers.containers.Network; -import org.web3j.utils.Restriction; - -public class PrivGetPrivateTransactionAcceptanceTest extends ParameterizedEnclaveTestBase { - - private final PrivacyNode alice; - private final PrivacyNode bob; - - public PrivGetPrivateTransactionAcceptanceTest( - final Restriction restriction, - final EnclaveType enclaveType, - final EnclaveEncryptorType enclaveEncryptorType) - throws IOException { - - super(restriction, enclaveType, enclaveEncryptorType); - - final Network containerNetwork = Network.newNetwork(); - - alice = - privacyBesu.createIbft2NodePrivacyEnabled( - "node1", - PrivacyAccountResolver.ALICE.resolve(enclaveEncryptorType), - false, - enclaveType, - Optional.of(containerNetwork), - false, - false, - restriction == UNRESTRICTED, - "0xAA"); - bob = - privacyBesu.createIbft2NodePrivacyEnabled( - "node2", - PrivacyAccountResolver.BOB.resolve(enclaveEncryptorType), - false, - enclaveType, - Optional.of(containerNetwork), - false, - false, - restriction == UNRESTRICTED, - "0xBB"); - - privacyCluster.start(alice, bob); - - alice.verify(priv.syncingStatus(false)); - bob.verify(priv.syncingStatus(false)); - } - - @Test - public void returnsTransaction() { - final Transaction onlyAlice = createPrivacyGroup("Only Alice", "", alice); - - final String privacyGroupId = alice.execute(onlyAlice); - - final PrivateTransaction validSignedPrivateTransaction = - getValidSignedPrivateTransaction(alice, privacyGroupId); - final BytesValueRLPOutput rlpOutput = getRLPOutput(validSignedPrivateTransaction); - - final Hash transactionHash = - alice.execute(privacyTransactions.sendRawTransaction(rlpOutput.encoded().toHexString())); - - alice.getBesu().verify(eth.expectSuccessfulTransactionReceipt(transactionHash.toString())); - - alice - .getBesu() - .verify(priv.getPrivateTransaction(transactionHash, validSignedPrivateTransaction)); - } - - @Test - public void nonExistentHashReturnsNull() { - alice.getBesu().verify(priv.getPrivateTransactionReturnsNull(Hash.ZERO)); - } - - @Test - public void returnsNullTransactionNotInNodesPrivacyGroup() { - final Transaction onlyAlice = createPrivacyGroup("Only Alice", "", alice); - - final String privacyGroupId = alice.execute(onlyAlice); - - final PrivateTransaction validSignedPrivateTransaction = - getValidSignedPrivateTransaction(alice, privacyGroupId); - final BytesValueRLPOutput rlpOutput = getRLPOutput(validSignedPrivateTransaction); - - final Hash transactionHash = - alice.execute(privacyTransactions.sendRawTransaction(rlpOutput.encoded().toHexString())); - - alice.getBesu().verify(eth.expectSuccessfulTransactionReceipt(transactionHash.toString())); - - bob.getBesu().verify(priv.getPrivateTransactionReturnsNull(transactionHash)); - } - - private BytesValueRLPOutput getRLPOutput(final PrivateTransaction privateTransaction) { - final BytesValueRLPOutput bvrlpo = new BytesValueRLPOutput(); - privateTransaction.writeTo(bvrlpo); - return bvrlpo; - } - - private PrivateTransaction getValidSignedPrivateTransaction( - final PrivacyNode node, final String privacyGoupId) { - - org.hyperledger.besu.plugin.data.Restriction besuRestriction = - restriction == RESTRICTED - ? org.hyperledger.besu.plugin.data.Restriction.RESTRICTED - : org.hyperledger.besu.plugin.data.Restriction.UNRESTRICTED; - - return PrivateTransaction.builder() - .nonce(0) - .gasPrice(Wei.of(999999)) - .gasLimit(3000000) - .to(null) - .value(Wei.ZERO) - .payload(Bytes.wrap(new byte[] {})) - .sender(node.getAddress()) - .privateFrom(Bytes.fromBase64String(node.getEnclaveKey())) - .restriction(besuRestriction) - .privacyGroupId(Bytes.fromBase64String(privacyGoupId)) - .signAndBuild(node.getBesu().getPrivacyParameters().getSigningKeyPair().get()); - } -} diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivTraceTransactionAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivTraceTransactionAcceptanceTest.java deleted file mode 100644 index 9cac6d8bf5..0000000000 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivTraceTransactionAcceptanceTest.java +++ /dev/null @@ -1,174 +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.privacy; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.web3j.utils.Restriction.UNRESTRICTED; - -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.ParameterizedEnclaveTestBase; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.account.PrivacyAccountResolver; -import org.hyperledger.besu.tests.web3j.generated.SimpleStorage; -import org.hyperledger.enclave.testutil.EnclaveEncryptorType; -import org.hyperledger.enclave.testutil.EnclaveType; - -import java.io.IOException; -import java.math.BigInteger; -import java.util.Optional; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.junit.Test; -import org.web3j.utils.Restriction; - -public class PrivTraceTransactionAcceptanceTest extends ParameterizedEnclaveTestBase { - - private final PrivacyNode node; - - private final PrivacyNode wrongNode; - - public PrivTraceTransactionAcceptanceTest( - final Restriction restriction, - final EnclaveType enclaveType, - final EnclaveEncryptorType enclaveEncryptorType) - throws IOException { - - super(restriction, enclaveType, enclaveEncryptorType); - - node = - privacyBesu.createPrivateTransactionEnabledMinerNode( - restriction + "-node", - PrivacyAccountResolver.ALICE.resolve(enclaveEncryptorType), - enclaveType, - Optional.empty(), - false, - false, - restriction == UNRESTRICTED); - - wrongNode = - privacyBesu.createPrivateTransactionEnabledMinerNode( - restriction + "-node", - PrivacyAccountResolver.BOB.resolve(enclaveEncryptorType), - enclaveType, - Optional.empty(), - false, - false, - restriction == UNRESTRICTED); - - privacyCluster.start(node); - privacyCluster.start(wrongNode); - } - - @Test - public void getTransactionTrace() throws JsonProcessingException { - final String privacyGroupId = createPrivacyGroup(); - final SimpleStorage simpleStorageContract = deploySimpleStorageContract(privacyGroupId); - - Hash transactionHash = - Hash.fromHexString(doTransaction(privacyGroupId, simpleStorageContract, 0)); - - final String result = - node.execute(privacyTransactions.privTraceTransaction(privacyGroupId, transactionHash)); - - assertThat(result).isNotNull(); - ObjectMapper mapper = new ObjectMapper(); - - JsonNode rootNode = mapper.readTree(result); - JsonNode resultNode = rootNode.get("result"); - - assertThat(resultNode).isNotNull(); - assertThat(resultNode.isArray()).isTrue(); - assertThat(resultNode.size()).isGreaterThan(0); - - JsonNode trace = resultNode.get(0); - assertThat(trace.get("action").get("callType").asText()).isEqualTo("call"); - assertThat(trace.get("action").get("from").asText()).isEqualTo(node.getAddress().toString()); - assertThat(trace.get("action").get("input").asText()).startsWith("0x60fe47b1"); - assertThat(trace.get("action").get("to").asText()) - .isEqualTo(simpleStorageContract.getContractAddress()); - assertThat(trace.get("action").get("value").asText()).isEqualTo("0x0"); - assertThat(trace.get("blockHash").asText()).isNotEmpty(); - assertThat(trace.get("blockNumber").asInt()).isGreaterThan(0); - assertThat(trace.get("transactionHash").asText()).isEqualTo(transactionHash.toString()); - assertThat(trace.get("type").asText()).isEqualTo("call"); - - final String wrongPrivacyGroupId = createWrongPrivacyGroup(); - - final String resultEmpty = - wrongNode.execute( - privacyTransactions.privTraceTransaction(wrongPrivacyGroupId, transactionHash)); - - ObjectMapper mapperEmpty = new ObjectMapper(); - - JsonNode rootNodeEmpty = mapperEmpty.readTree(resultEmpty); - JsonNode resultNodeEmpty = rootNodeEmpty.get("result"); - - assertThat(resultNodeEmpty).isNotNull(); - assertThat(resultNodeEmpty.isArray()).isTrue(); - assertThat(resultNodeEmpty.isEmpty()).isTrue(); - - final String resultWrongHash = - wrongNode.execute(privacyTransactions.privTraceTransaction(privacyGroupId, Hash.EMPTY)); - - ObjectMapper mapperWrongHash = new ObjectMapper(); - - JsonNode rootNodeWrongHash = mapperWrongHash.readTree(resultWrongHash); - JsonNode resultNodeWrongHash = rootNodeWrongHash.get("result"); - - assertThat(resultNodeWrongHash).isNotNull(); - assertThat(resultNodeWrongHash.isArray()).isTrue(); - assertThat(resultNodeWrongHash.isEmpty()).isTrue(); - } - - private String createPrivacyGroup() { - return node.execute(createPrivacyGroup("myGroupName", "my group description", node)); - } - - private String createWrongPrivacyGroup() { - return wrongNode.execute(createPrivacyGroup("myGroupName", "my group description", wrongNode)); - } - - private SimpleStorage deploySimpleStorageContract(final String privacyGroupId) { - final SimpleStorage simpleStorage = - node.execute( - privateContractTransactions.createSmartContractWithPrivacyGroupId( - SimpleStorage.class, - node.getTransactionSigningKey(), - restriction, - node.getEnclaveKey(), - privacyGroupId)); - - privateContractVerifier - .validPrivateContractDeployed( - simpleStorage.getContractAddress(), node.getAddress().toString()) - .verify(simpleStorage); - - return simpleStorage; - } - - private String doTransaction( - final String privacyGroupId, final SimpleStorage simpleStorageContract, final int value) { - return node.execute( - privateContractTransactions.callSmartContractWithPrivacyGroupId( - simpleStorageContract.getContractAddress(), - simpleStorageContract.set(BigInteger.valueOf(value)).encodeFunctionCall(), - node.getTransactionSigningKey(), - restriction, - node.getEnclaveKey(), - privacyGroupId)); - } -} diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivacyClusterAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivacyClusterAcceptanceTest.java deleted file mode 100644 index e1bb0a980e..0000000000 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivacyClusterAcceptanceTest.java +++ /dev/null @@ -1,407 +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.tests.acceptance.privacy; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.hyperledger.besu.ethereum.core.PrivacyParameters.DEFAULT_PRIVACY; -import static org.hyperledger.enclave.testutil.EnclaveEncryptorType.EC; -import static org.hyperledger.enclave.testutil.EnclaveEncryptorType.NACL; -import static org.hyperledger.enclave.testutil.EnclaveType.TESSERA; -import static org.web3j.utils.Restriction.RESTRICTED; - -import org.hyperledger.besu.enclave.Enclave; -import org.hyperledger.besu.enclave.EnclaveFactory; -import org.hyperledger.besu.enclave.types.ReceiveResponse; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyAcceptanceTestBase; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.account.PrivacyAccountResolver; -import org.hyperledger.besu.tests.web3j.generated.EventEmitter; -import org.hyperledger.enclave.testutil.EnclaveEncryptorType; -import org.hyperledger.enclave.testutil.EnclaveType; - -import java.io.IOException; -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Optional; - -import io.vertx.core.Vertx; -import org.apache.tuweni.bytes.Bytes; -import org.junit.After; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.junit.runners.Parameterized.Parameters; -import org.testcontainers.containers.Network; -import org.web3j.crypto.Credentials; -import org.web3j.crypto.RawTransaction; -import org.web3j.crypto.TransactionEncoder; -import org.web3j.protocol.besu.response.privacy.PrivateTransactionReceipt; -import org.web3j.protocol.eea.crypto.PrivateTransactionEncoder; -import org.web3j.protocol.eea.crypto.RawPrivateTransaction; -import org.web3j.utils.Base64String; -import org.web3j.utils.Numeric; - -@RunWith(Parameterized.class) -public class PrivacyClusterAcceptanceTest extends PrivacyAcceptanceTestBase { - - private final PrivacyNode alice; - private final PrivacyNode bob; - private final PrivacyNode charlie; - private final EnclaveEncryptorType enclaveEncryptorType; - private final Vertx vertx = Vertx.vertx(); - private final EnclaveFactory enclaveFactory = new EnclaveFactory(vertx); - - @Parameters(name = "{0} enclave type with {1} encryptor") - public static Collection enclaveParameters() { - return Arrays.asList( - new Object[][] { - {TESSERA, NACL}, - {TESSERA, EC} - }); - } - - public PrivacyClusterAcceptanceTest( - final EnclaveType enclaveType, final EnclaveEncryptorType enclaveEncryptorType) - throws IOException { - this.enclaveEncryptorType = enclaveEncryptorType; - final Network containerNetwork = Network.newNetwork(); - alice = - privacyBesu.createPrivateTransactionEnabledMinerNode( - "node1", - PrivacyAccountResolver.ALICE.resolve(enclaveEncryptorType), - enclaveType, - Optional.of(containerNetwork), - false, - false, - false); - bob = - privacyBesu.createPrivateTransactionEnabledNode( - "node2", - PrivacyAccountResolver.BOB.resolve(enclaveEncryptorType), - enclaveType, - Optional.of(containerNetwork), - false, - false, - false); - charlie = - privacyBesu.createPrivateTransactionEnabledNode( - "node3", - PrivacyAccountResolver.CHARLIE.resolve(enclaveEncryptorType), - enclaveType, - Optional.of(containerNetwork), - false, - false, - false); - privacyCluster.start(alice, bob, charlie); - - alice.verify(priv.syncingStatus(false)); - bob.verify(priv.syncingStatus(false)); - charlie.verify(priv.syncingStatus(false)); - } - - @After - public void cleanUp() { - vertx.close(); - } - - @Test - public void onlyAliceAndBobCanExecuteContract() { - // Contract address is generated from sender address and transaction nonce - final String contractAddress = - EnclaveEncryptorType.EC.equals(enclaveEncryptorType) - ? "0x3e5d325a03ad3ce5640502219833d30b89ce3ce1" - : "0xebf56429e6500e84442467292183d4d621359838"; - - final EventEmitter eventEmitter = - alice.execute( - privateContractTransactions.createSmartContract( - EventEmitter.class, - alice.getTransactionSigningKey(), - alice.getEnclaveKey(), - bob.getEnclaveKey())); - - privateContractVerifier - .validPrivateContractDeployed(contractAddress, alice.getAddress().toString()) - .verify(eventEmitter); - - final String transactionHash = - alice.execute( - privateContractTransactions.callSmartContract( - eventEmitter.getContractAddress(), - eventEmitter.store(BigInteger.ONE).encodeFunctionCall(), - alice.getTransactionSigningKey(), - RESTRICTED, - alice.getEnclaveKey(), - bob.getEnclaveKey())); - - final PrivateTransactionReceipt expectedReceipt = - alice.execute(privacyTransactions.getPrivateTransactionReceipt(transactionHash)); - - bob.verify( - privateTransactionVerifier.validPrivateTransactionReceipt( - transactionHash, expectedReceipt)); - - charlie.verify(privateTransactionVerifier.noPrivateTransactionReceipt(transactionHash)); - - // When Alice executes a contract call in the wrong privacy group the transaction should pass - // but it should NOT return any output - final String transactionHash2 = - alice.execute( - privateContractTransactions.callSmartContract( - eventEmitter.getContractAddress(), - eventEmitter.value().encodeFunctionCall(), - alice.getTransactionSigningKey(), - RESTRICTED, - alice.getEnclaveKey(), - charlie.getEnclaveKey())); - - final PrivateTransactionReceipt expectedReceipt2 = - alice.execute(privacyTransactions.getPrivateTransactionReceipt(transactionHash2)); - - assertThat(expectedReceipt2.getOutput()).isEqualTo("0x"); - - charlie.verify( - privateTransactionVerifier.validPrivateTransactionReceipt( - transactionHash2, expectedReceipt2)); - } - - @Test - public void aliceCanUsePrivDistributeTransaction() { - // Contract address is generated from sender address and transaction nonce - final String contractAddress = - EnclaveEncryptorType.EC.equals(enclaveEncryptorType) - ? "0x3e5d325a03ad3ce5640502219833d30b89ce3ce1" - : "0xebf56429e6500e84442467292183d4d621359838"; - final String receiptPrivacyGroupId = - EnclaveEncryptorType.EC.equals(enclaveEncryptorType) - ? "MjuFB4b9Hz+f8zvkWWasxZWRjHWXU4t7B2nOHo4mekA=" - : "DyAOiF/ynpc+JXa2YAGB0bCitSlOMNm+ShmB/7M6C4w="; - - final RawPrivateTransaction rawPrivateTransaction = - RawPrivateTransaction.createContractTransaction( - BigInteger.ZERO, - BigInteger.ZERO, - BigInteger.ZERO, - Numeric.prependHexPrefix(EventEmitter.BINARY), - Base64String.wrap(alice.getEnclaveKey()), - Collections.singletonList(Base64String.wrap(bob.getEnclaveKey())), - Base64String.wrap(receiptPrivacyGroupId), - RESTRICTED); - - final String signedPrivateTransaction = - Numeric.toHexString( - PrivateTransactionEncoder.signMessage( - rawPrivateTransaction, Credentials.create(alice.getTransactionSigningKey()))); - final String transactionKey = - alice.execute(privacyTransactions.privDistributeTransaction(signedPrivateTransaction)); - - final Enclave aliceEnclave = enclaveFactory.createVertxEnclave(alice.getEnclave().clientUrl()); - final ReceiveResponse aliceRR = - aliceEnclave.receive( - Bytes.fromHexString(transactionKey).toBase64String(), alice.getEnclaveKey()); - - final Enclave bobEnclave = enclaveFactory.createVertxEnclave(bob.getEnclave().clientUrl()); - final ReceiveResponse bobRR = - bobEnclave.receive( - Bytes.fromHexString(transactionKey).toBase64String(), bob.getEnclaveKey()); - - assertThat(bobRR).usingRecursiveComparison().isEqualTo(aliceRR); - - final RawTransaction pmt = - RawTransaction.createTransaction( - BigInteger.ZERO, - BigInteger.valueOf(1000), - BigInteger.valueOf(65000), - DEFAULT_PRIVACY.toString(), - transactionKey); - - final String signedPmt = - Numeric.toHexString( - TransactionEncoder.signMessage( - pmt, Credentials.create(alice.getTransactionSigningKey()))); - - final String transactionHash = alice.execute(ethTransactions.sendRawTransaction(signedPmt)); - - final String receiptPrivateFrom = - EnclaveEncryptorType.EC.equals(enclaveEncryptorType) - ? "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAES8nC4qT/KdoAoTSF3qs/47DUsDihyVbWiRjZAiyvqp9eSDkqV1RzlM+58oOwnpFRwvWNZM+AxMVxT+MvxdsqMA==" - : "A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo="; - final ArrayList receiptPrivateFor = - EnclaveEncryptorType.EC.equals(enclaveEncryptorType) - ? new ArrayList<>( - Collections.singletonList( - "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEXIgZqRA25V+3nN+Do6b5r0jiUunub6ubjPhqwHpPxP44uUYh9RKCQNRnsqCJ9PjeTnC8R3ieJk7HWAlycU1bug==")) - : new ArrayList<>( - Collections.singletonList("Ko2bVqD+nNlNYL5EE7y3IdOnviftjiizpjRt+HTuFBs=")); - - final PrivateTransactionReceipt expectedReceipt = - new PrivateTransactionReceipt( - contractAddress, - "0xfe3b557e8fb62b89f4916b721be55ceb828dbd73", - null, - null, // ignored in the following call, checked separately below - Collections.emptyList(), - "0x023955c49d6265c579561940287449242704d5fd239ff07ea36a3fc7aface61c", - "0x82e521ee16ff13104c5f81e8354ecaaafd5450b710b07f620204032bfe76041a", - receiptPrivateFrom, - receiptPrivateFor, - receiptPrivacyGroupId, - "0x1", - null); - - alice.verify( - privateTransactionVerifier.validPrivateTransactionReceipt( - transactionHash, expectedReceipt, true)); - - final PrivateTransactionReceipt alicePrivateTransactionReceipt = - alice.execute(privacyTransactions.getPrivateTransactionReceipt(transactionHash)); - assertThat(EventEmitter.BINARY) - .contains(alicePrivateTransactionReceipt.getOutput().substring(2)); - - bob.verify( - privateTransactionVerifier.validPrivateTransactionReceipt( - transactionHash, expectedReceipt, true)); - - final PrivateTransactionReceipt bobPrivateTransactionReceipt = - bob.execute(privacyTransactions.getPrivateTransactionReceipt(transactionHash)); - assertThat(EventEmitter.BINARY).contains(bobPrivateTransactionReceipt.getOutput().substring(2)); - } - - @Test - public void aliceCanDeployMultipleTimesInSingleGroup() { - final String firstDeployedAddress = - EnclaveEncryptorType.EC.equals(enclaveEncryptorType) - ? "0x3e5d325a03ad3ce5640502219833d30b89ce3ce1" - : "0xebf56429e6500e84442467292183d4d621359838"; - - final EventEmitter firstEventEmitter = - alice.execute( - privateContractTransactions.createSmartContract( - EventEmitter.class, - alice.getTransactionSigningKey(), - alice.getEnclaveKey(), - bob.getEnclaveKey())); - - privateContractVerifier - .validPrivateContractDeployed(firstDeployedAddress, alice.getAddress().toString()) - .verify(firstEventEmitter); - - final String secondDeployedAddress = - EnclaveEncryptorType.EC.equals(enclaveEncryptorType) - ? "0x5194e214fae257530710d18c868df7a295d9d53b" - : "0x10f807f8a905da5bd319196da7523c6bd768690f"; - - final EventEmitter secondEventEmitter = - alice.execute( - privateContractTransactions.createSmartContract( - EventEmitter.class, - alice.getTransactionSigningKey(), - alice.getEnclaveKey(), - bob.getEnclaveKey())); - - privateContractVerifier - .validPrivateContractDeployed(secondDeployedAddress, alice.getAddress().toString()) - .verify(secondEventEmitter); - } - - @Test - public void canInteractWithMultiplePrivacyGroups() { - // alice deploys contract - final String firstDeployedAddress = - EnclaveEncryptorType.EC.equals(enclaveEncryptorType) - ? "0x760359bc605b3848f5199829bde6b382d90fb8eb" - : "0xff206d21150a8da5b83629d8a722f3135ed532b1"; - - final EventEmitter firstEventEmitter = - alice.execute( - privateContractTransactions.createSmartContract( - EventEmitter.class, - alice.getTransactionSigningKey(), - alice.getEnclaveKey(), - bob.getEnclaveKey(), - charlie.getEnclaveKey())); - - privateContractVerifier - .validPrivateContractDeployed(firstDeployedAddress, alice.getAddress().toString()) - .verify(firstEventEmitter); - - // charlie interacts with contract - final String firstTransactionHash = - charlie.execute( - privateContractTransactions.callSmartContract( - firstEventEmitter.getContractAddress(), - firstEventEmitter.store(BigInteger.ONE).encodeFunctionCall(), - charlie.getTransactionSigningKey(), - RESTRICTED, - charlie.getEnclaveKey(), - alice.getEnclaveKey(), - bob.getEnclaveKey())); - - // alice gets receipt from charlie's interaction - final PrivateTransactionReceipt firstExpectedReceipt = - alice.execute(privacyTransactions.getPrivateTransactionReceipt(firstTransactionHash)); - - // verify bob and charlie have access to the same receipt - bob.verify( - privateTransactionVerifier.validPrivateTransactionReceipt( - firstTransactionHash, firstExpectedReceipt)); - charlie.verify( - privateTransactionVerifier.validPrivateTransactionReceipt( - firstTransactionHash, firstExpectedReceipt)); - - // alice deploys second contract - final String secondDeployedAddress = - EnclaveEncryptorType.EC.equals(enclaveEncryptorType) - ? "0x3e5d325a03ad3ce5640502219833d30b89ce3ce1" - : "0xebf56429e6500e84442467292183d4d621359838"; - - final EventEmitter secondEventEmitter = - alice.execute( - privateContractTransactions.createSmartContract( - EventEmitter.class, - alice.getTransactionSigningKey(), - alice.getEnclaveKey(), - bob.getEnclaveKey())); - - privateContractVerifier - .validPrivateContractDeployed(secondDeployedAddress, alice.getAddress().toString()) - .verify(secondEventEmitter); - - // bob interacts with contract - final String secondTransactionHash = - bob.execute( - privateContractTransactions.callSmartContract( - secondEventEmitter.getContractAddress(), - secondEventEmitter.store(BigInteger.ONE).encodeFunctionCall(), - bob.getTransactionSigningKey(), - RESTRICTED, - bob.getEnclaveKey(), - alice.getEnclaveKey())); - - // alice gets receipt from bob's interaction - final PrivateTransactionReceipt secondExpectedReceipt = - alice.execute(privacyTransactions.getPrivateTransactionReceipt(secondTransactionHash)); - - bob.verify( - privateTransactionVerifier.validPrivateTransactionReceipt( - secondTransactionHash, secondExpectedReceipt)); - - // charlie cannot see the receipt - charlie.verify(privateTransactionVerifier.noPrivateTransactionReceipt(secondTransactionHash)); - } -} diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivacyGroupAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivacyGroupAcceptanceTest.java deleted file mode 100644 index ea94bb293a..0000000000 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivacyGroupAcceptanceTest.java +++ /dev/null @@ -1,255 +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.tests.acceptance.privacy; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.hyperledger.enclave.testutil.EnclaveEncryptorType.EC; -import static org.hyperledger.enclave.testutil.EnclaveEncryptorType.NACL; -import static org.hyperledger.enclave.testutil.EnclaveType.TESSERA; -import static org.web3j.utils.Restriction.RESTRICTED; - -import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyAcceptanceTestBase; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.account.PrivacyAccountResolver; -import org.hyperledger.besu.tests.web3j.generated.EventEmitter; -import org.hyperledger.besu.util.LogConfigurator; -import org.hyperledger.enclave.testutil.EnclaveEncryptorType; -import org.hyperledger.enclave.testutil.EnclaveType; - -import java.io.IOException; -import java.math.BigInteger; -import java.util.Arrays; -import java.util.Collection; -import java.util.Optional; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.junit.runners.Parameterized.Parameters; -import org.testcontainers.containers.Network; -import org.web3j.protocol.besu.response.privacy.PrivacyGroup; -import org.web3j.protocol.besu.response.privacy.PrivateTransactionReceipt; -import org.web3j.utils.Base64String; - -@RunWith(Parameterized.class) -public class PrivacyGroupAcceptanceTest extends PrivacyAcceptanceTestBase { - - private final PrivacyNode alice; - private final PrivacyNode bob; - private final PrivacyNode charlie; - - @Parameters(name = "{0} enclave type with {1} encryptor") - public static Collection enclaveParameters() { - return Arrays.asList( - new Object[][] { - {TESSERA, NACL}, - {TESSERA, EC} - }); - } - - public PrivacyGroupAcceptanceTest( - final EnclaveType enclaveType, final EnclaveEncryptorType enclaveEncryptorType) - throws IOException { - - final Network containerNetwork = Network.newNetwork(); - - alice = - privacyBesu.createPrivateTransactionEnabledMinerNode( - "node1", - PrivacyAccountResolver.ALICE.resolve(enclaveEncryptorType), - enclaveType, - Optional.of(containerNetwork), - false, - false, - false); - bob = - privacyBesu.createPrivateTransactionEnabledNode( - "node2", - PrivacyAccountResolver.BOB.resolve(enclaveEncryptorType), - enclaveType, - Optional.of(containerNetwork), - false, - false, - false); - - charlie = - privacyBesu.createPrivateTransactionEnabledNode( - "node3", - PrivacyAccountResolver.CHARLIE.resolve(enclaveEncryptorType), - enclaveType, - Optional.of(containerNetwork), - false, - false, - false); - privacyCluster.start(alice, bob, charlie); - - alice.verify(priv.syncingStatus(false)); - bob.verify(priv.syncingStatus(false)); - charlie.verify(priv.syncingStatus(false)); - } - - @Test - public void nodeCanCreatePrivacyGroup() { - LogConfigurator.setLevel("", "DEBUG"); - final String privacyGroupId = - alice.execute( - privacyTransactions.createPrivacyGroup( - "myGroupName", "my group description", alice, bob)); - - assertThat(privacyGroupId).isNotNull(); - - final PrivacyGroup expected = - new PrivacyGroup( - privacyGroupId, - PrivacyGroup.Type.PANTHEON, - "myGroupName", - "my group description", - Base64String.wrapList(alice.getEnclaveKey(), bob.getEnclaveKey())); - - alice.verify(privateTransactionVerifier.validPrivacyGroupCreated(expected)); - - bob.verify(privateTransactionVerifier.validPrivacyGroupCreated(expected)); - } - - @Test - public void nodeCanCreatePrivacyGroupWithoutName() { - final String privacyGroupId = - alice.execute( - privacyTransactions.createPrivacyGroup(null, "my group description", alice, bob)); - - assertThat(privacyGroupId).isNotNull(); - - final PrivacyGroup expected = - new PrivacyGroup( - privacyGroupId, - PrivacyGroup.Type.PANTHEON, - "", - "my group description", - Base64String.wrapList(alice.getEnclaveKey(), bob.getEnclaveKey())); - - alice.verify(privateTransactionVerifier.validPrivacyGroupCreated(expected)); - - bob.verify(privateTransactionVerifier.validPrivacyGroupCreated(expected)); - } - - @Test - public void nodeCanCreatePrivacyGroupWithoutDescription() { - final String privacyGroupId = - alice.execute(privacyTransactions.createPrivacyGroup("myGroupName", null, alice, bob)); - - assertThat(privacyGroupId).isNotNull(); - - final PrivacyGroup expected = - new PrivacyGroup( - privacyGroupId, - PrivacyGroup.Type.PANTHEON, - "myGroupName", - "", - Base64String.wrapList(alice.getEnclaveKey(), bob.getEnclaveKey())); - - alice.verify(privateTransactionVerifier.validPrivacyGroupCreated(expected)); - - bob.verify(privateTransactionVerifier.validPrivacyGroupCreated(expected)); - } - - @Test - public void nodeCanCreatePrivacyGroupWithoutOptionalParams() { - final String privacyGroupId = - alice.execute(privacyTransactions.createPrivacyGroup(null, null, alice)); - - assertThat(privacyGroupId).isNotNull(); - - final PrivacyGroup expected = - new PrivacyGroup( - privacyGroupId, - PrivacyGroup.Type.PANTHEON, - "", - "", - Base64String.wrapList(alice.getEnclaveKey())); - - alice.verify(privateTransactionVerifier.validPrivacyGroupCreated(expected)); - } - - @Test - public void canInteractWithMultiplePrivacyGroups() { - final String privacyGroupIdABC = - alice.execute(privacyTransactions.createPrivacyGroup(null, null, alice, bob, charlie)); - - final EventEmitter firstEventEmitter = - alice.execute( - privateContractTransactions.createSmartContractWithPrivacyGroupId( - EventEmitter.class, - alice.getTransactionSigningKey(), - alice.getEnclaveKey(), - privacyGroupIdABC)); - - // charlie interacts with contract - final String firstTransactionHash = - charlie.execute( - privateContractTransactions.callSmartContractWithPrivacyGroupId( - firstEventEmitter.getContractAddress(), - firstEventEmitter.store(BigInteger.ONE).encodeFunctionCall(), - charlie.getTransactionSigningKey(), - RESTRICTED, - charlie.getEnclaveKey(), - privacyGroupIdABC)); - - // alice gets receipt from charlie's interaction - final PrivateTransactionReceipt firstExpectedReceipt = - alice.execute(privacyTransactions.getPrivateTransactionReceipt(firstTransactionHash)); - - // verify bob and charlie have access to the same receipt - bob.verify( - privateTransactionVerifier.validPrivateTransactionReceipt( - firstTransactionHash, firstExpectedReceipt)); - charlie.verify( - privateTransactionVerifier.validPrivateTransactionReceipt( - firstTransactionHash, firstExpectedReceipt)); - - // alice deploys second contract - final String privacyGroupIdAB = - alice.execute(privacyTransactions.createPrivacyGroup(null, null, alice, bob)); - - final EventEmitter secondEventEmitter = - alice.execute( - privateContractTransactions.createSmartContractWithPrivacyGroupId( - EventEmitter.class, - alice.getTransactionSigningKey(), - alice.getEnclaveKey(), - privacyGroupIdAB)); - - // bob interacts with contract - final String secondTransactionHash = - bob.execute( - privateContractTransactions.callSmartContractWithPrivacyGroupId( - secondEventEmitter.getContractAddress(), - secondEventEmitter.store(BigInteger.ONE).encodeFunctionCall(), - bob.getTransactionSigningKey(), - RESTRICTED, - bob.getEnclaveKey(), - privacyGroupIdAB)); - - // alice gets receipt from bob's interaction - final PrivateTransactionReceipt secondExpectedReceipt = - alice.execute(privacyTransactions.getPrivateTransactionReceipt(secondTransactionHash)); - - bob.verify( - privateTransactionVerifier.validPrivateTransactionReceipt( - secondTransactionHash, secondExpectedReceipt)); - - // charlie cannot see the receipt - charlie.verify(privateTransactionVerifier.noPrivateTransactionReceipt(secondTransactionHash)); - } -} diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivacyReceiptAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivacyReceiptAcceptanceTest.java deleted file mode 100644 index 56e2b04a36..0000000000 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivacyReceiptAcceptanceTest.java +++ /dev/null @@ -1,165 +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.tests.acceptance.privacy; - -import static java.util.Optional.empty; -import static org.web3j.utils.Restriction.RESTRICTED; -import static org.web3j.utils.Restriction.UNRESTRICTED; - -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.datatypes.Wei; -import org.hyperledger.besu.ethereum.privacy.PrivateTransaction; -import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.ParameterizedEnclaveTestBase; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.account.PrivacyAccountResolver; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.miner.MinerTransactions; -import org.hyperledger.enclave.testutil.EnclaveEncryptorType; -import org.hyperledger.enclave.testutil.EnclaveType; - -import java.io.IOException; -import java.util.Optional; - -import org.apache.tuweni.bytes.Bytes; -import org.junit.Test; -import org.web3j.utils.Restriction; - -public class PrivacyReceiptAcceptanceTest extends ParameterizedEnclaveTestBase { - final MinerTransactions minerTransactions = new MinerTransactions(); - - private final PrivacyNode alice; - - public PrivacyReceiptAcceptanceTest( - final Restriction restriction, - final EnclaveType enclaveType, - final EnclaveEncryptorType enclaveEncryptorType) - throws IOException { - super(restriction, enclaveType, enclaveEncryptorType); - - alice = - privacyBesu.createIbft2NodePrivacyEnabled( - "node1", - PrivacyAccountResolver.ALICE.resolve(enclaveEncryptorType), - false, - enclaveType, - Optional.empty(), - false, - false, - restriction == UNRESTRICTED, - "0xAA"); - privacyCluster.start(alice); - - alice.verify(priv.syncingStatus(false)); - } - - @Test - public void createPrivateTransactionReceiptSuccessfulTransaction() { - final Transaction onlyAlice = createPrivacyGroup("Only Alice", "", alice); - - final String privacyGroupId = alice.execute(onlyAlice); - - final PrivateTransaction validTransaction = - createSignedTransaction(alice, privacyGroupId, empty()); - final BytesValueRLPOutput rlpOutput = getRLPOutput(validTransaction); - - final Hash transactionHash = - alice.execute(privacyTransactions.sendRawTransaction(rlpOutput.encoded().toHexString())); - - // Successful PMT - alice.getBesu().verify(eth.expectSuccessfulTransactionReceipt(transactionHash.toString())); - // Successful private transaction - alice.getBesu().verify(priv.getSuccessfulTransactionReceipt(transactionHash)); - } - - @Test - public void createPrivateTransactionReceiptFailedTransaction() { - final Transaction onlyAlice = createPrivacyGroup("Only Alice", "", alice); - - final String privacyGroupId = alice.execute(onlyAlice); - - final PrivateTransaction invalidPayloadTransaction = - createSignedTransaction( - alice, privacyGroupId, Optional.of(Bytes.fromBase64String("invalidPayload"))); - final BytesValueRLPOutput rlpOutput = getRLPOutput(invalidPayloadTransaction); - - final Hash transactionHash = - alice.execute(privacyTransactions.sendRawTransaction(rlpOutput.encoded().toHexString())); - - // Successful PMT - alice.getBesu().verify(eth.expectSuccessfulTransactionReceipt(transactionHash.toString())); - // Failed private transaction - alice.getBesu().verify(priv.getFailedTransactionReceipt(transactionHash)); - } - - @Test - public void createPrivateTransactionReceiptInvalidTransaction() { - final Transaction onlyAlice = createPrivacyGroup("Only Alice", "", alice); - - final String privacyGroupId = alice.execute(onlyAlice); - - final PrivateTransaction validTransaction = - createSignedTransaction(alice, privacyGroupId, empty()); - final BytesValueRLPOutput rlpOutput = getRLPOutput(validTransaction); - - // Stop mining, to allow adding duplicate nonce block - alice.getBesu().execute(minerTransactions.minerStop()); - - final Hash transactionHash1 = - alice.execute(privacyTransactions.sendRawTransaction(rlpOutput.encoded().toHexString())); - final Hash transactionHash2 = - alice.execute(privacyTransactions.sendRawTransaction(rlpOutput.encoded().toHexString())); - - // Start mining again - alice.getBesu().execute(minerTransactions.minerStart()); - - // Successful PMTs - alice.getBesu().verify(eth.expectSuccessfulTransactionReceipt(transactionHash1.toString())); - alice.getBesu().verify(eth.expectSuccessfulTransactionReceipt(transactionHash2.toString())); - // Successful first private transaction - alice.getBesu().verify(priv.getSuccessfulTransactionReceipt(transactionHash1)); - // Invalid second private transaction - alice.getBesu().verify(priv.getInvalidTransactionReceipt(transactionHash2)); - } - - private BytesValueRLPOutput getRLPOutput(final PrivateTransaction privateTransaction) { - final BytesValueRLPOutput bvrlpo = new BytesValueRLPOutput(); - privateTransaction.writeTo(bvrlpo); - return bvrlpo; - } - - private PrivateTransaction createSignedTransaction( - final PrivacyNode node, final String privacyGoupId, final Optional payload) { - - org.hyperledger.besu.plugin.data.Restriction besuRestriction = - restriction == RESTRICTED - ? org.hyperledger.besu.plugin.data.Restriction.RESTRICTED - : org.hyperledger.besu.plugin.data.Restriction.UNRESTRICTED; - - final Bytes defaultPayload = Bytes.wrap(new byte[] {}); - return PrivateTransaction.builder() - .nonce(0) - .gasPrice(Wei.of(999999)) - .gasLimit(3000000) - .to(null) - .value(Wei.ZERO) - .payload(payload.orElse(defaultPayload)) - .sender(node.getAddress()) - .privateFrom(Bytes.fromBase64String(node.getEnclaveKey())) - .restriction(besuRestriction) - .privacyGroupId(Bytes.fromBase64String(privacyGoupId)) - .signAndBuild(node.getBesu().getPrivacyParameters().getSigningKeyPair().get()); - } -} diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivateContractPublicStateAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivateContractPublicStateAcceptanceTest.java deleted file mode 100644 index c0a63446ba..0000000000 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivateContractPublicStateAcceptanceTest.java +++ /dev/null @@ -1,225 +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.tests.acceptance.privacy; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.web3j.utils.Restriction.UNRESTRICTED; - -import org.hyperledger.besu.tests.acceptance.dsl.privacy.ParameterizedEnclaveTestBase; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.account.PrivacyAccountResolver; -import org.hyperledger.besu.tests.web3j.generated.CrossContractReader; -import org.hyperledger.besu.tests.web3j.generated.EventEmitter; -import org.hyperledger.besu.tests.web3j.generated.RemoteSimpleStorage; -import org.hyperledger.besu.tests.web3j.generated.SimpleStorage; -import org.hyperledger.enclave.testutil.EnclaveEncryptorType; -import org.hyperledger.enclave.testutil.EnclaveType; - -import java.io.IOException; -import java.math.BigInteger; -import java.util.Optional; - -import org.junit.Test; -import org.testcontainers.containers.Network; -import org.web3j.protocol.besu.response.privacy.PrivateTransactionReceipt; -import org.web3j.protocol.core.RemoteFunctionCall; -import org.web3j.protocol.core.methods.response.TransactionReceipt; -import org.web3j.protocol.exceptions.TransactionException; -import org.web3j.tx.exceptions.ContractCallException; -import org.web3j.utils.Restriction; - -public class PrivateContractPublicStateAcceptanceTest extends ParameterizedEnclaveTestBase { - - private final PrivacyNode transactionNode; - - public PrivateContractPublicStateAcceptanceTest( - final Restriction restriction, - final EnclaveType enclaveType, - final EnclaveEncryptorType enclaveEncryptorType) - throws IOException { - super(restriction, enclaveType, enclaveEncryptorType); - final Network containerNetwork = Network.newNetwork(); - - final PrivacyNode minerNode = - privacyBesu.createPrivateTransactionEnabledMinerNode( - restriction + "-miner-node", - PrivacyAccountResolver.ALICE.resolve(enclaveEncryptorType), - enclaveType, - Optional.of(containerNetwork), - false, - false, - restriction == UNRESTRICTED); - - transactionNode = - privacyBesu.createPrivateTransactionEnabledNode( - restriction + "-transaction-node", - PrivacyAccountResolver.BOB.resolve(enclaveEncryptorType), - enclaveType, - Optional.of(containerNetwork), - false, - false, - restriction == UNRESTRICTED); - - privacyCluster.start(minerNode, transactionNode); - - minerNode.verify(priv.syncingStatus(false)); - transactionNode.verify(priv.syncingStatus(false)); - } - - @Test - public void mustAllowAccessToPublicStateFromPrivateTx() throws Exception { - final EventEmitter publicEventEmitter = - transactionNode.execute(contractTransactions.createSmartContract(EventEmitter.class)); - - final TransactionReceipt receipt = publicEventEmitter.store(BigInteger.valueOf(12)).send(); - assertThat(receipt).isNotNull(); - - final CrossContractReader reader = - transactionNode.execute( - privateContractTransactions.createSmartContract( - CrossContractReader.class, - transactionNode.getTransactionSigningKey(), - transactionNode.getEnclaveKey())); - - final RemoteFunctionCall remoteFunctionCall = - reader.read(publicEventEmitter.getContractAddress()); - final BigInteger result = remoteFunctionCall.send(); - - assertThat(result).isEqualTo(BigInteger.valueOf(12)); - } - - @Test - public void mustNotAllowAccessToPrivateStateFromPublicTx() throws Exception { - final EventEmitter privateEventEmitter = - transactionNode.execute( - (privateContractTransactions.createSmartContract( - EventEmitter.class, - transactionNode.getTransactionSigningKey(), - transactionNode.getEnclaveKey()))); - - final TransactionReceipt receipt = privateEventEmitter.store(BigInteger.valueOf(12)).send(); - assertThat(receipt).isNotNull(); - - final CrossContractReader publicReader = - transactionNode.execute( - contractTransactions.createSmartContract(CrossContractReader.class)); - final RemoteFunctionCall functionCall = - publicReader.read(privateEventEmitter.getContractAddress()); - assertThatThrownBy(functionCall::send).isInstanceOf(ContractCallException.class); - } - - @Test - public void privateContractMustNotBeAbleToCallPublicContractWhichChangesState() throws Exception { - final CrossContractReader privateReader = - transactionNode.execute( - privateContractTransactions.createSmartContract( - CrossContractReader.class, - transactionNode.getTransactionSigningKey(), - transactionNode.getEnclaveKey())); - - final CrossContractReader publicReader = - transactionNode.execute( - contractTransactions.createSmartContract(CrossContractReader.class)); - - assertThatExceptionOfType(TransactionException.class) - .isThrownBy(() -> privateReader.incrementRemote(publicReader.getContractAddress()).send()) - .returns( - "0x", e -> ((PrivateTransactionReceipt) e.getTransactionReceipt().get()).getOutput()); - } - - @Test - public void privateContractMustNotBeAbleToCallPublicContractWhichInstantiatesContract() - throws Exception { - final CrossContractReader privateReader = - transactionNode.execute( - privateContractTransactions.createSmartContract( - CrossContractReader.class, - transactionNode.getTransactionSigningKey(), - transactionNode.getEnclaveKey())); - - final CrossContractReader publicReader = - transactionNode.execute( - contractTransactions.createSmartContract(CrossContractReader.class)); - - assertThatExceptionOfType(TransactionException.class) - .isThrownBy(() -> privateReader.deployRemote(publicReader.getContractAddress()).send()) - .returns(0, e -> e.getTransactionReceipt().get().getLogs().size()); - } - - @Test - public void privateContractMustNotBeAbleToCallSelfDestructOnPublicContract() throws Exception { - final CrossContractReader privateReader = - transactionNode.execute( - privateContractTransactions.createSmartContract( - CrossContractReader.class, - transactionNode.getTransactionSigningKey(), - transactionNode.getEnclaveKey())); - - final CrossContractReader publicReader = - transactionNode - .getBesu() - .execute(contractTransactions.createSmartContract(CrossContractReader.class)); - - assertThatExceptionOfType(TransactionException.class) - .isThrownBy(() -> privateReader.remoteDestroy(publicReader.getContractAddress()).send()) - .withMessage( - "Transaction null has failed with status: 0x0. Gas used: unknown. Revert reason: '0x'.") - .returns( - "0x", e -> ((PrivateTransactionReceipt) e.getTransactionReceipt().get()).getOutput()); - } - - @Test - public void privateContractCanCallPublicContractThatCallsPublicContract() throws Exception { - final SimpleStorage simpleStorage = - transactionNode - .getBesu() - .execute(contractTransactions.createSmartContract(SimpleStorage.class)); - - final RemoteSimpleStorage remoteSimpleStorage = - transactionNode - .getBesu() - .execute(contractTransactions.createSmartContract(RemoteSimpleStorage.class)); - - remoteSimpleStorage.setRemote(simpleStorage.getContractAddress()).send(); - - final RemoteSimpleStorage reallyRemoteSimpleStorage = - transactionNode - .getBesu() - .execute(contractTransactions.createSmartContract(RemoteSimpleStorage.class)); - - reallyRemoteSimpleStorage.setRemote(remoteSimpleStorage.getContractAddress()).send(); - - simpleStorage.set(BigInteger.valueOf(42)).send(); - - assertThat(simpleStorage.get().send()).isEqualTo(BigInteger.valueOf(42)); - assertThat(remoteSimpleStorage.get().send()).isEqualTo(BigInteger.valueOf(42)); - assertThat(reallyRemoteSimpleStorage.get().send()).isEqualTo(BigInteger.valueOf(42)); - - final RemoteSimpleStorage privateRemoteSimpleStorage = - transactionNode.execute( - privateContractTransactions.createSmartContract( - RemoteSimpleStorage.class, - transactionNode.getTransactionSigningKey(), - transactionNode.getEnclaveKey())); - - privateRemoteSimpleStorage.setRemote(simpleStorage.getContractAddress()).send(); - assertThat(privateRemoteSimpleStorage.get().send()).isEqualTo(BigInteger.valueOf(42)); - - privateRemoteSimpleStorage.setRemote(reallyRemoteSimpleStorage.getContractAddress()).send(); - assertThat(privateRemoteSimpleStorage.get().send()).isEqualTo(BigInteger.valueOf(42)); - } -} diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivateGenesisAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivateGenesisAcceptanceTest.java deleted file mode 100644 index 82267f8b52..0000000000 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivateGenesisAcceptanceTest.java +++ /dev/null @@ -1,100 +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.tests.acceptance.privacy; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.web3j.utils.Restriction.RESTRICTED; -import static org.web3j.utils.Restriction.UNRESTRICTED; - -import org.hyperledger.besu.tests.acceptance.dsl.privacy.ParameterizedEnclaveTestBase; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.account.PrivacyAccountResolver; -import org.hyperledger.besu.tests.web3j.generated.EventEmitter; -import org.hyperledger.enclave.testutil.EnclaveEncryptorType; -import org.hyperledger.enclave.testutil.EnclaveType; - -import java.io.IOException; -import java.math.BigInteger; -import java.util.Optional; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.web3j.protocol.core.methods.response.EthCall; -import org.web3j.utils.Restriction; - -@RunWith(Parameterized.class) -public class PrivateGenesisAcceptanceTest extends ParameterizedEnclaveTestBase { - private final PrivacyNode alice; - - public PrivateGenesisAcceptanceTest( - final Restriction restriction, - final EnclaveType enclaveType, - final EnclaveEncryptorType enclaveEncryptorType) - throws IOException { - - super(restriction, enclaveType, enclaveEncryptorType); - - alice = - privacyBesu.createIbft2NodePrivacyEnabledWithGenesis( - "node1", - PrivacyAccountResolver.ALICE.resolve(enclaveEncryptorType), - true, - enclaveType, - Optional.empty(), - false, - false, - restriction == UNRESTRICTED, - "AA"); - - privacyCluster.start(alice); - alice.verify(priv.syncingStatus(false)); - } - - @Test - public void canInteractWithPrivateGenesisPreCompile() throws Exception { - final String privacyGroupId = createPrivacyGroup(); - - final EventEmitter eventEmitter = - alice.execute( - privateContractTransactions.loadSmartContractWithPrivacyGroupId( - "0x1000000000000000000000000000000000000001", - EventEmitter.class, - alice.getTransactionSigningKey(), - alice.getEnclaveKey(), - privacyGroupId)); - - eventEmitter.store(BigInteger.valueOf(42)).send(); - - final EthCall response = - alice.execute( - privacyTransactions.privCall( - privacyGroupId, eventEmitter, eventEmitter.value().encodeFunctionCall())); - - final String value = response.getValue(); - - assertThat(new BigInteger(value.substring(2), 16)).isEqualByComparingTo(BigInteger.valueOf(42)); - } - - private String createPrivacyGroup() { - if (restriction == RESTRICTED) { - return alice.execute(privacyTransactions.createPrivacyGroup("name", "description", alice)); - } else if (restriction == UNRESTRICTED) { - return "gsvwYfGPurL7wgXKmgFtCamXarAl9fA5jaSXi8TLpJw="; - } else { - throw new RuntimeException("Do not know how to handle " + restriction); - } - } -} diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivateLogFilterAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivateLogFilterAcceptanceTest.java deleted file mode 100644 index e9307beda9..0000000000 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivateLogFilterAcceptanceTest.java +++ /dev/null @@ -1,162 +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.tests.acceptance.privacy; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.web3j.utils.Restriction.UNRESTRICTED; - -import org.hyperledger.besu.tests.acceptance.dsl.privacy.ParameterizedEnclaveTestBase; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.account.PrivacyAccountResolver; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.util.LogFilterJsonParameter; -import org.hyperledger.besu.tests.web3j.generated.EventEmitter; -import org.hyperledger.enclave.testutil.EnclaveEncryptorType; -import org.hyperledger.enclave.testutil.EnclaveType; - -import java.io.IOException; -import java.math.BigInteger; -import java.util.Collections; -import java.util.List; -import java.util.Optional; - -import org.junit.Test; -import org.web3j.protocol.besu.response.privacy.PrivateTransactionReceipt; -import org.web3j.protocol.core.methods.response.EthLog.LogResult; -import org.web3j.utils.Restriction; - -@SuppressWarnings("rawtypes") -public class PrivateLogFilterAcceptanceTest extends ParameterizedEnclaveTestBase { - - private final PrivacyNode node; - - public PrivateLogFilterAcceptanceTest( - final Restriction restriction, - final EnclaveType enclaveType, - final EnclaveEncryptorType enclaveEncryptorType) - throws IOException { - - super(restriction, enclaveType, enclaveEncryptorType); - - node = - privacyBesu.createPrivateTransactionEnabledMinerNode( - restriction + "-node", - PrivacyAccountResolver.ALICE.resolve(enclaveEncryptorType), - enclaveType, - Optional.empty(), - false, - false, - restriction == UNRESTRICTED); - - privacyCluster.start(node); - node.verify(priv.syncingStatus(false)); - } - - @Test - public void installAndUninstallFilter() { - final String privacyGroupId = createPrivacyGroup(); - final EventEmitter eventEmitterContract = deployEventEmitterContract(privacyGroupId); - - final LogFilterJsonParameter filter = - blockRangeLogFilter("earliest", "latest", eventEmitterContract.getContractAddress()); - - final String filterId = node.execute(privacyTransactions.newFilter(privacyGroupId, filter)); - - final boolean filterUninstalled = - node.execute(privacyTransactions.uninstallFilter(privacyGroupId, filterId)); - - assertThat(filterUninstalled).isTrue(); - } - - @Test - public void getFilterLogs() { - final String privacyGroupId = createPrivacyGroup(); - final EventEmitter eventEmitterContract = deployEventEmitterContract(privacyGroupId); - - final LogFilterJsonParameter filter = - blockRangeLogFilter("earliest", "latest", eventEmitterContract.getContractAddress()); - final String filterId = node.execute(privacyTransactions.newFilter(privacyGroupId, filter)); - - updateContractValue(privacyGroupId, eventEmitterContract, 1); - - final List logs = - node.execute(privacyTransactions.getFilterLogs(privacyGroupId, filterId)); - - assertThat(logs).hasSize(1); - } - - @Test - public void getFilterChanges() { - final String privacyGroupId = createPrivacyGroup(); - final EventEmitter eventEmitterContract = deployEventEmitterContract(privacyGroupId); - - final LogFilterJsonParameter filter = - blockRangeLogFilter("earliest", "latest", eventEmitterContract.getContractAddress()); - final String filterId = node.execute(privacyTransactions.newFilter(privacyGroupId, filter)); - - updateContractValue(privacyGroupId, eventEmitterContract, 1); - updateContractValue(privacyGroupId, eventEmitterContract, 2); - - assertThat(node.execute(privacyTransactions.getFilterChanges(privacyGroupId, filterId))) - .hasSize(2); - - updateContractValue(privacyGroupId, eventEmitterContract, 3); - - assertThat(node.execute(privacyTransactions.getFilterChanges(privacyGroupId, filterId))) - .hasSize(1); - } - - private LogFilterJsonParameter blockRangeLogFilter( - final String fromBlock, final String toBlock, final String contractAddress) { - return new LogFilterJsonParameter( - fromBlock, toBlock, List.of(contractAddress), Collections.emptyList(), null); - } - - private String createPrivacyGroup() { - return node.execute(createPrivacyGroup("myGroupName", "my group description", node)); - } - - private EventEmitter deployEventEmitterContract(final String privacyGroupId) { - final EventEmitter eventEmitter = - node.execute( - privateContractTransactions.createSmartContractWithPrivacyGroupId( - EventEmitter.class, - node.getTransactionSigningKey(), - restriction, - node.getEnclaveKey(), - privacyGroupId)); - - privateContractVerifier - .validPrivateContractDeployed( - eventEmitter.getContractAddress(), node.getAddress().toString()) - .verify(eventEmitter); - - return eventEmitter; - } - - private PrivateTransactionReceipt updateContractValue( - final String privacyGroupId, final EventEmitter eventEmitterContract, final int value) { - final String transactionHash = - node.execute( - privateContractTransactions.callSmartContractWithPrivacyGroupId( - eventEmitterContract.getContractAddress(), - eventEmitterContract.store(BigInteger.valueOf(value)).encodeFunctionCall(), - node.getTransactionSigningKey(), - restriction, - node.getEnclaveKey(), - privacyGroupId)); - - return node.execute(privacyTransactions.getPrivateTransactionReceipt(transactionHash)); - } -} diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/multitenancy/FlexibleMultiTenancyAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/multitenancy/FlexibleMultiTenancyAcceptanceTest.java deleted file mode 100644 index da692f21ba..0000000000 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/multitenancy/FlexibleMultiTenancyAcceptanceTest.java +++ /dev/null @@ -1,491 +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.tests.acceptance.privacy.multitenancy; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.hyperledger.enclave.testutil.EnclaveEncryptorType.EC; -import static org.hyperledger.enclave.testutil.EnclaveEncryptorType.NACL; -import static org.hyperledger.enclave.testutil.EnclaveType.TESSERA; - -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.tests.acceptance.dsl.node.BesuNode; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.account.PrivacyAccountResolver; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.contract.CallPrivateSmartContractFunction; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.transaction.CreateFlexiblePrivacyGroupTransaction; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.util.LogFilterJsonParameter; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.perm.PermissioningTransactions; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.privacy.PrivacyRequestFactory; -import org.hyperledger.besu.tests.acceptance.privacy.FlexiblePrivacyAcceptanceTestBase; -import org.hyperledger.besu.tests.web3j.generated.EventEmitter; -import org.hyperledger.enclave.testutil.EnclaveEncryptorType; -import org.hyperledger.enclave.testutil.EnclaveType; - -import java.math.BigInteger; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.web3j.crypto.Credentials; -import org.web3j.protocol.besu.response.privacy.PrivateTransactionReceipt; -import org.web3j.protocol.core.methods.response.EthCall; -import org.web3j.utils.Base64String; -import org.web3j.utils.Restriction; - -@RunWith(Parameterized.class) -public class FlexibleMultiTenancyAcceptanceTest extends FlexiblePrivacyAcceptanceTestBase { - - private final EnclaveType enclaveType; - private final EnclaveEncryptorType enclaveEncryptorType; - - public FlexibleMultiTenancyAcceptanceTest( - final EnclaveType enclaveType, final EnclaveEncryptorType enclaveEncryptorType) { - this.enclaveType = enclaveType; - this.enclaveEncryptorType = enclaveEncryptorType; - } - - @Parameterized.Parameters(name = "{0} enclave type with {1} encryptor") - public static Collection enclaveParameters() { - return Arrays.asList( - new Object[][] { - {TESSERA, NACL}, - {TESSERA, EC} - }); - } - - private static final PermissioningTransactions permissioningTransactions = - new PermissioningTransactions(); - private static final long VALUE_SET = 10L; - - private PrivacyNode alice; - private MultiTenancyPrivacyNode aliceMultiTenancyPrivacyNode; - - @Before - public void setUp() throws Exception { - alice = - privacyBesu.createFlexiblePrivacyGroupEnabledMinerNode( - "node1", - PrivacyAccountResolver.MULTI_TENANCY.resolve(enclaveEncryptorType), - true, - enclaveType, - Optional.empty()); - final BesuNode aliceBesu = alice.getBesu(); - privacyCluster.startNodes(alice); - final String alice1Token = - aliceBesu.execute(permissioningTransactions.createSuccessfulLogin("user", "pegasys")); - aliceBesu.useAuthenticationTokenInHeaderForJsonRpc(alice1Token); - final String alice2Token = - aliceBesu.execute(permissioningTransactions.createSuccessfulLogin("user2", "Password2")); - final String alice3Token = - aliceBesu.execute(permissioningTransactions.createSuccessfulLogin("user3", "Password3")); - privacyCluster.awaitPeerCount(alice); - - final String alice1EnclaveKey = alice.getEnclave().getPublicKeys().get(0); - final String alice2EnclaveKey = alice.getEnclave().getPublicKeys().get(1); - final String alice3EnclaveKey = alice.getEnclave().getPublicKeys().get(2); - - aliceMultiTenancyPrivacyNode = new MultiTenancyPrivacyNode(alice); - aliceMultiTenancyPrivacyNode - .addTenantWithToken(alice1EnclaveKey, alice1Token) - .addTenantWithToken(alice2EnclaveKey, alice2Token) - .addTenantWithToken(alice3EnclaveKey, alice3Token); - } - - @After - public void tearDown() { - privacyCluster.close(); - } - - @Test - public void createPrivacyGroup() { - createFlexiblePrivacyGroup(alice); - } - - @Test - public void createPrivacyGroupWithAllTenants() { - final MultiTenancyPrivacyGroup privacyGroup = new MultiTenancyPrivacyGroup(); - privacyGroup.addNodeWithTenants( - aliceMultiTenancyPrivacyNode, aliceMultiTenancyPrivacyNode.getTenants()); - createFlexiblePrivacyGroup(privacyGroup); - } - - @Test - public void noAccessWhenNotAMember() { - final MultiTenancyPrivacyGroup twoTenantsFromAlice = new MultiTenancyPrivacyGroup(); - final List tenants = aliceMultiTenancyPrivacyNode.getTenants(); - final String removedTenant = tenants.remove(tenants.size() - 1); - twoTenantsFromAlice.addNodeWithTenants(aliceMultiTenancyPrivacyNode, tenants); - final String privacyGroupId = createFlexiblePrivacyGroup(twoTenantsFromAlice); - - final MultiTenancyPrivacyNode multiTenancyPrivacyNode = - twoTenantsFromAlice.getPrivacyNodes().get(0); - final String tenant = tenants.get(0); - final PrivacyNode privacyNode = multiTenancyPrivacyNode.getPrivacyNode(); - final BesuNode privacyNodeBesu = privacyNode.getBesu(); - privacyNodeBesu.useAuthenticationTokenInHeaderForJsonRpc( - multiTenancyPrivacyNode.getTokenForTenant(tenant)); - final EventEmitter eventEmitter = - privacyNode.execute( - privateContractTransactions.createSmartContractWithPrivacyGroupId( - EventEmitter.class, - privacyNode.getTransactionSigningKey(), - tenant, - privacyGroupId)); - - final String transactionHash = getContractDeploymentCommitmentHash(eventEmitter); - - // check that a member can get the transaction receipt - privacyNodeBesu.useAuthenticationTokenInHeaderForJsonRpc( - multiTenancyPrivacyNode.getTokenForTenant(tenant)); - privacyNode.verify( - privateTransactionVerifier.validPrivateTransactionReceipt( - transactionHash, - (PrivateTransactionReceipt) eventEmitter.getTransactionReceipt().get())); - final String actual = - privacyNode - .execute( - privacyTransactions.privGetCode( - privacyGroupId, - Address.fromHexString(eventEmitter.getContractAddress()), - "latest")) - .toHexString(); - assertThat(EventEmitter.BINARY).contains(actual.substring(2)); - - // check that getting the transaction receipt does not work if you are not a member - privacyNodeBesu.useAuthenticationTokenInHeaderForJsonRpc( - multiTenancyPrivacyNode.getTokenForTenant(removedTenant)); - privacyNode.verify( - privateTransactionVerifier.noPrivateTransactionReceipt( - transactionHash)); // returning null because the RPC is using the enclave key - - // check that getting the code of the event emitter does not work when you are not a member - assertThatThrownBy( - () -> - privacyNode.execute( - privacyTransactions.privGetCode( - privacyGroupId, - Address.fromHexString(eventEmitter.getContractAddress()), - "latest"))) - .hasMessageContaining("Unauthorized"); - - final LogFilterJsonParameter filterParameter = - new LogFilterJsonParameter( - "earliest", - "latest", - List.of(eventEmitter.getContractAddress()), - Collections.emptyList(), - null); - - // create a valid filter - privacyNodeBesu.useAuthenticationTokenInHeaderForJsonRpc( - multiTenancyPrivacyNode.getTokenForTenant(tenant)); - final String filterId = - privacyNode.execute(privacyTransactions.newFilter(privacyGroupId, filterParameter)); - - privacyNodeBesu.useAuthenticationTokenInHeaderForJsonRpc( - multiTenancyPrivacyNode.getTokenForTenant(tenant)); - final CallPrivateSmartContractFunction storeTransaction = - privateContractTransactions.callSmartContractWithPrivacyGroupId( - eventEmitter.getContractAddress(), - eventEmitter.store(BigInteger.valueOf(VALUE_SET)).encodeFunctionCall(), - privacyNode.getTransactionSigningKey(), - Restriction.RESTRICTED, - tenant, - privacyGroupId); - final String storeTransactionHash = privacyNode.execute(storeTransaction); - - privacyNode.execute(privacyTransactions.getPrivateTransactionReceipt(storeTransactionHash)); - - // check that getting the filter changes works for a member - assertThat(privacyNode.execute(privacyTransactions.getFilterChanges(privacyGroupId, filterId))) - .hasSize(1); - - // check that getting the filter changes does not work if you are not a member - privacyNodeBesu.useAuthenticationTokenInHeaderForJsonRpc( - multiTenancyPrivacyNode.getTokenForTenant(removedTenant)); - assertThatThrownBy( - () -> - privacyNode.execute(privacyTransactions.getFilterChanges(privacyGroupId, filterId))) - .hasMessageContaining("Unauthorized"); - - // check that getting the filter logs works for a member - privacyNodeBesu.useAuthenticationTokenInHeaderForJsonRpc( - multiTenancyPrivacyNode.getTokenForTenant(tenant)); - assertThat(privacyNode.execute(privacyTransactions.getFilterLogs(privacyGroupId, filterId))) - .hasSize(3); // create privacy group, deploy event emitter, store on event emitter - - // check that getting the filter logs does not work if you are not a member - privacyNodeBesu.useAuthenticationTokenInHeaderForJsonRpc( - multiTenancyPrivacyNode.getTokenForTenant(removedTenant)); - assertThatThrownBy( - () -> privacyNode.execute(privacyTransactions.getFilterLogs(privacyGroupId, filterId))) - .hasMessageContaining("Unauthorized"); - - // check that getting the logs works for a member - privacyNodeBesu.useAuthenticationTokenInHeaderForJsonRpc( - multiTenancyPrivacyNode.getTokenForTenant(tenant)); - assertThat( - privacyNode.execute(privacyTransactions.privGetLogs(privacyGroupId, filterParameter))) - .hasSize(3); // create privacy group, deploy event emitter, store on event emitter - - // check that getting the logs does not work if you are not a member - privacyNodeBesu.useAuthenticationTokenInHeaderForJsonRpc( - multiTenancyPrivacyNode.getTokenForTenant(removedTenant)); - assertThatThrownBy( - () -> - privacyNode.execute( - privacyTransactions.privGetLogs(privacyGroupId, filterParameter))) - .hasMessageContaining("Unauthorized"); - - final List base64StringList = - tenants.stream().map(Base64String::wrap).collect(Collectors.toList()); - - // check that a member can find the on-chain privacy group - privacyNode - .getBesu() - .useAuthenticationTokenInHeaderForJsonRpc( - multiTenancyPrivacyNode.getTokenForTenant(tenant)); - final List group = - privacyNode.execute( - privacyTransactions.findFlexiblePrivacyGroup( - Base64String.unwrapList(base64StringList))); - assertThat(group.size()).isEqualTo(1); - assertThat(group.get(0).getMembers()).containsAll(base64StringList).hasSize(2); - - // check that when you are not a member you cannot find the privacy group - privacyNode - .getBesu() - .useAuthenticationTokenInHeaderForJsonRpc( - multiTenancyPrivacyNode.getTokenForTenant(removedTenant)); - assertThatThrownBy( - () -> - privacyNode.execute( - privacyTransactions.findFlexiblePrivacyGroup( - Base64String.unwrapList(base64StringList)))) - .hasMessageContaining("Error finding flexible privacy group"); - - // check that a member can do a priv_call - privacyNode - .getBesu() - .useAuthenticationTokenInHeaderForJsonRpc( - multiTenancyPrivacyNode.getTokenForTenant(tenant)); - final EthCall readValue = - privacyNode.execute( - privacyTransactions.privCall( - privacyGroupId, eventEmitter, eventEmitter.value().encodeFunctionCall())); - assertThat(new BigInteger(readValue.getValue().substring(2), 16)) - .isEqualByComparingTo(BigInteger.valueOf(VALUE_SET)); - - // check that when you are not a member you cannot do a priv_call - privacyNode - .getBesu() - .useAuthenticationTokenInHeaderForJsonRpc( - multiTenancyPrivacyNode.getTokenForTenant(removedTenant)); - assertThatThrownBy( - () -> - privacyNode.execute( - privacyTransactions.privCall( - privacyGroupId, eventEmitter, eventEmitter.value().encodeFunctionCall()))) - .hasMessageContaining("Unauthorized"); - - // check that a member can do a priv_getTransaction - privacyNode - .getBesu() - .useAuthenticationTokenInHeaderForJsonRpc( - multiTenancyPrivacyNode.getTokenForTenant(tenant)); - final PrivacyRequestFactory.GetPrivateTransactionResponse privTransaction = - privacyNode.execute(privacyTransactions.privGetTransaction(storeTransactionHash)); - assertThat(privTransaction.getResult().getPrivacyGroupId()).isEqualTo(privacyGroupId); - - // check that when you are not a member you cannot do a priv_getTransaction - privacyNode - .getBesu() - .useAuthenticationTokenInHeaderForJsonRpc( - multiTenancyPrivacyNode.getTokenForTenant(removedTenant)); - assertThatThrownBy( - () -> privacyNode.execute(privacyTransactions.privGetTransaction(storeTransactionHash))) - .hasMessageContaining( - "Expecting actual not to be null"); // TODO: returning null because the RPC is using the - // enclave key - } - - @Test - public void removedMemberCannotGetFilterChanges() { - final MultiTenancyPrivacyGroup allTenantsFromAlice = new MultiTenancyPrivacyGroup(); - final List tenants = aliceMultiTenancyPrivacyNode.getTenants(); - allTenantsFromAlice.addNodeWithTenants(aliceMultiTenancyPrivacyNode, tenants); - final String privacyGroupId = createFlexiblePrivacyGroup(allTenantsFromAlice); - final MultiTenancyPrivacyNode multiTenancyPrivacyNode = - allTenantsFromAlice.getPrivacyNodes().get(0); - final String groupCreatingTenant = allTenantsFromAlice.getGroupCreatingTenant(); - final String tenantToBeRemoved = - tenants.stream().filter(t -> !t.equals(groupCreatingTenant)).findFirst().orElseThrow(); - final PrivacyNode groupCreatingPrivacyNode = allTenantsFromAlice.getGroupCreatingPrivacyNode(); - final BesuNode groupCreatingPrivacyNodeBesu = groupCreatingPrivacyNode.getBesu(); - groupCreatingPrivacyNodeBesu.useAuthenticationTokenInHeaderForJsonRpc( - multiTenancyPrivacyNode.getTokenForTenant(groupCreatingTenant)); - - final EventEmitter eventEmitter = - groupCreatingPrivacyNode.execute( - privateContractTransactions.createSmartContractWithPrivacyGroupId( - EventEmitter.class, - groupCreatingPrivacyNode.getTransactionSigningKey(), - groupCreatingTenant, - privacyGroupId)); - - final LogFilterJsonParameter filterParameter = - new LogFilterJsonParameter( - "earliest", - "latest", - List.of(eventEmitter.getContractAddress()), - Collections.emptyList(), - null); - - final String filterId = - groupCreatingPrivacyNode.execute( - privacyTransactions.newFilter(privacyGroupId, filterParameter)); - - final CallPrivateSmartContractFunction storeTransaction = - privateContractTransactions.callSmartContractWithPrivacyGroupId( - eventEmitter.getContractAddress(), - eventEmitter.store(BigInteger.valueOf(VALUE_SET)).encodeFunctionCall(), - groupCreatingPrivacyNode.getTransactionSigningKey(), - Restriction.RESTRICTED, - groupCreatingTenant, - privacyGroupId); - final String storeTransactionHash = groupCreatingPrivacyNode.execute(storeTransaction); - - groupCreatingPrivacyNode.execute( - privacyTransactions.getPrivateTransactionReceipt(storeTransactionHash)); - - // check that getting the filter changes works for a member - groupCreatingPrivacyNodeBesu.useAuthenticationTokenInHeaderForJsonRpc( - multiTenancyPrivacyNode.getTokenForTenant(tenantToBeRemoved)); - - assertThat( - groupCreatingPrivacyNode.execute( - privacyTransactions.getFilterChanges(privacyGroupId, filterId))) - .hasSize(1); - - groupCreatingPrivacyNodeBesu.useAuthenticationTokenInHeaderForJsonRpc( - multiTenancyPrivacyNode.getTokenForTenant(groupCreatingTenant)); - final CallPrivateSmartContractFunction store2Transaction = - privateContractTransactions.callSmartContractWithPrivacyGroupId( - eventEmitter.getContractAddress(), - eventEmitter.store(BigInteger.valueOf(VALUE_SET)).encodeFunctionCall(), - groupCreatingPrivacyNode.getTransactionSigningKey(), - Restriction.RESTRICTED, - groupCreatingTenant, - privacyGroupId); - final String store2TransactionHash = groupCreatingPrivacyNode.execute(store2Transaction); - - groupCreatingPrivacyNode.execute( - privacyTransactions.getPrivateTransactionReceipt(store2TransactionHash)); - - // now remove from privacy group - final String removeTransactionHash = - removeFromPrivacyGroup( - privacyGroupId, - groupCreatingPrivacyNode, - groupCreatingTenant, - Credentials.create(groupCreatingPrivacyNode.getTransactionSigningKey()), - tenantToBeRemoved); - groupCreatingPrivacyNode.execute( - privacyTransactions.getPrivateTransactionReceipt(removeTransactionHash)); - - // check that it does not work anymore when member has been removed - groupCreatingPrivacyNodeBesu.useAuthenticationTokenInHeaderForJsonRpc( - multiTenancyPrivacyNode.getTokenForTenant(tenantToBeRemoved)); - assertThatThrownBy( - () -> - groupCreatingPrivacyNode.execute( - privacyTransactions.getFilterChanges(privacyGroupId, filterId))) - .hasMessageContaining("Unauthorized"); - } - - private String createFlexiblePrivacyGroup(final MultiTenancyPrivacyGroup group) { - final List multiTenancyPrivacyNodes = group.getPrivacyNodes(); - final MultiTenancyPrivacyNode groupCreatorMultiTenancyPrivacyNode = - multiTenancyPrivacyNodes.get(0); - final PrivacyNode groupCreatorNode = group.getGroupCreatingPrivacyNode(); - final String groupCreatorTenant = group.getGroupCreatingTenant(); - final List members = group.getTenants(); - final String token = groupCreatorMultiTenancyPrivacyNode.getTokenForTenant(groupCreatorTenant); - final CreateFlexiblePrivacyGroupTransaction createTx = - privacyTransactions.createFlexiblePrivacyGroup( - groupCreatorNode, groupCreatorTenant, members, token); - - final PrivacyRequestFactory.PrivxCreatePrivacyGroupResponse createResponse = - groupCreatorNode.execute(createTx); - final String privacyGroupId = createResponse.getPrivacyGroupId(); - - final List base64StringList = - members.stream().map(Base64String::wrap).collect(Collectors.toList()); - for (final MultiTenancyPrivacyNode mtpn : multiTenancyPrivacyNodes) { - final PrivacyNode privacyNode = mtpn.getPrivacyNode(); - for (final String tenant : mtpn.getTenants()) { - if (members.contains(tenant)) { - privacyNode - .getBesu() - .useAuthenticationTokenInHeaderForJsonRpc(mtpn.getTokenForTenant(tenant)); - privacyNode.verify(flexiblePrivacyGroupExists(privacyGroupId, base64StringList)); - } - } - } - groupCreatorNode.getBesu().useAuthenticationTokenInHeaderForJsonRpc(token); - final String commitmentHash = - callGetParticipantsMethodAndReturnCommitmentHash( - privacyGroupId, groupCreatorNode, groupCreatorTenant); - final PrivateTransactionReceipt expectedReceipt = - buildExpectedAddMemberTransactionReceipt( - privacyGroupId, groupCreatorNode, groupCreatorTenant, members); - - for (final MultiTenancyPrivacyNode mtpn : multiTenancyPrivacyNodes) { - final PrivacyNode privacyNode = mtpn.getPrivacyNode(); - for (final String tenant : mtpn.getTenants()) { - if (members.contains(tenant)) { - privacyNode - .getBesu() - .useAuthenticationTokenInHeaderForJsonRpc(mtpn.getTokenForTenant(tenant)); - privacyNode.verify( - privateTransactionVerifier.validPrivateTransactionReceipt( - commitmentHash, expectedReceipt)); - } - } - } - - return privacyGroupId; - } - - private String removeFromPrivacyGroup( - final String privacyGroupId, - final PrivacyNode node, - final String nodeRemovingMember, - final Credentials signer, - final String memberBeingRemoved) { - return node.execute( - privacyTransactions.removeFromPrivacyGroup( - privacyGroupId, nodeRemovingMember, signer, memberBeingRemoved)); - } -} From ac5e9af5e02ecfa8e86fe6fee563bc86aac8303b Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Mon, 2 Sep 2024 12:28:46 +1000 Subject: [PATCH 174/259] Set docker VCS_REF back to a 7 char hash (#7551) Signed-off-by: Matilda Clerke --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 75471c17de..f9ff1e8012 100644 --- a/build.gradle +++ b/build.gradle @@ -819,7 +819,7 @@ task distDocker { dockerPlatform = "--platform ${project.getProperty('docker-platform')}" println "Building for platform ${project.getProperty('docker-platform')}" } - def gitDetails = getGitCommitDetails() + def gitDetails = getGitCommitDetails(7) executable shell workingDir dockerBuildDir args "-c", "docker build ${dockerPlatform} --build-arg BUILD_DATE=${buildTime()} --build-arg VERSION=${dockerBuildVersion} --build-arg VCS_REF=${gitDetails.hash} -t ${image} ." From e1dd400aa5c2b282a5cee1eb9279efb9b1ee2d7c Mon Sep 17 00:00:00 2001 From: Fabio Di Fabio Date: Mon, 2 Sep 2024 12:12:31 +0200 Subject: [PATCH 175/259] Include current chain head block when computing eth_maxPriorityFeePerGas (#7485) Signed-off-by: Fabio Di Fabio --- CHANGELOG.md | 1 + .../api/graphql/GraphQLDataFetchers.java | 4 +- .../methods/EthMaxPriorityFeePerGas.java | 11 +- .../jsonrpc/methods/EthJsonRpcMethods.java | 2 +- .../ethereum/api/query/BlockchainQueries.java | 57 +++--- .../graphql/GraphQLHttpServiceCorsTest.java | 16 +- .../GraphQLHttpServiceHostWhitelistTest.java | 16 +- .../internal/methods/EthGasPriceTest.java | 2 +- .../methods/EthMaxPriorityFeePerGasTest.java | 190 ++++++++++++++---- 9 files changed, 207 insertions(+), 92 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f118aa503b..798e534571 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ ### Breaking Changes ### Additions and Improvements +- Include current chain head block when computing `eth_maxPriorityFeePerGas` [#7485](https://github.com/hyperledger/besu/pull/7485) ### Bug fixes diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/GraphQLDataFetchers.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/GraphQLDataFetchers.java index 0b97bdb2e9..d4338d58c3 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/GraphQLDataFetchers.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/GraphQLDataFetchers.java @@ -203,7 +203,7 @@ public class GraphQLDataFetchers { * *

The DataFetcher is a functional interface. It has a single method that takes a * DataFetchingEnvironment object as input and returns the maximum priority fee per gas as a Wei - * object. If the maximum priority fee per gas is not available, it returns Wei.ZERO. + * object. * * @return a DataFetcher that fetches the maximum priority fee per gas of the Ethereum node */ @@ -211,7 +211,7 @@ public class GraphQLDataFetchers { return dataFetchingEnvironment -> { final BlockchainQueries blockchainQuery = dataFetchingEnvironment.getGraphQlContext().get(GraphQLContextType.BLOCKCHAIN_QUERIES); - return blockchainQuery.gasPriorityFee().orElse(Wei.ZERO); + return blockchainQuery.gasPriorityFee(); }; } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthMaxPriorityFeePerGas.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthMaxPriorityFeePerGas.java index 2828fee7ac..71cb5ea3c6 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthMaxPriorityFeePerGas.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthMaxPriorityFeePerGas.java @@ -21,19 +21,13 @@ 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.Quantity; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; -import org.hyperledger.besu.ethereum.blockcreation.MiningCoordinator; - -import java.util.Optional; public class EthMaxPriorityFeePerGas implements JsonRpcMethod { private final BlockchainQueries blockchainQueries; - private final MiningCoordinator miningCoordinator; - public EthMaxPriorityFeePerGas( - final BlockchainQueries blockchainQueries, final MiningCoordinator miningCoordinator) { + public EthMaxPriorityFeePerGas(final BlockchainQueries blockchainQueries) { this.blockchainQueries = blockchainQueries; - this.miningCoordinator = miningCoordinator; } @Override @@ -48,7 +42,6 @@ public class EthMaxPriorityFeePerGas implements JsonRpcMethod { } private Wei fetchAndLimitPriorityFeePerGas() { - final Optional gasPrice = blockchainQueries.gasPriorityFee(); - return gasPrice.orElseGet(miningCoordinator::getMinPriorityFeePerGas); + return blockchainQueries.gasPriorityFee(); } } 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 c7575a5435..5baa110646 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 @@ -185,6 +185,6 @@ public class EthJsonRpcMethods extends ApiGroupJsonRpcMethods { new EthGetMinerDataByBlockHash(blockchainQueries, protocolSchedule), new EthGetMinerDataByBlockNumber(blockchainQueries, protocolSchedule), new EthBlobBaseFee(blockchainQueries.getBlockchain(), protocolSchedule), - new EthMaxPriorityFeePerGas(blockchainQueries, miningCoordinator)); + new EthMaxPriorityFeePerGas(blockchainQueries)); } } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/query/BlockchainQueries.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/query/BlockchainQueries.java index 6e0f0e3e35..c03bf124c4 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/query/BlockchainQueries.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/query/BlockchainQueries.java @@ -46,7 +46,6 @@ import org.hyperledger.besu.evm.log.LogsBloomFilter; import java.io.EOFException; import java.io.IOException; import java.io.RandomAccessFile; -import java.math.BigInteger; import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; @@ -1006,7 +1005,7 @@ public class BlockchainQueries { .sorted() .toArray(Wei[]::new); - return (gasCollection == null || gasCollection.length == 0) + return gasCollection.length == 0 ? gasPriceLowerBound(chainHeadHeader, nextBlockFeeMarket) : UInt256s.max( gasPriceLowerBound(chainHeadHeader, nextBlockFeeMarket), @@ -1045,31 +1044,39 @@ public class BlockchainQueries { return minGasPrice; } - public Optional gasPriorityFee() { - final long blockHeight = headBlockNumber(); - final BigInteger[] gasCollection = - LongStream.range(Math.max(0, blockHeight - apiConfig.getGasPriceBlocks()), blockHeight) - .mapToObj( - l -> - blockchain - .getBlockByNumber(l) - .map(Block::getBody) - .map(BlockBody::getTransactions) - .orElseThrow( - () -> new IllegalStateException("Could not retrieve block #" + l))) + public Wei gasPriorityFee() { + final Block chainHeadBlock = blockchain.getChainHeadBlock(); + final long blockHeight = chainHeadBlock.getHeader().getNumber(); + + final Wei[] gasCollection = + Stream.concat( + LongStream.range( + Math.max(0, blockHeight - apiConfig.getGasPriceBlocks() + 1), blockHeight) + .mapToObj( + l -> + blockchain + .getBlockByNumber(l) + .orElseThrow( + () -> + new IllegalStateException( + "Could not retrieve block #" + l))), + Stream.of(chainHeadBlock)) + .map(Block::getBody) + .map(BlockBody::getTransactions) .flatMap(Collection::stream) .filter(t -> t.getMaxPriorityFeePerGas().isPresent()) - .map(t -> t.getMaxPriorityFeePerGas().get().toBigInteger()) - .sorted(BigInteger::compareTo) - .toArray(BigInteger[]::new); - return (gasCollection.length == 0) - ? Optional.empty() - : Optional.of( - Wei.of( - gasCollection[ - Math.min( - gasCollection.length - 1, - (int) ((gasCollection.length) * apiConfig.getGasPriceFraction()))])); + .map(t -> t.getMaxPriorityFeePerGas().get()) + .sorted() + .toArray(Wei[]::new); + + return gasCollection.length == 0 + ? miningParameters.getMinPriorityFeePerGas() + : UInt256s.max( + miningParameters.getMinPriorityFeePerGas(), + gasCollection[ + Math.min( + gasCollection.length - 1, + (int) ((gasCollection.length) * apiConfig.getGasPriceFraction()))]); } /** diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/graphql/GraphQLHttpServiceCorsTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/graphql/GraphQLHttpServiceCorsTest.java index d6a04b4cb8..0e008568dc 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/graphql/GraphQLHttpServiceCorsTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/graphql/GraphQLHttpServiceCorsTest.java @@ -14,6 +14,10 @@ */ package org.hyperledger.besu.ethereum.api.graphql; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; import org.hyperledger.besu.ethereum.blockcreation.PoWMiningCoordinator; import org.hyperledger.besu.ethereum.core.Synchronizer; @@ -38,7 +42,6 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; -import org.mockito.Mockito; public class GraphQLHttpServiceCorsTest { @TempDir private Path folder; @@ -208,10 +211,11 @@ public class GraphQLHttpServiceCorsTest { config.setCorsAllowedDomains(Lists.newArrayList(corsAllowedDomains)); } - final BlockchainQueries blockchainQueries = Mockito.mock(BlockchainQueries.class); - final Synchronizer synchronizer = Mockito.mock(Synchronizer.class); + final BlockchainQueries blockchainQueries = mock(BlockchainQueries.class); + when(blockchainQueries.gasPriorityFee()).thenReturn(Wei.ONE); + final Synchronizer synchronizer = mock(Synchronizer.class); - final PoWMiningCoordinator miningCoordinatorMock = Mockito.mock(PoWMiningCoordinator.class); + final PoWMiningCoordinator miningCoordinatorMock = mock(PoWMiningCoordinator.class); // mock graphql context final Map graphQLContextMap = @@ -219,7 +223,7 @@ public class GraphQLHttpServiceCorsTest { GraphQLContextType.BLOCKCHAIN_QUERIES, blockchainQueries, GraphQLContextType.TRANSACTION_POOL, - Mockito.mock(TransactionPool.class), + mock(TransactionPool.class), GraphQLContextType.MINING_COORDINATOR, miningCoordinatorMock, GraphQLContextType.SYNCHRONIZER, @@ -233,7 +237,7 @@ public class GraphQLHttpServiceCorsTest { final GraphQLHttpService graphQLHttpService = new GraphQLHttpService( - vertx, folder, config, graphQL, graphQLContextMap, Mockito.mock(EthScheduler.class)); + vertx, folder, config, graphQL, graphQLContextMap, mock(EthScheduler.class)); graphQLHttpService.start().join(); return graphQLHttpService; diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/graphql/GraphQLHttpServiceHostWhitelistTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/graphql/GraphQLHttpServiceHostWhitelistTest.java index ec33bd9268..90833c42a5 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/graphql/GraphQLHttpServiceHostWhitelistTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/graphql/GraphQLHttpServiceHostWhitelistTest.java @@ -14,6 +14,10 @@ */ package org.hyperledger.besu.ethereum.api.graphql; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; import org.hyperledger.besu.ethereum.blockcreation.PoWMiningCoordinator; import org.hyperledger.besu.ethereum.core.Synchronizer; @@ -42,7 +46,6 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; -import org.mockito.Mockito; public class GraphQLHttpServiceHostWhitelistTest { @@ -69,17 +72,18 @@ public class GraphQLHttpServiceHostWhitelistTest { } private GraphQLHttpService createGraphQLHttpService() throws Exception { - final BlockchainQueries blockchainQueries = Mockito.mock(BlockchainQueries.class); - final Synchronizer synchronizer = Mockito.mock(Synchronizer.class); + final BlockchainQueries blockchainQueries = mock(BlockchainQueries.class); + when(blockchainQueries.gasPriorityFee()).thenReturn(Wei.ONE); + final Synchronizer synchronizer = mock(Synchronizer.class); - final PoWMiningCoordinator miningCoordinatorMock = Mockito.mock(PoWMiningCoordinator.class); + final PoWMiningCoordinator miningCoordinatorMock = mock(PoWMiningCoordinator.class); final Map graphQLContextMap = Map.of( GraphQLContextType.BLOCKCHAIN_QUERIES, blockchainQueries, GraphQLContextType.TRANSACTION_POOL, - Mockito.mock(TransactionPool.class), + mock(TransactionPool.class), GraphQLContextType.MINING_COORDINATOR, miningCoordinatorMock, GraphQLContextType.SYNCHRONIZER, @@ -92,7 +96,7 @@ public class GraphQLHttpServiceHostWhitelistTest { final GraphQL graphQL = GraphQLProvider.buildGraphQL(dataFetchers); return new GraphQLHttpService( - vertx, folder, graphQLConfig, graphQL, graphQLContextMap, Mockito.mock(EthScheduler.class)); + vertx, folder, graphQLConfig, graphQL, graphQLContextMap, mock(EthScheduler.class)); } private static GraphQLConfiguration createGraphQLConfig() { diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGasPriceTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGasPriceTest.java index 5d6aba7694..e428286444 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGasPriceTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGasPriceTest.java @@ -328,7 +328,7 @@ public class EthGasPriceTest { } when(blockchain.getChainHeadBlock()).thenReturn(blocksByNumber.get(chainHeadBlockNumber)); - if (chainHeadBlockNumber > 1) { + if (chainHeadBlockNumber > 0) { when(blockchain.getBlockByNumber(anyLong())) .thenAnswer( invocation -> Optional.of(blocksByNumber.get(invocation.getArgument(0, Long.class)))); 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 02d526107a..886c8a1d03 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 @@ -15,29 +15,43 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.verify; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.when; +import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.datatypes.Hash; +import org.hyperledger.besu.datatypes.TransactionType; import org.hyperledger.besu.datatypes.Wei; +import org.hyperledger.besu.ethereum.api.ImmutableApiConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; 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.response.JsonRpcResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; 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; +import org.hyperledger.besu.ethereum.core.BlockBody; +import org.hyperledger.besu.ethereum.core.BlockHeader; +import org.hyperledger.besu.ethereum.core.Difficulty; +import org.hyperledger.besu.ethereum.core.MiningParameters; +import org.hyperledger.besu.ethereum.core.Transaction; +import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; +import org.hyperledger.besu.ethereum.mainnet.feemarket.CancunFeeMarket; +import org.hyperledger.besu.evm.log.LogsBloomFilter; + +import java.math.BigInteger; +import java.util.HashMap; +import java.util.List; import java.util.Optional; -import java.util.stream.Stream; +import java.util.stream.IntStream; +import org.apache.tuweni.bytes.Bytes; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; import org.mockito.Mock; -import org.mockito.internal.verification.VerificationModeFactory; import org.mockito.junit.jupiter.MockitoExtension; @ExtendWith(MockitoExtension.class) @@ -45,13 +59,20 @@ public class EthMaxPriorityFeePerGasTest { private static final String JSON_RPC_VERSION = "2.0"; private static final String ETH_METHOD = RpcMethod.ETH_GET_MAX_PRIORITY_FEE_PER_GAS.getMethodName(); - private EthMaxPriorityFeePerGas method; + private static final Wei DEFAULT_MIN_PRIORITY_FEE_PER_GAS = Wei.ZERO; + private static final long DEFAULT_BLOCK_GAS_LIMIT = 100_000; + private static final long DEFAULT_BLOCK_GAS_USED = 21_000; + private static final Wei DEFAULT_BASE_FEE = Wei.of(100_000); - @Mock private BlockchainQueries blockchainQueries; - @Mock private MiningCoordinator miningCoordinator; + private EthMaxPriorityFeePerGas method; + @Mock private ProtocolSchedule protocolSchedule; + @Mock private Blockchain blockchain; + private MiningParameters miningParameters; @BeforeEach public void setUp() { + miningParameters = + MiningParameters.newDefault().setMinPriorityFeePerGas(DEFAULT_MIN_PRIORITY_FEE_PER_GAS); method = createEthMaxPriorityFeePerGasMethod(); } @@ -63,71 +84,156 @@ public class EthMaxPriorityFeePerGasTest { @Test public void whenNoTransactionsExistReturnMinPriorityFeePerGasPrice() { final JsonRpcRequestContext request = requestWithParams(); - final String expectedWei = Wei.ONE.toShortHexString(); + final Wei expectedWei = Wei.ONE; + miningParameters.setMinPriorityFeePerGas(expectedWei); final JsonRpcResponse expectedResponse = - new JsonRpcSuccessResponse(request.getRequest().getId(), expectedWei); - when(miningCoordinator.getMinPriorityFeePerGas()).thenReturn(Wei.ONE); + new JsonRpcSuccessResponse(request.getRequest().getId(), expectedWei.toShortHexString()); - mockBlockchainQueriesMaxPriorityFeePerGasPrice(Optional.empty()); + mockBlockchain(10, 0); final JsonRpcResponse actualResponse = method.response(request); assertThat(actualResponse).usingRecursiveComparison().isEqualTo(expectedResponse); - verify(miningCoordinator, VerificationModeFactory.times(1)).getMinPriorityFeePerGas(); } - @ParameterizedTest - @MethodSource("minPriorityFeePerGasValues") - public void whenNoTransactionsExistReturnMinPriorityFeePerGasPriceExist( - final Wei minPriorityFeePerGasValue) { + @Test + public void whenTransactionsExistReturnMedianMaxPriorityFeePerGasPrice() { final JsonRpcRequestContext request = requestWithParams(); - final String expectedWei = minPriorityFeePerGasValue.toShortHexString(); + final Wei expectedWei = Wei.of(51_000); // max priority fee per gas prices are 1000-100000 wei. final JsonRpcResponse expectedResponse = - new JsonRpcSuccessResponse(request.getRequest().getId(), expectedWei); - when(miningCoordinator.getMinPriorityFeePerGas()).thenReturn(minPriorityFeePerGasValue); + new JsonRpcSuccessResponse(request.getRequest().getId(), expectedWei.toShortHexString()); + + mockBlockchain(100, 1); - mockBlockchainQueriesMaxPriorityFeePerGasPrice(Optional.empty()); final JsonRpcResponse actualResponse = method.response(request); assertThat(actualResponse).usingRecursiveComparison().isEqualTo(expectedResponse); - verify(miningCoordinator, VerificationModeFactory.times(1)).getMinPriorityFeePerGas(); } @Test - public void whenNoTransactionsExistReturnNullMinPriorityFeePerGasPriceExist() { + public void returnMinPriorityFeePerGasWhenMedianValueIsLower() { final JsonRpcRequestContext request = requestWithParams(); + final Wei expectedWei = Wei.of(100_000); + miningParameters.setMinPriorityFeePerGas(expectedWei); + + mockBlockchain(100, 1); + + // median value is 51000 wei, that is lower than the value this node is willing to accept, + // so the configured min priority fee per gas is returned. final JsonRpcResponse expectedResponse = - new JsonRpcSuccessResponse(request.getRequest().getId(), null); - when(miningCoordinator.getMinPriorityFeePerGas()).thenReturn(null); + new JsonRpcSuccessResponse(request.getRequest().getId(), expectedWei.toShortHexString()); - mockBlockchainQueriesMaxPriorityFeePerGasPrice(Optional.empty()); final JsonRpcResponse actualResponse = method.response(request); assertThat(actualResponse).usingRecursiveComparison().isEqualTo(expectedResponse); - verify(miningCoordinator, VerificationModeFactory.times(1)).getMinPriorityFeePerGas(); } @Test - public void whenTransactionsExistReturnMaxPriorityFeePerGasPrice() { + public void atGenesisReturnMinPriorityFeePerGas() { final JsonRpcRequestContext request = requestWithParams(); - final String expectedWei = Wei.of(2000000000).toShortHexString(); + final Wei expectedWei = Wei.ONE; + miningParameters.setMinPriorityFeePerGas(expectedWei); final JsonRpcResponse expectedResponse = - new JsonRpcSuccessResponse(request.getRequest().getId(), expectedWei); - mockBlockchainQueriesMaxPriorityFeePerGasPrice(Optional.of(Wei.of(2000000000))); + new JsonRpcSuccessResponse(request.getRequest().getId(), expectedWei.toShortHexString()); + + mockBlockchain(0, 0); final JsonRpcResponse actualResponse = method.response(request); assertThat(actualResponse).usingRecursiveComparison().isEqualTo(expectedResponse); - verify(miningCoordinator, VerificationModeFactory.times(0)).getMinPriorityFeePerGas(); } - private static Stream minPriorityFeePerGasValues() { - return Stream.of(Arguments.of(Wei.ONE), Arguments.of(Wei.ZERO)); + private JsonRpcRequestContext requestWithParams(final Object... params) { + return new JsonRpcRequestContext(new JsonRpcRequest(JSON_RPC_VERSION, ETH_METHOD, params)); } - private void mockBlockchainQueriesMaxPriorityFeePerGasPrice(final Optional result) { - when(blockchainQueries.gasPriorityFee()).thenReturn(result); + private void mockBlockchain(final long chainHeadBlockNumber, final int txsNum) { + final var genesisBaseFee = DEFAULT_BASE_FEE; + final var blocksByNumber = new HashMap(); + + final var genesisBlock = createFakeBlock(0, 0, genesisBaseFee); + blocksByNumber.put(0L, genesisBlock); + + final var baseFeeMarket = new CancunFeeMarket(0, Optional.empty()); + + var baseFee = genesisBaseFee; + for (long i = 1; i <= chainHeadBlockNumber; i++) { + final var parentHeader = blocksByNumber.get(i - 1).getHeader(); + baseFee = + baseFeeMarket.computeBaseFee( + i, + parentHeader.getBaseFee().get(), + parentHeader.getGasUsed(), + parentHeader.getGasLimit()); + blocksByNumber.put(i, createFakeBlock(i, txsNum, baseFee)); + } + + when(blockchain.getChainHeadBlock()).thenReturn(blocksByNumber.get(chainHeadBlockNumber)); + if (chainHeadBlockNumber > 0) { + when(blockchain.getBlockByNumber(anyLong())) + .thenAnswer( + invocation -> Optional.of(blocksByNumber.get(invocation.getArgument(0, Long.class)))); + } + lenient() + .when(blockchain.getChainHeadHeader()) + .thenReturn(blocksByNumber.get(chainHeadBlockNumber).getHeader()); } - private JsonRpcRequestContext requestWithParams(final Object... params) { - return new JsonRpcRequestContext(new JsonRpcRequest(JSON_RPC_VERSION, ETH_METHOD, params)); + private Block createFakeBlock(final long height, final int txsNum, final Wei baseFee) { + return createFakeBlock( + height, txsNum, baseFee, DEFAULT_BLOCK_GAS_LIMIT, DEFAULT_BLOCK_GAS_USED * txsNum); + } + + private Block createFakeBlock( + final long height, + final int txsNum, + final Wei baseFee, + final long gasLimit, + final long gasUsed) { + return new Block( + new BlockHeader( + Hash.EMPTY, + Hash.EMPTY_TRIE_HASH, + Address.ZERO, + Hash.EMPTY_TRIE_HASH, + Hash.EMPTY_TRIE_HASH, + Hash.EMPTY_TRIE_HASH, + LogsBloomFilter.builder().build(), + Difficulty.ONE, + height, + gasLimit, + gasUsed, + 0, + Bytes.EMPTY, + baseFee, + Hash.EMPTY, + 0, + null, + null, + null, + null, + null, + null), + new BlockBody( + IntStream.range(0, txsNum) + .mapToObj( + i -> + new Transaction.Builder() + .chainId(BigInteger.ONE) + .type(TransactionType.EIP1559) + .nonce(i) + .maxFeePerGas(Wei.of(height * 10_000L)) + .maxPriorityFeePerGas(Wei.of(height * 1_000L)) + .gasLimit(gasUsed) + .value(Wei.ZERO) + .build()) + .toList(), + List.of())); } private EthMaxPriorityFeePerGas createEthMaxPriorityFeePerGasMethod() { - return new EthMaxPriorityFeePerGas(blockchainQueries, miningCoordinator); + return new EthMaxPriorityFeePerGas( + new BlockchainQueries( + protocolSchedule, + blockchain, + null, + Optional.empty(), + Optional.empty(), + ImmutableApiConfiguration.builder().build(), + miningParameters)); } } From 4c4f2f3362ed8599cf8d195cf38898d88e848fea Mon Sep 17 00:00:00 2001 From: Luis Pinto Date: Mon, 2 Sep 2024 13:16:44 +0100 Subject: [PATCH 176/259] refactor SimpleWorld to use Optional for storing accounts and extra null checks (#7532) Signed-off-by: Luis Pinto --- .../besu/evm/fluent/SimpleAccount.java | 17 - .../besu/evm/fluent/SimpleWorld.java | 47 +-- .../besu/evm/fluent/SimpleWorldTest.java | 331 ++++++++++++++++++ 3 files changed, 357 insertions(+), 38 deletions(-) create mode 100644 evm/src/test/java/org/hyperledger/besu/evm/fluent/SimpleWorldTest.java diff --git a/evm/src/main/java/org/hyperledger/besu/evm/fluent/SimpleAccount.java b/evm/src/main/java/org/hyperledger/besu/evm/fluent/SimpleAccount.java index f86bba699e..6ad10d37e4 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/fluent/SimpleAccount.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/fluent/SimpleAccount.java @@ -214,21 +214,4 @@ public class SimpleAccount implements MutableAccount { return false; } } - - /** - * Push changes into the parent account, if one exists - * - * @return true if a parent account was updated, false if not (this indicates the account should - * be inserted into the parent contact). - */ - public boolean updateParent() { - if (parent instanceof SimpleAccount simpleAccount) { - simpleAccount.balance = balance; - simpleAccount.nonce = nonce; - simpleAccount.storage.putAll(storage); - return true; - } else { - return false; - } - } } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/fluent/SimpleWorld.java b/evm/src/main/java/org/hyperledger/besu/evm/fluent/SimpleWorld.java index f52e788bab..6d2437a887 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/fluent/SimpleWorld.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/fluent/SimpleWorld.java @@ -29,10 +29,10 @@ import java.util.Optional; public class SimpleWorld implements WorldUpdater { /** The Parent. */ - SimpleWorld parent; + private final SimpleWorld parent; /** The Accounts. */ - Map accounts = new HashMap<>(); + private Map> accounts = new HashMap<>(); /** Instantiates a new Simple world. */ public SimpleWorld() { @@ -55,13 +55,15 @@ public class SimpleWorld implements WorldUpdater { @Override public Account get(final Address address) { + Optional account = Optional.empty(); if (accounts.containsKey(address)) { - return accounts.get(address); + account = accounts.get(address); } else if (parent != null) { - return parent.get(address); - } else { - return null; + if (parent.get(address) instanceof SimpleAccount accountFromParent) { + account = Optional.of(accountFromParent); + } } + return account.orElse(null); } @Override @@ -70,45 +72,46 @@ public class SimpleWorld implements WorldUpdater { throw new IllegalStateException("Cannot create an account when one already exists"); } SimpleAccount account = new SimpleAccount(address, nonce, balance); - accounts.put(address, account); + accounts.put(address, Optional.of(account)); return account; } @Override public MutableAccount getAccount(final Address address) { - SimpleAccount account = accounts.get(address); + Optional account = accounts.get(address); if (account != null) { - return account; + return account.orElse(null); } Account parentAccount = parent == null ? null : parent.getAccount(address); if (parentAccount != null) { account = - new SimpleAccount( - parentAccount, - parentAccount.getAddress(), - parentAccount.getNonce(), - parentAccount.getBalance(), - parentAccount.getCode()); + Optional.of( + new SimpleAccount( + parentAccount, + parentAccount.getAddress(), + parentAccount.getNonce(), + parentAccount.getBalance(), + parentAccount.getCode())); accounts.put(address, account); - return account; + return account.get(); } return null; } @Override public void deleteAccount(final Address address) { - accounts.put(address, null); + accounts.put(address, Optional.empty()); } @Override public Collection getTouchedAccounts() { - return accounts.values(); + return accounts.values().stream().filter(Optional::isPresent).map(Optional::get).toList(); } @Override public Collection

getDeletedAccountAddresses() { return accounts.entrySet().stream() - .filter(e -> e.getValue() == null) + .filter(e -> e.getValue().isEmpty()) .map(Map.Entry::getKey) .toList(); } @@ -122,8 +125,10 @@ public class SimpleWorld implements WorldUpdater { public void commit() { accounts.forEach( (address, account) -> { - if (!account.updateParent()) { - parent.accounts.put(address, account); + if (account.isEmpty() || !account.get().commit()) { + if (parent != null) { + parent.accounts.put(address, account); + } } }); } diff --git a/evm/src/test/java/org/hyperledger/besu/evm/fluent/SimpleWorldTest.java b/evm/src/test/java/org/hyperledger/besu/evm/fluent/SimpleWorldTest.java new file mode 100644 index 0000000000..c7f997bfb9 --- /dev/null +++ b/evm/src/test/java/org/hyperledger/besu/evm/fluent/SimpleWorldTest.java @@ -0,0 +1,331 @@ +/* + * Copyright contributors to Hyperledger Besu. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.evm.fluent; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.evm.account.Account; +import org.hyperledger.besu.evm.account.MutableAccount; +import org.hyperledger.besu.evm.worldstate.WorldUpdater; + +import org.apache.tuweni.units.bigints.UInt256; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class SimpleWorldTest { + private static final Address ADDRESS1 = Address.fromHexString("0x0"); + private static final Address ADDRESS2 = Address.fromHexString("0x1"); + private static final Address ADDRESS3 = Address.fromHexString("0x2"); + + private SimpleWorld simpleWorld; + + @BeforeEach + void setUp() { + simpleWorld = new SimpleWorld(); + } + + @Test + void get_noAccounts() { + assertThat(simpleWorld.get(ADDRESS1)).isNull(); + } + + @Test + void get_noAccountsWithParent() { + WorldUpdater childUpdater = simpleWorld.updater(); + assertThat(childUpdater.get(ADDRESS1)).isNull(); + } + + @Test + void createAccount_cannotCreateIfExists() { + simpleWorld.createAccount(ADDRESS1); + assertThatThrownBy(() -> simpleWorld.createAccount(ADDRESS1)) + .isInstanceOf(IllegalStateException.class); + } + + @Test + void get_createdAccountExistsInParent() { + MutableAccount account = simpleWorld.createAccount(ADDRESS1); + WorldUpdater childUpdater = simpleWorld.updater(); + assertThat(childUpdater.get(ADDRESS1)).isEqualTo(account); + } + + @Test + void get_createdAccountExistsInMultiParent() { + MutableAccount account = simpleWorld.createAccount(ADDRESS1); + WorldUpdater childUpdater = simpleWorld.updater(); + childUpdater = childUpdater.updater(); + childUpdater = childUpdater.updater(); + childUpdater = childUpdater.updater(); + assertThat(childUpdater.get(ADDRESS1)).isEqualTo(account); + } + + @Test + void get_createdAccountExists() { + MutableAccount account = simpleWorld.createAccount(ADDRESS1); + assertThat(simpleWorld.get(ADDRESS1)).isEqualTo(account); + } + + @Test + void get_createdAccountDeleted() { + simpleWorld.createAccount(ADDRESS1); + simpleWorld.deleteAccount(ADDRESS1); + assertThat(simpleWorld.get(ADDRESS1)).isNull(); + } + + @Test + void get_revertRemovesAllAccounts() { + simpleWorld.createAccount(ADDRESS1); + simpleWorld.createAccount(ADDRESS2); + simpleWorld.createAccount(ADDRESS3); + simpleWorld.revert(); + assertThat(simpleWorld.get(ADDRESS1)).isNull(); + assertThat(simpleWorld.get(ADDRESS2)).isNull(); + assertThat(simpleWorld.get(ADDRESS3)).isNull(); + } + + @Test + void get_commitKeepsAllAccounts() { + MutableAccount acc1 = simpleWorld.createAccount(ADDRESS1); + MutableAccount acc2 = simpleWorld.createAccount(ADDRESS2); + MutableAccount acc3 = simpleWorld.createAccount(ADDRESS3); + simpleWorld.commit(); + assertThat(simpleWorld.get(ADDRESS1)).isEqualTo(acc1); + assertThat(simpleWorld.get(ADDRESS2)).isEqualTo(acc2); + assertThat(simpleWorld.get(ADDRESS3)).isEqualTo(acc3); + } + + @Test + void get_createdAccountDeletedInChild() { + simpleWorld.createAccount(ADDRESS1); + WorldUpdater childUpdater = simpleWorld.updater(); + childUpdater.deleteAccount(ADDRESS1); + assertThat(childUpdater.get(ADDRESS1)).isNull(); + } + + @Test + void getAccount_noAccounts() { + assertThat(simpleWorld.getAccount(ADDRESS1)).isNull(); + } + + @Test + void getAccount_noAccountsWithParent() { + WorldUpdater childUpdater = simpleWorld.updater(); + assertThat(childUpdater.getAccount(ADDRESS1)).isNull(); + } + + @Test + void getAccount_createdAccountExistsInParent() { + MutableAccount account = simpleWorld.createAccount(ADDRESS1); + account.setStorageValue(UInt256.MAX_VALUE, UInt256.ONE); + WorldUpdater childUpdater = simpleWorld.updater(); + assertThat(childUpdater.getAccount(ADDRESS1).getOriginalStorageValue(UInt256.MAX_VALUE)) + .isEqualTo(UInt256.ONE); + } + + @Test + void getAccount_createdAccountExistsInMultiParent() { + MutableAccount account = simpleWorld.createAccount(ADDRESS1); + account.setStorageValue(UInt256.MAX_VALUE, UInt256.ONE); + WorldUpdater childUpdater = simpleWorld.updater(); + childUpdater = childUpdater.updater(); + childUpdater = childUpdater.updater(); + childUpdater = childUpdater.updater(); + assertThat(childUpdater.getAccount(ADDRESS1).getOriginalStorageValue(UInt256.MAX_VALUE)) + .isEqualTo(UInt256.ONE); + } + + @Test + void getAccount_createdAccountExists() { + MutableAccount account = simpleWorld.createAccount(ADDRESS1); + assertThat(simpleWorld.getAccount(ADDRESS1)).isEqualTo(account); + } + + @Test + void getAccount_createdAccountDeleted() { + simpleWorld.createAccount(ADDRESS1); + simpleWorld.deleteAccount(ADDRESS1); + assertThat(simpleWorld.getAccount(ADDRESS1)).isNull(); + } + + @Test + void getAccount_revertRemovesAllAccounts() { + simpleWorld.createAccount(ADDRESS1); + simpleWorld.createAccount(ADDRESS2); + simpleWorld.createAccount(ADDRESS3); + simpleWorld.revert(); + assertThat(simpleWorld.getAccount(ADDRESS1)).isNull(); + assertThat(simpleWorld.getAccount(ADDRESS2)).isNull(); + assertThat(simpleWorld.getAccount(ADDRESS3)).isNull(); + } + + @Test + void getAccount_commitKeepsAllAccounts() { + MutableAccount acc1 = simpleWorld.createAccount(ADDRESS1); + MutableAccount acc2 = simpleWorld.createAccount(ADDRESS2); + MutableAccount acc3 = simpleWorld.createAccount(ADDRESS3); + simpleWorld.commit(); + assertThat(simpleWorld.getAccount(ADDRESS1)).isEqualTo(acc1); + assertThat(simpleWorld.getAccount(ADDRESS2)).isEqualTo(acc2); + assertThat(simpleWorld.getAccount(ADDRESS3)).isEqualTo(acc3); + } + + @Test + void getAccount_createdAccountDeletedInChild() { + simpleWorld.createAccount(ADDRESS1); + WorldUpdater childUpdater = simpleWorld.updater(); + childUpdater.deleteAccount(ADDRESS1); + assertThat(childUpdater.getAccount(ADDRESS1)).isNull(); + } + + @Test + void getTouchedAccounts_createdAccounts() { + Account acc1 = simpleWorld.createAccount(ADDRESS1); + Account acc2 = simpleWorld.createAccount(ADDRESS2); + Account acc3 = simpleWorld.createAccount(ADDRESS3); + assertThat(simpleWorld.getTouchedAccounts().toArray()) + .containsExactlyInAnyOrder(acc1, acc2, acc3); + } + + @Test + void getTouchedAccounts_revertedAccounts() { + simpleWorld.createAccount(ADDRESS1); + simpleWorld.createAccount(ADDRESS2); + simpleWorld.createAccount(ADDRESS3); + simpleWorld.revert(); + assertThat(simpleWorld.getTouchedAccounts()).isEmpty(); + } + + @Test + void getTouchedAccounts_createdAndDeletedAccounts() { + Account acc1 = simpleWorld.createAccount(ADDRESS1); + simpleWorld.createAccount(ADDRESS2); + Account acc3 = simpleWorld.createAccount(ADDRESS3); + simpleWorld.deleteAccount(ADDRESS2); + assertThat(simpleWorld.getTouchedAccounts().toArray()).containsExactlyInAnyOrder(acc1, acc3); + } + + @Test + void getTouchedAccounts_allDeletedAccounts() { + simpleWorld.createAccount(ADDRESS1); + simpleWorld.createAccount(ADDRESS2); + simpleWorld.createAccount(ADDRESS3); + simpleWorld.deleteAccount(ADDRESS1); + simpleWorld.deleteAccount(ADDRESS2); + simpleWorld.deleteAccount(ADDRESS3); + assertThat(simpleWorld.getTouchedAccounts()).isEmpty(); + } + + @Test + void getTouchedAccounts_createdAndCommittedAccounts() { + Account acc1 = simpleWorld.createAccount(ADDRESS1); + Account acc2 = simpleWorld.createAccount(ADDRESS2); + Account acc3 = simpleWorld.createAccount(ADDRESS3); + simpleWorld.commit(); + assertThat(simpleWorld.getTouchedAccounts().toArray()) + .containsExactlyInAnyOrder(acc1, acc2, acc3); + } + + @Test + void getDeletedAccountAddresses_singleDeleted() { + simpleWorld.createAccount(ADDRESS1); + simpleWorld.createAccount(ADDRESS2); + simpleWorld.createAccount(ADDRESS3); + simpleWorld.deleteAccount(ADDRESS2); + assertThat(simpleWorld.getDeletedAccountAddresses().toArray()).containsExactly(ADDRESS2); + } + + @Test + void getDeletedAccountAddresses_allDeleted() { + simpleWorld.createAccount(ADDRESS1); + simpleWorld.createAccount(ADDRESS2); + simpleWorld.createAccount(ADDRESS3); + simpleWorld.deleteAccount(ADDRESS1); + simpleWorld.deleteAccount(ADDRESS2); + simpleWorld.deleteAccount(ADDRESS3); + assertThat(simpleWorld.getDeletedAccountAddresses().toArray()) + .containsExactlyInAnyOrder(ADDRESS1, ADDRESS2, ADDRESS3); + } + + @Test + void getDeletedAccountAddresses_allDeletedThenRevert() { + simpleWorld.createAccount(ADDRESS1); + simpleWorld.createAccount(ADDRESS2); + simpleWorld.createAccount(ADDRESS3); + simpleWorld.deleteAccount(ADDRESS1); + simpleWorld.deleteAccount(ADDRESS2); + simpleWorld.deleteAccount(ADDRESS3); + simpleWorld.revert(); + assertThat(simpleWorld.getDeletedAccountAddresses()).isEmpty(); + } + + @Test + void getDeletedAccountAddresses_allDeletedThenCommit() { + simpleWorld.createAccount(ADDRESS1); + simpleWorld.createAccount(ADDRESS2); + simpleWorld.createAccount(ADDRESS3); + simpleWorld.deleteAccount(ADDRESS1); + simpleWorld.deleteAccount(ADDRESS2); + simpleWorld.deleteAccount(ADDRESS3); + simpleWorld.commit(); + assertThat(simpleWorld.getDeletedAccountAddresses().toArray()) + .containsExactlyInAnyOrder(ADDRESS1, ADDRESS2, ADDRESS3); + } + + @Test + void commit_deletedAccountNoNPEs() { + simpleWorld.createAccount(ADDRESS1); + simpleWorld.createAccount(ADDRESS2); + simpleWorld.createAccount(ADDRESS3); + simpleWorld.deleteAccount(ADDRESS1); + simpleWorld.commit(); + } + + @Test + void commit_onlyCommitsNewAccountsToDirectParent() { + WorldUpdater simpleWorldLevel1 = simpleWorld.updater(); + WorldUpdater simpleWorldLevel2 = simpleWorldLevel1.updater(); + MutableAccount createdAccount = simpleWorldLevel2.createAccount(ADDRESS1); + simpleWorldLevel2.commit(); + assertThat(simpleWorldLevel1.getTouchedAccounts().toArray()).containsExactly(createdAccount); + assertThat(simpleWorld.getTouchedAccounts()).isEmpty(); + } + + @Test + void commit_onlyCommitsDeletedAccountsToDirectParent() { + WorldUpdater simpleWorldLevel1 = simpleWorld.updater(); + WorldUpdater simpleWorldLevel2 = simpleWorldLevel1.updater(); + simpleWorldLevel2.createAccount(ADDRESS2); + simpleWorldLevel2.deleteAccount(ADDRESS2); + simpleWorldLevel2.commit(); + assertThat(simpleWorldLevel1.getDeletedAccountAddresses().toArray()).containsExactly(ADDRESS2); + assertThat(simpleWorld.getDeletedAccountAddresses()).isEmpty(); + } + + @Test + void commit_accountsReflectChangesAfterCommit() { + MutableAccount account = simpleWorld.createAccount(ADDRESS1); + account.setStorageValue(UInt256.MAX_VALUE, UInt256.ONE); + WorldUpdater simpleWorldUpdater = simpleWorld.updater(); + + account = simpleWorldUpdater.getAccount(ADDRESS1); + account.setStorageValue(UInt256.MAX_VALUE, UInt256.valueOf(22L)); + simpleWorldUpdater.commit(); + + assertThat(simpleWorldUpdater.get(ADDRESS1).getStorageValue(UInt256.MAX_VALUE)) + .isEqualTo(simpleWorldUpdater.get(ADDRESS1).getOriginalStorageValue(UInt256.MAX_VALUE)); + } +} From d3705506b6278be9beb9f6a30ff32adb941112d5 Mon Sep 17 00:00:00 2001 From: Fabio Di Fabio Date: Mon, 2 Sep 2024 23:32:31 +0200 Subject: [PATCH 177/259] CI: new job to upload HTML test reports even if tests fail (#7555) Signed-off-by: Fabio Di Fabio --- .github/workflows/acceptance-tests.yml | 6 ++++++ .github/workflows/pre-review.yml | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/.github/workflows/acceptance-tests.yml b/.github/workflows/acceptance-tests.yml index 161d5d6da2..287f402bce 100644 --- a/.github/workflows/acceptance-tests.yml +++ b/.github/workflows/acceptance-tests.yml @@ -85,6 +85,12 @@ jobs: with: name: acceptance-node-${{matrix.runner_index}}-test-results path: 'acceptance-tests/tests/build/test-results/**/TEST-*.xml' + - name: Upload Acceptance Test HTML Reports + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 + if: success() || failure() + with: + name: acceptance-node-${{matrix.runner_index}}-test-html-reports + path: 'acceptance-tests/tests/build/reports/tests/**' accepttests-passed: name: "accepttests-passed" runs-on: ubuntu-22.04 diff --git a/.github/workflows/pre-review.yml b/.github/workflows/pre-review.yml index 0a5b3edf91..cba13f1ebd 100644 --- a/.github/workflows/pre-review.yml +++ b/.github/workflows/pre-review.yml @@ -141,6 +141,12 @@ jobs: with: name: unit-${{matrix.runner_index}}-test-results path: '**/test-results/**/TEST-*.xml' + - name: Upload Unit Test HTML Reports + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 + if: success() || failure() + with: + name: unit-${{matrix.runner_index}}-test-html-reports + path: '**/build/reports/tests/test/**' unittests-passed: name: "unittests-passed" runs-on: ubuntu-22.04 From 65240fdf4697a81824048d453a0d9818c37c2c3d Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Mon, 2 Sep 2024 16:06:19 -0600 Subject: [PATCH 178/259] Plumb maxCode overriddes into EVM (#7557) * Plumb maxCode overriddes into EVM Restore lost functionality: the maxcodesize and maxinitcodesize should be plumed into the operations and validation rules when set. Signed-off-by: Danno Ferrin --------- Signed-off-by: Danno Ferrin Co-authored-by: Sally MacFarlane --- CHANGELOG.md | 1 + .../ethereum/mainnet/MainnetProtocolSpecs.java | 6 +++--- .../ethereum/eof/EOFReferenceTestTools.java | 2 +- .../java/org/hyperledger/besu/evm/EVM.java | 18 ++++++++++++++++++ .../contractvalidation/MaxCodeSizeRule.java | 10 +++++++--- .../besu/evm/fluent/EVMExecutor.java | 17 +++++++++-------- .../evm/operation/AbstractCreateOperation.java | 2 +- .../evm/operation/ReturnContractOperation.java | 2 +- .../ContractCreationProcessorTest.java | 6 ++++-- 9 files changed, 45 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 798e534571..edaa050268 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ - Include current chain head block when computing `eth_maxPriorityFeePerGas` [#7485](https://github.com/hyperledger/besu/pull/7485) ### Bug fixes +- The genesis config override `contractSizeLimit` was not wired into code size limits [#7557](https://github.com/hyperledger/besu/issues/7557) ## 24.9.0 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 a96ca58fdd..ddc8b49b4f 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 @@ -650,7 +650,7 @@ public abstract class MainnetProtocolSpecs { TransactionType.FRONTIER, TransactionType.ACCESS_LIST, TransactionType.EIP1559), - evm.getEvmVersion().getMaxInitcodeSize())) + evm.getMaxInitcodeSize())) .withdrawalsProcessor(new WithdrawalsProcessor()) .withdrawalsValidator(new WithdrawalsValidator.AllowedWithdrawals()) .name("Shanghai"); @@ -730,7 +730,7 @@ public abstract class MainnetProtocolSpecs { TransactionType.ACCESS_LIST, TransactionType.EIP1559, TransactionType.BLOB), - evm.getEvmVersion().getMaxInitcodeSize())) + evm.getMaxInitcodeSize())) .precompileContractRegistryBuilder(MainnetPrecompiledContractRegistries::cancun) .blockHeaderValidatorBuilder(MainnetBlockHeaderValidator::cancunBlockHeaderValidator) .blockHashProcessor(new CancunBlockHashProcessor()) @@ -814,7 +814,7 @@ public abstract class MainnetProtocolSpecs { TransactionType.EIP1559, TransactionType.BLOB, TransactionType.SET_CODE), - evm.getEvmVersion().getMaxInitcodeSize())) + evm.getMaxInitcodeSize())) // EIP-2935 Blockhash processor .blockHashProcessor(new PragueBlockHashProcessor()) 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 3c0c2dbbb2..b5def9556d 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 @@ -124,7 +124,7 @@ public class EOFReferenceTestTools { // hardwire in the magic byte transaction checks if (evm.getMaxEOFVersion() < 1) { assertThat(expected.exception()).isEqualTo("EOF_InvalidCode"); - } else if (code.size() > evm.getEvmVersion().getMaxInitcodeSize()) { + } else if (code.size() > evm.getMaxInitcodeSize()) { // this check is in EOFCREATE and Transaction validator, but unit tests sniff it out. assertThat(false) .withFailMessage( diff --git a/evm/src/main/java/org/hyperledger/besu/evm/EVM.java b/evm/src/main/java/org/hyperledger/besu/evm/EVM.java index f2eb7cf29d..6957514392 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/EVM.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/EVM.java @@ -142,6 +142,24 @@ public class EVM { return evmSpecVersion.maxEofVersion; } + /** + * Gets the max code size, taking configuration and version into account + * + * @return The max code size override, if not set the max code size for the EVM version. + */ + public int getMaxCodeSize() { + return evmConfiguration.maxCodeSizeOverride().orElse(evmSpecVersion.maxCodeSize); + } + + /** + * Gets the max initcode Size, taking configuration and version into account + * + * @return The max initcode size override, if not set the max initcode size for the EVM version. + */ + public int getMaxInitcodeSize() { + return evmConfiguration.maxInitcodeSizeOverride().orElse(evmSpecVersion.maxInitcodeSize); + } + /** * Returns the non-fork related configuration parameters of the EVM. * diff --git a/evm/src/main/java/org/hyperledger/besu/evm/contractvalidation/MaxCodeSizeRule.java b/evm/src/main/java/org/hyperledger/besu/evm/contractvalidation/MaxCodeSizeRule.java index 794650a139..9fd7cb801d 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/contractvalidation/MaxCodeSizeRule.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/contractvalidation/MaxCodeSizeRule.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.evm.EVM; import org.hyperledger.besu.evm.EvmSpecVersion; import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; import org.hyperledger.besu.evm.frame.MessageFrame; +import org.hyperledger.besu.evm.internal.EvmConfiguration; import java.util.Optional; @@ -75,16 +76,19 @@ public class MaxCodeSizeRule implements ContractValidationRule { * @return the contract validation rule */ public static ContractValidationRule from(final EVM evm) { - return from(evm.getEvmVersion()); + return from(evm.getEvmVersion(), evm.getEvmConfiguration()); } /** * Fluent MaxCodeSizeRule from the EVM it is working with. * * @param evmspec The evm spec version to get the size rules from. + * @param evmConfiguration The evm configuration, including overrides * @return the contract validation rule */ - public static ContractValidationRule from(final EvmSpecVersion evmspec) { - return new MaxCodeSizeRule(evmspec.getMaxCodeSize()); + public static ContractValidationRule from( + final EvmSpecVersion evmspec, final EvmConfiguration evmConfiguration) { + return new MaxCodeSizeRule( + evmConfiguration.maxCodeSizeOverride().orElse(evmspec.getMaxCodeSize())); } } 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 a046198043..a182ae9454 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 @@ -77,7 +77,9 @@ public class EVMExecutor { private OperationTracer tracer = OperationTracer.NO_TRACING; private boolean requireDeposit = true; private List contractValidationRules = - List.of(MaxCodeSizeRule.from(EvmSpecVersion.SPURIOUS_DRAGON), PrefixCodeRule.of()); + List.of( + MaxCodeSizeRule.from(EvmSpecVersion.SPURIOUS_DRAGON, EvmConfiguration.DEFAULT), + PrefixCodeRule.of()); private long initialNonce = 1; private Collection
forceCommitAddresses = List.of(Address.fromHexString("0x03")); private Set
accessListWarmAddresses = new BytesTrieSet<>(Address.SIZE); @@ -241,8 +243,7 @@ public class EVMExecutor { final EVMExecutor executor = new EVMExecutor(MainnetEVMs.spuriousDragon(evmConfiguration)); executor.precompileContractRegistry = MainnetPrecompiledContracts.frontier(executor.evm.getGasCalculator()); - executor.contractValidationRules = - List.of(MaxCodeSizeRule.from(EvmSpecVersion.SPURIOUS_DRAGON)); + executor.contractValidationRules = List.of(MaxCodeSizeRule.from(executor.evm)); return executor; } @@ -256,7 +257,7 @@ public class EVMExecutor { final EVMExecutor executor = new EVMExecutor(MainnetEVMs.byzantium(evmConfiguration)); executor.precompileContractRegistry = MainnetPrecompiledContracts.byzantium(executor.evm.getGasCalculator()); - executor.contractValidationRules = List.of(MaxCodeSizeRule.from(EvmSpecVersion.BYZANTIUM)); + executor.contractValidationRules = List.of(MaxCodeSizeRule.from(executor.evm)); return executor; } @@ -270,7 +271,7 @@ public class EVMExecutor { final EVMExecutor executor = new EVMExecutor(MainnetEVMs.constantinople(evmConfiguration)); executor.precompileContractRegistry = MainnetPrecompiledContracts.byzantium(executor.evm.getGasCalculator()); - executor.contractValidationRules = List.of(MaxCodeSizeRule.from(EvmSpecVersion.CONSTANTINOPLE)); + executor.contractValidationRules = List.of(MaxCodeSizeRule.from(executor.evm)); return executor; } @@ -284,7 +285,7 @@ public class EVMExecutor { final EVMExecutor executor = new EVMExecutor(MainnetEVMs.petersburg(evmConfiguration)); executor.precompileContractRegistry = MainnetPrecompiledContracts.byzantium(executor.evm.getGasCalculator()); - executor.contractValidationRules = List.of(MaxCodeSizeRule.from(EvmSpecVersion.PETERSBURG)); + executor.contractValidationRules = List.of(MaxCodeSizeRule.from(executor.evm)); return executor; } @@ -319,7 +320,7 @@ public class EVMExecutor { final EVMExecutor executor = new EVMExecutor(MainnetEVMs.istanbul(chainId, evmConfiguration)); executor.precompileContractRegistry = MainnetPrecompiledContracts.istanbul(executor.evm.getGasCalculator()); - executor.contractValidationRules = List.of(MaxCodeSizeRule.from(EvmSpecVersion.ISTANBUL)); + executor.contractValidationRules = List.of(MaxCodeSizeRule.from(executor.evm)); return executor; } @@ -354,7 +355,7 @@ public class EVMExecutor { final EVMExecutor executor = new EVMExecutor(MainnetEVMs.berlin(chainId, evmConfiguration)); executor.precompileContractRegistry = MainnetPrecompiledContracts.istanbul(executor.evm.getGasCalculator()); - executor.contractValidationRules = List.of(MaxCodeSizeRule.from(EvmSpecVersion.BERLIN)); + executor.contractValidationRules = List.of(MaxCodeSizeRule.from(executor.evm)); return executor; } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCreateOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCreateOperation.java index 3a78016f2d..5d9bea61ce 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCreateOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCreateOperation.java @@ -97,7 +97,7 @@ public abstract class AbstractCreateOperation extends AbstractOperation { Code code = codeSupplier.get(); - if (code != null && code.getSize() > evm.getEvmVersion().getMaxInitcodeSize()) { + if (code != null && code.getSize() > evm.getMaxInitcodeSize()) { frame.popStackItems(getStackItemsConsumed()); return new OperationResult(cost, ExceptionalHaltReason.CODE_TOO_LARGE); } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/ReturnContractOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/ReturnContractOperation.java index 9789580076..2860c93795 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/ReturnContractOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/ReturnContractOperation.java @@ -64,7 +64,7 @@ public class ReturnContractOperation extends AbstractOperation { } Bytes auxData = frame.readMemory(from, length); - if (code.getDataSize() + auxData.size() > evm.getEvmVersion().getMaxCodeSize()) { + if (code.getDataSize() + auxData.size() > evm.getMaxCodeSize()) { return new OperationResult(cost, ExceptionalHaltReason.CODE_TOO_LARGE); } if (code.getDataSize() + auxData.size() < code.getDeclaredDataSize()) { 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 40ef063db1..3420df88dc 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 @@ -206,7 +206,8 @@ class ContractCreationProcessorTest new ContractCreationProcessor( evm, true, - Collections.singletonList(MaxCodeSizeRule.from(EvmSpecVersion.SPURIOUS_DRAGON)), + Collections.singletonList( + MaxCodeSizeRule.from(EvmSpecVersion.SPURIOUS_DRAGON, EvmConfiguration.DEFAULT)), 1, Collections.emptyList()); final Bytes contractCode = @@ -227,7 +228,8 @@ class ContractCreationProcessorTest new ContractCreationProcessor( evm, true, - Collections.singletonList(MaxCodeSizeRule.from(EvmSpecVersion.SPURIOUS_DRAGON)), + Collections.singletonList( + MaxCodeSizeRule.from(EvmSpecVersion.SPURIOUS_DRAGON, EvmConfiguration.DEFAULT)), 1, Collections.emptyList()); final Bytes contractCode = From d5c10e2b4eb182a039ef2b8c0324416c045f99d1 Mon Sep 17 00:00:00 2001 From: Justin Florentine Date: Tue, 3 Sep 2024 12:43:51 -0400 Subject: [PATCH 179/259] Dagger controller tests (#7567) Separate out flex group privacy test since it requires differently configured dependencies. test specific, inline module/component definitions reusable module for providing mockable enclaves, besu commands, and genesis dagger support for transaction simulation dagger support for plugin setup --------- Signed-off-by: jflo Signed-off-by: Justin Florentine --- .../perm/AllowListContainsKeyAndValue.java | 6 + .../dsl/node/ThreadBesuNodeRunner.java | 553 ++++++++++++------ .../acceptance/dsl/privacy/PrivacyNode.java | 2 +- ...ClusterThreadNodeRunnerAcceptanceTest.java | 2 +- besu/build.gradle | 2 + .../controller/BesuControllerBuilder.java | 1 + .../services/PermissioningServiceImpl.java | 2 + .../services/SecurityModuleServiceImpl.java | 7 +- .../besu/services/StorageServiceImpl.java | 2 + .../TransactionSelectionServiceImpl.java | 4 +- .../besu/FlexGroupPrivacyTest.java | 168 ++++++ .../hyperledger/besu/PrivacyReorgTest.java | 151 +++-- .../org/hyperledger/besu/PrivacyTest.java | 171 +++--- .../java/org/hyperledger/besu/RunnerTest.java | 3 + .../chainexport/RlpBlockExporterTest.java | 3 + .../chainimport/JsonBlockImporterTest.java | 3 + .../chainimport/RlpBlockImporterTest.java | 5 + .../besu/components/EnclaveModule.java | 98 ++++ .../besu/components/GenesisConfigModule.java | 38 ++ .../components/MockBesuCommandModule.java | 50 ++ .../components/NoOpMetricsSystemModule.java | 40 ++ .../components/PrivacyParametersModule.java | 47 ++ .../besu/components/PrivacyTestModule.java | 111 ++++ .../AbstractBftBesuControllerBuilderTest.java | 2 + .../CliqueBesuControllerBuilderTest.java | 2 + .../MergeBesuControllerBuilderTest.java | 2 + .../besu/ethereum/p2p/peers/EnodeURLImpl.java | 13 +- 27 files changed, 1167 insertions(+), 321 deletions(-) create mode 100644 besu/src/test/java/org/hyperledger/besu/FlexGroupPrivacyTest.java create mode 100644 besu/src/test/java/org/hyperledger/besu/components/EnclaveModule.java create mode 100644 besu/src/test/java/org/hyperledger/besu/components/GenesisConfigModule.java create mode 100644 besu/src/test/java/org/hyperledger/besu/components/MockBesuCommandModule.java create mode 100644 besu/src/test/java/org/hyperledger/besu/components/NoOpMetricsSystemModule.java create mode 100644 besu/src/test/java/org/hyperledger/besu/components/PrivacyParametersModule.java create mode 100644 besu/src/test/java/org/hyperledger/besu/components/PrivacyTestModule.java diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/perm/AllowListContainsKeyAndValue.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/perm/AllowListContainsKeyAndValue.java index a2ffc9b36d..0913fd227f 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/perm/AllowListContainsKeyAndValue.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/perm/AllowListContainsKeyAndValue.java @@ -24,11 +24,16 @@ import org.hyperledger.besu.tests.acceptance.dsl.node.Node; import java.nio.file.Path; import java.util.Collection; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + public class AllowListContainsKeyAndValue implements Condition { private final ALLOWLIST_TYPE allowlistType; private final Collection allowlistValues; private final Path configFilePath; + private static final Logger LOG = LoggerFactory.getLogger(AllowListContainsKeyAndValue.class); + public AllowListContainsKeyAndValue( final ALLOWLIST_TYPE allowlistType, final Collection allowlistValues, @@ -47,6 +52,7 @@ public class AllowListContainsKeyAndValue implements Condition { allowlistType, allowlistValues, configFilePath); } catch (final Exception e) { result = false; + LOG.error("Error verifying allowlist contains key and value", e); } assertThat(result).isTrue(); } 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 f28a1d8876..0177790831 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 @@ -1,5 +1,5 @@ /* - * Copyright ConsenSys AG. + * 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 @@ -18,8 +18,13 @@ import static org.hyperledger.besu.controller.BesuController.DATABASE_PATH; import org.hyperledger.besu.Runner; import org.hyperledger.besu.RunnerBuilder; +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.config.EthNetworkConfig; import org.hyperledger.besu.cli.config.NetworkName; +import org.hyperledger.besu.components.BesuComponent; import org.hyperledger.besu.config.GenesisConfigFile; import org.hyperledger.besu.controller.BesuController; import org.hyperledger.besu.controller.BesuControllerBuilder; @@ -30,23 +35,32 @@ import org.hyperledger.besu.ethereum.GasLimitCalculator; import org.hyperledger.besu.ethereum.api.ApiConfiguration; import org.hyperledger.besu.ethereum.api.graphql.GraphQLConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.InProcessRpcConfiguration; +import org.hyperledger.besu.ethereum.chain.Blockchain; import org.hyperledger.besu.ethereum.core.ImmutableMiningParameters; +import org.hyperledger.besu.ethereum.core.MiningParameters; import org.hyperledger.besu.ethereum.core.plugins.PluginConfiguration; import org.hyperledger.besu.ethereum.eth.EthProtocolConfiguration; import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration; +import org.hyperledger.besu.ethereum.eth.transactions.BlobCacheModule; import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration; +import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.p2p.peers.EnodeURLImpl; 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.trie.diffbased.bonsai.cache.BonsaiCachedMerkleTrieLoaderModule; +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.MetricsSystemFactory; +import org.hyperledger.besu.metrics.MetricsSystemModule; import org.hyperledger.besu.metrics.ObservableMetricsSystem; +import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration; import org.hyperledger.besu.plugin.data.EnodeURL; import org.hyperledger.besu.plugin.services.BesuConfiguration; import org.hyperledger.besu.plugin.services.BesuEvents; import org.hyperledger.besu.plugin.services.BlockchainService; +import org.hyperledger.besu.plugin.services.MetricsSystem; import org.hyperledger.besu.plugin.services.PermissioningService; import org.hyperledger.besu.plugin.services.PicoCLIOptions; import org.hyperledger.besu.plugin.services.PrivacyPluginService; @@ -70,6 +84,7 @@ import org.hyperledger.besu.services.StorageServiceImpl; 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 java.io.File; import java.nio.file.Path; @@ -78,9 +93,15 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; -import java.util.stream.Collectors; +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; +import dagger.Component; +import dagger.Module; +import dagger.Provides; import io.opentelemetry.api.GlobalOpenTelemetry; import io.vertx.core.Vertx; import org.slf4j.Logger; @@ -96,60 +117,6 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner { private final Map besuPluginContextMap = new ConcurrentHashMap<>(); - private BesuPluginContextImpl buildPluginContext( - final BesuNode node, - final StorageServiceImpl storageService, - final SecurityModuleServiceImpl securityModuleService, - final TransactionSimulationServiceImpl transactionSimulationServiceImpl, - final TransactionSelectionServiceImpl transactionSelectionServiceImpl, - final TransactionPoolValidatorServiceImpl transactionPoolValidatorServiceImpl, - final BlockchainServiceImpl blockchainServiceImpl, - final RpcEndpointServiceImpl rpcEndpointServiceImpl, - final BesuConfiguration commonPluginConfiguration, - final PermissioningServiceImpl permissioningService) { - final CommandLine commandLine = new CommandLine(CommandSpec.create()); - final BesuPluginContextImpl besuPluginContext = new BesuPluginContextImpl(); - besuPluginContext.addService(StorageService.class, storageService); - besuPluginContext.addService(SecurityModuleService.class, securityModuleService); - besuPluginContext.addService(PicoCLIOptions.class, new PicoCLIOptionsImpl(commandLine)); - besuPluginContext.addService(RpcEndpointService.class, rpcEndpointServiceImpl); - besuPluginContext.addService( - TransactionSelectionService.class, transactionSelectionServiceImpl); - besuPluginContext.addService( - TransactionPoolValidatorService.class, transactionPoolValidatorServiceImpl); - besuPluginContext.addService( - TransactionSimulationService.class, transactionSimulationServiceImpl); - besuPluginContext.addService(BlockchainService.class, blockchainServiceImpl); - besuPluginContext.addService(BesuConfiguration.class, commonPluginConfiguration); - - final Path pluginsPath; - final String pluginDir = System.getProperty("besu.plugins.dir"); - if (pluginDir == null || pluginDir.isEmpty()) { - pluginsPath = node.homeDirectory().resolve("plugins"); - final File pluginsDirFile = pluginsPath.toFile(); - if (!pluginsDirFile.isDirectory()) { - pluginsDirFile.mkdirs(); - pluginsDirFile.deleteOnExit(); - } - System.setProperty("besu.plugins.dir", pluginsPath.toString()); - } else { - pluginsPath = Path.of(pluginDir); - } - - besuPluginContext.addService(BesuConfiguration.class, commonPluginConfiguration); - besuPluginContext.addService(PermissioningService.class, permissioningService); - besuPluginContext.addService(PrivacyPluginService.class, new PrivacyPluginServiceImpl()); - - besuPluginContext.registerPlugins( - new PluginConfiguration.Builder().pluginsDir(pluginsPath).build()); - - commandLine.parseArgs(node.getConfiguration().getExtraCLIOptions().toArray(new String[0])); - - // register built-in plugins - new RocksDBPlugin().register(besuPluginContext); - return besuPluginContext; - } - @Override public void startNode(final BesuNode node) { @@ -162,114 +129,45 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner { throw new UnsupportedOperationException("commands are not supported with thread runner"); } - final StorageServiceImpl storageService = new StorageServiceImpl(); - final SecurityModuleServiceImpl securityModuleService = new SecurityModuleServiceImpl(); - final TransactionSimulationServiceImpl transactionSimulationServiceImpl = - new TransactionSimulationServiceImpl(); - final TransactionSelectionServiceImpl transactionSelectionServiceImpl = - new TransactionSelectionServiceImpl(); - final TransactionPoolValidatorServiceImpl transactionPoolValidatorServiceImpl = - new TransactionPoolValidatorServiceImpl(); - final BlockchainServiceImpl blockchainServiceImpl = new BlockchainServiceImpl(); - final RpcEndpointServiceImpl rpcEndpointServiceImpl = new RpcEndpointServiceImpl(); - final Path dataDir = node.homeDirectory(); - final BesuConfigurationImpl commonPluginConfiguration = new BesuConfigurationImpl(); - final PermissioningServiceImpl permissioningService = new PermissioningServiceImpl(); - - final var miningParameters = - ImmutableMiningParameters.builder() - .from(node.getMiningParameters()) - .transactionSelectionService(transactionSelectionServiceImpl) + BesuNodeProviderModule module = new BesuNodeProviderModule(node); + AcceptanceTestBesuComponent component = + DaggerThreadBesuNodeRunner_AcceptanceTestBesuComponent.builder() + .besuNodeProviderModule(module) .build(); - commonPluginConfiguration - .init(dataDir, dataDir.resolve(DATABASE_PATH), node.getDataStorageConfiguration()) - .withMiningParameters(miningParameters); - final BesuPluginContextImpl besuPluginContext = - besuPluginContextMap.computeIfAbsent( - node, - n -> - buildPluginContext( - node, - storageService, - securityModuleService, - transactionSimulationServiceImpl, - transactionSelectionServiceImpl, - transactionPoolValidatorServiceImpl, - blockchainServiceImpl, - rpcEndpointServiceImpl, - commonPluginConfiguration, - permissioningService)); + final Path dataDir = node.homeDirectory(); + final PermissioningServiceImpl permissioningService = new PermissioningServiceImpl(); GlobalOpenTelemetry.resetForTest(); - final ObservableMetricsSystem metricsSystem = - MetricsSystemFactory.create(node.getMetricsConfiguration()); + final ObservableMetricsSystem metricsSystem = component.getObservableMetricsSystem(); final List bootnodes = - node.getConfiguration().getBootnodes().stream() - .map(EnodeURLImpl::fromURI) - .collect(Collectors.toList()); - final NetworkName network = node.getNetwork() == null ? NetworkName.DEV : node.getNetwork(); - final EthNetworkConfig.Builder networkConfigBuilder = - new EthNetworkConfig.Builder(EthNetworkConfig.getNetworkConfig(network)) - .setBootNodes(bootnodes); + node.getConfiguration().getBootnodes().stream().map(EnodeURLImpl::fromURI).toList(); + + final EthNetworkConfig.Builder networkConfigBuilder = component.ethNetworkConfigBuilder(); + networkConfigBuilder.setBootNodes(bootnodes); node.getConfiguration() .getGenesisConfig() .map(GenesisConfigFile::fromConfig) .ifPresent(networkConfigBuilder::setGenesisConfigFile); final EthNetworkConfig ethNetworkConfig = networkConfigBuilder.build(); - final SynchronizerConfiguration synchronizerConfiguration = - new SynchronizerConfiguration.Builder().build(); - final BesuControllerBuilder builder = - new BesuController.Builder() - .fromEthNetworkConfig(ethNetworkConfig, synchronizerConfiguration.getSyncMode()); - - final KeyValueStorageProvider storageProvider = - new KeyValueStorageProviderBuilder() - .withStorageFactory(storageService.getByName("rocksdb").get()) - .withCommonConfiguration(commonPluginConfiguration) - .withMetricsSystem(metricsSystem) - .build(); + final BesuControllerBuilder builder = component.besuControllerBuilder(); + builder.isRevertReasonEnabled(node.isRevertReasonEnabled()); + builder.networkConfiguration(node.getNetworkingConfiguration()); - final TransactionPoolConfiguration txPoolConfig = - ImmutableTransactionPoolConfiguration.builder() - .from(node.getTransactionPoolConfiguration()) - .strictTransactionReplayProtectionEnabled(node.isStrictTxReplayProtectionEnabled()) - .transactionPoolValidatorService(transactionPoolValidatorServiceImpl) - .build(); - - final InProcessRpcConfiguration inProcessRpcConfiguration = node.inProcessRpcConfiguration(); - - final int maxPeers = 25; - - builder - .synchronizerConfiguration(new SynchronizerConfiguration.Builder().build()) - .dataDirectory(node.homeDirectory()) - .miningParameters(miningParameters) - .privacyParameters(node.getPrivacyParameters()) - .nodeKey(new NodeKey(new KeyPairSecurityModule(KeyPairUtil.loadKeyPair(dataDir)))) - .metricsSystem(metricsSystem) - .transactionPoolConfiguration(txPoolConfig) - .dataStorageConfiguration(node.getDataStorageConfiguration()) - .ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig()) - .clock(Clock.systemUTC()) - .isRevertReasonEnabled(node.isRevertReasonEnabled()) - .storageProvider(storageProvider) - .gasLimitCalculator(GasLimitCalculator.constant()) - .evmConfiguration(EvmConfiguration.DEFAULT) - .maxPeers(maxPeers) - .maxRemotelyInitiatedPeers(15) - .networkConfiguration(node.getNetworkingConfiguration()) - .randomPeerPriority(false); + builder.dataDirectory(dataDir); + builder.nodeKey(new NodeKey(new KeyPairSecurityModule(KeyPairUtil.loadKeyPair(dataDir)))); + builder.privacyParameters(node.getPrivacyParameters()); node.getGenesisConfig() .map(GenesisConfigFile::fromConfig) .ifPresent(builder::genesisConfigFile); - final BesuController besuController = builder.build(); + final BesuController besuController = component.besuController(); + + InProcessRpcConfiguration inProcessRpcConfiguration = node.inProcessRpcConfiguration(); - initTransactionSimulationService( - transactionSimulationServiceImpl, besuController, node.getApiConfiguration()); - initBlockchainService(blockchainServiceImpl, besuController); + final BesuPluginContextImpl besuPluginContext = + besuPluginContextMap.computeIfAbsent(node, n -> component.getBesuPluginContext()); final RunnerBuilder runnerBuilder = new RunnerBuilder(); runnerBuilder.permissioningConfiguration(node.getPermissioningConfiguration()); @@ -293,17 +191,13 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner { .p2pEnabled(node.isP2pEnabled()) .p2pTLSConfiguration(node.getTLSConfiguration()) .graphQLConfiguration(GraphQLConfiguration.createDefault()) - .staticNodes( - node.getStaticNodes().stream() - .map(EnodeURLImpl::fromString) - .collect(Collectors.toList())) + .staticNodes(node.getStaticNodes().stream().map(EnodeURLImpl::fromString).toList()) .besuPluginContext(besuPluginContext) .autoLogBloomCaching(false) - .storageProvider(storageProvider) - .rpcEndpointService(rpcEndpointServiceImpl) + .storageProvider(besuController.getStorageProvider()) + .rpcEndpointService(component.rpcEndpointService()) .inProcessRpcConfiguration(inProcessRpcConfiguration); node.engineRpcConfiguration().ifPresent(runnerBuilder::engineJsonRpcConfiguration); - besuPluginContext.beforeExternalServices(); final Runner runner = runnerBuilder.build(); @@ -318,7 +212,7 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner { besuController.getSyncState(), besuController.getProtocolContext().getBadBlockManager())); - rpcEndpointServiceImpl.init(runner.getInProcessRpcMethods()); + component.rpcEndpointService().init(runner.getInProcessRpcMethods()); besuPluginContext.startPlugins(); @@ -328,25 +222,6 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner { MDC.remove("node"); } - private void initBlockchainService( - final BlockchainServiceImpl blockchainServiceImpl, final BesuController besuController) { - blockchainServiceImpl.init( - besuController.getProtocolContext(), besuController.getProtocolSchedule()); - } - - private void initTransactionSimulationService( - final TransactionSimulationServiceImpl transactionSimulationService, - final BesuController besuController, - final ApiConfiguration apiConfiguration) { - transactionSimulationService.init( - besuController.getProtocolContext().getBlockchain(), - new TransactionSimulator( - besuController.getProtocolContext().getBlockchain(), - besuController.getProtocolContext().getWorldStateArchive(), - besuController.getProtocolSchedule(), - apiConfiguration.getGasCap())); - } - @Override public void stopNode(final BesuNode node) { final BesuPluginContextImpl pluginContext = besuPluginContextMap.remove(node); @@ -396,4 +271,332 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner { public String getConsoleContents() { throw new RuntimeException("Console contents can only be captured in process execution"); } + + @Module + static class BesuNodeProviderModule { + + private final BesuNode toProvide; + + public BesuNodeProviderModule(final BesuNode toProvide) { + this.toProvide = toProvide; + } + + @Provides + public BesuNode provideBesuNodeRunner() { + return toProvide; + } + + @Provides + @Named("ExtraCLIOptions") + public List provideExtraCLIOptions() { + return toProvide.getExtraCLIOptions(); + } + + @Provides + Path provideDataDir() { + return toProvide.homeDirectory(); + } + + @Provides + @Singleton + RpcEndpointServiceImpl provideRpcEndpointService() { + return new RpcEndpointServiceImpl(); + } + + @Provides + @Singleton + BlockchainServiceImpl provideBlockchainService(final BesuController besuController) { + BlockchainServiceImpl retval = new BlockchainServiceImpl(); + retval.init(besuController.getProtocolContext(), besuController.getProtocolSchedule()); + return retval; + } + + @Provides + @Singleton + Blockchain provideBlockchain(final BesuController besuController) { + return besuController.getProtocolContext().getBlockchain(); + } + + @Provides + @SuppressWarnings("CloseableProvides") + WorldStateArchive provideWorldStateArchive(final BesuController besuController) { + return besuController.getProtocolContext().getWorldStateArchive(); + } + + @Provides + ProtocolSchedule provideProtocolSchedule(final BesuController besuController) { + return besuController.getProtocolSchedule(); + } + + @Provides + ApiConfiguration provideApiConfiguration(final BesuNode node) { + return node.getApiConfiguration(); + } + + @Provides + @Singleton + TransactionPoolValidatorServiceImpl provideTransactionPoolValidatorService() { + return new TransactionPoolValidatorServiceImpl(); + } + + @Provides + @Singleton + TransactionSelectionServiceImpl provideTransactionSelectionService() { + return new TransactionSelectionServiceImpl(); + } + + @Provides + @Singleton + TransactionPoolConfiguration provideTransactionPoolConfiguration( + final BesuNode node, + final TransactionPoolValidatorServiceImpl transactionPoolValidatorServiceImpl) { + + TransactionPoolConfiguration txPoolConfig = + ImmutableTransactionPoolConfiguration.builder() + .from(node.getTransactionPoolConfiguration()) + .strictTransactionReplayProtectionEnabled(node.isStrictTxReplayProtectionEnabled()) + .transactionPoolValidatorService(transactionPoolValidatorServiceImpl) + .build(); + return txPoolConfig; + } + + @Provides + @Singleton + TransactionSimulator provideTransactionSimulator( + final Blockchain blockchain, + final WorldStateArchive worldStateArchive, + final ProtocolSchedule protocolSchedule, + final ApiConfiguration apiConfiguration) { + return new TransactionSimulator( + blockchain, worldStateArchive, protocolSchedule, apiConfiguration.getGasCap()); + } + + @Provides + @Singleton + TransactionSimulationServiceImpl provideTransactionSimulationService( + final Blockchain blockchain, final TransactionSimulator transactionSimulator) { + TransactionSimulationServiceImpl retval = new TransactionSimulationServiceImpl(); + retval.init(blockchain, transactionSimulator); + return retval; + } + } + + @Module + @SuppressWarnings("CloseableProvides") + static class BesuControllerModule { + @Provides + @Singleton + public SynchronizerConfiguration provideSynchronizationConfiguration() { + final SynchronizerConfiguration synchronizerConfiguration = + SynchronizerConfiguration.builder().build(); + return synchronizerConfiguration; + } + + @Singleton + @Provides + public BesuControllerBuilder provideBesuControllerBuilder( + final EthNetworkConfig ethNetworkConfig, + final SynchronizerConfiguration synchronizerConfiguration, + final TransactionPoolConfiguration transactionPoolConfiguration) { + + final BesuControllerBuilder builder = + new BesuController.Builder() + .fromEthNetworkConfig(ethNetworkConfig, synchronizerConfiguration.getSyncMode()); + builder.transactionPoolConfiguration(transactionPoolConfiguration); + return builder; + } + + @Provides + @Singleton + public BesuController provideBesuController( + final SynchronizerConfiguration synchronizerConfiguration, + final BesuControllerBuilder builder, + final ObservableMetricsSystem metricsSystem, + final KeyValueStorageProvider storageProvider, + final MiningParameters miningParameters) { + + builder + .synchronizerConfiguration(synchronizerConfiguration) + .metricsSystem(metricsSystem) + .dataStorageConfiguration(DataStorageConfiguration.DEFAULT_FOREST_CONFIG) + .ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig()) + .clock(Clock.systemUTC()) + .storageProvider(storageProvider) + .gasLimitCalculator(GasLimitCalculator.constant()) + .evmConfiguration(EvmConfiguration.DEFAULT) + .maxPeers(25) + .maxRemotelyInitiatedPeers(15) + .miningParameters(miningParameters) + .randomPeerPriority(false) + .besuComponent(null); + return builder.build(); + } + + @Provides + @Singleton + public EthNetworkConfig.Builder provideEthNetworkConfigBuilder() { + final EthNetworkConfig.Builder networkConfigBuilder = + new EthNetworkConfig.Builder(EthNetworkConfig.getNetworkConfig(NetworkName.DEV)); + return networkConfigBuilder; + } + + @Provides + public EthNetworkConfig provideEthNetworkConfig( + final EthNetworkConfig.Builder networkConfigBuilder) { + + final EthNetworkConfig ethNetworkConfig = networkConfigBuilder.build(); + return ethNetworkConfig; + } + + @Provides + @Named("besuPluginContext") + public BesuPluginContextImpl providePluginContext( + final StorageServiceImpl storageService, + final SecurityModuleServiceImpl securityModuleService, + final TransactionSimulationServiceImpl transactionSimulationServiceImpl, + final TransactionSelectionServiceImpl transactionSelectionServiceImpl, + final TransactionPoolValidatorServiceImpl transactionPoolValidatorServiceImpl, + final BlockchainServiceImpl blockchainServiceImpl, + final RpcEndpointServiceImpl rpcEndpointServiceImpl, + final BesuConfiguration commonPluginConfiguration, + final PermissioningServiceImpl permissioningService, + final @Named("ExtraCLIOptions") List extraCLIOptions) { + final CommandLine commandLine = new CommandLine(CommandSpec.create()); + final BesuPluginContextImpl besuPluginContext = new BesuPluginContextImpl(); + besuPluginContext.addService(StorageService.class, storageService); + besuPluginContext.addService(SecurityModuleService.class, securityModuleService); + besuPluginContext.addService(PicoCLIOptions.class, new PicoCLIOptionsImpl(commandLine)); + besuPluginContext.addService(RpcEndpointService.class, rpcEndpointServiceImpl); + besuPluginContext.addService( + TransactionSelectionService.class, transactionSelectionServiceImpl); + besuPluginContext.addService( + TransactionPoolValidatorService.class, transactionPoolValidatorServiceImpl); + besuPluginContext.addService( + TransactionSimulationService.class, transactionSimulationServiceImpl); + besuPluginContext.addService(BlockchainService.class, blockchainServiceImpl); + besuPluginContext.addService(BesuConfiguration.class, commonPluginConfiguration); + + final Path pluginsPath; + final String pluginDir = System.getProperty("besu.plugins.dir"); + if (pluginDir == null || pluginDir.isEmpty()) { + pluginsPath = commonPluginConfiguration.getDataPath().resolve("plugins"); + final File pluginsDirFile = pluginsPath.toFile(); + if (!pluginsDirFile.isDirectory()) { + pluginsDirFile.mkdirs(); + pluginsDirFile.deleteOnExit(); + } + System.setProperty("besu.plugins.dir", pluginsPath.toString()); + } else { + pluginsPath = Path.of(pluginDir); + } + + besuPluginContext.addService(BesuConfiguration.class, commonPluginConfiguration); + besuPluginContext.addService(PermissioningService.class, permissioningService); + besuPluginContext.addService(PrivacyPluginService.class, new PrivacyPluginServiceImpl()); + + besuPluginContext.registerPlugins( + new PluginConfiguration.Builder().pluginsDir(pluginsPath).build()); + commandLine.parseArgs(extraCLIOptions.toArray(new String[0])); + + // register built-in plugins + new RocksDBPlugin().register(besuPluginContext); + return besuPluginContext; + } + + @Provides + public KeyValueStorageProvider provideKeyValueStorageProvider( + final BesuConfiguration commonPluginConfiguration, final MetricsSystem metricsSystem) { + + final StorageServiceImpl storageService = new StorageServiceImpl(); + storageService.registerKeyValueStorage( + new InMemoryStoragePlugin.InMemoryKeyValueStorageFactory("memory")); + final KeyValueStorageProvider storageProvider = + new KeyValueStorageProviderBuilder() + .withStorageFactory(storageService.getByName("memory").get()) + .withCommonConfiguration(commonPluginConfiguration) + .withMetricsSystem(metricsSystem) + .build(); + + return storageProvider; + } + + @Provides + public MiningParameters provideMiningParameters( + final TransactionSelectionServiceImpl transactionSelectionServiceImpl, + final BesuNode node) { + final var miningParameters = + ImmutableMiningParameters.builder() + .from(node.getMiningParameters()) + .transactionSelectionService(transactionSelectionServiceImpl) + .build(); + + return miningParameters; + } + + @Provides + @Inject + BesuConfiguration provideBesuConfiguration( + final Path dataDir, final MiningParameters miningParameters, final BesuNode node) { + final BesuConfigurationImpl commonPluginConfiguration = new BesuConfigurationImpl(); + commonPluginConfiguration.init( + dataDir, dataDir.resolve(DATABASE_PATH), node.getDataStorageConfiguration()); + commonPluginConfiguration.withMiningParameters(miningParameters); + return commonPluginConfiguration; + } + } + + @Module + static class MockBesuCommandModule { + + @Provides + BesuCommand provideBesuCommand(final AcceptanceTestBesuComponent component) { + final BesuCommand besuCommand = + new BesuCommand( + component, + RlpBlockImporter::new, + JsonBlockImporter::new, + RlpBlockExporter::new, + new RunnerBuilder(), + new BesuController.Builder(), + Optional.ofNullable(component.getBesuPluginContext()).orElse(null), + System.getenv()); + besuCommand.toCommandLine(); + return besuCommand; + } + + @Provides + @Singleton + MetricsConfiguration provideMetricsConfiguration() { + return MetricsConfiguration.builder().build(); + } + + @Provides + @Named("besuCommandLogger") + @Singleton + Logger provideBesuCommandLogger() { + return LoggerFactory.getLogger(MockBesuCommandModule.class); + } + } + + @Singleton + @Component( + modules = { + ThreadBesuNodeRunner.BesuControllerModule.class, + ThreadBesuNodeRunner.MockBesuCommandModule.class, + BonsaiCachedMerkleTrieLoaderModule.class, + MetricsSystemModule.class, + ThreadBesuNodeRunner.BesuNodeProviderModule.class, + BlobCacheModule.class + }) + public interface AcceptanceTestBesuComponent extends BesuComponent { + BesuController besuController(); + + BesuControllerBuilder besuControllerBuilder(); // TODO: needing this sucks + + EthNetworkConfig.Builder ethNetworkConfigBuilder(); + + RpcEndpointServiceImpl rpcEndpointService(); + + BlockchainServiceImpl blockchainService(); + } } diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/PrivacyNode.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/PrivacyNode.java index 520cd7d574..d54bf90872 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/PrivacyNode.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/PrivacyNode.java @@ -276,7 +276,7 @@ public class PrivacyNode implements AutoCloseable { final Path dataLocation, final Path dbLocation) { final var besuConfiguration = new BesuConfigurationImpl(); besuConfiguration - .init(dataLocation, dbLocation, null) + .init(dataLocation, dbLocation, besuConfig.getDataStorageConfiguration()) .withMiningParameters(besuConfig.getMiningParameters()); return new PrivacyKeyValueStorageProviderBuilder() .withStorageFactory( diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bootstrap/ClusterThreadNodeRunnerAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bootstrap/ClusterThreadNodeRunnerAcceptanceTest.java index 8fbd0d3d62..39cc5ad26f 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bootstrap/ClusterThreadNodeRunnerAcceptanceTest.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bootstrap/ClusterThreadNodeRunnerAcceptanceTest.java @@ -38,7 +38,7 @@ public class ClusterThreadNodeRunnerAcceptanceTest extends AcceptanceTestBase { final BesuNodeRunner besuNodeRunner = new ThreadBesuNodeRunner(); noDiscoveryCluster = new Cluster(clusterConfiguration, net, besuNodeRunner); final BesuNode noDiscoveryNode = besu.createNodeWithNoDiscovery("noDiscovery"); - fullNode = besu.createArchiveNode("node2"); + fullNode = besu.createArchiveNode("archive"); noDiscoveryCluster.start(noDiscoveryNode, fullNode); } diff --git a/besu/build.gradle b/besu/build.gradle index a0e6c7843f..fa2b0548c5 100644 --- a/besu/build.gradle +++ b/besu/build.gradle @@ -105,6 +105,8 @@ dependencies { testImplementation 'org.mockito:mockito-core' testImplementation 'org.testcontainers:testcontainers' testImplementation 'tech.pegasys.discovery:discovery' + testImplementation 'com.google.dagger:dagger' annotationProcessor 'com.google.dagger:dagger-compiler' + testAnnotationProcessor 'com.google.dagger:dagger-compiler' } 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 ddb75fcded..6bb3fb117c 100644 --- a/besu/src/main/java/org/hyperledger/besu/controller/BesuControllerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/controller/BesuControllerBuilder.java @@ -552,6 +552,7 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides checkNotNull(evmConfiguration, "Missing evm config"); checkNotNull(networkingConfiguration, "Missing network configuration"); checkNotNull(dataStorageConfiguration, "Missing data storage configuration"); + prepForBuild(); final ProtocolSchedule protocolSchedule = createProtocolSchedule(); diff --git a/besu/src/main/java/org/hyperledger/besu/services/PermissioningServiceImpl.java b/besu/src/main/java/org/hyperledger/besu/services/PermissioningServiceImpl.java index eda202f6d4..e43bf1c054 100644 --- a/besu/src/main/java/org/hyperledger/besu/services/PermissioningServiceImpl.java +++ b/besu/src/main/java/org/hyperledger/besu/services/PermissioningServiceImpl.java @@ -19,6 +19,7 @@ import org.hyperledger.besu.plugin.services.permissioning.NodeConnectionPermissi import org.hyperledger.besu.plugin.services.permissioning.NodeMessagePermissioningProvider; import java.util.List; +import javax.inject.Inject; import com.google.common.collect.Lists; @@ -29,6 +30,7 @@ public class PermissioningServiceImpl implements PermissioningService { Lists.newArrayList(); /** Default Constructor. */ + @Inject public PermissioningServiceImpl() {} @Override diff --git a/besu/src/main/java/org/hyperledger/besu/services/SecurityModuleServiceImpl.java b/besu/src/main/java/org/hyperledger/besu/services/SecurityModuleServiceImpl.java index c3905c304b..5605fe49b5 100644 --- a/besu/src/main/java/org/hyperledger/besu/services/SecurityModuleServiceImpl.java +++ b/besu/src/main/java/org/hyperledger/besu/services/SecurityModuleServiceImpl.java @@ -21,15 +21,18 @@ import java.util.Map; import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Supplier; +import javax.inject.Inject; /** The Security module service implementation. */ public class SecurityModuleServiceImpl implements SecurityModuleService { - private final Map> securityModuleSuppliers = - new ConcurrentHashMap<>(); /** Default Constructor. */ + @Inject public SecurityModuleServiceImpl() {} + private final Map> securityModuleSuppliers = + new ConcurrentHashMap<>(); + @Override public void register(final String name, final Supplier securityModuleSupplier) { securityModuleSuppliers.put(name, securityModuleSupplier); diff --git a/besu/src/main/java/org/hyperledger/besu/services/StorageServiceImpl.java b/besu/src/main/java/org/hyperledger/besu/services/StorageServiceImpl.java index 6629da690e..dd5d822ccc 100644 --- a/besu/src/main/java/org/hyperledger/besu/services/StorageServiceImpl.java +++ b/besu/src/main/java/org/hyperledger/besu/services/StorageServiceImpl.java @@ -23,6 +23,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; +import javax.inject.Inject; /** The Storage service implementation. */ public class StorageServiceImpl implements StorageService { @@ -31,6 +32,7 @@ public class StorageServiceImpl implements StorageService { private final Map factories; /** Instantiates a new Storage service. */ + @Inject public StorageServiceImpl() { this.segments = List.of(KeyValueSegmentIdentifier.values()); this.factories = new ConcurrentHashMap<>(); diff --git a/besu/src/main/java/org/hyperledger/besu/services/TransactionSelectionServiceImpl.java b/besu/src/main/java/org/hyperledger/besu/services/TransactionSelectionServiceImpl.java index 8595a3c030..1ea8db7eab 100644 --- a/besu/src/main/java/org/hyperledger/besu/services/TransactionSelectionServiceImpl.java +++ b/besu/src/main/java/org/hyperledger/besu/services/TransactionSelectionServiceImpl.java @@ -23,11 +23,11 @@ import java.util.Optional; /** The Transaction Selection service implementation. */ public class TransactionSelectionServiceImpl implements TransactionSelectionService { - private Optional factory = Optional.empty(); - /** Default Constructor. */ public TransactionSelectionServiceImpl() {} + private Optional factory = Optional.empty(); + @Override public PluginTransactionSelector createPluginTransactionSelector() { return factory diff --git a/besu/src/test/java/org/hyperledger/besu/FlexGroupPrivacyTest.java b/besu/src/test/java/org/hyperledger/besu/FlexGroupPrivacyTest.java new file mode 100644 index 0000000000..a246d18d2f --- /dev/null +++ b/besu/src/test/java/org/hyperledger/besu/FlexGroupPrivacyTest.java @@ -0,0 +1,168 @@ +/* + * 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; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.hyperledger.besu.ethereum.core.PrivacyParameters.FLEXIBLE_PRIVACY; + +import org.hyperledger.besu.components.BesuComponent; +import org.hyperledger.besu.components.BesuPluginContextModule; +import org.hyperledger.besu.components.MockBesuCommandModule; +import org.hyperledger.besu.components.NoOpMetricsSystemModule; +import org.hyperledger.besu.components.PrivacyTestModule; +import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.controller.BesuController; +import org.hyperledger.besu.cryptoservices.NodeKeyUtils; +import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.enclave.EnclaveFactory; +import org.hyperledger.besu.ethereum.GasLimitCalculator; +import org.hyperledger.besu.ethereum.core.BlockHeader; +import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture; +import org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider; +import org.hyperledger.besu.ethereum.core.MiningParameters; +import org.hyperledger.besu.ethereum.core.PrivacyParameters; +import org.hyperledger.besu.ethereum.eth.EthProtocolConfiguration; +import org.hyperledger.besu.ethereum.eth.sync.SyncMode; +import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration; +import org.hyperledger.besu.ethereum.eth.transactions.BlobCacheModule; +import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration; +import org.hyperledger.besu.ethereum.p2p.config.NetworkingConfiguration; +import org.hyperledger.besu.ethereum.privacy.storage.PrivacyStorageProvider; +import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.cache.BonsaiCachedMerkleTrieLoaderModule; +import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; +import org.hyperledger.besu.evm.internal.EvmConfiguration; +import org.hyperledger.besu.evm.precompile.PrecompiledContract; +import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; +import org.hyperledger.besu.testutil.TestClock; + +import java.math.BigInteger; +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.file.Path; +import javax.inject.Named; +import javax.inject.Singleton; + +import dagger.Component; +import dagger.Module; +import dagger.Provides; +import io.vertx.core.Vertx; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; + +class FlexGroupPrivacyTest { + + private final Vertx vertx = Vertx.vertx(); + + @AfterEach + public void cleanUp() { + vertx.close(); + } + + @Test + void flexibleEnabledPrivacy() { + final BesuController besuController = + DaggerFlexGroupPrivacyTest_FlexGroupPrivacyTestComponent.builder() + .build() + .getBesuController(); + + final PrecompiledContract flexiblePrecompiledContract = + getPrecompile(besuController, FLEXIBLE_PRIVACY); + + assertThat(flexiblePrecompiledContract.getName()).isEqualTo("FlexiblePrivacy"); + } + + private PrecompiledContract getPrecompile( + final BesuController besuController, final Address defaultPrivacy) { + return besuController + .getProtocolSchedule() + .getByBlockHeader(blockHeader(0)) + .getPrecompileContractRegistry() + .get(defaultPrivacy); + } + + private BlockHeader blockHeader(final long number) { + return new BlockHeaderTestFixture().number(number).buildHeader(); + } + + @Singleton + @Component( + modules = { + FlexGroupPrivacyParametersModule.class, + FlexGroupPrivacyTest.PrivacyTestBesuControllerModule.class, + PrivacyTestModule.class, + MockBesuCommandModule.class, + BonsaiCachedMerkleTrieLoaderModule.class, + NoOpMetricsSystemModule.class, + BesuPluginContextModule.class, + BlobCacheModule.class + }) + interface FlexGroupPrivacyTestComponent extends BesuComponent { + BesuController getBesuController(); + } + + @Module + static class FlexGroupPrivacyParametersModule { + + @Provides + PrivacyParameters providePrivacyParameters( + final PrivacyStorageProvider storageProvider, final Vertx vertx) { + try { + return new PrivacyParameters.Builder() + .setEnabled(true) + .setEnclaveUrl(new URI("http://127.0.0.1:8000")) + .setStorageProvider(storageProvider) + .setEnclaveFactory(new EnclaveFactory(vertx)) + .setFlexiblePrivacyGroupsEnabled(true) + .build(); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + } + } + + @Module + static class PrivacyTestBesuControllerModule { + + @Provides + @Singleton + @SuppressWarnings("CloseableProvides") + BesuController provideBesuController( + final PrivacyParameters privacyParameters, + final DataStorageConfiguration dataStorageConfiguration, + final FlexGroupPrivacyTestComponent context, + @Named("dataDir") final Path dataDir) { + + return new BesuController.Builder() + .fromGenesisFile(GenesisConfigFile.mainnet(), SyncMode.FULL) + .synchronizerConfiguration(SynchronizerConfiguration.builder().build()) + .ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig()) + .storageProvider(new InMemoryKeyValueStorageProvider()) + .networkId(BigInteger.ONE) + .miningParameters(MiningParameters.newDefault()) + .dataStorageConfiguration(dataStorageConfiguration) + .nodeKey(NodeKeyUtils.generate()) + .metricsSystem(new NoOpMetricsSystem()) + .dataDirectory(dataDir) + .clock(TestClock.fixed()) + .privacyParameters(privacyParameters) + .transactionPoolConfiguration(TransactionPoolConfiguration.DEFAULT) + .gasLimitCalculator(GasLimitCalculator.constant()) + .evmConfiguration(EvmConfiguration.DEFAULT) + .networkConfiguration(NetworkingConfiguration.create()) + .besuComponent(context) + .build(); + } + } +} diff --git a/besu/src/test/java/org/hyperledger/besu/PrivacyReorgTest.java b/besu/src/test/java/org/hyperledger/besu/PrivacyReorgTest.java index ceb0be40fe..6298b70a95 100644 --- a/besu/src/test/java/org/hyperledger/besu/PrivacyReorgTest.java +++ b/besu/src/test/java/org/hyperledger/besu/PrivacyReorgTest.java @@ -21,6 +21,12 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import org.hyperledger.besu.components.BesuComponent; +import org.hyperledger.besu.components.BesuPluginContextModule; +import org.hyperledger.besu.components.EnclaveModule; +import org.hyperledger.besu.components.MockBesuCommandModule; +import org.hyperledger.besu.components.NoOpMetricsSystemModule; +import org.hyperledger.besu.components.PrivacyTestModule; import org.hyperledger.besu.config.GenesisConfigFile; import org.hyperledger.besu.controller.BesuController; import org.hyperledger.besu.crypto.KeyPair; @@ -47,7 +53,9 @@ import org.hyperledger.besu.ethereum.core.Transaction; import org.hyperledger.besu.ethereum.eth.EthProtocolConfiguration; import org.hyperledger.besu.ethereum.eth.sync.SyncMode; import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration; +import org.hyperledger.besu.ethereum.eth.transactions.BlobCacheModule; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration; +import org.hyperledger.besu.ethereum.mainnet.BlockImportResult; import org.hyperledger.besu.ethereum.mainnet.HeaderValidationMode; import org.hyperledger.besu.ethereum.p2p.config.NetworkingConfiguration; import org.hyperledger.besu.ethereum.privacy.PrivateStateRootResolver; @@ -56,6 +64,7 @@ import org.hyperledger.besu.ethereum.privacy.storage.PrivacyGroupHeadBlockMap; import org.hyperledger.besu.ethereum.privacy.storage.PrivacyStorageProvider; import org.hyperledger.besu.ethereum.privacy.storage.PrivateStateStorage; import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; +import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.cache.BonsaiCachedMerkleTrieLoaderModule; import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.evm.log.LogsBloomFilter; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; @@ -70,19 +79,21 @@ import java.nio.file.Path; import java.util.Collections; import java.util.Optional; import java.util.function.Supplier; +import javax.inject.Named; +import javax.inject.Singleton; import com.google.common.base.Suppliers; +import dagger.Component; +import dagger.Module; +import dagger.Provides; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.io.TempDir; @SuppressWarnings("rawtypes") public class PrivacyReorgTest { - @TempDir private Path folder; - private static final Supplier SIGNATURE_ALGORITHM = Suppliers.memoize(SignatureAlgorithmFactory::getInstance); @@ -130,11 +141,15 @@ public class PrivacyReorgTest { .signAndBuild(KEY_PAIR); private final BlockDataGenerator gen = new BlockDataGenerator(); - private BesuController besuController; - private PrivateStateRootResolver privateStateRootResolver; private PrivacyParameters privacyParameters; private Enclave mockEnclave; private Transaction privacyMarkerTransaction; + private final PrivacyReorgTestComponent component = + DaggerPrivacyReorgTest_PrivacyReorgTestComponent.create(); + + private final BesuController besuController = component.getBesuController(); + private final PrivateStateRootResolver privateStateRootResolver = + component.getPrivacyParameters().getPrivateStateRootResolver(); @BeforeEach public void setUp() throws IOException { @@ -174,29 +189,6 @@ public class PrivacyReorgTest { .build(); privacyParameters.setPrivacyUserId(ENCLAVE_PUBLIC_KEY.toBase64String()); - - privateStateRootResolver = - new PrivateStateRootResolver(privacyParameters.getPrivateStateStorage()); - - besuController = - new BesuController.Builder() - .fromGenesisFile( - GenesisConfigFile.fromResource("/privacy_reorg_genesis.json"), SyncMode.FULL) - .synchronizerConfiguration(SynchronizerConfiguration.builder().build()) - .ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig()) - .storageProvider(new InMemoryKeyValueStorageProvider()) - .networkId(BigInteger.ONE) - .miningParameters(MiningParameters.newDefault()) - .nodeKey(NodeKeyUtils.generate()) - .metricsSystem(new NoOpMetricsSystem()) - .dataDirectory(folder) - .clock(TestClock.fixed()) - .privacyParameters(privacyParameters) - .transactionPoolConfiguration(TransactionPoolConfiguration.DEFAULT) - .gasLimitCalculator(GasLimitCalculator.constant()) - .evmConfiguration(EvmConfiguration.DEFAULT) - .networkConfiguration(NetworkingConfiguration.create()) - .build(); } @Test @@ -204,7 +196,8 @@ public class PrivacyReorgTest { // Setup an initial blockchain with one private transaction final ProtocolContext protocolContext = besuController.getProtocolContext(); final DefaultBlockchain blockchain = (DefaultBlockchain) protocolContext.getBlockchain(); - final PrivateStateStorage privateStateStorage = privacyParameters.getPrivateStateStorage(); + final PrivateStateStorage privateStateStorage = + component.getPrivacyParameters().getPrivateStateStorage(); final Block firstBlock = gen.block( @@ -244,7 +237,7 @@ public class PrivacyReorgTest { // Setup an initial blockchain with one private transaction final ProtocolContext protocolContext = besuController.getProtocolContext(); final DefaultBlockchain blockchain = (DefaultBlockchain) protocolContext.getBlockchain(); - + assertThat(blockchain.getChainHeadBlockNumber()).isEqualTo(0); final Block firstBlock = gen.block( getBlockOptionsWithTransaction( @@ -252,8 +245,9 @@ public class PrivacyReorgTest { privacyMarkerTransaction, FIRST_BLOCK_WITH_SINGLE_TRANSACTION_STATE_ROOT)); - appendBlock(besuController, blockchain, protocolContext, firstBlock); - + var importResult = appendBlock(besuController, blockchain, protocolContext, firstBlock); + assertThat(importResult.isImported()).isTrue(); + assertThat(blockchain.getChainHeadBlockNumber()).isEqualTo(1); // Check that the private state root is not the empty state assertPrivateStateRoot( privateStateRootResolver, blockchain, STATE_ROOT_AFTER_TRANSACTION_APPENDED_TO_EMPTY_STATE); @@ -394,12 +388,12 @@ public class PrivacyReorgTest { } @SuppressWarnings("unchecked") - private void appendBlock( + private BlockImportResult appendBlock( final BesuController besuController, final DefaultBlockchain blockchain, final ProtocolContext protocolContext, final Block block) { - besuController + return besuController .getProtocolSchedule() .getByBlockHeader(blockchain.getChainHeadHeader()) .getBlockImporter() @@ -487,4 +481,93 @@ public class PrivacyReorgTest { .hasOmmers(false) .setLogsBloom(LogsBloomFilter.empty()); } + + @Singleton + @Component( + modules = { + PrivacyReorgTest.PrivacyReorgParametersModule.class, + PrivacyReorgTest.PrivacyReorgTestBesuControllerModule.class, + PrivacyReorgTest.PrivacyReorgTestGenesisConfigModule.class, + EnclaveModule.class, + PrivacyTestModule.class, + MockBesuCommandModule.class, + NoOpMetricsSystemModule.class, + BonsaiCachedMerkleTrieLoaderModule.class, + BlobCacheModule.class, + BesuPluginContextModule.class + }) + interface PrivacyReorgTestComponent extends BesuComponent { + + BesuController getBesuController(); + + PrivacyParameters getPrivacyParameters(); + } + + @Module + static class PrivacyReorgParametersModule { + + // TODO: copypasta, get this from the enclave factory + private static final Bytes ENCLAVE_PUBLIC_KEY = + Bytes.fromBase64String("A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo="); + + @Provides + PrivacyParameters providePrivacyReorgParameters( + final PrivacyStorageProvider storageProvider, final EnclaveFactory enclaveFactory) { + + PrivacyParameters retval = + new PrivacyParameters.Builder() + .setEnabled(true) + .setStorageProvider(storageProvider) + .setEnclaveUrl(URI.create("http//1.1.1.1:1234")) + .setEnclaveFactory(enclaveFactory) + .build(); + retval.setPrivacyUserId(ENCLAVE_PUBLIC_KEY.toBase64String()); + return retval; + } + } + + @Module + static class PrivacyReorgTestBesuControllerModule { + + @Provides + @Singleton + @SuppressWarnings("CloseableProvides") + BesuController provideBesuController( + final PrivacyParameters privacyParameters, + final GenesisConfigFile genesisConfigFile, + final PrivacyReorgTestComponent context, + final @Named("dataDir") Path dataDir) { + + // dataStorageConfiguration default + // named privacyReorgParams + BesuController retval = + new BesuController.Builder() + .fromGenesisFile(genesisConfigFile, SyncMode.FULL) + .synchronizerConfiguration(SynchronizerConfiguration.builder().build()) + .ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig()) + .storageProvider(new InMemoryKeyValueStorageProvider()) + .networkId(BigInteger.ONE) + .miningParameters(MiningParameters.newDefault()) + .nodeKey(NodeKeyUtils.generate()) + .metricsSystem(new NoOpMetricsSystem()) + .dataDirectory(dataDir) + .clock(TestClock.fixed()) + .privacyParameters(privacyParameters) + .transactionPoolConfiguration(TransactionPoolConfiguration.DEFAULT) + .gasLimitCalculator(GasLimitCalculator.constant()) + .evmConfiguration(EvmConfiguration.DEFAULT) + .networkConfiguration(NetworkingConfiguration.create()) + .besuComponent(context) + .build(); + return retval; + } + } + + @Module + static class PrivacyReorgTestGenesisConfigModule { + @Provides + GenesisConfigFile providePrivacyReorgGenesisConfigFile() { + return GenesisConfigFile.fromResource("/privacy_reorg_genesis.json"); + } + } } diff --git a/besu/src/test/java/org/hyperledger/besu/PrivacyTest.java b/besu/src/test/java/org/hyperledger/besu/PrivacyTest.java index dc5b7003c8..4d488ced3b 100644 --- a/besu/src/test/java/org/hyperledger/besu/PrivacyTest.java +++ b/besu/src/test/java/org/hyperledger/besu/PrivacyTest.java @@ -1,5 +1,5 @@ /* - * Copyright ConsenSys AG. + * 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 @@ -16,18 +16,17 @@ package org.hyperledger.besu; import static org.assertj.core.api.Assertions.assertThat; import static org.hyperledger.besu.ethereum.core.PrivacyParameters.DEFAULT_PRIVACY; -import static org.hyperledger.besu.ethereum.core.PrivacyParameters.FLEXIBLE_PRIVACY; -import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_BACKGROUND_THREAD_COUNT; -import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_CACHE_CAPACITY; -import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_IS_HIGH_SPEC; -import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_MAX_OPEN_FILES; - -import org.hyperledger.besu.cli.config.EthNetworkConfig; -import org.hyperledger.besu.cli.config.NetworkName; + +import org.hyperledger.besu.components.BesuComponent; +import org.hyperledger.besu.components.BesuPluginContextModule; +import org.hyperledger.besu.components.MockBesuCommandModule; +import org.hyperledger.besu.components.NoOpMetricsSystemModule; +import org.hyperledger.besu.components.PrivacyParametersModule; +import org.hyperledger.besu.components.PrivacyTestModule; +import org.hyperledger.besu.config.GenesisConfigFile; import org.hyperledger.besu.controller.BesuController; import org.hyperledger.besu.cryptoservices.NodeKeyUtils; import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.enclave.EnclaveFactory; import org.hyperledger.besu.ethereum.GasLimitCalculator; import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture; @@ -37,126 +36,47 @@ import org.hyperledger.besu.ethereum.core.PrivacyParameters; import org.hyperledger.besu.ethereum.eth.EthProtocolConfiguration; import org.hyperledger.besu.ethereum.eth.sync.SyncMode; import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration; +import org.hyperledger.besu.ethereum.eth.transactions.BlobCacheModule; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration; import org.hyperledger.besu.ethereum.p2p.config.NetworkingConfiguration; -import org.hyperledger.besu.ethereum.privacy.storage.PrivacyStorageProvider; -import org.hyperledger.besu.ethereum.privacy.storage.keyvalue.PrivacyKeyValueStorageProviderBuilder; -import org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier; +import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.cache.BonsaiCachedMerkleTrieLoaderModule; import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.evm.precompile.PrecompiledContract; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; -import org.hyperledger.besu.plugin.services.storage.rocksdb.RocksDBKeyValuePrivacyStorageFactory; -import org.hyperledger.besu.plugin.services.storage.rocksdb.RocksDBKeyValueStorageFactory; -import org.hyperledger.besu.plugin.services.storage.rocksdb.RocksDBMetricsFactory; -import org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBFactoryConfiguration; -import org.hyperledger.besu.services.BesuConfigurationImpl; import org.hyperledger.besu.testutil.TestClock; -import java.io.IOException; import java.math.BigInteger; -import java.net.URI; -import java.net.URISyntaxException; -import java.nio.file.Files; import java.nio.file.Path; -import java.util.Arrays; +import javax.inject.Named; +import javax.inject.Singleton; +import dagger.Component; +import dagger.Module; +import dagger.Provides; import io.vertx.core.Vertx; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.io.TempDir; -public class PrivacyTest { +class PrivacyTest { private final Vertx vertx = Vertx.vertx(); - @TempDir private Path dataDir; - @AfterEach public void cleanUp() { vertx.close(); } @Test - public void defaultPrivacy() throws IOException, URISyntaxException { - final BesuController besuController = setUpControllerWithPrivacyEnabled(false); + void defaultPrivacy() { + final BesuController besuController = + DaggerPrivacyTest_PrivacyTestComponent.builder().build().getBesuController(); final PrecompiledContract precompiledContract = getPrecompile(besuController, DEFAULT_PRIVACY); assertThat(precompiledContract.getName()).isEqualTo("Privacy"); } - @Test - public void flexibleEnabledPrivacy() throws IOException, URISyntaxException { - final BesuController besuController = setUpControllerWithPrivacyEnabled(true); - - final PrecompiledContract flexiblePrecompiledContract = - getPrecompile(besuController, FLEXIBLE_PRIVACY); - - assertThat(flexiblePrecompiledContract.getName()).isEqualTo("FlexiblePrivacy"); - } - - private BesuController setUpControllerWithPrivacyEnabled(final boolean flexibleEnabled) - throws IOException, URISyntaxException { - final Path dbDir = Files.createTempDirectory(dataDir, "database"); - final var miningParameters = MiningParameters.newDefault(); - final var dataStorageConfiguration = DataStorageConfiguration.DEFAULT_FOREST_CONFIG; - final PrivacyParameters privacyParameters = - new PrivacyParameters.Builder() - .setEnabled(true) - .setEnclaveUrl(new URI("http://127.0.0.1:8000")) - .setStorageProvider( - createKeyValueStorageProvider( - dataDir, dbDir, dataStorageConfiguration, miningParameters)) - .setEnclaveFactory(new EnclaveFactory(vertx)) - .setFlexiblePrivacyGroupsEnabled(flexibleEnabled) - .build(); - return new BesuController.Builder() - .fromEthNetworkConfig(EthNetworkConfig.getNetworkConfig(NetworkName.MAINNET), SyncMode.FULL) - .synchronizerConfiguration(SynchronizerConfiguration.builder().build()) - .ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig()) - .storageProvider(new InMemoryKeyValueStorageProvider()) - .networkId(BigInteger.ONE) - .miningParameters(miningParameters) - .dataStorageConfiguration(dataStorageConfiguration) - .nodeKey(NodeKeyUtils.generate()) - .metricsSystem(new NoOpMetricsSystem()) - .dataDirectory(dataDir) - .clock(TestClock.fixed()) - .privacyParameters(privacyParameters) - .transactionPoolConfiguration(TransactionPoolConfiguration.DEFAULT) - .gasLimitCalculator(GasLimitCalculator.constant()) - .evmConfiguration(EvmConfiguration.DEFAULT) - .networkConfiguration(NetworkingConfiguration.create()) - .build(); - } - - private PrivacyStorageProvider createKeyValueStorageProvider( - final Path dataDir, - final Path dbDir, - final DataStorageConfiguration dataStorageConfiguration, - final MiningParameters miningParameters) { - final var besuConfiguration = new BesuConfigurationImpl(); - besuConfiguration - .init(dataDir, dbDir, dataStorageConfiguration) - .withMiningParameters(miningParameters); - return new PrivacyKeyValueStorageProviderBuilder() - .withStorageFactory( - new RocksDBKeyValuePrivacyStorageFactory( - new RocksDBKeyValueStorageFactory( - () -> - new RocksDBFactoryConfiguration( - DEFAULT_MAX_OPEN_FILES, - DEFAULT_BACKGROUND_THREAD_COUNT, - DEFAULT_CACHE_CAPACITY, - DEFAULT_IS_HIGH_SPEC), - Arrays.asList(KeyValueSegmentIdentifier.values()), - RocksDBMetricsFactory.PRIVATE_ROCKS_DB_METRICS))) - .withCommonConfiguration(besuConfiguration) - .withMetricsSystem(new NoOpMetricsSystem()) - .build(); - } - private PrecompiledContract getPrecompile( final BesuController besuController, final Address defaultPrivacy) { return besuController @@ -169,4 +89,55 @@ public class PrivacyTest { private BlockHeader blockHeader(final long number) { return new BlockHeaderTestFixture().number(number).buildHeader(); } + + @Singleton + @Component( + modules = { + PrivacyParametersModule.class, + PrivacyTest.PrivacyTestBesuControllerModule.class, + PrivacyTestModule.class, + MockBesuCommandModule.class, + BonsaiCachedMerkleTrieLoaderModule.class, + NoOpMetricsSystemModule.class, + BesuPluginContextModule.class, + BlobCacheModule.class + }) + interface PrivacyTestComponent extends BesuComponent { + + BesuController getBesuController(); + } + + @Module + static class PrivacyTestBesuControllerModule { + + @Provides + @Singleton + @SuppressWarnings("CloseableProvides") + BesuController provideBesuController( + final PrivacyParameters privacyParameters, + final DataStorageConfiguration dataStorageConfiguration, + final PrivacyTestComponent context, + @Named("dataDir") final Path dataDir) { + + return new BesuController.Builder() + .fromGenesisFile(GenesisConfigFile.mainnet(), SyncMode.FULL) + .synchronizerConfiguration(SynchronizerConfiguration.builder().build()) + .ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig()) + .storageProvider(new InMemoryKeyValueStorageProvider()) + .networkId(BigInteger.ONE) + .miningParameters(MiningParameters.newDefault()) + .dataStorageConfiguration(dataStorageConfiguration) + .nodeKey(NodeKeyUtils.generate()) + .metricsSystem(new NoOpMetricsSystem()) + .dataDirectory(dataDir) + .clock(TestClock.fixed()) + .privacyParameters(privacyParameters) + .transactionPoolConfiguration(TransactionPoolConfiguration.DEFAULT) + .gasLimitCalculator(GasLimitCalculator.constant()) + .evmConfiguration(EvmConfiguration.DEFAULT) + .networkConfiguration(NetworkingConfiguration.create()) + .besuComponent(context) + .build(); + } + } } diff --git a/besu/src/test/java/org/hyperledger/besu/RunnerTest.java b/besu/src/test/java/org/hyperledger/besu/RunnerTest.java index 5b2a56078f..5fefc7ef22 100644 --- a/besu/src/test/java/org/hyperledger/besu/RunnerTest.java +++ b/besu/src/test/java/org/hyperledger/besu/RunnerTest.java @@ -22,8 +22,10 @@ import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_CACHE_CAPACITY; import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_IS_HIGH_SPEC; import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_MAX_OPEN_FILES; +import static org.mockito.Mockito.mock; 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; @@ -483,6 +485,7 @@ public final class RunnerTest { .evmConfiguration(EvmConfiguration.DEFAULT) .networkConfiguration(NetworkingConfiguration.create()) .randomPeerPriority(Boolean.FALSE) + .besuComponent(mock(BesuComponent.class)) .maxPeers(25) .maxRemotelyInitiatedPeers(15) .build(); diff --git a/besu/src/test/java/org/hyperledger/besu/chainexport/RlpBlockExporterTest.java b/besu/src/test/java/org/hyperledger/besu/chainexport/RlpBlockExporterTest.java index 05057f15c8..bbc7dea1ab 100644 --- a/besu/src/test/java/org/hyperledger/besu/chainexport/RlpBlockExporterTest.java +++ b/besu/src/test/java/org/hyperledger/besu/chainexport/RlpBlockExporterTest.java @@ -16,10 +16,12 @@ package org.hyperledger.besu.chainexport; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.Mockito.mock; import org.hyperledger.besu.chainimport.RlpBlockImporter; import org.hyperledger.besu.cli.config.EthNetworkConfig; import org.hyperledger.besu.cli.config.NetworkName; +import org.hyperledger.besu.components.BesuComponent; import org.hyperledger.besu.controller.BesuController; import org.hyperledger.besu.cryptoservices.NodeKeyUtils; import org.hyperledger.besu.ethereum.GasLimitCalculator; @@ -102,6 +104,7 @@ public final class RlpBlockExporterTest { .gasLimitCalculator(GasLimitCalculator.constant()) .evmConfiguration(EvmConfiguration.DEFAULT) .networkConfiguration(NetworkingConfiguration.create()) + .besuComponent(mock(BesuComponent.class)) .build(); } diff --git a/besu/src/test/java/org/hyperledger/besu/chainimport/JsonBlockImporterTest.java b/besu/src/test/java/org/hyperledger/besu/chainimport/JsonBlockImporterTest.java index 73015afd00..7b1a4bc7d2 100644 --- a/besu/src/test/java/org/hyperledger/besu/chainimport/JsonBlockImporterTest.java +++ b/besu/src/test/java/org/hyperledger/besu/chainimport/JsonBlockImporterTest.java @@ -17,7 +17,9 @@ package org.hyperledger.besu.chainimport; import static java.nio.charset.StandardCharsets.UTF_8; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.Mockito.mock; +import org.hyperledger.besu.components.BesuComponent; import org.hyperledger.besu.config.GenesisConfigFile; import org.hyperledger.besu.config.JsonUtil; import org.hyperledger.besu.controller.BesuController; @@ -463,6 +465,7 @@ public abstract class JsonBlockImporterTest { .gasLimitCalculator(GasLimitCalculator.constant()) .evmConfiguration(EvmConfiguration.DEFAULT) .networkConfiguration(NetworkingConfiguration.create()) + .besuComponent(mock(BesuComponent.class)) .build(); } } 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 e37b8a5fd0..7d4fabb222 100644 --- a/besu/src/test/java/org/hyperledger/besu/chainimport/RlpBlockImporterTest.java +++ b/besu/src/test/java/org/hyperledger/besu/chainimport/RlpBlockImporterTest.java @@ -16,9 +16,11 @@ package org.hyperledger.besu.chainimport; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +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.controller.BesuController; import org.hyperledger.besu.cryptoservices.NodeKeyUtils; @@ -77,6 +79,7 @@ public final class RlpBlockImporterTest { .gasLimitCalculator(GasLimitCalculator.constant()) .evmConfiguration(EvmConfiguration.DEFAULT) .networkConfiguration(NetworkingConfiguration.create()) + .besuComponent(mock(BesuComponent.class)) .build(); final RlpBlockImporter.ImportResult result = rlpBlockImporter.importBlockchain(source, targetController, false); @@ -110,6 +113,7 @@ public final class RlpBlockImporterTest { .gasLimitCalculator(GasLimitCalculator.constant()) .evmConfiguration(EvmConfiguration.DEFAULT) .networkConfiguration(NetworkingConfiguration.create()) + .besuComponent(mock(BesuComponent.class)) .build(); assertThatThrownBy( @@ -140,6 +144,7 @@ public final class RlpBlockImporterTest { .gasLimitCalculator(GasLimitCalculator.constant()) .evmConfiguration(EvmConfiguration.DEFAULT) .networkConfiguration(NetworkingConfiguration.create()) + .besuComponent(mock(BesuComponent.class)) .build(); final RlpBlockImporter.ImportResult result = diff --git a/besu/src/test/java/org/hyperledger/besu/components/EnclaveModule.java b/besu/src/test/java/org/hyperledger/besu/components/EnclaveModule.java new file mode 100644 index 0000000000..20f9c1bf49 --- /dev/null +++ b/besu/src/test/java/org/hyperledger/besu/components/EnclaveModule.java @@ -0,0 +1,98 @@ +/* + * 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.components; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.hyperledger.besu.crypto.KeyPair; +import org.hyperledger.besu.crypto.SignatureAlgorithm; +import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; +import org.hyperledger.besu.datatypes.Wei; +import org.hyperledger.besu.enclave.Enclave; +import org.hyperledger.besu.enclave.EnclaveFactory; +import org.hyperledger.besu.enclave.types.ReceiveResponse; +import org.hyperledger.besu.ethereum.privacy.PrivateTransaction; +import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; +import org.hyperledger.besu.plugin.data.Restriction; + +import java.math.BigInteger; +import java.nio.charset.StandardCharsets; +import java.util.Collections; +import java.util.function.Supplier; + +import com.google.common.base.Suppliers; +import dagger.Module; +import dagger.Provides; +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; + +@Module +public class EnclaveModule { + + private static final Supplier SIGNATURE_ALGORITHM = + Suppliers.memoize(SignatureAlgorithmFactory::getInstance); + + private static final Bytes ENCLAVE_PUBLIC_KEY = + Bytes.fromBase64String("A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo="); + + private static final Bytes32 PRIVACY_GROUP_BYTES32 = + Bytes32.fromHexString("0xf250d523ae9164722b06ca25cfa2a7f3c45df96b09e215236f886c876f715bfa"); + + private static final Bytes MOCK_PAYLOAD = + Bytes.fromHexString( + "0x608060405234801561001057600080fd5b5060008054600160a060020a03191633179055610199806100326000396000f3fe6080604052600436106100565763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416633fa4f245811461005b5780636057361d1461008257806367e404ce146100ae575b600080fd5b34801561006757600080fd5b506100706100ec565b60408051918252519081900360200190f35b34801561008e57600080fd5b506100ac600480360360208110156100a557600080fd5b50356100f2565b005b3480156100ba57600080fd5b506100c3610151565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b60025490565b604080513381526020810183905281517fc9db20adedc6cf2b5d25252b101ab03e124902a73fcb12b753f3d1aaa2d8f9f5929181900390910190a16002556001805473ffffffffffffffffffffffffffffffffffffffff191633179055565b60015473ffffffffffffffffffffffffffffffffffffffff169056fea165627a7a72305820c7f729cb24e05c221f5aa913700793994656f233fe2ce3b9fd9a505ea17e8d8a0029"); + + private static final KeyPair KEY_PAIR = + SIGNATURE_ALGORITHM + .get() + .createKeyPair( + SIGNATURE_ALGORITHM + .get() + .createPrivateKey( + new BigInteger( + "8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63", 16))); + + private static final PrivateTransaction PRIVATE_TRANSACTION = + PrivateTransaction.builder() + .chainId(BigInteger.valueOf(1337)) + .gasLimit(1000) + .gasPrice(Wei.ZERO) + .nonce(0) + .payload(MOCK_PAYLOAD) + .to(null) + .privateFrom(ENCLAVE_PUBLIC_KEY) + .privateFor(Collections.singletonList(ENCLAVE_PUBLIC_KEY)) + .restriction(Restriction.RESTRICTED) + .value(Wei.ZERO) + .signAndBuild(KEY_PAIR); + + @Provides + EnclaveFactory provideMockableEnclaveFactory() { + Enclave mockEnclave = mock(Enclave.class); + final BytesValueRLPOutput rlpOutput = new BytesValueRLPOutput(); + PRIVATE_TRANSACTION.writeTo(rlpOutput); + when(mockEnclave.receive(any())) + .thenReturn( + new ReceiveResponse( + rlpOutput.encoded().toBase64String().getBytes(StandardCharsets.UTF_8), + PRIVACY_GROUP_BYTES32.toBase64String(), + ENCLAVE_PUBLIC_KEY.toBase64String())); + EnclaveFactory enclaveFactory = mock(EnclaveFactory.class); + when(enclaveFactory.createVertxEnclave(any())).thenReturn(mockEnclave); + return enclaveFactory; + } +} diff --git a/besu/src/test/java/org/hyperledger/besu/components/GenesisConfigModule.java b/besu/src/test/java/org/hyperledger/besu/components/GenesisConfigModule.java new file mode 100644 index 0000000000..ae82b8b928 --- /dev/null +++ b/besu/src/test/java/org/hyperledger/besu/components/GenesisConfigModule.java @@ -0,0 +1,38 @@ +/* + * 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.components; + +import org.hyperledger.besu.config.GenesisConfigFile; + +import javax.inject.Named; + +import dagger.Module; +import dagger.Provides; + +@Module +public class GenesisConfigModule { + + @Named("default") + @Provides + GenesisConfigFile provideDefaultGenesisConfigFile() { + return GenesisConfigFile.DEFAULT; + } + + @Named("mainnet") + @Provides + GenesisConfigFile provideMainnetGenesisConfigFile() { + return GenesisConfigFile.mainnet(); + } +} diff --git a/besu/src/test/java/org/hyperledger/besu/components/MockBesuCommandModule.java b/besu/src/test/java/org/hyperledger/besu/components/MockBesuCommandModule.java new file mode 100644 index 0000000000..743b4ee8de --- /dev/null +++ b/besu/src/test/java/org/hyperledger/besu/components/MockBesuCommandModule.java @@ -0,0 +1,50 @@ +/* + * 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.components; + +import static org.mockito.Mockito.mock; + +import org.hyperledger.besu.cli.BesuCommand; +import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration; + +import javax.inject.Named; +import javax.inject.Singleton; + +import dagger.Module; +import dagger.Provides; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Module +public class MockBesuCommandModule { + + @Provides + BesuCommand provideBesuCommand() { + return mock(BesuCommand.class); + } + + @Provides + @Singleton + MetricsConfiguration provideMetricsConfiguration() { + return MetricsConfiguration.builder().build(); + } + + @Provides + @Named("besuCommandLogger") + @Singleton + Logger provideBesuCommandLogger() { + return LoggerFactory.getLogger(MockBesuCommandModule.class); + } +} diff --git a/besu/src/test/java/org/hyperledger/besu/components/NoOpMetricsSystemModule.java b/besu/src/test/java/org/hyperledger/besu/components/NoOpMetricsSystemModule.java new file mode 100644 index 0000000000..e7807e3d75 --- /dev/null +++ b/besu/src/test/java/org/hyperledger/besu/components/NoOpMetricsSystemModule.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.components; + +import org.hyperledger.besu.metrics.ObservableMetricsSystem; +import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; +import org.hyperledger.besu.plugin.services.MetricsSystem; + +import javax.inject.Singleton; + +import dagger.Module; +import dagger.Provides; + +@Module +public class NoOpMetricsSystemModule { + + @Provides + @Singleton + MetricsSystem provideMetricsSystem() { + return new NoOpMetricsSystem(); + } + + @Provides + @Singleton + ObservableMetricsSystem provideObservableMetricsSystem() { + return new NoOpMetricsSystem(); + } +} diff --git a/besu/src/test/java/org/hyperledger/besu/components/PrivacyParametersModule.java b/besu/src/test/java/org/hyperledger/besu/components/PrivacyParametersModule.java new file mode 100644 index 0000000000..0b8fcf744f --- /dev/null +++ b/besu/src/test/java/org/hyperledger/besu/components/PrivacyParametersModule.java @@ -0,0 +1,47 @@ +/* + * 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.components; + +import org.hyperledger.besu.enclave.EnclaveFactory; +import org.hyperledger.besu.ethereum.core.PrivacyParameters; +import org.hyperledger.besu.ethereum.privacy.storage.PrivacyStorageProvider; + +import java.net.URI; +import java.net.URISyntaxException; + +import dagger.Module; +import dagger.Provides; +import io.vertx.core.Vertx; + +/** Provides a general use PrivacyParameters instance for testing. */ +@Module +public class PrivacyParametersModule { + + @Provides + PrivacyParameters providePrivacyParameters( + final PrivacyStorageProvider storageProvider, final Vertx vertx) { + try { + return new PrivacyParameters.Builder() + .setEnabled(true) + .setEnclaveUrl(new URI("http://127.0.0.1:8000")) + .setStorageProvider(storageProvider) + .setEnclaveFactory(new EnclaveFactory(vertx)) + .setFlexiblePrivacyGroupsEnabled(false) + .build(); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + } +} diff --git a/besu/src/test/java/org/hyperledger/besu/components/PrivacyTestModule.java b/besu/src/test/java/org/hyperledger/besu/components/PrivacyTestModule.java new file mode 100644 index 0000000000..13cafe1ab4 --- /dev/null +++ b/besu/src/test/java/org/hyperledger/besu/components/PrivacyTestModule.java @@ -0,0 +1,111 @@ +/* + * 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.components; + +import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_BACKGROUND_THREAD_COUNT; +import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_CACHE_CAPACITY; +import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_IS_HIGH_SPEC; +import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_MAX_OPEN_FILES; + +import org.hyperledger.besu.ethereum.privacy.storage.PrivacyStorageProvider; +import org.hyperledger.besu.ethereum.privacy.storage.keyvalue.PrivacyKeyValueStorageProviderBuilder; +import org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier; +import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; +import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; +import org.hyperledger.besu.plugin.services.storage.rocksdb.RocksDBKeyValuePrivacyStorageFactory; +import org.hyperledger.besu.plugin.services.storage.rocksdb.RocksDBKeyValueStorageFactory; +import org.hyperledger.besu.plugin.services.storage.rocksdb.RocksDBMetricsFactory; +import org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBFactoryConfiguration; +import org.hyperledger.besu.services.BesuConfigurationImpl; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Arrays; +import javax.inject.Named; +import javax.inject.Singleton; + +import dagger.Module; +import dagger.Provides; +import io.vertx.core.Vertx; + +@Module +public class PrivacyTestModule { + + @Provides + @Named("dataDir") + Path provideDataDir() { + try { + return Files.createTempDirectory("PrivacyTestDatadir"); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Provides + Vertx provideVertx() { + return Vertx.vertx(); + } + + @Provides + DataStorageConfiguration provideDataStorageConfiguration() { + return DataStorageConfiguration.DEFAULT_FOREST_CONFIG; + } + + @Provides + @Singleton + @Named("dbDir") + Path provideDbDir(@Named("dataDir") final Path dataDir) { + try { + final Path dbDir = Files.createTempDirectory(dataDir, "database"); + return dbDir; + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Provides + @Singleton + @Named("flexibleEnabled") + Boolean provideFlexibleEnabled() { + return true; + } + + @Provides + @Singleton + @SuppressWarnings("CloseableProvides") + PrivacyStorageProvider provideKeyValueStorageProvider( + @Named("dbDir") final Path dbDir, + final DataStorageConfiguration dataStorageConfiguration, + @Named("dataDir") final Path dataDir) { + final var besuConfiguration = new BesuConfigurationImpl(); + besuConfiguration.init(dataDir, dbDir, dataStorageConfiguration); + return new PrivacyKeyValueStorageProviderBuilder() + .withStorageFactory( + new RocksDBKeyValuePrivacyStorageFactory( + new RocksDBKeyValueStorageFactory( + () -> + new RocksDBFactoryConfiguration( + DEFAULT_MAX_OPEN_FILES, + DEFAULT_BACKGROUND_THREAD_COUNT, + DEFAULT_CACHE_CAPACITY, + DEFAULT_IS_HIGH_SPEC), + Arrays.asList(KeyValueSegmentIdentifier.values()), + RocksDBMetricsFactory.PRIVATE_ROCKS_DB_METRICS))) + .withCommonConfiguration(besuConfiguration) + .withMetricsSystem(new NoOpMetricsSystem()) + .build(); + } +} diff --git a/besu/src/test/java/org/hyperledger/besu/controller/AbstractBftBesuControllerBuilderTest.java b/besu/src/test/java/org/hyperledger/besu/controller/AbstractBftBesuControllerBuilderTest.java index f9e671f522..621ae8a98c 100644 --- a/besu/src/test/java/org/hyperledger/besu/controller/AbstractBftBesuControllerBuilderTest.java +++ b/besu/src/test/java/org/hyperledger/besu/controller/AbstractBftBesuControllerBuilderTest.java @@ -19,6 +19,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.mock; +import org.hyperledger.besu.components.BesuComponent; import org.hyperledger.besu.config.CheckpointConfigOptions; import org.hyperledger.besu.config.GenesisConfigFile; import org.hyperledger.besu.config.GenesisConfigOptions; @@ -156,6 +157,7 @@ public abstract class AbstractBftBesuControllerBuilderTest { .storageProvider(storageProvider) .gasLimitCalculator(gasLimitCalculator) .evmConfiguration(EvmConfiguration.DEFAULT) + .besuComponent(mock(BesuComponent.class)) .networkConfiguration(NetworkingConfiguration.create()); } diff --git a/besu/src/test/java/org/hyperledger/besu/controller/CliqueBesuControllerBuilderTest.java b/besu/src/test/java/org/hyperledger/besu/controller/CliqueBesuControllerBuilderTest.java index 39904df798..e9e93de9b9 100644 --- a/besu/src/test/java/org/hyperledger/besu/controller/CliqueBesuControllerBuilderTest.java +++ b/besu/src/test/java/org/hyperledger/besu/controller/CliqueBesuControllerBuilderTest.java @@ -20,6 +20,7 @@ import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import org.hyperledger.besu.components.BesuComponent; import org.hyperledger.besu.config.CheckpointConfigOptions; import org.hyperledger.besu.config.GenesisConfigFile; import org.hyperledger.besu.config.GenesisConfigOptions; @@ -189,6 +190,7 @@ public class CliqueBesuControllerBuilderTest { .storageProvider(storageProvider) .gasLimitCalculator(gasLimitCalculator) .evmConfiguration(EvmConfiguration.DEFAULT) + .besuComponent(mock(BesuComponent.class)) .networkConfiguration(NetworkingConfiguration.create()); } diff --git a/besu/src/test/java/org/hyperledger/besu/controller/MergeBesuControllerBuilderTest.java b/besu/src/test/java/org/hyperledger/besu/controller/MergeBesuControllerBuilderTest.java index 544b633015..f8c00b20ea 100644 --- a/besu/src/test/java/org/hyperledger/besu/controller/MergeBesuControllerBuilderTest.java +++ b/besu/src/test/java/org/hyperledger/besu/controller/MergeBesuControllerBuilderTest.java @@ -23,6 +23,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; +import org.hyperledger.besu.components.BesuComponent; import org.hyperledger.besu.config.CheckpointConfigOptions; import org.hyperledger.besu.config.GenesisConfigFile; import org.hyperledger.besu.config.GenesisConfigOptions; @@ -189,6 +190,7 @@ public class MergeBesuControllerBuilderTest { .storageProvider(storageProvider) .evmConfiguration(EvmConfiguration.DEFAULT) .networkConfiguration(NetworkingConfiguration.create()) + .besuComponent(mock(BesuComponent.class)) .networkId(networkId); } diff --git a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/peers/EnodeURLImpl.java b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/peers/EnodeURLImpl.java index e1d158f3fc..e087edd431 100644 --- a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/peers/EnodeURLImpl.java +++ b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/peers/EnodeURLImpl.java @@ -381,10 +381,11 @@ public class EnodeURLImpl implements EnodeURL { return ipAddress(ip, EnodeDnsConfiguration.dnsDisabled()); } - public Builder ipAddress(final String ip, final EnodeDnsConfiguration enodeDnsConfiguration) { + public Builder ipAddress( + final String hostField, final EnodeDnsConfiguration enodeDnsConfiguration) { if (enodeDnsConfiguration.dnsEnabled()) { try { - this.ip = InetAddress.getByName(ip); + this.ip = InetAddress.getByName(hostField); if (enodeDnsConfiguration.updateEnabled()) { if (this.ip.isLoopbackAddress()) { this.ip = InetAddress.getLocalHost(); @@ -398,10 +399,10 @@ public class EnodeURLImpl implements EnodeURL { this.ip = InetAddresses.forString("127.0.0.1"); } } - } else if (InetAddresses.isUriInetAddress(ip)) { - this.ip = InetAddresses.forUriString(ip); - } else if (InetAddresses.isInetAddress(ip)) { - this.ip = InetAddresses.forString(ip); + } else if (InetAddresses.isUriInetAddress(hostField)) { + this.ip = InetAddresses.forUriString(hostField); + } else if (InetAddresses.isInetAddress(hostField)) { + this.ip = InetAddresses.forString(hostField); } else { throw new IllegalArgumentException("Invalid ip address."); } From 5d3b2708bc8cd7f86d81c6f2a6610d3fc91a9b65 Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Tue, 3 Sep 2024 11:33:16 -0600 Subject: [PATCH 180/259] Update reference tests to 14.1 (#7568) Updates the reference tests to 14.1, which mostly consists of removing duplicate tests covered by execution-spec-tests or invalid tests from EOF portions of the Prague tests. Signed-off-by: Danno Ferrin --- ethereum/referencetests/build.gradle | 2 +- .../src/reference-test/external-resources | 2 +- .../ethereum/eof/EOFReferenceTestTools.java | 21 ------------------- 3 files changed, 2 insertions(+), 23 deletions(-) diff --git a/ethereum/referencetests/build.gradle b/ethereum/referencetests/build.gradle index 426c1084db..22f22c70a5 100644 --- a/ethereum/referencetests/build.gradle +++ b/ethereum/referencetests/build.gradle @@ -232,7 +232,7 @@ tasks.register('validateReferenceTestSubmodule') { description = "Checks that the reference tests submodule is not accidentally changed" doLast { def result = new ByteArrayOutputStream() - def expectedHash = 'faf33b471465d3c6cdc3d04fbd690895f78d33f2' + def expectedHash = '9201075490807f58811078e9bb5ec895b4ac01a5' def submodulePath = java.nio.file.Path.of("${rootProject.projectDir}", "ethereum/referencetests/src/reference-test/external-resources").toAbsolutePath() try { exec { diff --git a/ethereum/referencetests/src/reference-test/external-resources b/ethereum/referencetests/src/reference-test/external-resources index faf33b4714..9201075490 160000 --- a/ethereum/referencetests/src/reference-test/external-resources +++ b/ethereum/referencetests/src/reference-test/external-resources @@ -1 +1 @@ -Subproject commit faf33b471465d3c6cdc3d04fbd690895f78d33f2 +Subproject commit 9201075490807f58811078e9bb5ec895b4ac01a5 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 b5def9556d..6a736831ff 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 @@ -79,27 +79,6 @@ public class EOFReferenceTestTools { if (EIPS_TO_RUN.isEmpty()) { params.ignoreAll(); } - - // TXCREATE still in tests, but has been removed - params.ignore("EOF1_undefined_opcodes_186"); - - // embedded containers rules changed - params.ignore("efValidation/EOF1_embedded_container-Prague\\[EOF1_embedded_container_\\d+\\]"); - - // truncated data is only allowed in embedded containers - params.ignore("ori/validInvalid-Prague\\[validInvalid_48\\]"); - params.ignore("efExample/validInvalid-Prague\\[validInvalid_1\\]"); - params.ignore("efValidation/EOF1_truncated_section-Prague\\[EOF1_truncated_section_3\\]"); - params.ignore("efValidation/EOF1_truncated_section-Prague\\[EOF1_truncated_section_4\\]"); - params.ignore("EIP3540/validInvalid-Prague\\[validInvalid_2\\]"); - params.ignore("EIP3540/validInvalid-Prague\\[validInvalid_3\\]"); - - // Orphan containers are no longer allowed - params.ignore("efValidation/EOF1_returncontract_valid-Prague\\[EOF1_returncontract_valid_1\\]"); - params.ignore("efValidation/EOF1_returncontract_valid-Prague\\[EOF1_returncontract_valid_2\\]"); - params.ignore("efValidation/EOF1_eofcreate_valid-Prague\\[EOF1_eofcreate_valid_1\\]"); - params.ignore("efValidation/EOF1_eofcreate_valid-Prague\\[EOF1_eofcreate_valid_2\\]"); - params.ignore("efValidation/EOF1_section_order-Prague\\[EOF1_section_order_6\\]"); } private EOFReferenceTestTools() { From 6d3316474200bc32acec9b8fda318800b8a2716d Mon Sep 17 00:00:00 2001 From: Sally MacFarlane Date: Wed, 4 Sep 2024 07:09:25 +1000 Subject: [PATCH 181/259] removed unused methods (#7561) Signed-off-by: Sally MacFarlane --- .../node/configuration/BesuNodeFactory.java | 25 ------------------- 1 file changed, 25 deletions(-) diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeFactory.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeFactory.java index efbf91246b..9660f6ee9d 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeFactory.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeFactory.java @@ -511,31 +511,6 @@ public class BesuNodeFactory { return create(builder.build()); } - public BesuNode createQbftNodeWithTLS(final String name, final String type) throws IOException { - return create( - new BesuNodeConfigurationBuilder() - .name(name) - .miningEnabled() - .p2pTLSEnabled(name, type) - .jsonRpcConfiguration(node.createJsonRpcWithQbftEnabledConfig(false)) - .webSocketConfiguration(node.createWebSocketEnabledConfig()) - .devMode(false) - .genesisConfigProvider(GenesisConfigurationFactory::createQbftGenesisConfig) - .build()); - } - - public BesuNode createQbftNodeWithTLSJKS(final String name) throws IOException { - return createQbftNodeWithTLS(name, KeyStoreWrapper.KEYSTORE_TYPE_JKS); - } - - public BesuNode createQbftNodeWithTLSPKCS12(final String name) throws IOException { - return createQbftNodeWithTLS(name, KeyStoreWrapper.KEYSTORE_TYPE_PKCS12); - } - - public BesuNode createQbftNodeWithTLSPKCS11(final String name) throws IOException { - return createQbftNodeWithTLS(name, KeyStoreWrapper.KEYSTORE_TYPE_PKCS11); - } - public BesuNode createQbftNode( final String name, final boolean fixedPort, final DataStorageFormat storageFormat) throws IOException { From 563afdb3ec3cc082a7e487bc270ded7f46e245ab Mon Sep 17 00:00:00 2001 From: Justin Florentine Date: Tue, 3 Sep 2024 18:40:57 -0400 Subject: [PATCH 182/259] Dagger plugin context (#7465) * Eliminates dependency from Controller on BesuComponent --------- Signed-off-by: Justin Florentine Co-authored-by: garyschulte --- .../dsl/node/ThreadBesuNodeRunner.java | 10 ++-- .../org/hyperledger/besu/cli/BesuCommand.java | 46 +++++++++---------- .../subcommands/blocks/BlocksSubCommand.java | 4 +- .../storage/TrieLogSubCommand.java | 2 +- .../besu/components/BesuCommandModule.java | 12 +++-- .../besu/components/BesuComponent.java | 1 - .../components/BesuPluginContextModule.java | 17 +++++-- .../besu/cli/CommandTestAbstract.java | 41 ++++++++--------- 8 files changed, 67 insertions(+), 66 deletions(-) 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 0177790831..d4ec54045d 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 @@ -93,7 +93,6 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; import javax.inject.Inject; import javax.inject.Named; @@ -449,7 +448,6 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner { } @Provides - @Named("besuPluginContext") public BesuPluginContextImpl providePluginContext( final StorageServiceImpl storageService, final SecurityModuleServiceImpl securityModuleService, @@ -549,17 +547,17 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner { static class MockBesuCommandModule { @Provides - BesuCommand provideBesuCommand(final AcceptanceTestBesuComponent component) { + BesuCommand provideBesuCommand(final BesuPluginContextImpl pluginContext) { final BesuCommand besuCommand = new BesuCommand( - component, RlpBlockImporter::new, JsonBlockImporter::new, RlpBlockExporter::new, new RunnerBuilder(), new BesuController.Builder(), - Optional.ofNullable(component.getBesuPluginContext()).orElse(null), - System.getenv()); + pluginContext, + System.getenv(), + LoggerFactory.getLogger(MockBesuCommandModule.class)); besuCommand.toCommandLine(); return besuCommand; } 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 00ea6e1efd..f79ef45b99 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java @@ -84,7 +84,6 @@ import org.hyperledger.besu.cli.util.BesuCommandCustomFactory; import org.hyperledger.besu.cli.util.CommandLineUtils; import org.hyperledger.besu.cli.util.ConfigDefaultValueProviderStrategy; import org.hyperledger.besu.cli.util.VersionProvider; -import org.hyperledger.besu.components.BesuComponent; import org.hyperledger.besu.config.CheckpointConfigOptions; import org.hyperledger.besu.config.GenesisConfigFile; import org.hyperledger.besu.config.GenesisConfigOptions; @@ -865,13 +864,9 @@ public class BesuCommand implements DefaultCommandValues, Runnable { private BesuController besuController; private BesuConfigurationImpl pluginCommonConfiguration; - private BesuComponent besuComponent; private final Supplier metricsSystem = - Suppliers.memoize( - () -> - besuComponent == null || besuComponent.getObservableMetricsSystem() == null - ? MetricsSystemFactory.create(metricsConfiguration()) - : besuComponent.getObservableMetricsSystem()); + Suppliers.memoize(() -> MetricsSystemFactory.create(metricsConfiguration())); + private Vertx vertx; private EnodeDnsConfiguration enodeDnsConfiguration; private KeyValueStorageProvider keyValueStorageProvider; @@ -879,7 +874,6 @@ public class BesuCommand implements DefaultCommandValues, Runnable { /** * Besu command constructor. * - * @param besuComponent BesuComponent which acts as our application context * @param rlpBlockImporter RlpBlockImporter supplier * @param jsonBlockImporterFactory instance of {@code Function} * @param rlpBlockExporterFactory instance of {@code Function} @@ -887,18 +881,18 @@ public class BesuCommand implements DefaultCommandValues, Runnable { * @param controllerBuilder instance of BesuController.Builder * @param besuPluginContext instance of BesuPluginContextImpl * @param environment Environment variables map + * @param commandLogger instance of Logger for outputting to the CLI */ public BesuCommand( - final BesuComponent besuComponent, final Supplier rlpBlockImporter, final Function jsonBlockImporterFactory, final Function rlpBlockExporterFactory, final RunnerBuilder runnerBuilder, final BesuController.Builder controllerBuilder, final BesuPluginContextImpl besuPluginContext, - final Map environment) { + final Map environment, + final Logger commandLogger) { this( - besuComponent, rlpBlockImporter, jsonBlockImporterFactory, rlpBlockExporterFactory, @@ -914,13 +908,13 @@ public class BesuCommand implements DefaultCommandValues, Runnable { new TransactionSelectionServiceImpl(), new TransactionPoolValidatorServiceImpl(), new TransactionSimulationServiceImpl(), - new BlockchainServiceImpl()); + new BlockchainServiceImpl(), + commandLogger); } /** * Overloaded Besu command constructor visible for testing. * - * @param besuComponent BesuComponent which acts as our application context * @param rlpBlockImporter RlpBlockImporter supplier * @param jsonBlockImporterFactory instance of {@code Function} * @param rlpBlockExporterFactory instance of {@code Function} @@ -937,10 +931,10 @@ public class BesuCommand implements DefaultCommandValues, Runnable { * @param transactionValidatorServiceImpl instance of TransactionValidatorServiceImpl * @param transactionSimulationServiceImpl instance of TransactionSimulationServiceImpl * @param blockchainServiceImpl instance of BlockchainServiceImpl + * @param commandLogger instance of Logger for outputting to the CLI */ @VisibleForTesting protected BesuCommand( - final BesuComponent besuComponent, final Supplier rlpBlockImporter, final Function jsonBlockImporterFactory, final Function rlpBlockExporterFactory, @@ -956,9 +950,10 @@ public class BesuCommand implements DefaultCommandValues, Runnable { final TransactionSelectionServiceImpl transactionSelectionServiceImpl, final TransactionPoolValidatorServiceImpl transactionValidatorServiceImpl, final TransactionSimulationServiceImpl transactionSimulationServiceImpl, - final BlockchainServiceImpl blockchainServiceImpl) { - this.besuComponent = besuComponent; - this.logger = besuComponent.getBesuCommandLogger(); + final BlockchainServiceImpl blockchainServiceImpl, + final Logger commandLogger) { + + this.logger = commandLogger; this.rlpBlockImporter = rlpBlockImporter; this.rlpBlockExporterFactory = rlpBlockExporterFactory; this.jsonBlockImporterFactory = jsonBlockImporterFactory; @@ -970,8 +965,13 @@ public class BesuCommand implements DefaultCommandValues, Runnable { this.securityModuleService = securityModuleService; this.permissioningService = permissioningService; this.privacyPluginService = privacyPluginService; - this.pluginCommonConfiguration = new BesuConfigurationImpl(); - besuPluginContext.addService(BesuConfiguration.class, pluginCommonConfiguration); + if (besuPluginContext.getService(BesuConfigurationImpl.class).isPresent()) { + this.pluginCommonConfiguration = + besuPluginContext.getService(BesuConfigurationImpl.class).get(); + } else { + this.pluginCommonConfiguration = new BesuConfigurationImpl(); + besuPluginContext.addService(BesuConfiguration.class, this.pluginCommonConfiguration); + } this.rpcEndpointServiceImpl = rpcEndpointServiceImpl; this.transactionSelectionServiceImpl = transactionSelectionServiceImpl; this.transactionValidatorServiceImpl = transactionValidatorServiceImpl; @@ -1821,9 +1821,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { */ public BesuController buildController() { try { - return this.besuComponent == null - ? getControllerBuilder().build() - : getControllerBuilder().besuComponent(this.besuComponent).build(); + return setupControllerBuilder().build(); } catch (final Exception e) { throw new ExecutionException(this.commandLine, e.getMessage(), e); } @@ -1834,7 +1832,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { * * @return instance of BesuControllerBuilder */ - public BesuControllerBuilder getControllerBuilder() { + public BesuControllerBuilder setupControllerBuilder() { pluginCommonConfiguration .init(dataDir(), dataDir().resolve(DATABASE_PATH), getDataStorageConfiguration()) .withMiningParameters(miningParametersSupplier.get()) @@ -2800,7 +2798,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { builder.setTxPoolImplementation(buildTransactionPoolConfiguration().getTxPoolImplementation()); builder.setWorldStateUpdateMode(unstableEvmOptions.toDomainObject().worldUpdaterMode()); - builder.setPluginContext(besuComponent.getBesuPluginContext()); + builder.setPluginContext(this.besuPluginContext); return builder.build(); } 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 3d1630013b..9a0a453768 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 @@ -254,7 +254,7 @@ public class BlocksSubCommand implements Runnable { // Set some defaults return parentCommand .parentCommand - .getControllerBuilder() + .setupControllerBuilder() // set to mainnet genesis block so validation rules won't reject it. .clock(Clock.fixed(Instant.ofEpochSecond(startTime), ZoneOffset.UTC)) .miningParameters(getMiningParameters()) @@ -374,7 +374,7 @@ public class BlocksSubCommand implements Runnable { private BesuController createBesuController() { return parentCommand .parentCommand - .getControllerBuilder() + .setupControllerBuilder() .miningParameters(MiningParameters.newDefault()) .build(); } 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 e054bfb615..6fe6d058b3 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 @@ -87,7 +87,7 @@ public class TrieLogSubCommand implements Runnable { // disable limit trie logs to avoid preloading during subcommand execution return parentCommand .besuCommand - .getControllerBuilder() + .setupControllerBuilder() .dataStorageConfiguration( ImmutableDataStorageConfiguration.copyOf(config).withBonsaiLimitTrieLogsEnabled(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 6ce62b518e..86aa8c7594 100644 --- a/besu/src/main/java/org/hyperledger/besu/components/BesuCommandModule.java +++ b/besu/src/main/java/org/hyperledger/besu/components/BesuCommandModule.java @@ -22,8 +22,8 @@ import org.hyperledger.besu.chainimport.RlpBlockImporter; import org.hyperledger.besu.cli.BesuCommand; import org.hyperledger.besu.controller.BesuController; import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration; +import org.hyperledger.besu.services.BesuPluginContextImpl; -import java.util.Optional; import javax.inject.Named; import javax.inject.Singleton; @@ -42,17 +42,19 @@ public class BesuCommandModule { @Provides @Singleton - BesuCommand provideBesuCommand(final BesuComponent besuComponent) { + BesuCommand provideBesuCommand( + final BesuPluginContextImpl pluginContext, + final @Named("besuCommandLogger") Logger commandLogger) { final BesuCommand besuCommand = new BesuCommand( - besuComponent, RlpBlockImporter::new, JsonBlockImporter::new, RlpBlockExporter::new, new RunnerBuilder(), new BesuController.Builder(), - Optional.ofNullable(besuComponent.getBesuPluginContext()).orElse(null), - System.getenv()); + pluginContext, + System.getenv(), + commandLogger); besuCommand.toCommandLine(); return besuCommand; } diff --git a/besu/src/main/java/org/hyperledger/besu/components/BesuComponent.java b/besu/src/main/java/org/hyperledger/besu/components/BesuComponent.java index ba31fccb2b..9f810a6dc6 100644 --- a/besu/src/main/java/org/hyperledger/besu/components/BesuComponent.java +++ b/besu/src/main/java/org/hyperledger/besu/components/BesuComponent.java @@ -75,7 +75,6 @@ public interface BesuComponent { * * @return BesuPluginContextImpl */ - @Named("besuPluginContext") BesuPluginContextImpl getBesuPluginContext(); /** diff --git a/besu/src/main/java/org/hyperledger/besu/components/BesuPluginContextModule.java b/besu/src/main/java/org/hyperledger/besu/components/BesuPluginContextModule.java index 8ebae32bb2..d62ab70224 100644 --- a/besu/src/main/java/org/hyperledger/besu/components/BesuPluginContextModule.java +++ b/besu/src/main/java/org/hyperledger/besu/components/BesuPluginContextModule.java @@ -14,9 +14,10 @@ */ package org.hyperledger.besu.components; +import org.hyperledger.besu.plugin.services.BesuConfiguration; +import org.hyperledger.besu.services.BesuConfigurationImpl; import org.hyperledger.besu.services.BesuPluginContextImpl; -import javax.inject.Named; import javax.inject.Singleton; import dagger.Module; @@ -29,15 +30,23 @@ public class BesuPluginContextModule { /** Default constructor. */ public BesuPluginContextModule() {} + @Provides + @Singleton + BesuConfigurationImpl provideBesuPluginConfig() { + return new BesuConfigurationImpl(); + } + /** * Creates a BesuPluginContextImpl, used for plugin service discovery. * + * @param pluginConfig the BesuConfigurationImpl * @return the BesuPluginContext */ @Provides - @Named("besuPluginContext") @Singleton - public BesuPluginContextImpl provideBesuPluginContext() { - return new BesuPluginContextImpl(); + public BesuPluginContextImpl provideBesuPluginContext(final BesuConfigurationImpl pluginConfig) { + BesuPluginContextImpl retval = new BesuPluginContextImpl(); + retval.addService(BesuConfiguration.class, pluginConfig); + return retval; } } 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 f6fa2e4798..3dd9641b48 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/CommandTestAbstract.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/CommandTestAbstract.java @@ -229,9 +229,6 @@ public abstract class CommandTestAbstract { @Mock protected Logger mockLogger; - @Mock(lenient = true) - protected BesuComponent mockBesuComponent; - @Captor protected ArgumentCaptor> bytesCollectionCollector; @Captor protected ArgumentCaptor pathArgumentCaptor; @Captor protected ArgumentCaptor stringArgumentCaptor; @@ -384,8 +381,6 @@ public abstract class CommandTestAbstract { lenient() .when(mockBesuPluginContext.getService(TransactionSelectionService.class)) .thenReturn(Optional.of(txSelectionService)); - - when(mockBesuComponent.getBesuCommandLogger()).thenReturn(mockLogger); } @BeforeEach @@ -470,7 +465,6 @@ public abstract class CommandTestAbstract { switch (testType) { case REQUIRED_OPTION: return new TestBesuCommandWithRequiredOption( - mockBesuComponent, () -> rlpBlockImporter, this::jsonBlockImporterFactory, (blockchain) -> rlpBlockExporter, @@ -480,10 +474,10 @@ public abstract class CommandTestAbstract { environment, storageService, securityModuleService, - privacyPluginService); + privacyPluginService, + mockLogger); case PORT_CHECK: return new TestBesuCommand( - mockBesuComponent, () -> rlpBlockImporter, this::jsonBlockImporterFactory, (blockchain) -> rlpBlockExporter, @@ -493,10 +487,10 @@ public abstract class CommandTestAbstract { environment, storageService, securityModuleService, - privacyPluginService); + privacyPluginService, + mockLogger); default: return new TestBesuCommandWithoutPortCheck( - mockBesuComponent, () -> rlpBlockImporter, this::jsonBlockImporterFactory, (blockchain) -> rlpBlockExporter, @@ -506,7 +500,8 @@ public abstract class CommandTestAbstract { environment, storageService, securityModuleService, - privacyPluginService); + privacyPluginService, + mockLogger); } } @@ -536,7 +531,6 @@ public abstract class CommandTestAbstract { private Vertx vertx; TestBesuCommand( - final BesuComponent besuComponent, final Supplier mockBlockImporter, final Function jsonBlockImporterFactory, final Function rlpBlockExporterFactory, @@ -546,9 +540,9 @@ public abstract class CommandTestAbstract { final Map environment, final StorageServiceImpl storageService, final SecurityModuleServiceImpl securityModuleService, - final PrivacyPluginServiceImpl privacyPluginService) { + final PrivacyPluginServiceImpl privacyPluginService, + final Logger commandLogger) { super( - besuComponent, mockBlockImporter, jsonBlockImporterFactory, rlpBlockExporterFactory, @@ -564,7 +558,8 @@ public abstract class CommandTestAbstract { new TransactionSelectionServiceImpl(), new TransactionPoolValidatorServiceImpl(), new TransactionSimulationServiceImpl(), - new BlockchainServiceImpl()); + new BlockchainServiceImpl(), + commandLogger); } @Override @@ -635,7 +630,6 @@ public abstract class CommandTestAbstract { private final Boolean acceptTermsAndConditions = false; TestBesuCommandWithRequiredOption( - final BesuComponent besuComponent, final Supplier mockBlockImporter, final Function jsonBlockImporterFactory, final Function rlpBlockExporterFactory, @@ -645,9 +639,9 @@ public abstract class CommandTestAbstract { final Map environment, final StorageServiceImpl storageService, final SecurityModuleServiceImpl securityModuleService, - final PrivacyPluginServiceImpl privacyPluginService) { + final PrivacyPluginServiceImpl privacyPluginService, + final Logger commandLogger) { super( - besuComponent, mockBlockImporter, jsonBlockImporterFactory, rlpBlockExporterFactory, @@ -657,7 +651,8 @@ public abstract class CommandTestAbstract { environment, storageService, securityModuleService, - privacyPluginService); + privacyPluginService, + commandLogger); } public Boolean getAcceptTermsAndConditions() { @@ -669,7 +664,6 @@ public abstract class CommandTestAbstract { public static class TestBesuCommandWithoutPortCheck extends TestBesuCommand { TestBesuCommandWithoutPortCheck( - final BesuComponent context, final Supplier mockBlockImporter, final Function jsonBlockImporterFactory, final Function rlpBlockExporterFactory, @@ -679,9 +673,9 @@ public abstract class CommandTestAbstract { final Map environment, final StorageServiceImpl storageService, final SecurityModuleServiceImpl securityModuleService, - final PrivacyPluginServiceImpl privacyPluginService) { + final PrivacyPluginServiceImpl privacyPluginService, + final Logger commandLogger) { super( - context, mockBlockImporter, jsonBlockImporterFactory, rlpBlockExporterFactory, @@ -691,7 +685,8 @@ public abstract class CommandTestAbstract { environment, storageService, securityModuleService, - privacyPluginService); + privacyPluginService, + commandLogger); } @Override From dcfcb9a68c00bae74242d722cb27cebc0c28fa66 Mon Sep 17 00:00:00 2001 From: Gabriel-Trintinalia Date: Wed, 4 Sep 2024 09:55:25 +1000 Subject: [PATCH 183/259] Fix incorrect key filtering in `LayeredKeyValueStorage` stream (#7535) Signed-off-by: Gabriel-Trintinalia --- .../segmented/LayeredKeyValueStorageTest.java | 339 ++++++++++++++++++ .../kvstore/LayeredKeyValueStorage.java | 103 +++--- 2 files changed, 390 insertions(+), 52 deletions(-) create mode 100644 plugins/rocksdb/src/test/java/org/hyperledger/besu/plugin/services/storage/rocksdb/segmented/LayeredKeyValueStorageTest.java diff --git a/plugins/rocksdb/src/test/java/org/hyperledger/besu/plugin/services/storage/rocksdb/segmented/LayeredKeyValueStorageTest.java b/plugins/rocksdb/src/test/java/org/hyperledger/besu/plugin/services/storage/rocksdb/segmented/LayeredKeyValueStorageTest.java new file mode 100644 index 0000000000..6ecc057d6f --- /dev/null +++ b/plugins/rocksdb/src/test/java/org/hyperledger/besu/plugin/services/storage/rocksdb/segmented/LayeredKeyValueStorageTest.java @@ -0,0 +1,339 @@ +/* + * 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.services.storage.rocksdb.segmented; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.hyperledger.besu.plugin.services.storage.SegmentIdentifier; +import org.hyperledger.besu.plugin.services.storage.SegmentedKeyValueStorage; +import org.hyperledger.besu.services.kvstore.LayeredKeyValueStorage; + +import java.util.List; +import java.util.NavigableMap; +import java.util.Optional; +import java.util.TreeMap; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.apache.commons.lang3.tuple.Pair; +import org.apache.tuweni.bytes.Bytes; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +public class LayeredKeyValueStorageTest { + + @Mock private SegmentedKeyValueStorage parentStorage; + + private LayeredKeyValueStorage layeredKeyValueStorage; + private SegmentIdentifier segmentId; + + @BeforeEach + void setUp() { + segmentId = mock(SegmentIdentifier.class); + layeredKeyValueStorage = new LayeredKeyValueStorage(parentStorage); + } + + @Test + void shouldReturnEmptyStreamWhenParentAndLayerAreEmpty() { + when(parentStorage.stream(segmentId)).thenReturn(Stream.empty()); + Stream> result = layeredKeyValueStorage.stream(segmentId); + assertTrue(result.collect(Collectors.toList()).isEmpty()); + } + + private ConcurrentMap>> + createSegmentMap() { + ConcurrentMap>> map = + new ConcurrentHashMap<>(); + NavigableMap> segmentMap = new TreeMap<>(); + map.put(segmentId, segmentMap); + return map; + } + + @Test + void shouldReturnParentDataWhenLayerIsEmpty() { + byte[] key1 = {1}; + byte[] value1 = {10}; + + when(parentStorage.stream(segmentId)).thenReturn(Stream.of(Pair.of(key1, value1))); + + Stream> result = layeredKeyValueStorage.stream(segmentId); + + List> resultList = result.collect(Collectors.toList()); + assertEquals(1, resultList.size()); + assertArrayEquals(key1, resultList.get(0).getKey()); + assertArrayEquals(value1, resultList.get(0).getValue()); + } + + @Test + void shouldReturnLayerDataWhenParentIsEmpty() { + byte[] key1 = {1}; + byte[] value1 = {10}; + + when(parentStorage.stream(segmentId)).thenReturn(Stream.empty()); + + var hashValueStore = createSegmentMap(); + hashValueStore.get(segmentId).put(Bytes.wrap(key1), Optional.of(value1)); + layeredKeyValueStorage = new LayeredKeyValueStorage(hashValueStore, parentStorage); + + Stream> result = layeredKeyValueStorage.stream(segmentId); + List> resultList = result.toList(); + assertEquals(1, resultList.size()); + assertArrayEquals(key1, resultList.get(0).getKey()); + assertArrayEquals(value1, resultList.get(0).getValue()); + } + + @Test + void shouldMergeParentAndLayerData() { + byte[] key1 = {1}; + byte[] value1 = {10}; + byte[] key2 = {2}; + byte[] value2 = {20}; + byte[] key3 = {3}; + byte[] value3 = {30}; + + when(parentStorage.stream(segmentId)) + .thenReturn(Stream.of(Pair.of(key1, value1), Pair.of(key3, value3))); + + var hashValueStore = createSegmentMap(); + hashValueStore.get(segmentId).put(Bytes.wrap(key2), Optional.of(value2)); + layeredKeyValueStorage = new LayeredKeyValueStorage(hashValueStore, parentStorage); + + Stream> result = layeredKeyValueStorage.stream(segmentId); + + List> resultList = result.toList(); + assertEquals(3, resultList.size()); + assertArrayEquals(key1, resultList.get(0).getKey()); + assertArrayEquals(value1, resultList.get(0).getValue()); + assertArrayEquals(key2, resultList.get(1).getKey()); + assertArrayEquals(value2, resultList.get(1).getValue()); + assertArrayEquals(key3, resultList.get(2).getKey()); + assertArrayEquals(value3, resultList.get(2).getValue()); + } + + @Test + void shouldPreferLayerDataOverParentDataForSameKey() { + byte[] key = {1}; + byte[] parentValue = {10}; + byte[] layerValue = {20}; + + when(parentStorage.stream(segmentId)).thenReturn(Stream.of(Pair.of(key, parentValue))); + + var hashValueStore = createSegmentMap(); + hashValueStore.get(segmentId).put(Bytes.wrap(key), Optional.of(layerValue)); + layeredKeyValueStorage = new LayeredKeyValueStorage(hashValueStore, parentStorage); + + Stream> result = layeredKeyValueStorage.stream(segmentId); + + List> resultList = result.toList(); + assertEquals(1, resultList.size()); + assertArrayEquals(key, resultList.get(0).getKey()); + // Layer value should be returned + assertArrayEquals(layerValue, resultList.get(0).getValue()); + } + + @Test + void shouldNotStreamKeyIfLayerKeyIsEmpty() { + byte[] key1 = {1}; + byte[] value1 = {10}; + byte[] key2 = {2}; + byte[] value2 = {20}; + + when(parentStorage.stream(segmentId)) + .thenReturn(Stream.of(Pair.of(key1, value1), Pair.of(key2, value2))); + + var hashValueStore = createSegmentMap(); + hashValueStore.get(segmentId).put(Bytes.wrap(key1), Optional.empty()); + + layeredKeyValueStorage = new LayeredKeyValueStorage(hashValueStore, parentStorage); + + var resultList = layeredKeyValueStorage.stream(segmentId).toList(); + assertEquals(1, resultList.size()); + assertArrayEquals(key2, resultList.get(0).getKey()); + assertArrayEquals(value2, resultList.get(0).getValue()); + } + + /** + * Tests that the stream method correctly handles multiple layers where the current layer + * overrides the parent layers. + */ + @Test + void shouldStreamWithMultipleLayersAndCurrentLayerOverrides() { + byte[] key1 = {1}; + byte[] value1 = {10}; + byte[] key2 = {2}; + byte[] value2 = {20}; + byte[] key3 = {3}; + byte[] value3 = {30}; + + // Parent Layer 0 + when(parentStorage.stream(segmentId)) + .thenReturn(Stream.of(Pair.of(key1, null), Pair.of(key2, value2))); + + // Parent Layer 1 + var parentLayer1 = createSegmentMap(); + parentLayer1.get(segmentId).put(Bytes.wrap(key1), Optional.of(value1)); + parentLayer1.get(segmentId).put(Bytes.wrap(key2), Optional.of(value2)); + + // Current Layer + var currentLayer = createSegmentMap(); + currentLayer.get(segmentId).put(Bytes.wrap(key1), Optional.empty()); + currentLayer.get(segmentId).put(Bytes.wrap(key3), Optional.of(value3)); + + layeredKeyValueStorage = + new LayeredKeyValueStorage( + currentLayer, new LayeredKeyValueStorage(parentLayer1, parentStorage)); + + Stream> result = layeredKeyValueStorage.stream(segmentId); + + List> resultList = result.toList(); + assertEquals(2, resultList.size()); + assertArrayEquals(key2, resultList.get(0).getKey()); + assertArrayEquals(value2, resultList.get(0).getValue()); + assertArrayEquals(key3, resultList.get(1).getKey()); + assertArrayEquals(value3, resultList.get(1).getValue()); + } + + /** + * Tests that the stream method correctly handles multiple layers where the current layer + * overrides the parent layers with specific values. + */ + @Test + void shouldStreamWithMultipleLayersAndCurrentLayerOverridesWithValues() { + byte[] key1 = {1}; + byte[] value1 = {10}; + byte[] key2 = {2}; + byte[] value2 = {20}; + byte[] key3 = {3}; + byte[] value3 = {30}; + + // Parent Layer 0 + when(parentStorage.stream(segmentId)) + .thenReturn(Stream.of(Pair.of(key1, value1), Pair.of(key2, value2))); + + // Parent Layer 1 + var parentLayer1 = createSegmentMap(); + parentLayer1.get(segmentId).put(Bytes.wrap(key1), Optional.empty()); + parentLayer1.get(segmentId).put(Bytes.wrap(key2), Optional.of(value2)); + + // Current Layer + var currentLayer = createSegmentMap(); + currentLayer.get(segmentId).put(Bytes.wrap(key1), Optional.of(value1)); + currentLayer.get(segmentId).put(Bytes.wrap(key3), Optional.of(value3)); + + layeredKeyValueStorage = + new LayeredKeyValueStorage( + currentLayer, new LayeredKeyValueStorage(parentLayer1, parentStorage)); + + Stream> result = layeredKeyValueStorage.stream(segmentId); + + List> resultList = result.toList(); + assertEquals(3, resultList.size()); + assertArrayEquals(key1, resultList.get(0).getKey()); + assertArrayEquals(value1, resultList.get(0).getValue()); + assertArrayEquals(key2, resultList.get(1).getKey()); + assertArrayEquals(value2, resultList.get(1).getValue()); + assertArrayEquals(key3, resultList.get(2).getKey()); + assertArrayEquals(value3, resultList.get(2).getValue()); + } + + /** + * Tests that the stream method correctly handles multiple layers where the current layer + * overrides the parent layers with empty values. + */ + @Test + void shouldStreamWithMultipleLayersAndCurrentLayerOverridesWithEmptyValues() { + byte[] key1 = {1}; + byte[] value1 = {10}; + byte[] key2 = {2}; + byte[] value2 = {20}; + byte[] key3 = {3}; + byte[] value3 = {30}; + + // Parent Layer 0 + when(parentStorage.stream(segmentId)) + .thenReturn(Stream.of(Pair.of(key1, null), Pair.of(key2, value2))); + + // Parent Layer 1 + var parentLayer1 = createSegmentMap(); + parentLayer1.get(segmentId).put(Bytes.wrap(key1), Optional.empty()); + parentLayer1.get(segmentId).put(Bytes.wrap(key2), Optional.of(value2)); + + // Current Layer + var currentLayer = createSegmentMap(); + currentLayer.get(segmentId).put(Bytes.wrap(key1), Optional.of(value1)); + currentLayer.get(segmentId).put(Bytes.wrap(key3), Optional.of(value3)); + + layeredKeyValueStorage = + new LayeredKeyValueStorage( + currentLayer, new LayeredKeyValueStorage(parentLayer1, parentStorage)); + + Stream> result = layeredKeyValueStorage.stream(segmentId); + + List> resultList = result.toList(); + assertEquals(3, resultList.size()); + assertArrayEquals(key1, resultList.get(0).getKey()); + assertArrayEquals(value1, resultList.get(0).getValue()); + assertArrayEquals(key2, resultList.get(1).getKey()); + assertArrayEquals(value2, resultList.get(1).getValue()); + assertArrayEquals(key3, resultList.get(2).getKey()); + assertArrayEquals(value3, resultList.get(2).getValue()); + } + + /** + * Tests that the stream method correctly handles a parent layer and a current layer where the + * current layer overrides the parent layer. + */ + @Test + void shouldStreamWithParentLayerAndCurrentLayerOverrides() { + byte[] key1 = {1}; + byte[] value1 = {10}; + byte[] key2 = {2}; + byte[] value2 = {20}; + byte[] key3 = {3}; + byte[] value3 = {30}; + + // Parent Layer 0 + when(parentStorage.stream(segmentId)) + .thenReturn(Stream.of(Pair.of(key1, null), Pair.of(key2, value2))); + + // Current Layer + var currentLayer = createSegmentMap(); + currentLayer.get(segmentId).put(Bytes.wrap(key1), Optional.of(value1)); + currentLayer.get(segmentId).put(Bytes.wrap(key3), Optional.of(value3)); + + layeredKeyValueStorage = new LayeredKeyValueStorage(currentLayer, parentStorage); + + Stream> result = layeredKeyValueStorage.stream(segmentId); + + List> resultList = result.toList(); + assertEquals(3, resultList.size()); + assertArrayEquals(key1, resultList.get(0).getKey()); + assertArrayEquals(value1, resultList.get(0).getValue()); + assertArrayEquals(key2, resultList.get(1).getKey()); + assertArrayEquals(value2, resultList.get(1).getValue()); + assertArrayEquals(key3, resultList.get(2).getKey()); + assertArrayEquals(value3, resultList.get(2).getValue()); + } +} diff --git a/services/kvstore/src/main/java/org/hyperledger/besu/services/kvstore/LayeredKeyValueStorage.java b/services/kvstore/src/main/java/org/hyperledger/besu/services/kvstore/LayeredKeyValueStorage.java index de9abcaf29..9f44c3bc79 100644 --- a/services/kvstore/src/main/java/org/hyperledger/besu/services/kvstore/LayeredKeyValueStorage.java +++ b/services/kvstore/src/main/java/org/hyperledger/besu/services/kvstore/LayeredKeyValueStorage.java @@ -178,61 +178,60 @@ public class LayeredKeyValueStorage extends SegmentedInMemoryKeyValueStorage throwIfClosed(); var ourLayerState = hashValueStore.computeIfAbsent(segmentId, s -> newSegmentMap()); - // otherwise, interleave the sorted streams: - final PeekingIterator>> ourIterator = - new PeekingIterator<>( - ourLayerState.entrySet().stream() - .filter(entry -> entry.getValue().isPresent()) - .iterator()); - - final PeekingIterator> parentIterator = + PeekingIterator>> ourIterator = + new PeekingIterator<>(ourLayerState.entrySet().stream().iterator()); + PeekingIterator> parentIterator = new PeekingIterator<>(parent.stream(segmentId).iterator()); return StreamSupport.stream( - Spliterators.spliteratorUnknownSize( - new Iterator<>() { - @Override - public boolean hasNext() { - return ourIterator.hasNext() || parentIterator.hasNext(); - } - - private Pair mapEntryToPair( - final Map.Entry> entry) { - return Optional.of(entry) - .map( - e -> - Pair.of( - e.getKey().toArrayUnsafe(), - e.getValue().orElseGet(() -> new byte[0]))) - .get(); - } - - @Override - public Pair next() { - var ourPeek = ourIterator.peek(); - var parentPeek = parentIterator.peek(); - - if (ourPeek == null || parentPeek == null) { - return ourPeek == null - ? parentIterator.next() - : mapEntryToPair(ourIterator.next()); - } - - // otherwise compare: - int comparison = ourPeek.getKey().compareTo(Bytes.wrap(parentPeek.getKey())); - if (comparison < 0) { - return mapEntryToPair(ourIterator.next()); - } else if (comparison == 0) { - // skip dupe key from parent, return ours: - parentIterator.next(); - return mapEntryToPair(ourIterator.next()); - } else { - return parentIterator.next(); - } - } - }, - ORDERED | SORTED | DISTINCT), - false); + Spliterators.spliteratorUnknownSize( + new LayeredIterator(ourIterator, parentIterator), ORDERED | SORTED | DISTINCT), + false) + .filter(e -> e.getValue() != null); + } + + private static class LayeredIterator implements Iterator> { + private final PeekingIterator>> ourIterator; + private final PeekingIterator> parentIterator; + + LayeredIterator( + final PeekingIterator>> ourIterator, + final PeekingIterator> parentIterator) { + this.ourIterator = ourIterator; + this.parentIterator = parentIterator; + } + + @Override + public boolean hasNext() { + return ourIterator.hasNext() || parentIterator.hasNext(); + } + + private Pair mapEntryToPair(final Map.Entry> entry) { + byte[] value = entry.getValue().orElse(null); + return Pair.of(entry.getKey().toArrayUnsafe(), value); + } + + @Override + public Pair next() { + var ourPeek = ourIterator.peek(); + var parentPeek = parentIterator.peek(); + + if (ourPeek == null || parentPeek == null) { + return ourPeek == null ? parentIterator.next() : mapEntryToPair(ourIterator.next()); + } + + // otherwise compare: + int comparison = ourPeek.getKey().compareTo(Bytes.wrap(parentPeek.getKey())); + if (comparison < 0) { + return mapEntryToPair(ourIterator.next()); + } else if (comparison == 0) { + // skip dupe key from parent, return ours: + parentIterator.next(); + return mapEntryToPair(ourIterator.next()); + } else { + return parentIterator.next(); + } + } } @Override From 1d9fa864246b1ae45461f946227828aa159baf15 Mon Sep 17 00:00:00 2001 From: Fabio Di Fabio Date: Wed, 4 Sep 2024 03:20:12 +0200 Subject: [PATCH 184/259] Fix LayersTest flaky test by using the `DeterministicEthScheduler` (#7556) Signed-off-by: Fabio Di Fabio --- .../besu/ethereum/eth/transactions/layered/LayersTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 84ac759a79..3df5fb6d3a 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 @@ -45,7 +45,7 @@ import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolMetrics; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolReplacementHandler; import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; import org.hyperledger.besu.evm.account.Account; -import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; +import org.hyperledger.besu.testutil.DeterministicEthScheduler; import java.util.ArrayList; import java.util.Arrays; @@ -174,7 +174,7 @@ public class LayersTest extends BaseTransactionPoolTest { final TransactionPoolMetrics txPoolMetrics = new TransactionPoolMetrics(metricsSystem); final EvictCollectorLayer evictCollector = new EvictCollectorLayer(txPoolMetrics); - final EthScheduler ethScheduler = new EthScheduler(1, 4, 1, 1, new NoOpMetricsSystem()); + final EthScheduler ethScheduler = new DeterministicEthScheduler(); final SparseTransactions sparseTransactions = new SparseTransactions( poolConfig, From ffd23e122d729ec7373a001071d7327ceaaaf244 Mon Sep 17 00:00:00 2001 From: Sally MacFarlane Date: Wed, 4 Sep 2024 11:56:30 +1000 Subject: [PATCH 185/259] [CHANGELOG] remove docs updates from changelog (#7562) * remove docs updates from changelog * add changelog entry Signed-off-by: Sally MacFarlane --------- Signed-off-by: Sally MacFarlane --- CHANGELOG.md | 165 ++------------------------------------------------- 1 file changed, 5 insertions(+), 160 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index edaa050268..aab2389fc5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ ### Additions and Improvements - Include current chain head block when computing `eth_maxPriorityFeePerGas` [#7485](https://github.com/hyperledger/besu/pull/7485) +- Remove (old) documentation updates from the changelog [#7562](https://github.com/hyperledger/besu/pull/7562) ### Bug fixes - The genesis config override `contractSizeLimit` was not wired into code size limits [#7557](https://github.com/hyperledger/besu/issues/7557) @@ -3006,10 +3007,7 @@ For compatibility with ETC Agharta upgrade, use 1.3.7 or later. - Performance improvements: * Multithread Websockets to increase throughput [\#231](https://github.com/hyperledger/besu/pull/231) * NewBlockHeaders performance improvement [\#230](https://github.com/hyperledger/besu/pull/230) -- EIP2384 - Ice Age Adustment around Istanbul [\#211](https://github.com/hyperledger/besu/pull/211) -- Documentation updates include: - * [Configuring mining using the Stratum protocol](https://besu.hyperledger.org/en/latest/HowTo/Configure/Configure-Mining/) - * [ETC network command line options](https://besu.hyperledger.org/en/latest/Reference/CLI/CLI-Syntax/#network) +- EIP2384 - Ice Age Adjustment around Istanbul [\#211](https://github.com/hyperledger/besu/pull/211) - Hard Fork Support: * MuirGlacier for Ethereum Mainnet and Ropsten Testnet * Agharta for Kotti and Mordor Testnets @@ -3135,16 +3133,6 @@ For compatibility with ETC Agharta upgrade, use 1.3.7 or later. - Store db metadata file in the root data directory. [\#46](https://github.com/hyperledger/besu/pull/46) - Add `--target-gas-limit` command line option. [\#24](https://github.com/hyperledger/besu/pull/24)(thanks to new contributor [cfelde](https://github.com/cfelde)) - Allow private contracts to access public state. [\#9](https://github.com/hyperledger/besu/pull/9) -- Documentation updates include: - - Added [sample load balancer configurations](https://besu.hyperledger.org/en/latest/HowTo/Configure/Configure-HA/Sample-Configuration/) - - Added [`retesteth`](https://besu.hyperledger.org/en/latest/Reference/CLI/CLI-Subcommands/#retesteth) subcommand - - Added [`debug_accountRange`](https://besu.hyperledger.org/en/latest/Reference/API-Methods/#debug_accountrange) JSON-RPC API method - - Clarified purpose of [static nodes](https://besu.hyperledger.org/en/latest/HowTo/Find-and-Connect/Managing-Peers/#static-nodes) - - Added links [Kubernetes reference implementations](https://besu.hyperledger.org/en/latest/HowTo/Deploy/Kubernetes/) - - Added content about [access between private and public states](https://besu.hyperledger.org/en/latest/Concepts/Privacy/Privacy-Groups/#access-between-states) - - Added restriction that [account permissioning cannot be used with random key signing](https://besu.hyperledger.org/en/latest/HowTo/Use-Privacy/Sign-Privacy-Marker-Transactions/). - - Added high availability requirement for [private transaction manager](https://besu.hyperledger.org/en/latest/Concepts/Privacy/Privacy-Overview/#availability) (ie, Orion) - - Added [genesis file reference](https://besu.hyperledger.org/en/latest/Reference/Config-Items/) ### Technical Improvements @@ -3214,11 +3202,6 @@ For compatibility with ETC Agharta upgrade, use 1.3.7 or later. - Added eea\_getTransactionCount Json Rpc [\#1861](https://github.com/PegaSysEng/pantheon/pull/1861) - PrivacyMarkerTransaction to be signed with a randomly generated key [\#1844](https://github.com/PegaSysEng/pantheon/pull/1844) - Implement eth\_getproof JSON RPC API [\#1824](https://github.com/PegaSysEng/pantheon/pull/1824) (thanks to [matkt](https://github.com/matkt)) -- Documentation updates include: - - [Improved navigation](https://docs.pantheon.pegasys.tech/en/latest/) - - [Added permissioning diagram](https://docs.pantheon.pegasys.tech/en/latest/Concepts/Permissioning/Permissioning-Overview/#onchain) - - [Added Responsible Disclosure policy](https://docs.pantheon.pegasys.tech/en/latest/Reference/Responsible-Disclosure/) - - [Added `blocks export` subcommand](https://besu.hyperledger.org/en/latest/Reference/CLI/CLI-Subcommands/#export) ### Technical Improvements - Update the `pantheon blocks export` command usage [\#1887](https://github.com/PegaSysEng/pantheon/pull/1887) (thanks to [matkt](https://github.com/matkt)) @@ -3326,18 +3309,10 @@ For compatibility with ETC Agharta upgrade, use 1.3.7 or later. - Added JSON-RPC API to report validator block production information [#1687](https://github.com/PegaSysEng/pantheon/pull/1687) (thanks to [matkt](https://github.com/matkt)) - Added Mark Sweep Pruner [#1638](https://github.com/PegaSysEng/pantheon/pull/1638) - Added the Blake2b F compression function as a precompile in Besu [#1614](https://github.com/PegaSysEng/pantheon/pull/1614) (thanks to [iikirilov](https://github.com/iikirilov)) -- Documentation updates include: - - Added CPU requirements [#1734](https://github.com/PegaSysEng/pantheon/pull/1734) - - Added reference to Ansible role [#1733](https://github.com/PegaSysEng/pantheon/pull/1733) - - Updated revert reason example [#1754](https://github.com/PegaSysEng/pantheon/pull/1754) - - Added content on deploying for production [#1774](https://github.com/PegaSysEng/pantheon/pull/1774) - - Updated docker docs for location of data path [#1790](https://github.com/PegaSysEng/pantheon/pull/1790) - - Updated permissiong documentation [#1792](https://github.com/PegaSysEng/pantheon/pull/1792) [#1652](https://github.com/PegaSysEng/pantheon/pull/1652) - Added permissioning webinar in the resources [#1717](https://github.com/PegaSysEng/pantheon/pull/1717) - Add web3.js-eea reference doc [#1617](https://github.com/PegaSysEng/pantheon/pull/1617) - - Updated privacy documentation [#1650](https://github.com/PegaSysEng/pantheon/pull/1650) [#1721](https://github.com/PegaSysEng/pantheon/pull/1721) [#1722](https://github.com/PegaSysEng/pantheon/pull/1722) @@ -3360,9 +3335,7 @@ For compatibility with ETC Agharta upgrade, use 1.3.7 or later. [#1803](https://github.com/PegaSysEng/pantheon/pull/1803) [#1810](https://github.com/PegaSysEng/pantheon/pull/1810) [#1817](https://github.com/PegaSysEng/pantheon/pull/1817) - - Added documentation for getSignerMetrics [#1723](https://github.com/PegaSysEng/pantheon/pull/1723) (thanks to [matkt](https://github.com/matkt)) - Added Java 11+ as a prerequisite for installing Besu using Homebrew. [#1755](https://github.com/PegaSysEng/pantheon/pull/1755) - - Fixed documentation formatting and typos [#1718](https://github.com/PegaSysEng/pantheon/pull/1718) [#1742](https://github.com/PegaSysEng/pantheon/pull/1742) [#1763](https://github.com/PegaSysEng/pantheon/pull/1763) [#1779](https://github.com/PegaSysEng/pantheon/pull/1779) @@ -3392,25 +3365,6 @@ For compatibility with ETC Agharta upgrade, use 1.3.7 or later. - Add eea\_findPrivacyGroup endpoint to Besu [\#1635](https://github.com/PegaSysEng/pantheon/pull/1635) (thanks to [Puneetha17](https://github.com/Puneetha17)) - Updated eea send raw transaction with privacy group ID [\#1611](https://github.com/PegaSysEng/pantheon/pull/1611) (thanks to [iikirilov](https://github.com/iikirilov)) - Added Revert Reason [\#1603](https://github.com/PegaSysEng/pantheon/pull/1603) -- Documentation updates include: - - Added [UPnP content](https://besu.hyperledger.org/en/latest/HowTo/Find-and-Connect/Using-UPnP/) - - Added [load balancer image](https://besu.hyperledger.org/en/stable/) - - Added [revert reason](https://besu.hyperledger.org/en/latest/HowTo/Send-Transactions/Revert-Reason/) - - Added [admin\_changeLogLevel](https://besu.hyperledger.org/en/latest/Reference/API-Methods/#admin_changeloglevel) JSON RPC API (thanks to [matkt](https://github.com/matkt)) - - Updated for [new Docker image](https://besu.hyperledger.org/en/stable/) - - Added [Docker image migration content](https://besu.hyperledger.org/en/latest/HowTo/Get-Started/Migration-Docker/) - - Added [transaction validation content](https://besu.hyperledger.org/en/latest/Concepts/Transactions/Transaction-Validation/) - - Updated [permissioning overview](https://besu.hyperledger.org/en/stable/) for onchain account permissioning - - Updated [quickstart](https://besu.hyperledger.org/en/latest/HowTo/Deploy/Monitoring-Performance/#monitor-node-performance-using-prometheus) to include Prometheus and Grafana - - Added [remote connections limits options](https://besu.hyperledger.org/en/latest/Reference/CLI/CLI-Syntax/#remote-connections-limit-enabled) - - Updated [web3.js-eea reference](https://docs.pantheon.pegasys.tech/en/latest/Reference/web3js-eea-Methods/) to include privacy group methods - - Updated [onchain permissioning to include account permissioning](hhttps://besu.hyperledger.org/en/latest/Concepts/Permissioning/Onchain-Permissioning/) and [Permissioning Management Dapp](https://besu.hyperledger.org/en/latest/Tutorials/Permissioning/Getting-Started-Onchain-Permissioning/#start-the-development-server-for-the-permissioning-management-dapp) - - Added [deployment procedure for Permissioning Management Dapp](https://besu.hyperledger.org/en/stable/) - - Added privacy content for [EEA-compliant and Besu-extended privacy](https://besu.hyperledger.org/en/latest/Concepts/Privacy/Privacy-Groups/) - - Added content on [creating and managing privacy groups](https://besu.hyperledger.org/en/latest/Reference/web3js-eea-Methods/#createprivacygroup) - - Added content on [accessing private and privacy marker transactions](https://besu.hyperledger.org/en/latest/HowTo/Use-Privacy/Access-Private-Transactions/) - - Added content on [system requirements](https://besu.hyperledger.org/en/latest/HowTo/Get-Started/System-Requirements/) - - Added reference to [Besu role on Galaxy to deploy using Ansible](https://besu.hyperledger.org/en/latest/HowTo/Deploy/Ansible/). ### Technical Improvements @@ -3479,12 +3433,6 @@ For compatibility with ETC Agharta upgrade, use 1.3.7 or later. - Print Besu version when starting [\#1593](https://github.com/PegaSysEng/pantheon/pull/1593) - \[PAN-2746\] Add eea\_createPrivacyGroup & eea\_deletePrivacyGroup endpoint [\#1560](https://github.com/PegaSysEng/pantheon/pull/1560) (thanks to [Puneetha17](https://github.com/Puneetha17)) -Documentation updates include: -- Added [readiness and liveness endpoints](https://besu.hyperledger.org/en/latest/HowTo/Interact/APIs/Using-JSON-RPC-API/#readiness-and-liveness-endpoints) -- Added [high availability content](https://besu.hyperledger.org/en/latest/HowTo/Configure/Configure-HA/High-Availability/) -- Added [web3js-eea client library](https://besu.hyperledger.org/en/latest/Tutorials/Quickstarts/Privacy-Quickstart/#clone-eeajs-libraries) -- Added content on [setting CLI options using environment variables](https://besu.hyperledger.org/en/latest/Reference/CLI/CLI-Syntax/#specifying-options) - ### Technical Improvements - Read config from env vars when no config file specified [\#1639](https://github.com/PegaSysEng/pantheon/pull/1639) @@ -3533,16 +3481,6 @@ Documentation updates include: - Add subscribe and unsubscribe count metrics [\#1541](https://github.com/PegaSysEng/pantheon/pull/1541) - Add pivot block metrics [\#1537](https://github.com/PegaSysEng/pantheon/pull/1537) -Documentation updates include: - -- Updated [IBFT 2.0 tutorial](https://besu.hyperledger.org/en/latest/Tutorials/Private-Network/Create-IBFT-Network/) to use network configuration tool -- Added [debug\_traceBlock\* methods](https://besu.hyperledger.org/en/latest/Reference/API-Methods/#debug_traceblock) -- Reorganised [monitoring documentation](https://besu.hyperledger.org/en/latest/HowTo/Deploy/Monitoring-Performance/) -- Added [link to sample Grafana dashboard](https://besu.hyperledger.org/en/latest/HowTo/Deploy/Monitoring-Performance/#monitor-node-performance-using-prometheus) -- Added [note about replacing transactions in transaction pool](https://besu.hyperledger.org/en/latest/Concepts/Transactions/Transaction-Pool/#replacing-transactions-with-same-nonce) -- Updated [example transaction scripts](https://besu.hyperledger.org/en/latest/HowTo/Send-Transactions/Transactions/#example-javascript-scripts) -- Updated [Alethio Ethstats and Explorer documentation](https://besu.hyperledger.org/en/latest/Concepts/AlethioOverview/) - ### Technical Improvements - PAN-2816: Hiding experimental account permissioning cli options [\#1584](https://github.com/PegaSysEng/pantheon/pull/1584) @@ -3578,14 +3516,6 @@ Documentation updates include: ### Additions and Improvements -Documentation updates include: - -- Added [GraphQL options](https://besu.hyperledger.org/en/latest/Reference/CLI/CLI-Syntax/#graphql-http-cors-origins) -- Added [troubleshooting point about illegal reflective access error](https://besu.hyperledger.org/en/latest/HowTo/Troubleshoot/Troubleshooting/#illegal-reflective-access-error-on-startup) -- Added [trusted bootnode behaviour for permissioning](https://besu.hyperledger.org/en/latest/Concepts/Permissioning/Onchain-Permissioning/#bootnodes) -- Added [how to obtain a WS authentication token](https://besu.hyperledger.org/en/latest/HowTo/Interact/APIs/Authentication/#obtaining-an-authentication-token) -- Updated [example scripts and added package.json file for creating signed transactions](https://besu.hyperledger.org/en/latest/HowTo/Send-Transactions/Transactions/) - ### Technical Improvements - Replaced Void datatype with void [\#1530](https://github.com/PegaSysEng/pantheon/pull/1530) @@ -3634,12 +3564,6 @@ Documentation updates include: - Added [`--tx-pool-retention-hours`](https://besu.hyperledger.org/en/latest/Reference/CLI/CLI-Syntax/#tx-pool-retention-hours) [\#1333](https://github.com/PegaSysEng/pantheon/pull/1333) - Added Genesis file support for specifying the maximum stack size. [\#1431](https://github.com/PegaSysEng/pantheon/pull/1431) - Included transaction details when subscribed to Pending transactions [\#1410](https://github.com/PegaSysEng/pantheon/pull/1410) -- Documentation updates include: - - [Added configuration items specified in the genesis file](https://besu.hyperledger.org/en/latest/Reference/Config-Items/#configuration-items) - - [Added pending transaction details subscription](https://besu.hyperledger.org/en/latest/HowTo/Interact/APIs/RPC-PubSub/#pending-transactionss) - - [Added Troubleshooting content](https://besu.hyperledger.org/en/latest/HowTo/Troubleshoot/Troubleshooting/) - - [Added Privacy Quickstart](https://besu.hyperledger.org/en/latest/Tutorials/Quickstarts/Privacy-Quickstart/) - - [Added privacy roadmap](https://github.com/hyperledger/besu/blob/master/ROADMAP.md) ### Technical Improvements @@ -3747,12 +3671,6 @@ Documentation updates include: - [Privacy](https://besu.hyperledger.org/en/latest/Concepts/Privacy/Privacy-Overview/) - [Onchain Permissioning](https://besu.hyperledger.org/en/latest/Concepts/Permissioning/Permissioning-Overview/#onchain) - [Fastsync](https://besu.hyperledger.org/en/latest/Reference/CLI/CLI-Syntax/#fast-sync-min-peers) -- Documentation updates include: - - Added JSON-RPC methods: - - [`txpool_pantheonStatistics`](https://besu.hyperledger.org/en/latest/Reference/API-Methods/#txpool_besustatistics) - - [`net_services`](https://besu.hyperledger.org/en/latest/Reference/API-Methods/#net_services) - - [Updated to indicate Docker image doesn't run on Windows](https://besu.hyperledger.org/en/latest/HowTo/Get-Started/Run-Docker-Image/) - - [Added how to configure a free gas network](https://besu.hyperledger.org/en/latest/HowTo/Configure/FreeGas/) ### Technical Improvements @@ -3806,17 +3724,6 @@ Documentation updates include: ### Additions and Improvements - Notify of dropped messages [\#1156](https://github.com/PegaSysEng/pantheon/pull/1156) -- Documentation updates include: - - Added [Permissioning Overview](https://besu.hyperledger.org/en/latest/Concepts/Permissioning/Permissioning-Overview/) - - Added content on [Network vs Node Configuration](https://besu.hyperledger.org/en/latest/HowTo/Configure/Using-Configuration-File/) - - Updated [RAM requirements](https://besu.hyperledger.org/en/latest/HowTo/Get-Started/System-Requirements/#ram) - - Added [Privacy Overview](https://besu.hyperledger.org/en/latest/Concepts/Privacy/Privacy-Overview/) and [Processing Private Transactions](https://besu.hyperledger.org/en/latest/Concepts/Privacy/Private-Transaction-Processing/) - - Renaming of Ethstats Lite Explorer to [Ethereum Lite Explorer](https://besu.hyperledger.org/en/latest/HowTo/Deploy/Lite-Block-Explorer/#lite-block-explorer-documentation) (thanks to [tzapu](https://github.com/tzapu)) - - Added content on using [Truffle with Besu](https://besu.hyperledger.org/en/latest/HowTo/Develop-Dapps/Truffle/) - - Added [`droppedPendingTransactions` RPC Pub/Sub subscription](https://besu.hyperledger.org/en/latest/HowTo/Interact/APIs/RPC-PubSub/#dropped-transactions) - - Added [`eea_*` JSON-RPC API methods](https://besu.hyperledger.org/en/latest/Reference/API-Methods/#eea-methods) - - Added [architecture diagram](https://besu.hyperledger.org/en/latest/Concepts/ArchitectureOverview/) - - Updated [permissioning CLI options](https://besu.hyperledger.org/en/latest/Reference/CLI/CLI-Syntax/#permissions-accounts-config-file-enabled) and [permissioned network tutorial](https://besu.hyperledger.org/en/stable/) ### Technical Improvements @@ -3871,31 +3778,6 @@ Documentation updates include: - Added PendingTransactions JSON-RPC [\#1043](https://github.com/PegaSysEng/pantheon/pull/1043) (thanks to [EdwinLeeGreene](https://github.com/EdwinLeeGreene)) - Added `admin_nodeInfo` JSON-RPC [\#1012](https://github.com/PegaSysEng/pantheon/pull/1012) - Added `--metrics-category` CLI to only enable select metrics [\#969](https://github.com/PegaSysEng/pantheon/pull/969) -- Documentation updates include: - - Updated endpoints in [Private Network Quickstart](https://besu.hyperledger.org/en/latest/Tutorials/Quickstarts/Private-Network-Quickstart/) (thanks to [laubai](https://github.com/laubai)) - - Updated [documentation contribution guidelines](https://besu.hyperledger.org/en/stable/) - - Added [`admin_removePeer`](https://besu.hyperledger.org/en/latest/Reference/API-Methods/#admin_removepeer) - - Updated [tutorials](https://besu.hyperledger.org/en/latest/Tutorials/Private-Network/Create-Private-Clique-Network/) for printing of enode on startup - - Added [`txpool_pantheonTransactions`](https://besu.hyperledger.org/en/stable/Reference/API-Methods/#txpool_besutransactions) - - Added [Transaction Pool content](https://besu.hyperledger.org/en/latest/Concepts/Transactions/Transaction-Pool/) - - Added [`tx-pool-max-size` CLI option](https://besu.hyperledger.org/en/latest/Reference/CLI/CLI-Syntax/#tx-pool-max-size) - - Updated [developer build instructions to use installDist](https://besu.hyperledger.org/en/stable/) - - Added [Azure quickstart tutorial](https://besu.hyperledger.org/en/latest/Tutorials/Quickstarts/Azure-Private-Network-Quickstart/) - - Enabled copy button in code blocks - - Added [IBFT 1.0](https://besu.hyperledger.org/en/latest/HowTo/Configure/Consensus-Protocols/QuorumIBFT/) - - Added section on using [Geth attach with Besu](https://besu.hyperledger.org/en/latest/HowTo/Interact/APIs/Using-JSON-RPC-API/#geth-console) - - Enabled the edit link doc site to ease external doc contributions - - Added [EthStats docs](https://besu.hyperledger.org/HowTo/Deploy/Lite-Network-Monitor/) (thanks to [baxy](https://github.com/baxy)) - - Updated [Postman collection](https://besu.hyperledger.org/en/latest/HowTo/Interact/APIs/Authentication/#postman) - - Added [`metrics-category` CLI option](https://besu.hyperledger.org/en/latest/Reference/CLI/CLI-Syntax/#metrics-category) - - Added information on [block time and timeout settings](https://besu.hyperledger.org/en/latest/HowTo/Configure/Consensus-Protocols/IBFT/#block-time) for IBFT 2.0 - - Added [`admin_nodeInfo`](https://besu.hyperledger.org/en/latest/Reference/API-Methods/#admin_nodeinfo) - - Added [permissions images](https://besu.hyperledger.org/en/latest/Concepts/Permissioning/Permissioning-Overview/) - - Added permissioning blog to [Resources](https://besu.hyperledger.org/en/latest/Reference/Resources/) - - Updated [Create Permissioned Network](https://besu.hyperledger.org/en/latest/Tutorials/Permissioning/Create-Permissioned-Network/) tutorial to use `export-address` - - Updated [Clique](https://besu.hyperledger.org/en/latest/HowTo/Configure/Consensus-Protocols/Clique/) and [IBFT 2.0](https://besu.hyperledger.org/en/latest/HowTo/Configure/Consensus-Protocols/IBFT/) docs to include complete genesis file - - Updated [Clique tutorial](https://besu.hyperledger.org/en/latest/Tutorials/Private-Network/Create-Private-Clique-Network/) to use `export-address` subcommand - - Added IBFT 2.0 [future message configuration options](https://besu.hyperledger.org/en/latest/HowTo/Configure/Consensus-Protocols/IBFT/#optional-configuration-options) ### Technical Improvements - Fixed so self persists to the whitelist [\#1176](https://github.com/PegaSysEng/pantheon/pull/1176) @@ -4040,8 +3922,6 @@ Public key address export subcommand was missing in 1.0 release. ### Additions and Improvements - Added `public-key export-address` subcommand [\#888](https://github.com/PegaSysEng/pantheon/pull/888) -- Documentation update for the [`public-key export-address`](https://besu.hyperledger.org/en/stable/) subcommand. -- Updated [IBFT 2.0 overview](https://besu.hyperledger.org/en/stable/) to include use of `rlp encode` command and information on setting IBFT 2.0 properties to achieve your desired block time. ## 1.0 @@ -4052,16 +3932,7 @@ Public key address export subcommand was missing in 1.0 release. - Added `rlp encode` subcommand [\#965](https://github.com/PegaSysEng/pantheon/pull/965) - Method to reload permissions file [\#834](https://github.com/PegaSysEng/pantheon/pull/834) - Added rebind mitigation for Websockets. [\#905](https://github.com/PegaSysEng/pantheon/pull/905) -- Support genesis contract code [\#749](https://github.com/PegaSysEng/pantheon/pull/749) (thanks to [kziemianek](https://github.com/kziemianek)). -- Documentation updates include: - - Added details on [port configuration](https://besu.hyperledger.org/en/latest/HowTo/Find-and-Connect/Configuring-Ports/) - - Added [Resources page](https://besu.hyperledger.org/en/latest/Reference/Resources/) linking to Besu blog posts and webinars - - Added [JSON-RPC Authentication](https://besu.hyperledger.org/en/latest/HowTo/Interact/APIs/Authentication/) - - Added [tutorial to create permissioned network](https://besu.hyperledger.org/en/latest/Tutorials/Permissioning/Create-Permissioned-Network/) - - Added [Permissioning](https://besu.hyperledger.org/en/latest/Concepts/Permissioning/Permissioning-Overview/) content - - Added [Permissioning API methods](https://besu.hyperledger.org/en/latest/Reference/API-Methods/#permissioning-methods) - - Added [tutorial to create Clique private network](https://besu.hyperledger.org/en/latest/Tutorials/Private-Network/Create-Private-Clique-Network/) - - Added [tutorial to create IBFT 2.0 private network](https://besu.hyperledger.org/en/latest/Tutorials/Private-Network/Create-IBFT-Network/) +- Support genesis contract code [\#749](https://github.com/PegaSysEng/pantheon/pull/749) (thanks to [kziemianek](https://github.com/kziemianek)) ### Technical Improvements - RoundChangeCertificateValidator requires unique authors [\#997](https://github.com/PegaSysEng/pantheon/pull/997) @@ -4205,7 +4076,7 @@ Public key address export subcommand was missing in 1.0 release. - Updated IbftRound and RoundState APIs to use wrapped messages [\#740](https://github.com/PegaSysEng/pantheon/pull/740) - Exception handling [\#739](https://github.com/PegaSysEng/pantheon/pull/739) - Upgrade dependency versions and build cleanup [\#738](https://github.com/PegaSysEng/pantheon/pull/738) -- Update IbftBlockHeigntManager to accept new message types. [\#737](https://github.com/PegaSysEng/pantheon/pull/737) +- Update IbftBlockHeightManager to accept new message types. [\#737](https://github.com/PegaSysEng/pantheon/pull/737) - Error response handling for permissions APIs [\#736](https://github.com/PegaSysEng/pantheon/pull/736) - IPV6 bootnodes don't work [\#735](https://github.com/PegaSysEng/pantheon/pull/735) - Updated to use tags of pantheon build rather than another repo [\#734](https://github.com/PegaSysEng/pantheon/pull/734) @@ -4219,7 +4090,7 @@ Public key address export subcommand was missing in 1.0 release. ## 0.9.1 -Built and compatible with with JDK8. +Built and compatible with JDK8. ## 0.9 @@ -4282,13 +4153,6 @@ has been updated to use the moved quickstart. - Implement Petersburg hardfork [\#601](https://github.com/PegaSysEng/pantheon/pull/601) - Added private transaction abstraction [\#592](https://github.com/PegaSysEng/pantheon/pull/592) (thanks to [iikirilov](https://github.com/iikirilov)) - Added privacy command line commands [\#584](https://github.com/PegaSysEng/pantheon/pull/584) (thanks to [Puneetha17](https://github.com/Puneetha17)) -- Documentation updates include: - - Updated [Private Network Quickstart tutorial](https://besu.hyperledger.org/en/latest/Tutorials/Quickstarts/Private-Network-Quickstart/) - to use quickstart in `pantheon-quickstart` repository and indicate that the quickstart is not supported on Windows. - - Added IBFT 2.0 [content](https://besu.hyperledger.org/en/latest/HowTo/Configure/Consensus-Protocols/IBFT/) and [JSON RPC API methods](https://besu.hyperledger.org/en/latest/Reference/API-Methods/#ibft-20-methods). - - Added [consensus protocols content](https://besu.hyperledger.org/en/latest/Concepts/Consensus-Protocols/Comparing-PoA/). - - Added content on [events and logs](https://besu.hyperledger.org/en/latest/Concepts/Events-and-Logs/), and [using filters](https://besu.hyperledger.org/en/latest/HowTo/Interact/Filters/Accessing-Logs-Using-JSON-RPC/). - - Added content on integrating with [Prometheus Push Gateway](https://besu.hyperledger.org/en/latest/HowTo/Deploy/Monitoring-Performance/#running-prometheus-with-besu-in-push-mode) ### Technical Improvements @@ -4410,11 +4274,6 @@ When restarting your node with the v0.8.4 Docker image: - Added account whitelisting [\#460](https://github.com/PegaSysEng/pantheon/pull/460) - Added configurable refresh delay for SyncingSubscriptionService on start up [\#383](https://github.com/PegaSysEng/pantheon/pull/383) - Added the Command Line Style Guide [\#530](https://github.com/PegaSysEng/pantheon/pull/530) -- Documentation updates include: - * Migrated to new [documentation site](https://docs.pantheon.pegasys.tech/en/latest/) - * Added [configuration file content](https://besu.hyperledger.org/en/stable/) - * Added [tutorial to create private network](https://besu.hyperledger.org/en/latest/Tutorials/Private-Network/Create-Private-Network/) - * Added content on [enabling non-default APIs](https://besu.hyperledger.org/en/latest/Reference/API-Methods/) ## Technical Improvements @@ -4498,11 +4357,6 @@ Specify `*` or `all` for `--host-whitelist` to effectively disable host protecti - IBFT block mining [\#169](https://github.com/PegaSysEng/pantheon/pull/169) - Added `--goerli` CLI option [\#370](https://github.com/PegaSysEng/pantheon/pull/370) (Thanks to [@Nashatyrev](https://github.com/Nashatyrev)) - Begin capturing metrics to better understand Besu's behaviour [\#326](https://github.com/PegaSysEng/pantheon/pull/326) -- Documentation updates include: - * Added Coding Conventions [\#342](https://github.com/PegaSysEng/pantheon/pull/342) - * Reorganised [Installation documentation](https://github.com/PegaSysEng/pantheon/wiki/Installation) and added [Chocolatey installation](https://github.com/PegaSysEng/pantheon/wiki/Install-Binaries#windows-with-chocolatey) for Windows - * Reorganised [JSON-RPC API documentation](https://github.com/PegaSysEng/pantheon/wiki/JSON-RPC-API) - * Updated [RPC Pub/Sub API documentation](https://github.com/PegaSysEng/pantheon/wiki/RPC-PubSub) ### Technical Improvements @@ -4579,15 +4433,6 @@ Specify `*` or `all` for `--host-whitelist` to effectively disable host protecti - Added `--banned-nodeids` option to prevent connection to specific nodes (PR [#254](https://github.com/PegaSysEng/pantheon/pull/254)) - 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)) - - Improved documentation by adding the following pages: - * [Getting Started](https://github.com/PegaSysEng/pantheon/wiki/Getting-Started) - * [Network ID and Chain ID](https://github.com/PegaSysEng/pantheon/wiki/NetworkID-And-ChainID) - * [Node Keys](https://github.com/PegaSysEng/pantheon/wiki/Node-Keys) - * [Networking](https://github.com/PegaSysEng/pantheon/wiki/Networking) - * [Accounts for Testing](https://github.com/PegaSysEng/pantheon/wiki/Accounts-for-Testing) - * [Logging](https://github.com/PegaSysEng/pantheon/wiki/Logging) - * [Proof of Authority](https://github.com/PegaSysEng/pantheon/wiki/Proof-of-Authority) - * [Passing JVM Options](https://github.com/PegaSysEng/pantheon/wiki/Passing-JVM-Options) ### Technical Improvements From 2881994f0f895b8a373e577ab5d2c8f86b55d805 Mon Sep 17 00:00:00 2001 From: garyschulte Date: Wed, 4 Sep 2024 09:31:26 -0700 Subject: [PATCH 186/259] update changelog to reflect 24.9.0-RC2 (#7574) Signed-off-by: garyschulte --- CHANGELOG.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aab2389fc5..102a0c5817 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,11 +7,8 @@ ### Breaking Changes ### Additions and Improvements -- Include current chain head block when computing `eth_maxPriorityFeePerGas` [#7485](https://github.com/hyperledger/besu/pull/7485) -- Remove (old) documentation updates from the changelog [#7562](https://github.com/hyperledger/besu/pull/7562) ### Bug fixes -- The genesis config override `contractSizeLimit` was not wired into code size limits [#7557](https://github.com/hyperledger/besu/issues/7557) ## 24.9.0 @@ -27,6 +24,8 @@ - Implement engine_getClientVersionV1 [#7512](https://github.com/hyperledger/besu/pull/7512) - Performance optimzation for ECMUL (1 of 2) [#7509](https://github.com/hyperledger/besu/pull/7509) - Performance optimzation for ECMUL (2 of 2) [#7543](https://github.com/hyperledger/besu/pull/7543) +- Include current chain head block when computing `eth_maxPriorityFeePerGas` [#7485](https://github.com/hyperledger/besu/pull/7485) +- Remove (old) documentation updates from the changelog [#7562](https://github.com/hyperledger/besu/pull/7562) ### Bug fixes - Fix tracing in precompiled contracts when halting for out of gas [#7318](https://github.com/hyperledger/besu/issues/7318) @@ -35,6 +34,8 @@ - Correctly drops messages that exceeds local message size limit [#5455](https://github.com/hyperledger/besu/pull/7507) - **DebugMetrics**: Fixed a `ClassCastException` occurring in `DebugMetrics` when handling nested metric structures. Previously, `Double` values within these structures were incorrectly cast to `Map` objects, leading to errors. This update allows for proper handling of both direct values and nested structures at the same level. Issue# [#7383](https://github.com/hyperledger/besu/pull/7383) - `evmtool` was not respecting the `--genesis` setting, resulting in unexpected trace results. [#7433](https://github.com/hyperledger/besu/pull/7433) +- The genesis config override `contractSizeLimit`q was not wired into code size limits [#7557](https://github.com/hyperledger/besu/pull/7557) +- Fix incorrect key filtering in LayeredKeyValueStorage stream [#7535](https://github.com/hyperledger/besu/pull/7557) ## 24.8.0 From b763d96c75913d79d4344e0cafefe8410935c222 Mon Sep 17 00:00:00 2001 From: Lucas Saldanha Date: Thu, 5 Sep 2024 13:33:30 +1200 Subject: [PATCH 187/259] Fix consolidation request json (#7577) Signed-off-by: Lucas Saldanha --- .../engine/prague/test-cases/16_prague_getPayloadV4.json | 4 ++-- .../internal/parameters/ConsolidationRequestParameter.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) 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 c3fdd33ada..51843931e7 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 @@ -40,8 +40,8 @@ "consolidationRequests": [ { "sourceAddress": "0x23618e81e3f5cdf7f54c3d65f7fbc0abf5b21e8f", - "sourcePubKey": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - "targetPubKey": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe" + "sourcePubkey": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "targetPubkey": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe" } ], "blockNumber": "0x4", 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 index d33b12c6a7..c6c600329d 100644 --- 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 @@ -61,12 +61,12 @@ public class ConsolidationRequestParameter { } @JsonGetter - public String getSourcePubKey() { + public String getSourcePubkey() { return sourcePubkey; } @JsonGetter - public String getTargetPubKey() { + public String getTargetPubkey() { return targetPubkey; } From 7f0982d2289ba3bf954c4b590f9db5f181e092c4 Mon Sep 17 00:00:00 2001 From: Fabio Di Fabio Date: Thu, 5 Sep 2024 12:55:32 +0200 Subject: [PATCH 188/259] Layered txpool: do not send notifications when moving tx between layers (#7539) Signed-off-by: Fabio Di Fabio --- CHANGELOG.md | 3 +- .../transactions/TransactionPoolMetrics.java | 6 +- .../AbstractSequentialTransactionsLayer.java | 3 +- .../layered/AbstractTransactionsLayer.java | 42 ++++++----- .../BaseFeePrioritizedTransactions.java | 3 +- .../eth/transactions/layered/EndLayer.java | 3 +- .../layered/LayeredPendingTransactions.java | 7 +- .../layered/TransactionsLayer.java | 57 ++++++++++++++- ...stractPrioritizedTransactionsTestBase.java | 7 +- .../layered/BaseTransactionPoolTest.java | 6 +- .../layered/EvictCollectorLayer.java | 5 +- .../LayeredPendingTransactionsTest.java | 70 +++++++++++++++---- 12 files changed, 165 insertions(+), 47 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 102a0c5817..3cc2b57843 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ ### Additions and Improvements ### Bug fixes +- Layered txpool: do not send notifications when moving tx between layers [#7539](https://github.com/hyperledger/besu/pull/7539) ## 24.9.0 @@ -34,7 +35,7 @@ - Correctly drops messages that exceeds local message size limit [#5455](https://github.com/hyperledger/besu/pull/7507) - **DebugMetrics**: Fixed a `ClassCastException` occurring in `DebugMetrics` when handling nested metric structures. Previously, `Double` values within these structures were incorrectly cast to `Map` objects, leading to errors. This update allows for proper handling of both direct values and nested structures at the same level. Issue# [#7383](https://github.com/hyperledger/besu/pull/7383) - `evmtool` was not respecting the `--genesis` setting, resulting in unexpected trace results. [#7433](https://github.com/hyperledger/besu/pull/7433) -- The genesis config override `contractSizeLimit`q was not wired into code size limits [#7557](https://github.com/hyperledger/besu/pull/7557) +- The genesis config override `contractSizeLimit` was not wired into code size limits [#7557](https://github.com/hyperledger/besu/pull/7557) - Fix incorrect key filtering in LayeredKeyValueStorage stream [#7535](https://github.com/hyperledger/besu/pull/7557) ## 24.8.0 diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolMetrics.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolMetrics.java index 90e9628e5c..45f895881c 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolMetrics.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolMetrics.java @@ -15,6 +15,7 @@ package org.hyperledger.besu.ethereum.eth.transactions; import org.hyperledger.besu.datatypes.TransactionType; +import org.hyperledger.besu.ethereum.eth.transactions.layered.TransactionsLayer.AddReason; import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason; import org.hyperledger.besu.metrics.BesuMetricCategory; import org.hyperledger.besu.metrics.ReplaceableDoubleSupplier; @@ -68,6 +69,7 @@ public class TransactionPoolMetrics { "Count of transactions added to the transaction pool", "source", "priority", + "reason", "layer"); removedCounter = @@ -215,11 +217,13 @@ public class TransactionPoolMetrics { SKIPPED_MESSAGES_LOGGING_THRESHOLD)); } - public void incrementAdded(final PendingTransaction pendingTransaction, final String layer) { + public void incrementAdded( + final PendingTransaction pendingTransaction, final AddReason addReason, final String layer) { addedCounter .labels( location(pendingTransaction.isReceivedFromLocalSource()), priority(pendingTransaction.hasPriority()), + addReason.label(), layer) .inc(); } 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 619611edd4..2725f0012e 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 @@ -14,6 +14,7 @@ */ package org.hyperledger.besu.ethereum.eth.transactions.layered; +import static org.hyperledger.besu.ethereum.eth.transactions.layered.TransactionsLayer.AddReason.MOVE; import static org.hyperledger.besu.ethereum.eth.transactions.layered.TransactionsLayer.RemovalReason.EVICTED; import static org.hyperledger.besu.ethereum.eth.transactions.layered.TransactionsLayer.RemovalReason.FOLLOW_INVALIDATED; @@ -77,7 +78,7 @@ public abstract class AbstractSequentialTransactionsLayer extends AbstractTransa senderTxs.remove(txToRemove.getNonce()); processRemove(senderTxs, txToRemove.getTransaction(), FOLLOW_INVALIDATED); }) - .forEach(followingTx -> nextLayer.add(followingTx, gap)); + .forEach(followingTx -> nextLayer.add(followingTx, gap, MOVE)); } @Override 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 b4f6e927c0..81178a0709 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 @@ -19,10 +19,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.REJECTED_UNDERPRICED_REPLACEMENT; import static org.hyperledger.besu.ethereum.eth.transactions.TransactionAddedResult.TRY_NEXT_LAYER; +import static org.hyperledger.besu.ethereum.eth.transactions.layered.TransactionsLayer.AddReason.MOVE; import static org.hyperledger.besu.ethereum.eth.transactions.layered.TransactionsLayer.RemovalReason.CONFIRMED; import static org.hyperledger.besu.ethereum.eth.transactions.layered.TransactionsLayer.RemovalReason.CROSS_LAYER_REPLACED; import static org.hyperledger.besu.ethereum.eth.transactions.layered.TransactionsLayer.RemovalReason.EVICTED; -import static org.hyperledger.besu.ethereum.eth.transactions.layered.TransactionsLayer.RemovalReason.PROMOTED; import static org.hyperledger.besu.ethereum.eth.transactions.layered.TransactionsLayer.RemovalReason.REPLACED; import org.hyperledger.besu.datatypes.Address; @@ -169,7 +169,8 @@ public abstract class AbstractTransactionsLayer implements TransactionsLayer { final PendingTransaction pendingTransaction, final int gap); @Override - public TransactionAddedResult add(final PendingTransaction pendingTransaction, final int gap) { + public TransactionAddedResult add( + final PendingTransaction pendingTransaction, final int gap, final AddReason addReason) { // is replacing an existing one? TransactionAddedResult addStatus = maybeReplaceTransaction(pendingTransaction); @@ -178,21 +179,26 @@ public abstract class AbstractTransactionsLayer implements TransactionsLayer { } if (addStatus.equals(TRY_NEXT_LAYER)) { - return addToNextLayer(pendingTransaction, gap); + return addToNextLayer(pendingTransaction, gap, addReason); } if (addStatus.isSuccess()) { - processAdded(pendingTransaction.detachedCopy()); + final var addedPendingTransaction = + addReason.makeCopy() ? pendingTransaction.detachedCopy() : pendingTransaction; + processAdded(addedPendingTransaction, addReason); addStatus.maybeReplacedTransaction().ifPresent(this::replaced); - nextLayer.notifyAdded(pendingTransaction); + nextLayer.notifyAdded(addedPendingTransaction); if (!maybeFull()) { // if there is space try to see if the added tx filled some gaps - tryFillGap(addStatus, pendingTransaction, getRemainingPromotionsPerType()); + tryFillGap(addStatus, addedPendingTransaction, getRemainingPromotionsPerType()); + } + + if (addReason.sendNotification()) { + ethScheduler.scheduleTxWorkerTask(() -> notifyTransactionAdded(addedPendingTransaction)); } - ethScheduler.scheduleTxWorkerTask(() -> notifyTransactionAdded(pendingTransaction)); } else { final var rejectReason = addStatus.maybeInvalidReason().orElseThrow(); metrics.incrementRejected(pendingTransaction, rejectReason, name()); @@ -238,7 +244,7 @@ public abstract class AbstractTransactionsLayer implements TransactionsLayer { pendingTransaction.getNonce(), remainingPromotionsPerType); if (promotedTx != null) { - processAdded(promotedTx); + processAdded(promotedTx, AddReason.PROMOTED); if (!maybeFull()) { tryFillGap(ADDED, promotedTx, remainingPromotionsPerType); } @@ -286,7 +292,7 @@ public abstract class AbstractTransactionsLayer implements TransactionsLayer { if (remainingPromotionsPerType[txType.ordinal()] > 0) { senderTxs.pollFirstEntry(); - processRemove(senderTxs, candidateTx.getTransaction(), PROMOTED); + processRemove(senderTxs, candidateTx.getTransaction(), RemovalReason.PROMOTED); metrics.incrementRemoved(candidateTx, "promoted", name()); if (senderTxs.isEmpty()) { @@ -302,32 +308,34 @@ public abstract class AbstractTransactionsLayer implements TransactionsLayer { } private TransactionAddedResult addToNextLayer( - final PendingTransaction pendingTransaction, final int distance) { + final PendingTransaction pendingTransaction, final int distance, final AddReason addReason) { return addToNextLayer( txsBySender.getOrDefault(pendingTransaction.getSender(), EMPTY_SENDER_TXS), pendingTransaction, - distance); + distance, + addReason); } protected TransactionAddedResult addToNextLayer( final NavigableMap senderTxs, final PendingTransaction pendingTransaction, - final int distance) { + final int distance, + final AddReason addReason) { final int nextLayerDistance; if (senderTxs.isEmpty()) { nextLayerDistance = distance; } else { nextLayerDistance = (int) (pendingTransaction.getNonce() - (senderTxs.lastKey() + 1)); } - return nextLayer.add(pendingTransaction, nextLayerDistance); + return nextLayer.add(pendingTransaction, nextLayerDistance, addReason); } - private void processAdded(final PendingTransaction addedTx) { + private void processAdded(final PendingTransaction addedTx, final AddReason addReason) { pendingTransactions.put(addedTx.getHash(), addedTx); final var senderTxs = txsBySender.computeIfAbsent(addedTx.getSender(), s -> new TreeMap<>()); senderTxs.put(addedTx.getNonce(), addedTx); increaseCounters(addedTx); - metrics.incrementAdded(addedTx, name()); + metrics.incrementAdded(addedTx, addReason, name()); internalAdd(senderTxs, addedTx); } @@ -353,7 +361,7 @@ public abstract class AbstractTransactionsLayer implements TransactionsLayer { ++evictedCount; evictedSize += lastTx.memorySize(); // evicted can always be added to the next layer - addToNextLayer(lessReadySenderTxs, lastTx, 0); + addToNextLayer(lessReadySenderTxs, lastTx, 0, MOVE); } if (lessReadySenderTxs.isEmpty()) { @@ -459,7 +467,7 @@ public abstract class AbstractTransactionsLayer implements TransactionsLayer { nextLayer .promote( this::promotionFilter, cacheFreeSpace(), freeSlots, getRemainingPromotionsPerType()) - .forEach(this::processAdded); + .forEach(addedTx -> processAdded(addedTx, AddReason.PROMOTED)); } } 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 b3dec34b77..170205e498 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 @@ -14,6 +14,7 @@ */ package org.hyperledger.besu.ethereum.eth.transactions.layered; +import static org.hyperledger.besu.ethereum.eth.transactions.layered.TransactionsLayer.AddReason.MOVE; import static org.hyperledger.besu.ethereum.eth.transactions.layered.TransactionsLayer.RemovalReason.BELOW_BASE_FEE; import org.hyperledger.besu.datatypes.Wei; @@ -133,7 +134,7 @@ public class BaseFeePrioritizedTransactions extends AbstractPrioritizedTransacti .addArgument(newNextBlockBaseFee::toHumanReadableString) .log(); processEvict(senderTxs, demoteTx, BELOW_BASE_FEE); - addToNextLayer(senderTxs, demoteTx, 0); + addToNextLayer(senderTxs, demoteTx, 0, MOVE); } }); 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 f383f178c2..16571e7aef 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 @@ -75,7 +75,8 @@ public class EndLayer implements TransactionsLayer { } @Override - public TransactionAddedResult add(final PendingTransaction pendingTransaction, final int gap) { + public TransactionAddedResult add( + final PendingTransaction pendingTransaction, final int gap, final AddReason reason) { notifyTransactionDropped(pendingTransaction); metrics.incrementRemoved(pendingTransaction, DROPPED.label(), name()); ++droppedCount; 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 5297f08021..3e0a87da2f 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 @@ -20,6 +20,7 @@ import static java.util.stream.Collectors.reducing; import static org.hyperledger.besu.ethereum.eth.transactions.TransactionAddedResult.ALREADY_KNOWN; 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.TransactionsLayer.AddReason.NEW; import static org.hyperledger.besu.ethereum.eth.transactions.layered.TransactionsLayer.RemovalReason.INVALIDATED; import static org.hyperledger.besu.ethereum.eth.transactions.layered.TransactionsLayer.RemovalReason.RECONCILED; @@ -100,7 +101,7 @@ public class LayeredPendingTransactions implements PendingTransactions { } try { - return prioritizedTransactions.add(pendingTransaction, (int) nonceDistance); + return prioritizedTransactions.add(pendingTransaction, (int) nonceDistance, NEW); } catch (final Throwable throwable) { return reconcileAndRetryAdd( pendingTransaction, stateSenderNonce, (int) nonceDistance, throwable); @@ -123,7 +124,7 @@ public class LayeredPendingTransactions implements PendingTransactions { .log(); reconcileSender(pendingTransaction.getSender(), stateSenderNonce); try { - return prioritizedTransactions.add(pendingTransaction, nonceDistance); + return prioritizedTransactions.add(pendingTransaction, nonceDistance, NEW); } catch (final Throwable throwable2) { // the error should have been solved by the reconcile, logging at higher level now LOG.atWarn() @@ -210,7 +211,7 @@ public class LayeredPendingTransactions implements PendingTransactions { final long lowestNonce = reAddTxs.getFirst().getNonce(); final int newNonceDistance = (int) Math.max(0, lowestNonce - stateSenderNonce); - reAddTxs.forEach(ptx -> prioritizedTransactions.add(ptx, newNonceDistance)); + reAddTxs.forEach(ptx -> prioritizedTransactions.add(ptx, newNonceDistance, NEW)); } LOG.atDebug() 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 531add0af7..0117ed71b6 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 @@ -41,7 +41,19 @@ public interface TransactionsLayer { boolean contains(Transaction transaction); - TransactionAddedResult add(PendingTransaction pendingTransaction, int gap); + /** + * Try to add a pending transaction to this layer. The {@code addReason} is used to discriminate + * between a new tx that is added to the pool, or a tx that is already in the pool, but is moving + * internally between layers, for example, due to a promotion or demotion. The distinction is + * needed since we only need to send a notification for a new tx, and not when it is only an + * internal move. + * + * @param pendingTransaction the tx to try to add to this layer + * @param gap the nonce gap between the current sender nonce and the tx + * @param addReason define if it is a new tx or an internal move + * @return the result of the add operation + */ + TransactionAddedResult add(PendingTransaction pendingTransaction, int gap, AddReason addReason); void remove(PendingTransaction pendingTransaction, RemovalReason reason); @@ -108,6 +120,49 @@ public interface TransactionsLayer { String logSender(Address sender); + /** Describe why we are trying to add a tx to a layer. */ + enum AddReason { + /** When adding a tx, that is not present in the pool. */ + NEW(true, true), + /** When adding a tx as result of an internal move between layers. */ + MOVE(false, false), + /** When adding a tx as result of a promotion from a lower layer. */ + PROMOTED(false, false); + + private final boolean sendNotification; + private final boolean makeCopy; + private final String label; + + AddReason(final boolean sendNotification, final boolean makeCopy) { + this.sendNotification = sendNotification; + this.makeCopy = makeCopy; + this.label = name().toLowerCase(Locale.ROOT); + } + + /** + * Should we send add notification for this reason? + * + * @return true if notification should be sent + */ + public boolean sendNotification() { + return sendNotification; + } + + /** + * Should the layer make a copy of the pending tx before adding it, to avoid keeping reference + * to potentially large underlying byte buffers? + * + * @return true is a copy is necessary + */ + public boolean makeCopy() { + return makeCopy; + } + + public String label() { + return label; + } + } + enum RemovalReason { CONFIRMED, CROSS_LAYER_REPLACED, diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/AbstractPrioritizedTransactionsTestBase.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/AbstractPrioritizedTransactionsTestBase.java index d247ca1e8b..f9e16fa0ea 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/AbstractPrioritizedTransactionsTestBase.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/AbstractPrioritizedTransactionsTestBase.java @@ -17,6 +17,7 @@ package org.hyperledger.besu.ethereum.eth.transactions.layered; 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.DROPPED; +import static org.hyperledger.besu.ethereum.eth.transactions.layered.TransactionsLayer.AddReason.NEW; import org.hyperledger.besu.datatypes.TransactionType; import org.hyperledger.besu.datatypes.Wei; @@ -169,7 +170,7 @@ public abstract class AbstractPrioritizedTransactionsTestBase extends BaseTransa .mapToObj( i -> { final var lowPriceTx = lowValueTxSupplier.next(); - final var prioritizeResult = transactions.add(lowPriceTx, 0); + final var prioritizeResult = transactions.add(lowPriceTx, 0, NEW); assertThat(prioritizeResult).isEqualTo(ADDED); assertThat(evictCollector.getEvictedTransactions()).isEmpty(); @@ -180,7 +181,7 @@ public abstract class AbstractPrioritizedTransactionsTestBase extends BaseTransa assertThat(transactions.count()).isEqualTo(MAX_TRANSACTIONS); // This should kick the oldest tx with the low gas price out, namely the first one we added - final var highValuePrioRes = transactions.add(highValueTx, 0); + final var highValuePrioRes = transactions.add(highValueTx, 0, NEW); assertThat(highValuePrioRes).isEqualTo(ADDED); assertEvicted(expectedDroppedTx); @@ -195,7 +196,7 @@ public abstract class AbstractPrioritizedTransactionsTestBase extends BaseTransa } protected TransactionAddedResult prioritizeTransaction(final PendingTransaction tx) { - return transactions.add(tx, 0); + return transactions.add(tx, 0, NEW); } protected void assertTransactionPrioritized(final PendingTransaction tx) { diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/BaseTransactionPoolTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/BaseTransactionPoolTest.java index bbd4e7322f..5cd098ef6f 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/BaseTransactionPoolTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/BaseTransactionPoolTest.java @@ -35,6 +35,7 @@ import org.hyperledger.besu.ethereum.eth.manager.EthScheduler; import org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction; import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolMetrics; +import org.hyperledger.besu.ethereum.eth.transactions.layered.TransactionsLayer.AddReason; import org.hyperledger.besu.evm.account.Account; import org.hyperledger.besu.metrics.StubMetricsSystem; import org.hyperledger.besu.testutil.DeterministicEthScheduler; @@ -258,9 +259,10 @@ public class BaseTransactionPoolTest { } } - protected long getAddedCount(final String source, final String priority, final String layer) { + protected long getAddedCount( + final String source, final String priority, final AddReason addReason, final String layer) { return metricsSystem.getCounterValue( - TransactionPoolMetrics.ADDED_COUNTER_NAME, source, priority, layer); + TransactionPoolMetrics.ADDED_COUNTER_NAME, source, priority, addReason.label(), layer); } protected long getRemovedCount( diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/EvictCollectorLayer.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/EvictCollectorLayer.java index 4b39f26cb2..31cedb1d94 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/EvictCollectorLayer.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/EvictCollectorLayer.java @@ -35,8 +35,9 @@ public class EvictCollectorLayer extends EndLayer { } @Override - public TransactionAddedResult add(final PendingTransaction pendingTransaction, final int gap) { - final var res = super.add(pendingTransaction, gap); + public TransactionAddedResult add( + final PendingTransaction pendingTransaction, final int gap, final AddReason addReason) { + final var res = super.add(pendingTransaction, gap, addReason); evictedTxs.add(pendingTransaction); return res; } 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 b2f03ce175..a5e7a151e2 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 @@ -20,6 +20,8 @@ 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.layered.TransactionsLayer.AddReason.MOVE; +import static org.hyperledger.besu.ethereum.eth.transactions.layered.TransactionsLayer.AddReason.NEW; import static org.hyperledger.besu.ethereum.eth.transactions.layered.TransactionsLayer.RemovalReason.DROPPED; import static org.hyperledger.besu.ethereum.eth.transactions.layered.TransactionsLayer.RemovalReason.REPLACED; import static org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason.GAS_PRICE_BELOW_CURRENT_BASE_FEE; @@ -207,14 +209,14 @@ public class LayeredPendingTransactionsTest extends BaseTransactionPoolTest { createRemotePendingTransaction(transaction0), Optional.empty()); assertThat(pendingTransactions.size()).isEqualTo(1); - assertThat(getAddedCount(REMOTE, NO_PRIORITY, layers.prioritizedTransactions.name())) + assertThat(getAddedCount(REMOTE, NO_PRIORITY, NEW, layers.prioritizedTransactions.name())) .isEqualTo(1); pendingTransactions.addTransaction( createRemotePendingTransaction(transaction1), Optional.empty()); assertThat(pendingTransactions.size()).isEqualTo(2); - assertThat(getAddedCount(REMOTE, NO_PRIORITY, layers.prioritizedTransactions.name())) + assertThat(getAddedCount(REMOTE, NO_PRIORITY, NEW, layers.prioritizedTransactions.name())) .isEqualTo(2); } @@ -270,12 +272,48 @@ public class LayeredPendingTransactionsTest extends BaseTransactionPoolTest { getRemovedCount( REMOTE, NO_PRIORITY, DROPPED.label(), smallLayers.evictedCollector.name())) .isEqualTo(1); + // before get evicted definitively, the tx moves to the lower layers, where it does not fix, + // until is discarded + assertThat(getAddedCount(REMOTE, NO_PRIORITY, MOVE, smallLayers.readyTransactions.name())) + .isEqualTo(1); + assertThat(getAddedCount(REMOTE, NO_PRIORITY, MOVE, smallLayers.sparseTransactions.name())) + .isEqualTo(1); assertThat(smallLayers.evictedCollector.getEvictedTransactions()) .map(PendingTransaction::getTransaction) .contains(firstTxs.get(0)); verify(droppedListener).onTransactionDropped(firstTxs.get(0)); } + @Test + public void txsMovingToNextLayerWhenFirstIsFull() { + final List txs = new ArrayList<>(MAX_TRANSACTIONS + 1); + + pendingTransactions.subscribeDroppedTransactions(droppedListener); + + for (int i = 0; i < MAX_TRANSACTIONS + 1; i++) { + final Account sender = mock(Account.class); + when(sender.getNonce()).thenReturn((long) i); + final var tx = + createTransaction( + i, DEFAULT_BASE_FEE.add(i), SIGNATURE_ALGORITHM.get().generateKeyPair()); + pendingTransactions.addTransaction(createRemotePendingTransaction(tx), Optional.of(sender)); + txs.add(tx); + assertTransactionPending(pendingTransactions, tx); + } + + assertThat(pendingTransactions.size()).isEqualTo(MAX_TRANSACTIONS + 1); + assertThat(getAddedCount(REMOTE, NO_PRIORITY, NEW, layers.prioritizedTransactions.name())) + .isEqualTo(MAX_TRANSACTIONS + 1); + + // one tx moved to the ready layer since the prioritized was full + assertThat(getAddedCount(REMOTE, NO_PRIORITY, MOVE, layers.readyTransactions.name())) + .isEqualTo(1); + + // first tx is the lowest value one so it is the first to be moved to ready + assertThat(layers.readyTransactions.contains(txs.get(0))).isTrue(); + verifyNoInteractions(droppedListener); + } + @Test public void addTransactionForMultipleSenders() { final var transactionSenderA = createTransaction(0, KEYS1); @@ -574,7 +612,7 @@ public class LayeredPendingTransactionsTest extends BaseTransactionPoolTest { assertTransactionPending(pendingTransactions, transaction1b); assertTransactionPending(pendingTransactions, transaction2); assertThat(pendingTransactions.size()).isEqualTo(2); - assertThat(getAddedCount(REMOTE, NO_PRIORITY, layers.prioritizedTransactions.name())) + assertThat(getAddedCount(REMOTE, NO_PRIORITY, NEW, layers.prioritizedTransactions.name())) .isEqualTo(3); assertThat( getRemovedCount( @@ -612,7 +650,7 @@ public class LayeredPendingTransactionsTest extends BaseTransactionPoolTest { assertTransactionPending(pendingTransactions, independentTx); assertThat(pendingTransactions.size()).isEqualTo(2); - assertThat(getAddedCount(REMOTE, NO_PRIORITY, layers.prioritizedTransactions.name())) + assertThat(getAddedCount(REMOTE, NO_PRIORITY, NEW, layers.prioritizedTransactions.name())) .isEqualTo(replacedTxCount + 2); assertThat( getRemovedCount( @@ -660,9 +698,9 @@ public class LayeredPendingTransactionsTest extends BaseTransactionPoolTest { final int localDuplicateCount = replacedTxCount - remoteDuplicateCount; assertThat(pendingTransactions.size()).isEqualTo(2); - assertThat(getAddedCount(REMOTE, NO_PRIORITY, layers.prioritizedTransactions.name())) + assertThat(getAddedCount(REMOTE, NO_PRIORITY, NEW, layers.prioritizedTransactions.name())) .isEqualTo(remoteDuplicateCount + 1); - assertThat(getAddedCount(LOCAL, NO_PRIORITY, layers.prioritizedTransactions.name())) + assertThat(getAddedCount(LOCAL, NO_PRIORITY, NEW, layers.prioritizedTransactions.name())) .isEqualTo(localDuplicateCount + 1); assertThat( getRemovedCount( @@ -814,18 +852,20 @@ public class LayeredPendingTransactionsTest extends BaseTransactionPoolTest { pendingTransactions.addTransaction( createLocalPendingTransaction(transaction0), Optional.empty()); assertThat(pendingTransactions.size()).isEqualTo(1); - assertThat(getAddedCount(LOCAL, NO_PRIORITY, layers.prioritizedTransactions.name())) + assertThat(getAddedCount(LOCAL, NO_PRIORITY, NEW, layers.prioritizedTransactions.name())) .isEqualTo(1); - assertThat(getAddedCount(REMOTE, NO_PRIORITY, layers.prioritizedTransactions.name())).isZero(); + assertThat(getAddedCount(REMOTE, NO_PRIORITY, NEW, layers.prioritizedTransactions.name())) + .isZero(); assertThat( pendingTransactions.addTransaction( createRemotePendingTransaction(transaction0), Optional.empty())) .isEqualTo(ALREADY_KNOWN); assertThat(pendingTransactions.size()).isEqualTo(1); - assertThat(getAddedCount(LOCAL, NO_PRIORITY, layers.prioritizedTransactions.name())) + assertThat(getAddedCount(LOCAL, NO_PRIORITY, NEW, layers.prioritizedTransactions.name())) .isEqualTo(1); - assertThat(getAddedCount(REMOTE, NO_PRIORITY, layers.prioritizedTransactions.name())).isZero(); + assertThat(getAddedCount(REMOTE, NO_PRIORITY, NEW, layers.prioritizedTransactions.name())) + .isZero(); } @Test @@ -833,8 +873,9 @@ public class LayeredPendingTransactionsTest extends BaseTransactionPoolTest { pendingTransactions.addTransaction( createRemotePendingTransaction(transaction0), Optional.empty()); assertThat(pendingTransactions.size()).isEqualTo(1); - assertThat(getAddedCount(LOCAL, NO_PRIORITY, layers.prioritizedTransactions.name())).isZero(); - assertThat(getAddedCount(REMOTE, NO_PRIORITY, layers.prioritizedTransactions.name())) + assertThat(getAddedCount(LOCAL, NO_PRIORITY, NEW, layers.prioritizedTransactions.name())) + .isZero(); + assertThat(getAddedCount(REMOTE, NO_PRIORITY, NEW, layers.prioritizedTransactions.name())) .isEqualTo(1); assertThat( @@ -842,8 +883,9 @@ public class LayeredPendingTransactionsTest extends BaseTransactionPoolTest { createLocalPendingTransaction(transaction0), Optional.empty())) .isEqualTo(ALREADY_KNOWN); assertThat(pendingTransactions.size()).isEqualTo(1); - assertThat(getAddedCount(LOCAL, NO_PRIORITY, layers.prioritizedTransactions.name())).isZero(); - assertThat(getAddedCount(REMOTE, NO_PRIORITY, layers.prioritizedTransactions.name())) + assertThat(getAddedCount(LOCAL, NO_PRIORITY, NEW, layers.prioritizedTransactions.name())) + .isZero(); + assertThat(getAddedCount(REMOTE, NO_PRIORITY, NEW, layers.prioritizedTransactions.name())) .isEqualTo(1); } From edd3c4f0a08c87fe37c36809db411c25839d5e75 Mon Sep 17 00:00:00 2001 From: Fabio Di Fabio Date: Thu, 5 Sep 2024 15:10:49 +0200 Subject: [PATCH 189/259] Update dependencies (#7571) Signed-off-by: Fabio Di Fabio --- CHANGELOG.md | 1 + build.gradle | 10 +- .../EthCreateAccessListIntegrationTest.java | 7 +- .../eth/transactions/PendingTransaction.java | 4 +- gradle/license-normalizer-bundle.json | 3 +- gradle/verification-metadata.xml | 3221 +++++++++-------- gradle/versions.gradle | 115 +- 7 files changed, 1771 insertions(+), 1590 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3cc2b57843..40bdb40ed1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ ### Breaking Changes ### Additions and Improvements +- Update Java and Gradle dependecies [#7571](https://github.com/hyperledger/besu/pull/7571) ### Bug fixes - Layered txpool: do not send notifications when moving tx between layers [#7539](https://github.com/hyperledger/besu/pull/7539) diff --git a/build.gradle b/build.gradle index f9ff1e8012..792355417f 100644 --- a/build.gradle +++ b/build.gradle @@ -25,13 +25,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.7' - id 'com.jfrog.artifactory' version '5.2.0' - id 'io.spring.dependency-management' version '1.1.5' + 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 '3.1.0' + id 'net.ltgt.errorprone' version '4.0.1' id 'maven-publish' - id 'org.sonarqube' version '4.4.1.3373' + id 'org.sonarqube' version '5.1.0.4882' } sonarqube { diff --git a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/frontier/EthCreateAccessListIntegrationTest.java b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/frontier/EthCreateAccessListIntegrationTest.java index 49b9659fd9..6a1bbea260 100644 --- a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/frontier/EthCreateAccessListIntegrationTest.java +++ b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/frontier/EthCreateAccessListIntegrationTest.java @@ -236,7 +236,12 @@ public class EthCreateAccessListIntegrationTest { new JsonRpcSuccessResponse(null, new CreateAccessListResult(accessList, gasUsed)); final JsonRpcResponse response = method.response(request); - assertThat(response).usingRecursiveComparison().isEqualTo(expectedResponse); + assertThat(response) + .usingRecursiveComparison() + // customize the comparison for the type that lazy compute the hashCode + .withEqualsForType(UInt256::equals, UInt256.class) + .withEqualsForType(Address::equals, Address.class) + .isEqualTo(expectedResponse); } private JsonRpcRequestContext requestWithParams(final Object... params) { diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/PendingTransaction.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/PendingTransaction.java index bd98bee5ad..e15fe417a8 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/PendingTransaction.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/PendingTransaction.java @@ -31,8 +31,8 @@ import java.util.concurrent.atomic.AtomicLong; public abstract class PendingTransaction implements org.hyperledger.besu.datatypes.PendingTransaction { static final int NOT_INITIALIZED = -1; - static final int FRONTIER_AND_ACCESS_LIST_SHALLOW_MEMORY_SIZE = 888; - static final int EIP1559_AND_EIP4844_SHALLOW_MEMORY_SIZE = 1000; + static final int FRONTIER_AND_ACCESS_LIST_SHALLOW_MEMORY_SIZE = 904; + static final int EIP1559_AND_EIP4844_SHALLOW_MEMORY_SIZE = 1016; static final int OPTIONAL_TO_MEMORY_SIZE = 112; static final int OPTIONAL_CHAIN_ID_MEMORY_SIZE = 80; static final int PAYLOAD_BASE_MEMORY_SIZE = 32; diff --git a/gradle/license-normalizer-bundle.json b/gradle/license-normalizer-bundle.json index 8c0af450fd..06c6f8d27d 100644 --- a/gradle/license-normalizer-bundle.json +++ b/gradle/license-normalizer-bundle.json @@ -57,6 +57,7 @@ { "bundleName" : "CC0-1.0", "licenseUrlPattern" : ".*(www\\.)?creativecommons\\.org/publicdomain/zero/1\\.0/" }, { "bundleName" : "CDDL-1.0", "licenseFileContentPattern" : ".*CDDL.*1\\.0" }, { "bundleName" : "CDDL-1.0", "licenseUrlPattern" : ".*CDDL.*.?1\\.0" }, + { "bundleName" : "CDDL-1.0", "licenseNamePattern" : "CDDL-1\\.0" }, { "bundleName" : "CDDL-1.1", "licenseUrlPattern" : ".*CDDL.*.?1\\.1" }, { "bundleName" : "CDDL-1.0", "licenseNamePattern" : "Common Development and Distribution License( \\(CDDL\\),?)? (version )?(.?\\s?)?1\\.0" }, { "bundleName" : "CDDL-1.1", "licenseNamePattern" : "Common Development and Distribution License( \\(CDDL\\),?)? (version )?(.?\\s?)?1\\.1" }, @@ -68,7 +69,7 @@ { "bundleName" : "BSD-2-Clause", "licenseUrlPattern" : ".*(www\\.)?opensource\\.org/licenses/BSD-2-Clause" }, { "bundleName" : "BSD-2-Clause", "licenseUrlPattern" : ".*(www\\.)?opensource\\.org/licenses/bsd-license(\\.php)?" }, { "bundleName" : "CDDL-1.0", "licenseNamePattern" : "Common Development and Distribution( License)?" }, - { "bundleName" : "CDDL-1.0", "licenseNamePattern" : "CDDL 1(\\.0)" }, + { "bundleName" : "CDDL-1.0", "licenseNamePattern" : "CDDL( |-)1(\\.0)" }, { "bundleName" : "CDDL-1.1", "licenseNamePattern" : "CDDL 1\\.1" }, { "bundleName" : "CDDL-1.1", "licenseUrlPattern" : ".*(www\\.).opensource\\.org/licenses/CDDL-1\\.0" }, { "bundleName" : "EPL-1.0", "licenseNamePattern" : "Eclipse Publish License.*(v|version)\\.?\\s?1(\\.?0)?" }, diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index f9304c9f8e..3778a2d60a 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -86,12 +86,12 @@ - - - + + + - - + + @@ -104,16 +104,16 @@ - - - - - + + + + + @@ -134,6 +134,11 @@ + + + + + @@ -154,21 +159,16 @@ - - - - - - - - - - + + + + + @@ -179,16 +179,16 @@ - - - - - + + + + + @@ -213,12 +213,12 @@ - - - + + + - - + + @@ -253,6 +253,14 @@ + + + + + + + + @@ -277,55 +285,55 @@ - - - + + + - - + + - - - + + + - - + + - - + + - - - + + + - - - + + + - - + + - - + + - - - + + + - - + + - - + + - - - + + + @@ -352,46 +360,46 @@ - - - + + + - - + + - - - + + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + @@ -426,6 +434,17 @@ + + + + + + + + + + + @@ -453,6 +472,14 @@ + + + + + + + + @@ -461,6 +488,14 @@ + + + + + + + + @@ -477,6 +512,14 @@ + + + + + + + + @@ -485,6 +528,14 @@ + + + + + + + + @@ -493,6 +544,14 @@ + + + + + + + + @@ -517,17 +576,17 @@ - - - + + + - - + + - - - + + + @@ -559,33 +618,33 @@ - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + @@ -635,12 +694,12 @@ - - - + + + - - + + @@ -651,9 +710,9 @@ - - - + + + @@ -661,6 +720,19 @@ + + + + + + + + + + + + + @@ -677,6 +749,14 @@ + + + + + + + + @@ -687,41 +767,46 @@ + + + + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + @@ -732,40 +817,24 @@ - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + @@ -782,31 +851,21 @@ - - - - - - - - - - - - - - - + + + + + @@ -870,14 +929,6 @@ - - - - - - - - @@ -886,23 +937,15 @@ - - - - - - - - - - - + + + - - + + - - + + @@ -910,14 +953,9 @@ - - - - - - - - + + + @@ -928,30 +966,30 @@ - - - + + + - - + + - - - + + + - - - + + + - - + + - - - + + + @@ -967,12 +1005,12 @@ - - - + + + - - + + @@ -990,9 +1028,9 @@ - - - + + + @@ -1016,20 +1054,20 @@ - - - + + + - - + + - - - + + + - - + + @@ -1047,9 +1085,9 @@ - - - + + + @@ -1076,31 +1114,23 @@ - - - + + + - - + + - - - + + + - - - - - - - + + - - - - - + + @@ -1111,6 +1141,14 @@ + + + + + + + + @@ -1124,28 +1162,28 @@ - - - + + + - - + + - - + + - - - + + + - - - + + + - - + + @@ -1215,6 +1253,17 @@ + + + + + + + + + + + @@ -1305,6 +1354,14 @@ + + + + + + + + @@ -1322,9 +1379,6 @@ - - - @@ -1337,6 +1391,14 @@ + + + + + + + + @@ -1361,12 +1423,12 @@ - - - + + + - - + + @@ -1385,20 +1447,12 @@ - - - - - - - - - - - + + + - - + + @@ -1414,20 +1468,20 @@ - - - + + + - - + + - - - + + + - - + + @@ -1446,6 +1500,17 @@ + + + + + + + + + + + @@ -1467,180 +1532,188 @@ - - - + + + + + + + + + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + @@ -1680,22 +1753,22 @@ - - - + + + - - + + - - - + + + - - - + + + @@ -1703,44 +1776,73 @@ - - - + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + @@ -1748,84 +1850,113 @@ - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1833,20 +1964,28 @@ - - - + + + - - + + - - - + + + - - + + + + + + + + + + @@ -1854,395 +1993,407 @@ - - - + + + - - - + + + - - + + + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - - - - + + - - - + + + - - + + - - - + + + - - + + - - - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + + + - - - + + + - - + + - - + + + + + + + - - + + + + - - + + - - - + + + + + + - - + + - - + + - - + + - - - + + + - - + + + + + + + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - + + - - - + + + - - + + - - + + - - - + + + - - + + - - + + - - - + + + - - + + - - + + - - - + + + - - + + - - + + - - - + + + - - + + - - + + - - - + + + - - + + - - + + - - - + + + - - + + - - + + - - - + + + - - + + - - + + - - - + + + - - + + - - + + - - - + + + - - + + - - + + - - - + + + - - + + - - + + - - - + + + - - + + - - + + - - - + + + - - + + - - + + - - - + + + - - + + - - + + - - - - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - + + @@ -2295,15 +2446,15 @@ - - - + + + - - + + - - + + @@ -2327,15 +2478,15 @@ - - - + + + - - + + - - + + @@ -2441,17 +2592,17 @@ - - - + + + - - - + + + - - + + @@ -2563,49 +2714,49 @@ - - - + + + - - + + - - - + + + - - + + - - - + + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + @@ -2613,9 +2764,9 @@ - - - + + + @@ -2628,12 +2779,12 @@ - - - + + + - - + + @@ -2662,49 +2813,49 @@ - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + @@ -2778,38 +2929,38 @@ - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - - + + + @@ -2838,30 +2989,30 @@ - - - + + + - - + + - - - + + + - - - + + + - - - + + + - - + + @@ -2872,20 +3023,20 @@ - - - + + + - - + + - - - + + + - - + + @@ -2996,6 +3147,11 @@ + + + + + @@ -3019,20 +3175,20 @@ - - - + + + - - + + - - - + + + - - + + @@ -3044,9 +3200,6 @@ - - - @@ -3059,6 +3212,14 @@ + + + + + + + + @@ -3125,11 +3286,6 @@ - - - - - @@ -3140,9 +3296,9 @@ - - - + + + @@ -3150,12 +3306,22 @@ - - - + + + + + + + + + + + + + - - + + @@ -3171,14 +3337,6 @@ - - - - - - - - @@ -3187,21 +3345,11 @@ - - - - - - - - - - @@ -3217,14 +3365,6 @@ - - - - - - - - @@ -3233,38 +3373,38 @@ - - - + + + - - + + - - - + + + - - - + + + - - + + - - - + + + - - + + - - - + + + @@ -3275,51 +3415,51 @@ - - - + + + - - - + + + - - - + + + - - + + - - - + + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + @@ -3340,44 +3480,44 @@ - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + @@ -3396,25 +3536,25 @@ - - - + + + - - + + - - - + + + - - + + - - - + + + @@ -3433,20 +3573,12 @@ - - - + + + - - - - - - - - - - + + @@ -3465,12 +3597,20 @@ - - - + + + - - + + + + + + + + + + @@ -3481,51 +3621,43 @@ - - - - - - - - - - - + + + - - + + - - + + - - - + + + - - - + + + - - + + - - - + + + - - - + + + @@ -3644,173 +3776,173 @@ - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - - + + + - - + + - - - + + + - - - + + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - - + + + - - + + @@ -4712,25 +4844,25 @@ - - - + + + - - - + + + - - + + - - - + + + - - + + @@ -4751,6 +4883,14 @@ + + + + + + + + @@ -4764,12 +4904,17 @@ - - - + + + + + + + + - - + + @@ -4788,12 +4933,12 @@ - - - + + + - - + + @@ -4899,15 +5044,15 @@ - - - + + + - - + + - - + + @@ -4941,12 +5086,12 @@ - - - + + + - - + + @@ -5065,36 +5210,36 @@ - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + @@ -5121,6 +5266,22 @@ + + + + + + + + + + + + + + + + @@ -5129,6 +5290,14 @@ + + + + + + + + @@ -5161,14 +5330,6 @@ - - - - - - - - @@ -5177,26 +5338,26 @@ - - - + + + - - + + - - + + - - - + + + - - + + - - + + @@ -5207,15 +5368,15 @@ - - - + + + - - + + - - + + @@ -5226,26 +5387,26 @@ - - - + + + - - + + - - + + - - - + + + - - + + - - + + @@ -5261,23 +5422,28 @@ - - - + + + - - + + - - - - - + + + + + + + + + + @@ -5293,12 +5459,12 @@ - - - + + + - - + + @@ -5309,12 +5475,12 @@ - - - + + + - - + + @@ -5333,30 +5499,30 @@ - - - + + + - - - + + + - - + + - - - + + + - - + + - - - + + + @@ -5364,28 +5530,20 @@ - - - - - - - - - - - + + + - - + + - - - + + + - - + + @@ -5438,12 +5596,12 @@ - - - + + + - - + + @@ -5594,12 +5752,12 @@ - - - + + + - - + + @@ -5615,6 +5773,11 @@ + + + + + @@ -5623,12 +5786,12 @@ - - - + + + - - + + @@ -5639,12 +5802,12 @@ - - - + + + - - + + @@ -5655,17 +5818,17 @@ - - - + + + - - + + - - - + + + @@ -5724,14 +5887,6 @@ - - - - - - - - @@ -5740,9 +5895,12 @@ - - - + + + + + + @@ -5750,12 +5908,17 @@ - - - + + + - - + + + + + + + @@ -5763,19 +5926,19 @@ - - - - - - - - + + + + + + + + @@ -5796,12 +5959,12 @@ - - - + + + - - + + @@ -5819,28 +5982,36 @@ - - - + + + + + + + + + + + - - + + - - + + - - - + + + - - + + - - - + + + @@ -5851,17 +6022,6 @@ - - - - - - - - - - - @@ -5870,15 +6030,26 @@ - - - + + + - - + + - - + + + + + + + + + + + + + @@ -5889,17 +6060,6 @@ - - - - - - - - - - - @@ -5911,15 +6071,15 @@ - - - + + + - - + + - - + + @@ -5930,31 +6090,31 @@ - - - + + + - - + + - - + + - - - + + + - - - - + + - - + + - - + + + + @@ -5965,15 +6125,15 @@ - - - + + + - - + + - - + + @@ -5987,15 +6147,15 @@ - - - + + + - - + + - - + + @@ -6006,6 +6166,17 @@ + + + + + + + + + + + @@ -6035,52 +6206,52 @@ - - - + + + - - + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - - + + + - - + + @@ -6110,15 +6281,15 @@ - - - + + + - - + + - - + + diff --git a/gradle/versions.gradle b/gradle/versions.gradle index f7599a8498..b7a286e69a 100644 --- a/gradle/versions.gradle +++ b/gradle/versions.gradle @@ -17,12 +17,7 @@ dependencyManagement { dependencies { applyMavenExclusions = false - dependencySet(group: 'org.antlr', version: '4.11.1') { - entry 'antlr4' - entry 'antlr4-runtime' - } - - dependencySet(group:'com.fasterxml.jackson.core', version:'2.16.1') { + dependencySet(group:'com.fasterxml.jackson.core', version:'2.17.2') { entry 'jackson-databind' entry 'jackson-datatype' entry 'jackson-datatype-jdk8' @@ -30,20 +25,20 @@ dependencyManagement { dependency 'com.github.ben-manes.caffeine:caffeine:3.1.8' - dependency 'com.github.oshi:oshi-core:6.4.10' + 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.50') { + 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.0.0-jre' + dependency 'com.google.guava:guava:33.3.0-jre' - dependency 'com.graphql-java:graphql-java:21.5' + dependency 'com.graphql-java:graphql-java:22.2' dependency 'com.splunk.logging:splunk-library-javalogging:1.11.8' @@ -51,16 +46,18 @@ dependencyManagement { dependency 'commons-codec:commons-codec:1.16.0' - dependency 'commons-io:commons-io:2.15.1' + dependency 'commons-io:commons-io:2.16.1' + + dependency 'commons-net:commons-net:3.11.1' - dependency 'dnsjava:dnsjava:3.6.0' + dependency 'dnsjava:dnsjava:3.6.1' - dependencySet(group: 'info.picocli', version: '4.7.5') { + dependencySet(group: 'info.picocli', version: '4.7.6') { entry 'picocli' entry 'picocli-codegen' } - dependencySet(group: 'io.grpc', version: '1.60.1') { + dependencySet(group: 'io.grpc', version: '1.66.0') { entry 'grpc-all' entry 'grpc-core' entry 'grpc-netty' @@ -69,22 +66,22 @@ dependencyManagement { dependency 'io.kubernetes:client-java:18.0.1' - dependency 'io.netty:netty-all:4.1.110.Final' - dependency 'io.netty:netty-tcnative-boringssl-static:2.0.62.Final' - dependency group: 'io.netty', name: 'netty-transport-native-epoll', version:'4.1.110.Final', classifier: 'linux-x86_64' - dependency group: 'io.netty', name: 'netty-transport-native-kqueue', version:'4.1.110.Final', classifier: 'osx-x86_64' - dependency 'io.netty:netty-transport-native-unix-common:4.1.110.Final' - - dependency 'io.opentelemetry:opentelemetry-api:1.33.0' - dependency 'io.opentelemetry:opentelemetry-exporter-otlp:1.33.0' - dependency 'io.opentelemetry:opentelemetry-extension-trace-propagators:1.33.0' - dependency 'io.opentelemetry:opentelemetry-sdk-metrics:1.33.0' - dependency 'io.opentelemetry:opentelemetry-sdk-trace:1.33.0' - dependency 'io.opentelemetry:opentelemetry-sdk:1.33.0' - dependency 'io.opentelemetry:opentelemetry-sdk-extension-autoconfigure:1.33.0' - dependency 'io.opentelemetry.instrumentation:opentelemetry-okhttp-3.0:1.32.0-alpha' - dependency 'io.opentelemetry.proto:opentelemetry-proto:1.0.0-alpha' - dependency 'io.opentelemetry.semconv:opentelemetry-semconv:1.23.1-alpha' + 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' @@ -115,7 +112,7 @@ dependencyManagement { entry 'tuweni-units' } - dependencySet(group: 'io.vertx', version: '4.5.8') { + dependencySet(group: 'io.vertx', version: '4.5.9') { entry 'vertx-auth-jwt' entry 'vertx-codegen' entry 'vertx-core' @@ -130,24 +127,28 @@ dependencyManagement { dependency 'net.java.dev.jna:jna:5.14.0' - dependency 'org.apache.commons:commons-compress:1.26.0' - dependency 'org.apache.commons:commons-lang3:3.14.0' - dependency 'org.apache.commons:commons-text:1.11.0' + dependencySet(group: 'org.antlr', version: '4.11.1') { + entry 'antlr4' + entry 'antlr4-runtime' + } + dependency 'org.apache.commons:commons-collections4:4.4' - dependency 'commons-net:commons-net:3.11.0' + 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.22.1') { + 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.25.1' + dependency 'org.assertj:assertj-core:3.26.3' - dependency 'org.awaitility:awaitility:4.2.0' + dependency 'org.awaitility:awaitility:4.2.2' - dependencySet(group: 'org.bouncycastle', version: '1.77') { + dependencySet(group: 'org.bouncycastle', version: '1.78.1') { entry'bcpkix-jdk18on' entry'bcprov-jdk18on' } @@ -164,19 +165,21 @@ dependencyManagement { entry 'gnark' } - dependencySet(group: 'org.immutables', version: '2.10.0') { + dependencySet(group: 'org.immutables', version: '2.10.1') { entry 'value-annotations' entry 'value' } - dependency 'org.java-websocket:Java-WebSocket:1.5.5' + dependency 'org.java-websocket:Java-WebSocket:1.5.7' - dependency 'org.jacoco:org.jacoco.agent:0.8.11' - dependency 'org.jacoco:org.jacoco.core:0.8.11' + dependencySet(group: 'org.jacoco', version: '0.8.12') { + entry 'org.jacoco.agent' + entry 'org.jacoco.core' + } - dependency 'org.jetbrains.kotlin:kotlin-stdlib:1.9.22' + dependency 'org.jetbrains.kotlin:kotlin-stdlib:2.0.20' - dependencySet(group: 'org.junit.jupiter', version: '5.10.1') { + dependencySet(group: 'org.junit.jupiter', version: '5.11.0') { entry 'junit-jupiter' entry 'junit-jupiter-api' entry 'junit-jupiter-engine' @@ -189,47 +192,47 @@ dependencyManagement { dependency 'org.junit.vintage:junit-vintage-engine:5.10.1' - dependencySet(group: 'org.jupnp', version:'2.7.1') { + dependencySet(group: 'org.jupnp', version:'3.0.2') { entry 'org.jupnp.support' entry 'org.jupnp' } - dependencySet(group: 'org.mockito', version:'5.8.0') { + dependencySet(group: 'org.mockito', version:'5.13.0') { entry 'mockito-core' entry 'mockito-junit-jupiter' } - dependencySet(group: 'org.openjdk.jmh', version:'1.36') { + dependencySet(group: 'org.openjdk.jmh', version:'1.37') { entry 'jmh-core' entry 'jmh-generator-annprocess' } - dependency 'org.owasp.encoder:encoder:1.2.3' + 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.10') { + dependencySet(group: 'org.slf4j', version:'2.0.16') { entry 'slf4j-api' entry 'slf4j-nop' } - dependency 'org.springframework.security:spring-security-crypto:6.2.1' + dependency 'org.springframework.security:spring-security-crypto:6.3.3' - dependency 'org.testcontainers:testcontainers:1.19.3' + dependency 'org.testcontainers:testcontainers:1.20.1' dependency 'org.web3j:quorum:4.10.0' - dependencySet(group: 'org.web3j', version: '4.11.1') { + dependencySet(group: 'org.web3j', version: '4.12.1') { entry 'abi' entry 'besu' entry 'core' entry 'crypto' } - dependencySet(group: 'org.wiremock', version: '3.3.1') { + dependencySet(group: 'org.wiremock', version: '3.9.1') { entry 'wiremock' } - dependency 'org.xerial.snappy:snappy-java:1.1.10.5' + dependency 'org.xerial.snappy:snappy-java:1.1.10.6' dependency 'org.yaml:snakeyaml:2.0' @@ -237,6 +240,6 @@ dependencyManagement { dependency 'tech.pegasys:jc-kzg-4844:1.0.0' - dependency 'tech.pegasys.discovery:discovery:22.12.0' + dependency 'tech.pegasys.discovery:discovery:24.6.0' } } From dc6324c8d03f585bf8bf33f91d9a44c0631a7161 Mon Sep 17 00:00:00 2001 From: Fabio Di Fabio Date: Thu, 5 Sep 2024 15:54:12 +0200 Subject: [PATCH 190/259] Layered txpool: fix for unsent drop notifications on remove (#7538) Signed-off-by: Fabio Di Fabio --- CHANGELOG.md | 1 + .../transactions/TransactionPoolMetrics.java | 2 +- .../AbstractSequentialTransactionsLayer.java | 9 +- .../layered/AbstractTransactionsLayer.java | 17 +- .../eth/transactions/layered/AddReason.java | 65 ++ .../BaseFeePrioritizedTransactions.java | 18 +- .../eth/transactions/layered/EndLayer.java | 5 +- .../layered/LayeredPendingTransactions.java | 35 +- .../layered/ReadyTransactions.java | 2 +- .../transactions/layered/RemovalReason.java | 131 ++++ .../layered/SparseTransactions.java | 7 +- .../layered/TransactionsLayer.java | 76 +-- ...stractPrioritizedTransactionsTestBase.java | 2 +- .../layered/BaseTransactionPoolTest.java | 1 - .../LayeredPendingTransactionsTest.java | 8 +- .../eth/transactions/layered/LayersTest.java | 609 ++++++++++++------ .../eth/transactions/layered/ReplayTest.java | 2 +- 17 files changed, 682 insertions(+), 308 deletions(-) create mode 100644 ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/AddReason.java create mode 100644 ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/RemovalReason.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 40bdb40ed1..c6e16c0d8a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ ### Bug fixes - Layered txpool: do not send notifications when moving tx between layers [#7539](https://github.com/hyperledger/besu/pull/7539) +- Layered txpool: fix for unsent drop notifications on remove [#7538](https://github.com/hyperledger/besu/pull/7538) ## 24.9.0 diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolMetrics.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolMetrics.java index 45f895881c..e08805551f 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolMetrics.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolMetrics.java @@ -15,7 +15,7 @@ package org.hyperledger.besu.ethereum.eth.transactions; import org.hyperledger.besu.datatypes.TransactionType; -import org.hyperledger.besu.ethereum.eth.transactions.layered.TransactionsLayer.AddReason; +import org.hyperledger.besu.ethereum.eth.transactions.layered.AddReason; import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason; import org.hyperledger.besu.metrics.BesuMetricCategory; import org.hyperledger.besu.metrics.ReplaceableDoubleSupplier; 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 2725f0012e..f7d71ca372 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 @@ -14,9 +14,9 @@ */ package org.hyperledger.besu.ethereum.eth.transactions.layered; -import static org.hyperledger.besu.ethereum.eth.transactions.layered.TransactionsLayer.AddReason.MOVE; -import static org.hyperledger.besu.ethereum.eth.transactions.layered.TransactionsLayer.RemovalReason.EVICTED; -import static org.hyperledger.besu.ethereum.eth.transactions.layered.TransactionsLayer.RemovalReason.FOLLOW_INVALIDATED; +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 org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.ethereum.eth.manager.EthScheduler; @@ -24,6 +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 java.util.Map; import java.util.NavigableMap; @@ -45,7 +46,7 @@ public abstract class AbstractSequentialTransactionsLayer extends AbstractTransa } @Override - public void remove(final PendingTransaction invalidatedTx, final RemovalReason reason) { + public void remove(final PendingTransaction invalidatedTx, final PoolRemovalReason reason) { nextLayer.remove(invalidatedTx, reason); final var senderTxs = txsBySender.get(invalidatedTx.getSender()); 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 81178a0709..b429de4a75 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 @@ -19,11 +19,12 @@ 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.REJECTED_UNDERPRICED_REPLACEMENT; import static org.hyperledger.besu.ethereum.eth.transactions.TransactionAddedResult.TRY_NEXT_LAYER; -import static org.hyperledger.besu.ethereum.eth.transactions.layered.TransactionsLayer.AddReason.MOVE; -import static org.hyperledger.besu.ethereum.eth.transactions.layered.TransactionsLayer.RemovalReason.CONFIRMED; -import static org.hyperledger.besu.ethereum.eth.transactions.layered.TransactionsLayer.RemovalReason.CROSS_LAYER_REPLACED; -import static org.hyperledger.besu.ethereum.eth.transactions.layered.TransactionsLayer.RemovalReason.EVICTED; -import static org.hyperledger.besu.ethereum.eth.transactions.layered.TransactionsLayer.RemovalReason.REPLACED; +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.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 org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Hash; @@ -292,7 +293,8 @@ public abstract class AbstractTransactionsLayer implements TransactionsLayer { if (remainingPromotionsPerType[txType.ordinal()] > 0) { senderTxs.pollFirstEntry(); - processRemove(senderTxs, candidateTx.getTransaction(), RemovalReason.PROMOTED); + processRemove( + senderTxs, candidateTx.getTransaction(), RemovalReason.LayerMoveReason.PROMOTED); metrics.incrementRemoved(candidateTx, "promoted", name()); if (senderTxs.isEmpty()) { @@ -419,6 +421,9 @@ public abstract class AbstractTransactionsLayer implements TransactionsLayer { decreaseCounters(removedTx); metrics.incrementRemoved(removedTx, removalReason.label(), name()); internalRemove(senderTxs, removedTx, removalReason); + if (removalReason.removedFrom().equals(POOL)) { + notifyTransactionDropped(removedTx); + } } return removedTx; } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/AddReason.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/AddReason.java new file mode 100644 index 0000000000..895dd61e3e --- /dev/null +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/AddReason.java @@ -0,0 +1,65 @@ +/* + * 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.layered; + +import java.util.Locale; + +/** Describe why we are trying to add a tx to a layer. */ +public enum AddReason { + /** When adding a tx, that is not present in the pool. */ + NEW(true, true), + /** When adding a tx as result of an internal move between layers. */ + MOVE(false, false), + /** When adding a tx as result of a promotion from a lower layer. */ + PROMOTED(false, false); + + private final boolean sendNotification; + private final boolean makeCopy; + private final String label; + + AddReason(final boolean sendNotification, final boolean makeCopy) { + this.sendNotification = sendNotification; + this.makeCopy = makeCopy; + this.label = name().toLowerCase(Locale.ROOT); + } + + /** + * Should we send add notification for this reason? + * + * @return true if notification should be sent + */ + public boolean sendNotification() { + return sendNotification; + } + + /** + * Should the layer make a copy of the pending tx before adding it, to avoid keeping reference to + * potentially large underlying byte buffers? + * + * @return true is a copy is necessary + */ + public boolean makeCopy() { + return makeCopy; + } + + /** + * Return a label that identify this reason to be used in the metric system. + * + * @return a label + */ + public String label() { + return label; + } +} 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 170205e498..c06fb53e33 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 @@ -14,8 +14,8 @@ */ package org.hyperledger.besu.ethereum.eth.transactions.layered; -import static org.hyperledger.besu.ethereum.eth.transactions.layered.TransactionsLayer.AddReason.MOVE; -import static org.hyperledger.besu.ethereum.eth.transactions.layered.TransactionsLayer.RemovalReason.BELOW_BASE_FEE; +import static org.hyperledger.besu.ethereum.eth.transactions.layered.AddReason.MOVE; +import static org.hyperledger.besu.ethereum.eth.transactions.layered.RemovalReason.LayerMoveReason.DEMOTED; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.core.BlockHeader; @@ -105,7 +105,7 @@ public class BaseFeePrioritizedTransactions extends AbstractPrioritizedTransacti while (itTxsBySender.hasNext()) { final var senderTxs = itTxsBySender.next().getValue(); - Optional maybeFirstUnderpricedNonce = Optional.empty(); + Optional maybeFirstDemotedNonce = Optional.empty(); for (final var e : senderTxs.entrySet()) { final PendingTransaction tx = e.getValue(); @@ -115,25 +115,27 @@ public class BaseFeePrioritizedTransactions extends AbstractPrioritizedTransacti } else { // otherwise sender txs starting from this nonce need to be demoted to next layer, // and we can go to next sender - maybeFirstUnderpricedNonce = Optional.of(e.getKey()); + maybeFirstDemotedNonce = Optional.of(e.getKey()); break; } } - maybeFirstUnderpricedNonce.ifPresent( + maybeFirstDemotedNonce.ifPresent( nonce -> { - // demote all txs after the first underpriced to the next layer, because none of them is + // demote all txs after the first demoted to the next layer, because none of them is // executable now, and we can avoid sorting them until they are candidate for execution // again final var demoteTxs = senderTxs.tailMap(nonce, true); while (!demoteTxs.isEmpty()) { final PendingTransaction demoteTx = demoteTxs.pollLastEntry().getValue(); LOG.atTrace() - .setMessage("Demoting tx {} with max gas price below next block base fee {}") + .setMessage( + "Demoting tx {} since it does not respect anymore the requisites to stay in this layer." + + " Next block base fee {}") .addArgument(demoteTx::toTraceLog) .addArgument(newNextBlockBaseFee::toHumanReadableString) .log(); - processEvict(senderTxs, demoteTx, BELOW_BASE_FEE); + processEvict(senderTxs, demoteTx, DEMOTED); addToNextLayer(senderTxs, demoteTx, 0, MOVE); } }); 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 16571e7aef..c76d2ab97a 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.TransactionsLayer.RemovalReason.DROPPED; +import static org.hyperledger.besu.ethereum.eth.transactions.layered.RemovalReason.PoolRemovalReason.DROPPED; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Hash; @@ -25,6 +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.mainnet.feemarket.FeeMarket; import org.hyperledger.besu.util.Subscribers; @@ -84,7 +85,7 @@ public class EndLayer implements TransactionsLayer { } @Override - public void remove(final PendingTransaction pendingTransaction, final RemovalReason reason) {} + public void remove(final PendingTransaction pendingTransaction, final PoolRemovalReason reason) {} @Override public void penalize(final PendingTransaction penalizedTx) {} 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 3e0a87da2f..0209900eac 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 @@ -20,9 +20,9 @@ import static java.util.stream.Collectors.reducing; import static org.hyperledger.besu.ethereum.eth.transactions.TransactionAddedResult.ALREADY_KNOWN; 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.TransactionsLayer.AddReason.NEW; -import static org.hyperledger.besu.ethereum.eth.transactions.layered.TransactionsLayer.RemovalReason.INVALIDATED; -import static org.hyperledger.besu.ethereum.eth.transactions.layered.TransactionsLayer.RemovalReason.RECONCILED; +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 org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Hash; @@ -316,7 +316,6 @@ public class LayeredPendingTransactions implements PendingTransactions { @Override public void selectTransactions(final PendingTransactions.TransactionSelector selector) { - final List invalidTransactions = new ArrayList<>(); final List penalizedTransactions = new ArrayList<>(); final Set
skipSenders = new HashSet<>(); @@ -347,7 +346,12 @@ public class LayeredPendingTransactions implements PendingTransactions { .log(); if (selectionResult.discard()) { - invalidTransactions.add(candidatePendingTx); + ethScheduler.scheduleTxWorkerTask( + () -> { + synchronized (this) { + prioritizedTransactions.remove(candidatePendingTx, INVALIDATED); + } + }); logDiscardedTransaction(candidatePendingTx, selectionResult); } @@ -377,20 +381,13 @@ public class LayeredPendingTransactions implements PendingTransactions { } ethScheduler.scheduleTxWorkerTask( - () -> { - invalidTransactions.forEach( - invalidTx -> { - synchronized (this) { - prioritizedTransactions.remove(invalidTx, INVALIDATED); - } - }); - penalizedTransactions.forEach( - penalizedTx -> { - synchronized (this) { - prioritizedTransactions.internalPenalize(penalizedTx); - } - }); - }); + () -> + penalizedTransactions.forEach( + penalizedTx -> { + synchronized (this) { + prioritizedTransactions.penalize(penalizedTx); + } + })); } @Override 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 0f52e1c5c3..7c7ddcdaeb 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.TransactionsLayer.RemovalReason.PROMOTED; +import static org.hyperledger.besu.ethereum.eth.transactions.layered.RemovalReason.LayerMoveReason.PROMOTED; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.ethereum.core.BlockHeader; 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/RemovalReason.java new file mode 100644 index 0000000000..8b97861b88 --- /dev/null +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/layered/RemovalReason.java @@ -0,0 +1,131 @@ +/* + * 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.layered; + +import java.util.Locale; + +/** The reason why a pending tx has been removed */ +public interface RemovalReason { + /** + * From where the tx has been removed + * + * @return removed from item + */ + 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 { + /** + * Removing from a layer, can be also seen as a move between layers, since it is removed + * from the current layer and added to another layer, for example in the case the layer is full + * and some txs need to be moved to the next layer, or in the opposite case when some txs are + * promoted to the upper layer. + */ + LAYER, + /** + * Removing from the pool, instead means that the tx is directly removed from the pool, and it + * will not be present in any layer, for example, when it is added to an imported block, or it + * is replaced by another tx. + */ + POOL + } + + /** 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(), + /** + * Tx removed since found invalid after it was added to the pool, for example during txs + * selection for a new block proposal. + */ + INVALIDATED(), + /** + * 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. + */ + RECONCILED(); + + private final String label; + + PoolRemovalReason() { + this.label = name().toLowerCase(Locale.ROOT); + } + + @Override + public RemovedFrom removedFrom() { + return RemovedFrom.POOL; + } + + @Override + public String label() { + return label; + } + } + + /** The reason why the tx has been moved across layers */ + enum LayerMoveReason implements RemovalReason { + /** + * When the current layer is full, and this tx needs to be moved to the lower layer, in order to + * free space. + */ + EVICTED(), + /** + * Specific to sequential layers, when a tx is removed because found invalid, then if the sender + * has other txs with higher nonce, then a gap is created, and since sequential layers do not + * permit gaps, txs following the invalid one need to be moved to lower layers. + */ + FOLLOW_INVALIDATED(), + /** + * When a tx is moved to the upper layer, since it satisfies all the requirement to be promoted. + */ + PROMOTED(), + /** + * When a tx is moved to the lower layer, since it, or a preceding one from the same sender, + * does not respect anymore the requisites to stay in this layer. + */ + DEMOTED(); + + private final String label; + + LayerMoveReason() { + this.label = name().toLowerCase(Locale.ROOT); + } + + @Override + public RemovedFrom removedFrom() { + return RemovedFrom.LAYER; + } + + @Override + public String label() { + return label; + } + } +} 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 aef318e6df..7a20f94540 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.TransactionsLayer.RemovalReason.INVALIDATED; -import static org.hyperledger.besu.ethereum.eth.transactions.layered.TransactionsLayer.RemovalReason.PROMOTED; +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 org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.ethereum.core.BlockHeader; @@ -26,6 +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.mainnet.feemarket.FeeMarket; import java.util.ArrayList; @@ -225,7 +226,7 @@ public class SparseTransactions extends AbstractTransactionsLayer { @Override public synchronized void remove( - final PendingTransaction invalidatedTx, final RemovalReason reason) { + final PendingTransaction invalidatedTx, final PoolRemovalReason reason) { final var senderTxs = txsBySender.get(invalidatedTx.getSender()); if (senderTxs != null && senderTxs.containsKey(invalidatedTx.getNonce())) { 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 0117ed71b6..16ce957fb8 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,10 +22,10 @@ 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.mainnet.feemarket.FeeMarket; import java.util.List; -import java.util.Locale; import java.util.Map; import java.util.Optional; import java.util.OptionalLong; @@ -55,7 +55,13 @@ public interface TransactionsLayer { */ TransactionAddedResult add(PendingTransaction pendingTransaction, int gap, AddReason addReason); - void remove(PendingTransaction pendingTransaction, RemovalReason reason); + /** + * Remove the pending tx from the pool + * + * @param pendingTransaction the pending tx + * @param reason the reason it is removed from the pool + */ + void remove(PendingTransaction pendingTransaction, PoolRemovalReason reason); /** * Penalize a pending transaction. Penalization could be applied to notify the txpool that this @@ -119,70 +125,4 @@ public interface TransactionsLayer { String logStats(); String logSender(Address sender); - - /** Describe why we are trying to add a tx to a layer. */ - enum AddReason { - /** When adding a tx, that is not present in the pool. */ - NEW(true, true), - /** When adding a tx as result of an internal move between layers. */ - MOVE(false, false), - /** When adding a tx as result of a promotion from a lower layer. */ - PROMOTED(false, false); - - private final boolean sendNotification; - private final boolean makeCopy; - private final String label; - - AddReason(final boolean sendNotification, final boolean makeCopy) { - this.sendNotification = sendNotification; - this.makeCopy = makeCopy; - this.label = name().toLowerCase(Locale.ROOT); - } - - /** - * Should we send add notification for this reason? - * - * @return true if notification should be sent - */ - public boolean sendNotification() { - return sendNotification; - } - - /** - * Should the layer make a copy of the pending tx before adding it, to avoid keeping reference - * to potentially large underlying byte buffers? - * - * @return true is a copy is necessary - */ - public boolean makeCopy() { - return makeCopy; - } - - public String label() { - return label; - } - } - - enum RemovalReason { - CONFIRMED, - CROSS_LAYER_REPLACED, - EVICTED, - DROPPED, - FOLLOW_INVALIDATED, - INVALIDATED, - PROMOTED, - REPLACED, - RECONCILED, - BELOW_BASE_FEE; - - private final String label; - - RemovalReason() { - this.label = name().toLowerCase(Locale.ROOT); - } - - public String label() { - return label; - } - } } diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/AbstractPrioritizedTransactionsTestBase.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/AbstractPrioritizedTransactionsTestBase.java index f9e16fa0ea..6a0005eec6 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/AbstractPrioritizedTransactionsTestBase.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/AbstractPrioritizedTransactionsTestBase.java @@ -17,7 +17,7 @@ package org.hyperledger.besu.ethereum.eth.transactions.layered; 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.DROPPED; -import static org.hyperledger.besu.ethereum.eth.transactions.layered.TransactionsLayer.AddReason.NEW; +import static org.hyperledger.besu.ethereum.eth.transactions.layered.AddReason.NEW; import org.hyperledger.besu.datatypes.TransactionType; import org.hyperledger.besu.datatypes.Wei; diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/BaseTransactionPoolTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/BaseTransactionPoolTest.java index 5cd098ef6f..864c8c9181 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/BaseTransactionPoolTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/BaseTransactionPoolTest.java @@ -35,7 +35,6 @@ import org.hyperledger.besu.ethereum.eth.manager.EthScheduler; import org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction; import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolMetrics; -import org.hyperledger.besu.ethereum.eth.transactions.layered.TransactionsLayer.AddReason; import org.hyperledger.besu.evm.account.Account; import org.hyperledger.besu.metrics.StubMetricsSystem; import org.hyperledger.besu.testutil.DeterministicEthScheduler; 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 a5e7a151e2..4fa3fa727a 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 @@ -20,10 +20,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.layered.TransactionsLayer.AddReason.MOVE; -import static org.hyperledger.besu.ethereum.eth.transactions.layered.TransactionsLayer.AddReason.NEW; -import static org.hyperledger.besu.ethereum.eth.transactions.layered.TransactionsLayer.RemovalReason.DROPPED; -import static org.hyperledger.besu.ethereum.eth.transactions.layered.TransactionsLayer.RemovalReason.REPLACED; +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.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; 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 3df5fb6d3a..2036e46d63 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 @@ -15,6 +15,8 @@ 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.awaitility.Awaitility.await; 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; @@ -25,7 +27,7 @@ import static org.hyperledger.besu.ethereum.eth.transactions.layered.LayersTest. 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.TransactionsLayer.RemovalReason.INVALIDATED; +import static org.hyperledger.besu.ethereum.eth.transactions.layered.RemovalReason.PoolRemovalReason.INVALIDATED; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -35,6 +37,7 @@ import org.hyperledger.besu.datatypes.TransactionType; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.MiningParameters; +import org.hyperledger.besu.ethereum.core.Transaction; import org.hyperledger.besu.ethereum.core.Util; import org.hyperledger.besu.ethereum.eth.manager.EthScheduler; import org.hyperledger.besu.ethereum.eth.transactions.BlobCache; @@ -51,11 +54,14 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.EnumMap; +import java.util.EnumSet; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.NavigableMap; import java.util.Optional; import java.util.OptionalLong; +import java.util.TreeMap; import java.util.stream.Stream; import org.junit.jupiter.api.Test; @@ -156,7 +162,7 @@ public class LayersTest extends BaseTransactionPoolTest { @ParameterizedTest @MethodSource("providerMaxPrioritizedByType") void maxPrioritizedByType(final Scenario scenario) { - assertScenario(scenario, BLOB_TX_POOL_CONFIG); + assertScenario(scenario); } @ParameterizedTest @@ -166,54 +172,7 @@ public class LayersTest extends BaseTransactionPoolTest { } private void assertScenario(final Scenario scenario) { - assertScenario(scenario, DEFAULT_TX_POOL_CONFIG); - } - - private void assertScenario( - final Scenario scenario, final TransactionPoolConfiguration poolConfig) { - final TransactionPoolMetrics txPoolMetrics = new TransactionPoolMetrics(metricsSystem); - - final EvictCollectorLayer evictCollector = new EvictCollectorLayer(txPoolMetrics); - final EthScheduler ethScheduler = new DeterministicEthScheduler(); - final SparseTransactions sparseTransactions = - new SparseTransactions( - poolConfig, - ethScheduler, - evictCollector, - txPoolMetrics, - (pt1, pt2) -> transactionReplacementTester(poolConfig, pt1, pt2), - new BlobCache()); - - final ReadyTransactions readyTransactions = - new ReadyTransactions( - poolConfig, - ethScheduler, - sparseTransactions, - txPoolMetrics, - (pt1, pt2) -> transactionReplacementTester(poolConfig, pt1, pt2), - new BlobCache()); - - final BaseFeePrioritizedTransactions prioritizedTransactions = - new BaseFeePrioritizedTransactions( - poolConfig, - LayersTest::mockBlockHeader, - ethScheduler, - readyTransactions, - txPoolMetrics, - (pt1, pt2) -> transactionReplacementTester(poolConfig, pt1, pt2), - FeeMarket.london(0L), - new BlobCache(), - MiningParameters.newDefault().setMinTransactionGasPrice(MIN_GAS_PRICE)); - - final LayeredPendingTransactions pendingTransactions = - new LayeredPendingTransactions(poolConfig, prioritizedTransactions, ethScheduler); - - scenario.execute( - pendingTransactions, - prioritizedTransactions, - readyTransactions, - sparseTransactions, - evictCollector); + scenario.run(); } static Stream providerAddTransactions() { @@ -452,7 +411,7 @@ public class LayersTest extends BaseTransactionPoolTest { .expectedReadyForSenders(S1, 0, S1, 1) .expectedSparseForSender(S3, 2) .addForSenders(S3, 1) - // ToDo: only S3[1] is prioritized because there is no space to try to fill gaps + // only S3[1] is prioritized because there is no space to try to fill gaps .expectedPrioritizedForSenders(S3, 0, S3, 1, S2, 0) .expectedReadyForSenders(S2, 1, S1, 0, S1, 1) .expectedSparseForSender(S3, 2) @@ -465,11 +424,11 @@ public class LayersTest extends BaseTransactionPoolTest { Arguments.of( new Scenario("replacement cross layer") .addForSenders(S2, 0, S3, 2, S1, 1, S2, 1, S3, 0, S1, 0, S3, 1) - // ToDo: only S3[1] is prioritized because there is no space to try to fill gaps + // only S3[1] is prioritized because there is no space to try to fill gaps .expectedPrioritizedForSenders(S3, 0, S3, 1, S2, 0) .expectedReadyForSenders(S2, 1, S1, 0, S1, 1) .expectedSparseForSender(S3, 2) - .addForSenders(S3, 2) // added in prioritized, but replacement in sparse + .replaceForSenders(S3, 2) // added in prioritized, but replacement in sparse .expectedPrioritizedForSenders(S3, 0, S3, 1, S3, 2) .expectedReadyForSenders(S2, 0, S2, 1, S1, 0) .expectedSparseForSender(S1, 1))); @@ -477,6 +436,8 @@ public class LayersTest extends BaseTransactionPoolTest { static Stream providerRemoveTransactions() { return Stream.of( + // when expected*ForSender(s) is not present, by default there is a check that the layers + // are empty Arguments.of(new Scenario("remove not existing").removeForSender(S1, 0)), Arguments.of(new Scenario("add/remove first").addForSender(S1, 0).removeForSender(S1, 0)), Arguments.of( @@ -1060,10 +1021,10 @@ public class LayersTest extends BaseTransactionPoolTest { .expectedNextNonceForSenders(S1, 3) .addForSender(S1, 3) .expectedPrioritizedForSender(S1, 2, 3) - .setAccountNonce(S1, 0) // rewind nonce due to reorg - .addForSender(S1, 0) - .expectedPrioritizedForSender(S1, 0) - .expectedSparseForSender(S1, 2, 3))); + .reorgForSenders(S1, 0) // rewind nonce due to reorg + .addForSender(S1, 0, 1) // re-add reorged txs + .expectedPrioritizedForSender(S1, 0, 1, 2) + .expectedReadyForSender(S1, 3))); } static Stream providerAsyncWorldStateUpdates() { @@ -1221,22 +1182,22 @@ public class LayersTest extends BaseTransactionPoolTest { static Stream providerMaxPrioritizedByType() { return Stream.of( Arguments.of( - new Scenario("first blob tx is prioritized") + new Scenario("first blob tx is prioritized", BLOB_TX_POOL_CONFIG) .addForSender(S1, BLOB, 0) .expectedPrioritizedForSender(S1, 0)), Arguments.of( - new Scenario("multiple senders only first blob tx is prioritized") + new Scenario("multiple senders only first blob tx is prioritized", BLOB_TX_POOL_CONFIG) .addForSender(S1, BLOB, 0) .addForSender(S2, BLOB, 0) .expectedPrioritizedForSender(S1, 0) .expectedReadyForSender(S2, 0)), Arguments.of( - new Scenario("same sender following blob txs are moved to ready") + new Scenario("same sender following blob txs are moved to ready", BLOB_TX_POOL_CONFIG) .addForSender(S1, BLOB, 0, 1, 2) .expectedPrioritizedForSender(S1, 0) .expectedReadyForSender(S1, 1, 2)), Arguments.of( - new Scenario("promoting txs respect prioritized count limit") + new Scenario("promoting txs respect prioritized count limit", BLOB_TX_POOL_CONFIG) .addForSender(S1, BLOB, 0, 1, 2) .expectedPrioritizedForSender(S1, 0) .expectedReadyForSender(S1, 1, 2) @@ -1244,14 +1205,14 @@ public class LayersTest extends BaseTransactionPoolTest { .expectedPrioritizedForSender(S1, 1) .expectedReadyForSender(S1, 2)), Arguments.of( - new Scenario("filling gaps respect prioritized count limit") + new Scenario("filling gaps respect prioritized count limit", BLOB_TX_POOL_CONFIG) .addForSender(S1, BLOB, 1) .expectedSparseForSender(S1, 1) .addForSender(S1, BLOB, 0) .expectedPrioritizedForSender(S1, 0) .expectedSparseForSender(S1, 1)), Arguments.of( - new Scenario("promoting to ready is unbounded") + new Scenario("promoting to ready is unbounded", BLOB_TX_POOL_CONFIG) .addForSender(S1, BLOB, 0, 1, 2, 3, 4, 5, 6) .expectedPrioritizedForSender(S1, 0) .expectedReadyForSender(S1, 1, 2, 3) @@ -1351,18 +1312,18 @@ public class LayersTest extends BaseTransactionPoolTest { return transactionReplacementHandler.shouldReplace(pt1, pt2, mockBlockHeader()); } - static class Scenario extends BaseTransactionPoolTest { - interface TransactionLayersConsumer { - void accept( - LayeredPendingTransactions pending, - AbstractPrioritizedTransactions prioritized, - ReadyTransactions ready, - SparseTransactions sparse, - EvictCollectorLayer dropped); - } + static class Scenario extends BaseTransactionPoolTest implements Runnable { final String description; - final List actions = new ArrayList<>(); + final TransactionPoolConfiguration poolConfig; + final EvictCollectorLayer dropped; + final SparseTransactions sparse; + final ReadyTransactions ready; + final AbstractPrioritizedTransactions prio; + final LayeredPendingTransactions pending; + + final NotificationsChecker notificationsChecker = new NotificationsChecker(); + final List actions = new ArrayList<>(); List lastExpectedPrioritized = new ArrayList<>(); List lastExpectedReady = new ArrayList<>(); List lastExpectedSparse = new ArrayList<>(); @@ -1374,94 +1335,281 @@ public class LayersTest extends BaseTransactionPoolTest { Arrays.stream(Sender.values()).forEach(e -> nonceBySender.put(e, 0L)); } - final EnumMap> txsBySender = new EnumMap<>(Sender.class); + final EnumSet sendersWithReorg = EnumSet.noneOf(Sender.class); + + final EnumMap> liveTxsBySender = + new EnumMap<>(Sender.class); + + { + Arrays.stream(Sender.values()).forEach(e -> liveTxsBySender.put(e, new TreeMap<>())); + } + + final EnumMap> droppedTxsBySender = + new EnumMap<>(Sender.class); { - Arrays.stream(Sender.values()).forEach(e -> txsBySender.put(e, new HashMap<>())); + Arrays.stream(Sender.values()).forEach(e -> droppedTxsBySender.put(e, new TreeMap<>())); } Scenario(final String description) { + this(description, DEFAULT_TX_POOL_CONFIG); + } + + Scenario(final String description, final TransactionPoolConfiguration poolConfig) { this.description = description; + this.poolConfig = poolConfig; + + final TransactionPoolMetrics txPoolMetrics = new TransactionPoolMetrics(metricsSystem); + + this.dropped = new EvictCollectorLayer(txPoolMetrics); + final EthScheduler ethScheduler = new DeterministicEthScheduler(); + this.sparse = + new SparseTransactions( + poolConfig, + ethScheduler, + this.dropped, + txPoolMetrics, + (pt1, pt2) -> transactionReplacementTester(poolConfig, pt1, pt2), + new BlobCache()); + + this.ready = + new ReadyTransactions( + poolConfig, + ethScheduler, + this.sparse, + txPoolMetrics, + (pt1, pt2) -> transactionReplacementTester(poolConfig, pt1, pt2), + new BlobCache()); + + this.prio = + new BaseFeePrioritizedTransactions( + poolConfig, + LayersTest::mockBlockHeader, + ethScheduler, + this.ready, + txPoolMetrics, + (pt1, pt2) -> transactionReplacementTester(poolConfig, pt1, pt2), + FeeMarket.london(0L), + new BlobCache(), + MiningParameters.newDefault().setMinTransactionGasPrice(MIN_GAS_PRICE)); + + this.pending = new LayeredPendingTransactions(poolConfig, this.prio, ethScheduler); + + this.pending.subscribePendingTransactions(notificationsChecker::collectAddNotification); + this.pending.subscribeDroppedTransactions(notificationsChecker::collectDropNotification); } - Scenario addForSender(final Sender sender, final long... nonce) { + @Override + public void run() { + actions.forEach(Runnable::run); + assertExpectedPrioritized(prio, lastExpectedPrioritized); + assertExpectedReady(ready, lastExpectedReady); + assertExpectedSparse(sparse, lastExpectedSparse); + assertExpectedDropped(dropped, lastExpectedDropped); + } + + public Scenario addForSender(final Sender sender, final long... nonce) { return addForSender(sender, EIP1559, nonce); } - Scenario addForSender(final Sender sender, final TransactionType type, final long... nonce) { - Arrays.stream(nonce) - .forEach( - n -> { - final var pendingTx = getOrCreate(sender, type, n); - actions.add( - (pending, prio, ready, sparse, dropped) -> { + public Scenario addForSender( + final Sender sender, final TransactionType type, final long... nonce) { + internalAddForSender(sender, type, nonce); + actions.add(notificationsChecker::assertExpectedNotifications); + return this; + } + + private void internalAddForSender( + final Sender sender, final TransactionType type, final long... nonce) { + actions.add( + () -> { + Arrays.stream(nonce) + .forEach( + n -> { + final var pendingTx = create(sender, type, n); final Account mockSender = mock(Account.class); when(mockSender.getNonce()).thenReturn(nonceBySender.get(sender)); pending.addTransaction(pendingTx, Optional.of(mockSender)); + notificationsChecker.addExpectedAddNotification(pendingTx); }); + + // reorg case + if (sendersWithReorg.contains(sender)) { + // reorg is removing and re-adding all sender txs, so assert notifications accordingly + final var currentPendingTxs = + liveTxsBySender.get(sender).tailMap(nonce[nonce.length - 1], false).values(); + currentPendingTxs.forEach( + pt -> { + notificationsChecker.addExpectedAddNotification(pt); + notificationsChecker.addExpectedDropNotification(pt); + }); + sendersWithReorg.remove(sender); + } + + // reconciliation case + final var txsRemovedByReconciliation = + liveTxsBySender.get(sender).headMap(nonceBySender.get(sender), false).values(); + if (!txsRemovedByReconciliation.isEmpty()) { + // reconciliation is removing all sender txs, and re-adding only the ones with a + // larger nonce, so assert notifications accordingly + final var reconciledPendingTxs = + liveTxsBySender.get(sender).tailMap(nonce[nonce.length - 1], false).values(); + txsRemovedByReconciliation.forEach(notificationsChecker::addExpectedDropNotification); + reconciledPendingTxs.forEach( + pt -> { + notificationsChecker.addExpectedDropNotification(pt); + notificationsChecker.addExpectedAddNotification(pt); + }); + txsRemovedByReconciliation.clear(); + } + + handleDropped(); + }); + } + + private void handleDropped() { + // handle dropped tx due to layer or pool full + final var droppedTxs = dropped.getEvictedTransactions(); + droppedTxs.forEach(notificationsChecker::addExpectedDropNotification); + droppedTxs.stream() + .forEach( + pt -> { + liveTxsBySender.get(Sender.getByAddress(pt.getSender())).remove(pt.getNonce()); + droppedTxsBySender.get(Sender.getByAddress(pt.getSender())).put(pt.getNonce(), pt); }); - return this; } - Scenario addForSenders(final Object... args) { + public Scenario addForSenders(final Object... args) { for (int i = 0; i < args.length; i = i + 2) { final Sender sender = (Sender) args[i]; final long nonce = (int) args[i + 1]; - addForSender(sender, nonce); + internalAddForSender(sender, EIP1559, nonce); } + actions.add(notificationsChecker::assertExpectedNotifications); return this; } - public Scenario confirmedForSenders(final Object... args) { - final Map maxConfirmedNonceBySender = new HashMap<>(); + public Scenario replaceForSender(final Sender sender, final long... nonce) { + internalReplaceForSender(sender, nonce); + actions.add(notificationsChecker::assertExpectedNotifications); + return this; + } + + private Scenario internalReplaceForSender(final Sender sender, final long... nonce) { + actions.add( + () -> { + Arrays.stream(nonce) + .forEach( + n -> { + final var maybeExistingTx = getMaybe(sender, n); + maybeExistingTx.ifPresentOrElse( + existingTx -> { + final var pendingTx = replace(sender, existingTx); + final Account mockSender = mock(Account.class); + when(mockSender.getNonce()).thenReturn(nonceBySender.get(sender)); + pending.addTransaction(pendingTx, Optional.of(mockSender)); + notificationsChecker.addExpectedAddNotification(pendingTx); + notificationsChecker.addExpectedDropNotification(existingTx); + }, + () -> + fail( + "Could not replace non-existing transaction with nonce " + + n + + " for sender " + + sender.name())); + }); + }); + return this; + } + + public Scenario replaceForSenders(final Object... args) { for (int i = 0; i < args.length; i = i + 2) { final Sender sender = (Sender) args[i]; final long nonce = (int) args[i + 1]; - maxConfirmedNonceBySender.put(sender.address, nonce); - setAccountNonce(sender, nonce + 1); + internalReplaceForSender(sender, nonce); } + actions.add(notificationsChecker::assertExpectedNotifications); + return this; + } + + public Scenario confirmedForSenders(final Object... args) { actions.add( - (pending, prio, ready, sparse, dropped) -> - prio.blockAdded(FeeMarket.london(0L), mockBlockHeader(), maxConfirmedNonceBySender)); + () -> { + final Map maxConfirmedNonceBySender = new HashMap<>(); + for (int i = 0; i < args.length; i = i + 2) { + final Sender sender = (Sender) args[i]; + final long nonce = (int) args[i + 1]; + maxConfirmedNonceBySender.put(sender.address, nonce); + nonceBySender.put(sender, nonce + 1); + for (final var pendingTx : getAll(sender)) { + if (pendingTx.getNonce() <= nonce) { + notificationsChecker.addExpectedDropNotification( + liveTxsBySender.get(sender).remove(pendingTx.getNonce())); + } + } + } + + prio.blockAdded(FeeMarket.london(0L), mockBlockHeader(), maxConfirmedNonceBySender); + notificationsChecker.assertExpectedNotifications(); + }); return this; } - Scenario setAccountNonce(final Sender sender, final long nonce) { - actions.add((pending, prio, ready, sparse, dropped) -> nonceBySender.put(sender, nonce)); + public Scenario setAccountNonce(final Sender sender, final long nonce) { + actions.add(() -> nonceBySender.put(sender, nonce)); return this; } - void execute( - final LayeredPendingTransactions pending, - final AbstractPrioritizedTransactions prioritized, - final ReadyTransactions ready, - final SparseTransactions sparse, - final EvictCollectorLayer dropped) { - actions.forEach(action -> action.accept(pending, prioritized, ready, sparse, dropped)); - assertExpectedPrioritized(prioritized, lastExpectedPrioritized); - assertExpectedReady(ready, lastExpectedReady); - assertExpectedSparse(sparse, lastExpectedSparse); - assertExpectedDropped(dropped, lastExpectedDropped); + public Scenario reorgForSenders(final Object... args) { + actions.add( + () -> { + for (int i = 0; i < args.length; i = i + 2) { + final Sender sender = (Sender) args[i]; + final long nonce = (int) args[i + 1]; + nonceBySender.put(sender, nonce); + sendersWithReorg.add(sender); + } + }); + return this; } - private PendingTransaction getOrCreate( + private PendingTransaction create( final Sender sender, final TransactionType type, final long nonce) { - return txsBySender - .get(sender) - .computeIfAbsent( - nonce, - n -> - switch (type) { - case FRONTIER -> createFrontierPendingTransaction(sender, n); - case ACCESS_LIST -> createAccessListPendingTransaction(sender, n); - case EIP1559 -> createEIP1559PendingTransaction(sender, n); - case BLOB -> createBlobPendingTransaction(sender, n); - case SET_CODE -> throw new UnsupportedOperationException(); - }); + if (liveTxsBySender.get(sender).containsKey(nonce)) { + fail( + "Transaction for sender " + sender.name() + " with nonce " + nonce + " already exists"); + } + final var newPendingTx = + switch (type) { + case FRONTIER -> createFrontierPendingTransaction(sender, nonce); + case ACCESS_LIST -> createAccessListPendingTransaction(sender, nonce); + case EIP1559 -> createEIP1559PendingTransaction(sender, nonce); + case BLOB -> createBlobPendingTransaction(sender, nonce); + case SET_CODE -> throw new UnsupportedOperationException(); + }; + liveTxsBySender.get(sender).put(nonce, newPendingTx); + return newPendingTx; + } + + private PendingTransaction replace(final Sender sender, final PendingTransaction pendingTx) { + final var replaceTx = + createRemotePendingTransaction( + createTransactionReplacement(pendingTx.getTransaction(), sender.key), + sender.hasPriority); + liveTxsBySender.get(sender).replace(pendingTx.getNonce(), replaceTx); + return replaceTx; + } + + private Optional getMaybe(final Sender sender, final long nonce) { + return Optional.ofNullable(liveTxsBySender.get(sender).get(nonce)); } private PendingTransaction get(final Sender sender, final long nonce) { - return txsBySender.get(sender).get(nonce); + return getMaybe(sender, nonce).get(); + } + + private List getAll(final Sender sender) { + return List.copyOf(liveTxsBySender.get(sender).values()); } private PendingTransaction createFrontierPendingTransaction( @@ -1489,102 +1637,114 @@ public class LayersTest extends BaseTransactionPoolTest { } public Scenario expectedPrioritizedForSender(final Sender sender, final long... nonce) { - lastExpectedPrioritized = expectedForSender(sender, nonce); - final var expectedCopy = List.copyOf(lastExpectedPrioritized); actions.add( - (pending, prio, ready, sparse, dropped) -> assertExpectedPrioritized(prio, expectedCopy)); + () -> { + lastExpectedPrioritized = expectedForSender(sender, nonce); + assertExpectedPrioritized(prio, lastExpectedPrioritized); + }); return this; } public Scenario expectedReadyForSender(final Sender sender, final long... nonce) { - lastExpectedReady = expectedForSender(sender, nonce); - final var expectedCopy = List.copyOf(lastExpectedReady); actions.add( - (pending, prio, ready, sparse, dropped) -> assertExpectedReady(ready, expectedCopy)); + () -> { + lastExpectedReady = expectedForSender(sender, nonce); + assertExpectedReady(ready, lastExpectedReady); + }); return this; } public Scenario expectedSparseForSender(final Sender sender, final long... nonce) { - lastExpectedSparse = expectedForSender(sender, nonce); - final var expectedCopy = List.copyOf(lastExpectedSparse); actions.add( - (pending, prio, ready, sparse, dropped) -> assertExpectedSparse(sparse, expectedCopy)); + () -> { + lastExpectedSparse = expectedForSender(sender, nonce); + assertExpectedSparse(sparse, lastExpectedSparse); + }); return this; } public Scenario expectedDroppedForSender(final Sender sender, final long... nonce) { - lastExpectedDropped = expectedForSender(sender, nonce); - final var expectedCopy = List.copyOf(lastExpectedDropped); actions.add( - (pending, prio, ready, sparse, dropped) -> assertExpectedDropped(dropped, expectedCopy)); + () -> { + lastExpectedDropped = droppedForSender(sender, nonce); + assertExpectedDropped(dropped, lastExpectedDropped); + }); return this; } public Scenario expectedPrioritizedForSenders( - final Sender sender1, final long nonce1, final Sender sender2, Object... args) { - lastExpectedPrioritized = expectedForSenders(sender1, nonce1, sender2, args); - final var expectedCopy = List.copyOf(lastExpectedPrioritized); + final Sender sender1, final long nonce1, final Sender sender2, final Object... args) { actions.add( - (pending, prio, ready, sparse, dropped) -> assertExpectedPrioritized(prio, expectedCopy)); + () -> { + lastExpectedPrioritized = expectedForSenders(sender1, nonce1, sender2, args); + assertExpectedPrioritized(prio, lastExpectedPrioritized); + }); return this; } public Scenario expectedPrioritizedForSenders() { - lastExpectedPrioritized = List.of(); - final var expectedCopy = List.copyOf(lastExpectedPrioritized); actions.add( - (pending, prio, ready, sparse, dropped) -> assertExpectedPrioritized(prio, expectedCopy)); + () -> { + lastExpectedPrioritized = List.of(); + assertExpectedPrioritized(prio, lastExpectedPrioritized); + }); return this; } public Scenario expectedReadyForSenders( final Sender sender1, final long nonce1, final Sender sender2, final Object... args) { - lastExpectedReady = expectedForSenders(sender1, nonce1, sender2, args); - final var expectedCopy = List.copyOf(lastExpectedReady); actions.add( - (pending, prio, ready, sparse, dropped) -> assertExpectedReady(ready, expectedCopy)); + () -> { + lastExpectedReady = expectedForSenders(sender1, nonce1, sender2, args); + assertExpectedReady(ready, lastExpectedReady); + }); return this; } public Scenario expectedReadyForSenders() { - lastExpectedReady = List.of(); - final var expectedCopy = List.copyOf(lastExpectedReady); actions.add( - (pending, prio, ready, sparse, dropped) -> assertExpectedReady(ready, expectedCopy)); + () -> { + lastExpectedReady = List.of(); + assertExpectedReady(ready, lastExpectedReady); + }); return this; } public Scenario expectedSparseForSenders( final Sender sender1, final long nonce1, final Sender sender2, final Object... args) { - lastExpectedSparse = expectedForSenders(sender1, nonce1, sender2, args); - final var expectedCopy = List.copyOf(lastExpectedSparse); actions.add( - (pending, prio, ready, sparse, dropped) -> assertExpectedSparse(sparse, expectedCopy)); + () -> { + lastExpectedSparse = expectedForSenders(sender1, nonce1, sender2, args); + assertExpectedSparse(sparse, lastExpectedSparse); + }); return this; } public Scenario expectedSparseForSenders() { - lastExpectedSparse = List.of(); - final var expectedCopy = List.copyOf(lastExpectedSparse); actions.add( - (pending, prio, ready, sparse, dropped) -> assertExpectedSparse(sparse, expectedCopy)); + () -> { + lastExpectedSparse = List.of(); + assertExpectedSparse(sparse, lastExpectedSparse); + }); return this; } public Scenario expectedDroppedForSenders( final Sender sender1, final long nonce1, final Sender sender2, final Object... args) { - lastExpectedDropped = expectedForSenders(sender1, nonce1, sender2, args); - final var expectedCopy = List.copyOf(lastExpectedDropped); actions.add( - (pending, prio, ready, sparse, dropped) -> assertExpectedDropped(dropped, expectedCopy)); + () -> { + lastExpectedDropped = expectedForSenders(sender1, nonce1, sender2, args); + assertExpectedDropped(dropped, lastExpectedDropped); + }); return this; } public Scenario expectedDroppedForSenders() { - lastExpectedDropped = List.of(); - final var expectedCopy = List.copyOf(lastExpectedDropped); actions.add( - (pending, prio, ready, sparse, dropped) -> assertExpectedDropped(dropped, expectedCopy)); + () -> { + lastExpectedDropped = List.of(); + assertExpectedDropped(dropped, lastExpectedDropped); + }); return this; } @@ -1639,59 +1799,74 @@ public class LayersTest extends BaseTransactionPoolTest { return Arrays.stream(nonce).mapToObj(n -> get(sender, n)).toList(); } + private List droppedForSender(final Sender sender, final long... nonce) { + return Arrays.stream(nonce).mapToObj(n -> droppedTxsBySender.get(sender).get(n)).toList(); + } + public Scenario expectedNextNonceForSenders(final Object... args) { for (int i = 0; i < args.length; i = i + 2) { final Sender sender = (Sender) args[i]; final Integer nullableInt = (Integer) args[i + 1]; final OptionalLong nonce = nullableInt == null ? OptionalLong.empty() : OptionalLong.of(nullableInt); - actions.add( - (pending, prio, ready, sparse, dropped) -> - assertThat(prio.getNextNonceFor(sender.address)).isEqualTo(nonce)); + actions.add(() -> assertThat(prio.getNextNonceFor(sender.address)).isEqualTo(nonce)); } return this; } public Scenario removeForSender(final Sender sender, final long... nonce) { - Arrays.stream(nonce) - .forEach( - n -> { - final var pendingTx = getOrCreate(sender, EIP1559, n); - actions.add( - (pending, prio, ready, sparse, dropped) -> prio.remove(pendingTx, INVALIDATED)); - }); + actions.add( + () -> { + Arrays.stream(nonce) + .forEach( + n -> { + final var maybeLiveTx = getMaybe(sender, n); + final var pendingTx = maybeLiveTx.orElseGet(() -> create(sender, EIP1559, n)); + prio.remove(pendingTx, INVALIDATED); + maybeLiveTx.ifPresent( + liveTx -> { + notificationsChecker.addExpectedDropNotification(liveTx); + liveTxsBySender.get(sender).remove(liveTx.getNonce()); + droppedTxsBySender.get(sender).put(liveTx.getNonce(), liveTx); + }); + }); + handleDropped(); + notificationsChecker.assertExpectedNotifications(); + }); return this; } public Scenario penalizeForSender(final Sender sender, final long... nonce) { - Arrays.stream(nonce) - .forEach( - n -> { - actions.add( - (pending, prio, ready, sparse, dropped) -> { - final var senderTxs = prio.getAllFor(sender.address); - Arrays.stream(nonce) - .mapToObj( - n2 -> senderTxs.stream().filter(pt -> pt.getNonce() == n2).findAny()) - .map(Optional::get) - .forEach(prio::penalize); - }); - }); + actions.add( + () -> + Arrays.stream(nonce) + .forEach( + n -> { + final var senderTxs = prio.getAllFor(sender.address); + Arrays.stream(nonce) + .mapToObj( + n2 -> + senderTxs.stream().filter(pt -> pt.getNonce() == n2).findAny()) + .map(Optional::get) + .forEach(prio::penalize); + })); return this; } public Scenario expectedSelectedTransactions(final Object... args) { - List expectedSelected = new ArrayList<>(); - for (int i = 0; i < args.length; i = i + 2) { - final Sender sender = (Sender) args[i]; - final long nonce = (int) args[i + 1]; - expectedSelected.add(get(sender, nonce)); - } actions.add( - (pending, prio, ready, sparse, dropped) -> - assertThat(prio.getBySender()) - .flatExtracting(SenderPendingTransactions::pendingTransactions) - .containsExactlyElementsOf(expectedSelected)); + () -> { + List expectedSelected = new ArrayList<>(); + for (int i = 0; i < args.length; i = i + 2) { + final Sender sender = (Sender) args[i]; + final long nonce = (int) args[i + 1]; + expectedSelected.add(get(sender, nonce)); + } + + assertThat(prio.getBySender()) + .flatExtracting(SenderPendingTransactions::pendingTransactions) + .containsExactlyElementsOf(expectedSelected); + }); return this; } @@ -1721,6 +1896,62 @@ public class LayersTest extends BaseTransactionPoolTest { this.gasFeeMultiplier = gasFeeMultiplier; this.hasPriority = hasPriority; } + + static Sender getByAddress(final Address address) { + return Arrays.stream(values()).filter(s -> s.address.equals(address)).findAny().get(); + } + } + + static class NotificationsChecker { + private final List collectedAddNotifications = + Collections.synchronizedList(new ArrayList<>()); + private final List collectedDropNotifications = + Collections.synchronizedList(new ArrayList<>()); + private final List expectedAddNotifications = new ArrayList<>(); + private final List expectedDropNotifications = new ArrayList<>(); + + void collectAddNotification(final Transaction tx) { + collectedAddNotifications.add(tx); + } + + void collectDropNotification(final Transaction tx) { + collectedDropNotifications.add(tx); + } + + void addExpectedAddNotification(final PendingTransaction tx) { + expectedAddNotifications.add(tx.getTransaction()); + } + + void addExpectedDropNotification(final PendingTransaction tx) { + expectedDropNotifications.add(tx.getTransaction()); + } + + void assertExpectedNotifications() { + assertAddNotifications(expectedAddNotifications); + assertDropNotifications(expectedDropNotifications); + } + + private void assertAddNotifications(final List expectedAddedTxs) { + await() + .untilAsserted( + () -> + assertThat(collectedAddNotifications) + .describedAs("Added notifications") + .containsExactlyInAnyOrderElementsOf(expectedAddedTxs)); + collectedAddNotifications.clear(); + expectedAddNotifications.clear(); + } + + private void assertDropNotifications(final List expectedDroppedTxs) { + await() + .untilAsserted( + () -> + assertThat(collectedDropNotifications) + .describedAs("Dropped notifications") + .containsExactlyInAnyOrderElementsOf(expectedDroppedTxs)); + collectedDropNotifications.clear(); + expectedDropNotifications.clear(); + } } @Test 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 14ed39c2e5..18ce6f49ed 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.TransactionsLayer.RemovalReason.INVALIDATED; +import static org.hyperledger.besu.ethereum.eth.transactions.layered.RemovalReason.PoolRemovalReason.INVALIDATED; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; From dad05d407e0ede69eb20acbbb01d8723b4f615d6 Mon Sep 17 00:00:00 2001 From: Fabio Di Fabio Date: Thu, 5 Sep 2024 16:25:46 +0200 Subject: [PATCH 191/259] Honor block number or tag parameter in eth_estimateGas and eth_createAccessList (#7502) Signed-off-by: Fabio Di Fabio --- CHANGELOG.md | 1 + .../internal/methods/AbstractEstimateGas.java | 70 +++++-- .../internal/methods/EthCreateAccessList.java | 72 ++----- .../internal/methods/EthEstimateGas.java | 111 +++++------ .../methods/EthCreateAccessListTest.java | 142 +++++++++----- .../internal/methods/EthEstimateGasTest.java | 180 ++++++++++-------- ...stimateGas_from_contract_withBlockNum.json | 21 ++ ...stimateGas_from_contract_withBlockTag.json | 21 ++ ...imateGas_insufficientGas_withBlockNum.json | 21 ++ ...eth_estimateGas_transfer_withBlockTag.json | 21 ++ 10 files changed, 404 insertions(+), 256 deletions(-) create mode 100644 ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_estimateGas_from_contract_withBlockNum.json create mode 100644 ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_estimateGas_from_contract_withBlockTag.json create mode 100644 ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_estimateGas_insufficientGas_withBlockNum.json create mode 100644 ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_estimateGas_transfer_withBlockTag.json diff --git a/CHANGELOG.md b/CHANGELOG.md index c6e16c0d8a..c7c7a33e40 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ ### Bug fixes - Layered txpool: do not send notifications when moving tx between layers [#7539](https://github.com/hyperledger/besu/pull/7539) - Layered txpool: fix for unsent drop notifications on remove [#7538](https://github.com/hyperledger/besu/pull/7538) +- Honor block number or tag parameter in eth_estimateGas and eth_createAccessList [#7502](https://github.com/hyperledger/besu/pull/7502) ## 24.9.0 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 ef8ca5b316..4cbfb818db 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 @@ -14,15 +14,19 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; +import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonCallParameterUtil.validateAndGetCallParams; + import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcErrorConverter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonCallParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; -import org.hyperledger.besu.ethereum.chain.Blockchain; import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.mainnet.ValidationResult; import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult; @@ -34,32 +38,68 @@ import org.hyperledger.besu.evm.tracing.EstimateGasOperationTracer; import java.util.Optional; -public abstract class AbstractEstimateGas implements JsonRpcMethod { +public abstract class AbstractEstimateGas extends AbstractBlockParameterMethod { private static final double SUB_CALL_REMAINING_GAS_RATIO = 65D / 64D; - protected final BlockchainQueries blockchainQueries; protected final TransactionSimulator transactionSimulator; public AbstractEstimateGas( final BlockchainQueries blockchainQueries, final TransactionSimulator transactionSimulator) { - this.blockchainQueries = blockchainQueries; + super(blockchainQueries); this.transactionSimulator = transactionSimulator; } - protected BlockHeader blockHeader() { - final Blockchain theChain = blockchainQueries.getBlockchain(); - - // Optimistically get the block header for the chain head without taking a lock, - // but revert to the safe implementation if it returns an empty optional. (It's - // possible the chain head has been updated but the block is still being persisted - // to storage/cache under the lock). - return theChain - .getBlockHeader(theChain.getChainHeadHash()) - .or(() -> theChain.getBlockHeaderSafe(theChain.getChainHeadHash())) - .orElse(null); + @Override + protected BlockParameter blockParameter(final JsonRpcRequestContext request) { + try { + return request.getOptionalParameter(1, BlockParameter.class).orElse(BlockParameter.LATEST); + } catch (JsonRpcParameter.JsonRpcParameterException e) { + throw new InvalidJsonRpcParameters( + "Invalid block parameter (index 1)", RpcErrorType.INVALID_BLOCK_PARAMS, e); + } + } + + protected Optional blockHeader(final long blockNumber) { + if (getBlockchainQueries().headBlockNumber() == blockNumber) { + // chain head header if cached, and we can return it form memory + return Optional.of(getBlockchainQueries().getBlockchain().getChainHeadHeader()); + } + return getBlockchainQueries().getBlockHeaderByNumber(blockNumber); + } + + protected Optional validateBlockHeader( + final Optional maybeBlockHeader) { + if (maybeBlockHeader.isEmpty()) { + return Optional.of(RpcErrorType.BLOCK_NOT_FOUND); + } + + final var blockHeader = maybeBlockHeader.get(); + if (!getBlockchainQueries() + .getWorldStateArchive() + .isWorldStateAvailable(blockHeader.getStateRoot(), blockHeader.getHash())) { + return Optional.of(RpcErrorType.WORLD_STATE_UNAVAILABLE); + } + return Optional.empty(); } + @Override + protected Object resultByBlockNumber( + final JsonRpcRequestContext requestContext, final long blockNumber) { + final JsonCallParameter jsonCallParameter = validateAndGetCallParams(requestContext); + final Optional maybeBlockHeader = blockHeader(blockNumber); + final Optional jsonRpcError = validateBlockHeader(maybeBlockHeader); + if (jsonRpcError.isPresent()) { + return errorResponse(requestContext, jsonRpcError.get()); + } + return resultByBlockHeader(requestContext, jsonCallParameter, maybeBlockHeader.get()); + } + + protected abstract Object resultByBlockHeader( + final JsonRpcRequestContext requestContext, + final JsonCallParameter jsonCallParameter, + final BlockHeader blockHeader); + protected CallParameter overrideGasLimitAndPrice( final JsonCallParameter callParams, final long gasLimit) { return new CallParameter( diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCreateAccessList.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCreateAccessList.java index 2be5047a24..2b8e79a81e 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCreateAccessList.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCreateAccessList.java @@ -14,15 +14,11 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; -import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonCallParameterUtil.validateAndGetCallParams; - import org.hyperledger.besu.datatypes.AccessListEntry; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonCallParameter; -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.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.CreateAccessListResult; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; @@ -52,44 +48,29 @@ public class EthCreateAccessList extends AbstractEstimateGas { } @Override - public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { - final JsonCallParameter jsonCallParameter = validateAndGetCallParams(requestContext); - final BlockHeader blockHeader = blockHeader(); - final Optional jsonRpcError = validateBlockHeader(blockHeader); - if (jsonRpcError.isPresent()) { - return errorResponse(requestContext, jsonRpcError.get()); - } + protected Object resultByBlockHeader( + final JsonRpcRequestContext requestContext, + final JsonCallParameter jsonCallParameter, + final BlockHeader blockHeader) { final AccessListSimulatorResult maybeResult = processTransaction(jsonCallParameter, blockHeader); // if the call accessList is different from the simulation result, calculate gas and return - if (shouldProcessWithAccessListOverride(jsonCallParameter, maybeResult.getTracer())) { + if (shouldProcessWithAccessListOverride(jsonCallParameter, maybeResult.tracer())) { final AccessListSimulatorResult result = processTransactionWithAccessListOverride( - jsonCallParameter, blockHeader, maybeResult.getTracer().getAccessList()); + jsonCallParameter, blockHeader, maybeResult.tracer().getAccessList()); return createResponse(requestContext, result); } else { return createResponse(requestContext, maybeResult); } } - private Optional validateBlockHeader(final BlockHeader blockHeader) { - if (blockHeader == null) { - return Optional.of(RpcErrorType.INTERNAL_ERROR); - } - if (!blockchainQueries - .getWorldStateArchive() - .isWorldStateAvailable(blockHeader.getStateRoot(), blockHeader.getHash())) { - return Optional.of(RpcErrorType.WORLD_STATE_UNAVAILABLE); - } - return Optional.empty(); - } - - private JsonRpcResponse createResponse( + private Object createResponse( final JsonRpcRequestContext requestContext, final AccessListSimulatorResult result) { return result - .getResult() - .map(createResponse(requestContext, result.getTracer())) - .orElse(errorResponse(requestContext, RpcErrorType.INTERNAL_ERROR)); + .result() + .map(createResponse(requestContext, result.tracer())) + .orElseGet(() -> errorResponse(requestContext, RpcErrorType.INTERNAL_ERROR)); } private TransactionValidationParams transactionValidationParams( @@ -117,14 +98,12 @@ public class EthCreateAccessList extends AbstractEstimateGas { return !Objects.equals(tracer.getAccessList(), parameters.getAccessList().get()); } - private Function createResponse( + private Function createResponse( final JsonRpcRequestContext request, final AccessListOperationTracer operationTracer) { return result -> result.isSuccessful() - ? new JsonRpcSuccessResponse( - request.getRequest().getId(), - new CreateAccessListResult( - operationTracer.getAccessList(), processEstimateGas(result, operationTracer))) + ? new CreateAccessListResult( + operationTracer.getAccessList(), processEstimateGas(result, operationTracer)) : errorResponse(request, result); } @@ -138,8 +117,7 @@ public class EthCreateAccessList extends AbstractEstimateGas { final AccessListOperationTracer tracer = AccessListOperationTracer.create(); final Optional result = - transactionSimulator.process( - callParams, transactionValidationParams, tracer, blockHeader.getNumber()); + transactionSimulator.process(callParams, transactionValidationParams, tracer, blockHeader); return new AccessListSimulatorResult(result, tracer); } @@ -156,7 +134,7 @@ public class EthCreateAccessList extends AbstractEstimateGas { final Optional result = transactionSimulator.process( - callParameter, transactionValidationParams, tracer, blockHeader.getNumber()); + callParameter, transactionValidationParams, tracer, blockHeader); return new AccessListSimulatorResult(result, tracer); } @@ -176,22 +154,6 @@ public class EthCreateAccessList extends AbstractEstimateGas { Optional.ofNullable(accessListEntries)); } - private static class AccessListSimulatorResult { - final Optional result; - final AccessListOperationTracer tracer; - - public AccessListSimulatorResult( - final Optional result, final AccessListOperationTracer tracer) { - this.result = result; - this.tracer = tracer; - } - - public Optional getResult() { - return result; - } - - public AccessListOperationTracer getTracer() { - return tracer; - } - } + private record AccessListSimulatorResult( + Optional result, AccessListOperationTracer tracer) {} } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthEstimateGas.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthEstimateGas.java index ca084ba0fb..c713ea20a7 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthEstimateGas.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthEstimateGas.java @@ -1,5 +1,5 @@ /* - * Copyright ConsenSys AG. + * 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 @@ -14,13 +14,10 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; -import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonCallParameterUtil.validateAndGetCallParams; - import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonCallParameter; -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.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.Quantity; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; @@ -38,7 +35,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class EthEstimateGas extends AbstractEstimateGas { - private static final Logger LOG = LoggerFactory.getLogger(EthEstimateGas.class); public EthEstimateGas( @@ -52,19 +48,10 @@ public class EthEstimateGas extends AbstractEstimateGas { } @Override - public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { - final JsonCallParameter callParams = validateAndGetCallParams(requestContext); - - final BlockHeader blockHeader = blockHeader(); - if (blockHeader == null) { - LOG.error("Chain head block not found"); - return errorResponse(requestContext, RpcErrorType.INTERNAL_ERROR); - } - if (!blockchainQueries - .getWorldStateArchive() - .isWorldStateAvailable(blockHeader.getStateRoot(), blockHeader.getHash())) { - return errorResponse(requestContext, RpcErrorType.WORLD_STATE_UNAVAILABLE); - } + protected Object resultByBlockHeader( + final JsonRpcRequestContext requestContext, + final JsonCallParameter callParams, + final BlockHeader blockHeader) { final CallParameter modifiedCallParams = overrideGasLimitAndPrice(callParams, blockHeader.getGasLimit()); @@ -72,44 +59,48 @@ public class EthEstimateGas extends AbstractEstimateGas { final boolean isAllowExceedingBalance = !callParams.isMaybeStrict().orElse(Boolean.FALSE); final EstimateGasOperationTracer operationTracer = new EstimateGasOperationTracer(); - - var gasUsed = - executeSimulation( - blockHeader, modifiedCallParams, operationTracer, isAllowExceedingBalance); - - if (gasUsed.isEmpty()) { - LOG.error("gasUsed is empty after simulating transaction."); - return errorResponse(requestContext, RpcErrorType.INTERNAL_ERROR); - } - - // if the transaction is invalid or doesn't have enough gas with the max it never will! - if (gasUsed.get().isInvalid() || !gasUsed.get().isSuccessful()) { - return errorResponse(requestContext, gasUsed.get()); + final var transactionValidationParams = + ImmutableTransactionValidationParams.builder() + .from(TransactionValidationParams.transactionSimulator()) + .isAllowExceedingBalance(isAllowExceedingBalance) + .build(); + + LOG.debug("Processing transaction with params: {}", modifiedCallParams); + final var maybeResult = + transactionSimulator.process( + modifiedCallParams, transactionValidationParams, operationTracer, blockHeader); + + final Optional maybeErrorResponse = + validateSimulationResult(requestContext, maybeResult); + if (maybeErrorResponse.isPresent()) { + return maybeErrorResponse.get(); } - var low = gasUsed.get().result().getEstimateGasUsedByTransaction(); - var lowResult = - executeSimulation( - blockHeader, + final var result = maybeResult.get(); + long low = result.result().getEstimateGasUsedByTransaction(); + final var lowResult = + transactionSimulator.process( overrideGasLimitAndPrice(callParams, low), + transactionValidationParams, operationTracer, - isAllowExceedingBalance); + blockHeader); if (lowResult.isPresent() && lowResult.get().isSuccessful()) { - return new JsonRpcSuccessResponse(requestContext.getRequest().getId(), Quantity.create(low)); + return Quantity.create(low); } - var high = processEstimateGas(gasUsed.get(), operationTracer); - var mid = high; - while (low + 1 < high) { - mid = (high + low) / 2; + long high = processEstimateGas(result, operationTracer); + long mid; + while (low + 1 < high) { + mid = (low + high) / 2; var binarySearchResult = - executeSimulation( - blockHeader, + transactionSimulator.process( overrideGasLimitAndPrice(callParams, mid), + transactionValidationParams, operationTracer, - isAllowExceedingBalance); + blockHeader); + if (binarySearchResult.isEmpty() || !binarySearchResult.get().isSuccessful()) { low = mid; } else { @@ -117,21 +108,23 @@ public class EthEstimateGas extends AbstractEstimateGas { } } - return new JsonRpcSuccessResponse(requestContext.getRequest().getId(), Quantity.create(high)); + return Quantity.create(high); } - private Optional executeSimulation( - final BlockHeader blockHeader, - final CallParameter modifiedCallParams, - final EstimateGasOperationTracer operationTracer, - final boolean allowExceedingBalance) { - return transactionSimulator.process( - modifiedCallParams, - ImmutableTransactionValidationParams.builder() - .from(TransactionValidationParams.transactionSimulator()) - .isAllowExceedingBalance(allowExceedingBalance) - .build(), - operationTracer, - blockHeader.getNumber()); + private Optional validateSimulationResult( + final JsonRpcRequestContext requestContext, + final Optional maybeResult) { + if (maybeResult.isEmpty()) { + LOG.error("No result after simulating transaction."); + return Optional.of( + new JsonRpcErrorResponse( + requestContext.getRequest().getId(), RpcErrorType.INTERNAL_ERROR)); + } + + // if the transaction is invalid or doesn't have enough gas with the max it never will! + if (maybeResult.get().isInvalid() || !maybeResult.get().isSuccessful()) { + return Optional.of(errorResponse(requestContext, maybeResult.get())); + } + return Optional.empty(); } } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCreateAccessListTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCreateAccessListTest.java index 8812a1e0a6..f7c0c31914 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCreateAccessListTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCreateAccessListTest.java @@ -16,7 +16,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -24,7 +24,6 @@ import static org.mockito.Mockito.when; import org.hyperledger.besu.datatypes.AccessListEntry; import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; @@ -70,7 +69,9 @@ public class EthCreateAccessListTest { private final String METHOD = "eth_createAccessList"; private EthCreateAccessList method; - @Mock private BlockHeader blockHeader; + @Mock private BlockHeader latestBlockHeader; + @Mock private BlockHeader finalizedBlockHeader; + @Mock private BlockHeader genesisBlockHeader; @Mock private Blockchain blockchain; @Mock private BlockchainQueries blockchainQueries; @Mock private TransactionSimulator transactionSimulator; @@ -80,16 +81,18 @@ public class EthCreateAccessListTest { public void setUp() { when(blockchainQueries.getBlockchain()).thenReturn(blockchain); when(blockchainQueries.getWorldStateArchive()).thenReturn(worldStateArchive); - when(blockchain.getChainHeadHash()) - .thenReturn( - Hash.fromHexString( - "0x3f07a9c83155594c000642e7d60e8a8a00038d03e9849171a05ed0e2d47acbb3")); - when(blockchain.getBlockHeader( - Hash.fromHexString( - "0x3f07a9c83155594c000642e7d60e8a8a00038d03e9849171a05ed0e2d47acbb3"))) - .thenReturn(Optional.of(blockHeader)); - when(blockHeader.getGasLimit()).thenReturn(Long.MAX_VALUE); - when(blockHeader.getNumber()).thenReturn(1L); + when(blockchainQueries.headBlockNumber()).thenReturn(2L); + when(blockchainQueries.getBlockHeaderByNumber(0L)).thenReturn(Optional.of(genesisBlockHeader)); + when(blockchainQueries.finalizedBlockHeader()).thenReturn(Optional.of(finalizedBlockHeader)); + when(blockchainQueries.getBlockHeaderByNumber(1L)) + .thenReturn(Optional.of(finalizedBlockHeader)); + when(genesisBlockHeader.getGasLimit()).thenReturn(Long.MAX_VALUE); + when(genesisBlockHeader.getNumber()).thenReturn(0L); + when(finalizedBlockHeader.getGasLimit()).thenReturn(Long.MAX_VALUE); + when(finalizedBlockHeader.getNumber()).thenReturn(1L); + when(blockchain.getChainHeadHeader()).thenReturn(latestBlockHeader); + when(latestBlockHeader.getGasLimit()).thenReturn(Long.MAX_VALUE); + when(latestBlockHeader.getNumber()).thenReturn(2L); when(worldStateArchive.isWorldStateAvailable(any(), any())).thenReturn(true); method = new EthCreateAccessList(blockchainQueries, transactionSimulator); @@ -105,18 +108,22 @@ public class EthCreateAccessListTest { new JsonRpcRequest("2.0", METHOD, new Object[] {callParameter})); } + private JsonRpcRequestContext ethCreateAccessListRequest( + final CallParameter callParameter, final String blockParam) { + return new JsonRpcRequestContext( + new JsonRpcRequest("2.0", METHOD, new Object[] {callParameter, blockParam})); + } + @Test public void shouldReturnGasEstimateWhenTransientLegacyTransactionProcessorReturnsResultSuccess() { final JsonRpcRequestContext request = ethCreateAccessListRequest(legacyTransactionCallParameter(Wei.ZERO)); - mockTransactionSimulatorResult(true, false, 1L); + mockTransactionSimulatorResult(true, false, 1L, latestBlockHeader); final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse(null, new CreateAccessListResult(new ArrayList<>(), 1L)); - Assertions.assertThat(method.response(request)) - .usingRecursiveComparison() - .isEqualTo(expectedResponse); + assertThat(method.response(request)).usingRecursiveComparison().isEqualTo(expectedResponse); } @Test @@ -124,21 +131,19 @@ public class EthCreateAccessListTest { final Wei gasPrice = Wei.of(1000); final JsonRpcRequestContext request = ethCreateAccessListRequest(legacyTransactionCallParameter(gasPrice)); - mockTransactionSimulatorResult(true, false, 1L); + mockTransactionSimulatorResult(true, false, 1L, latestBlockHeader); final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse(null, new CreateAccessListResult(new ArrayList<>(), 1L)); - Assertions.assertThat(method.response(request)) - .usingRecursiveComparison() - .isEqualTo(expectedResponse); + assertThat(method.response(request)).usingRecursiveComparison().isEqualTo(expectedResponse); } @Test public void shouldReturnGasEstimateErrorWhenGasPricePresentForEip1559Transaction() { final JsonRpcRequestContext request = ethCreateAccessListRequest(eip1559TransactionCallParameter(Optional.of(Wei.of(10)))); - mockTransactionSimulatorResult(false, false, 1L); + mockTransactionSimulatorResult(false, false, 1L, latestBlockHeader); Assertions.assertThatThrownBy(() -> method.response(request)) .isInstanceOf(InvalidJsonRpcParameters.class) @@ -150,29 +155,25 @@ public class EthCreateAccessListTest { when(worldStateArchive.isWorldStateAvailable(any(), any())).thenReturn(false); final JsonRpcRequestContext request = ethCreateAccessListRequest(legacyTransactionCallParameter(Wei.ZERO)); - mockTransactionSimulatorResult(false, false, 1L); + mockTransactionSimulatorResult(false, false, 1L, latestBlockHeader); final JsonRpcResponse expectedResponse = new JsonRpcErrorResponse(null, RpcErrorType.WORLD_STATE_UNAVAILABLE); - Assertions.assertThat(method.response(request)) - .usingRecursiveComparison() - .isEqualTo(expectedResponse); + assertThat(method.response(request)).usingRecursiveComparison().isEqualTo(expectedResponse); } @Test public void shouldReturnErrorWhenTransactionReverted() { final JsonRpcRequestContext request = ethCreateAccessListRequest(legacyTransactionCallParameter(Wei.ZERO)); - mockTransactionSimulatorResult(false, true, 1L); + mockTransactionSimulatorResult(false, true, 1L, latestBlockHeader); final String errorReason = "0x00"; final JsonRpcResponse expectedResponse = new JsonRpcErrorResponse(null, new JsonRpcError(RpcErrorType.REVERT_ERROR, errorReason)); - Assertions.assertThat(method.response(request)) - .usingRecursiveComparison() - .isEqualTo(expectedResponse); + assertThat(method.response(request)).usingRecursiveComparison().isEqualTo(expectedResponse); } @Test @@ -182,12 +183,10 @@ public class EthCreateAccessListTest { new JsonRpcSuccessResponse(null, new CreateAccessListResult(expectedAccessList, 1L)); final JsonRpcRequestContext request = ethCreateAccessListRequest(eip1559TransactionCallParameter()); - mockTransactionSimulatorResult(true, false, 1L); + mockTransactionSimulatorResult(true, false, 1L, latestBlockHeader); - Assertions.assertThat(method.response(request)) - .usingRecursiveComparison() - .isEqualTo(expectedResponse); - verify(transactionSimulator, times(1)).process(any(), any(), any(), anyLong()); + assertThat(method.response(request)).usingRecursiveComparison().isEqualTo(expectedResponse); + verify(transactionSimulator, times(1)).process(any(), any(), any(), eq(latestBlockHeader)); } @Test @@ -204,11 +203,11 @@ public class EthCreateAccessListTest { final AccessListOperationTracer tracer = createMockTracer(expectedAccessList); // Set TransactionSimulator.process response - mockTransactionSimulatorResult(true, false, 1L); - Assertions.assertThat(responseWithMockTracer(request, tracer)) + mockTransactionSimulatorResult(true, false, 1L, latestBlockHeader); + assertThat(responseWithMockTracer(request, tracer)) .usingRecursiveComparison() .isEqualTo(expectedResponse); - verify(transactionSimulator, times(2)).process(any(), any(), any(), anyLong()); + verify(transactionSimulator, times(2)).process(any(), any(), any(), eq(latestBlockHeader)); } @Test @@ -223,11 +222,9 @@ public class EthCreateAccessListTest { ethCreateAccessListRequest(eip1559TransactionCallParameter(accessListParam)); // Set TransactionSimulator.process response - mockTransactionSimulatorResult(true, false, 1L); - Assertions.assertThat(method.response(request)) - .usingRecursiveComparison() - .isEqualTo(expectedResponse); - verify(transactionSimulator, times(1)).process(any(), any(), any(), anyLong()); + mockTransactionSimulatorResult(true, false, 1L, latestBlockHeader); + assertThat(method.response(request)).usingRecursiveComparison().isEqualTo(expectedResponse); + verify(transactionSimulator, times(1)).process(any(), any(), any(), eq(latestBlockHeader)); } @Test @@ -244,11 +241,11 @@ public class EthCreateAccessListTest { final AccessListOperationTracer tracer = createMockTracer(expectedAccessList); // Set TransactionSimulator.process response - mockTransactionSimulatorResult(true, false, 1L); - Assertions.assertThat(responseWithMockTracer(request, tracer)) + mockTransactionSimulatorResult(true, false, 1L, latestBlockHeader); + assertThat(responseWithMockTracer(request, tracer)) .usingRecursiveComparison() .isEqualTo(expectedResponse); - verify(transactionSimulator, times(1)).process(any(), any(), any(), anyLong()); + verify(transactionSimulator, times(1)).process(any(), any(), any(), eq(latestBlockHeader)); } @Test @@ -268,11 +265,51 @@ public class EthCreateAccessListTest { final AccessListOperationTracer tracer = createMockTracer(expectedAccessList); // Set TransactionSimulator.process response - mockTransactionSimulatorResult(true, false, 1L); - Assertions.assertThat(responseWithMockTracer(request, tracer)) + mockTransactionSimulatorResult(true, false, 1L, latestBlockHeader); + assertThat(responseWithMockTracer(request, tracer)) + .usingRecursiveComparison() + .isEqualTo(expectedResponse); + verify(transactionSimulator, times(2)).process(any(), any(), any(), eq(latestBlockHeader)); + } + + @Test + public void shouldReturnAccessListWhenBlockTagParamIsPresent() { + final JsonRpcRequestContext request = + ethCreateAccessListRequest(eip1559TransactionCallParameter(), "finalized"); + // Create a list with one access list entry + final List expectedAccessList = createAccessList(); + + // expect a list with the mocked access list + final JsonRpcResponse expectedResponse = + new JsonRpcSuccessResponse(null, new CreateAccessListResult(expectedAccessList, 1L)); + final AccessListOperationTracer tracer = createMockTracer(expectedAccessList); + + // Set TransactionSimulator.process response + mockTransactionSimulatorResult(true, false, 1L, finalizedBlockHeader); + assertThat(responseWithMockTracer(request, tracer)) + .usingRecursiveComparison() + .isEqualTo(expectedResponse); + verify(transactionSimulator, times(2)).process(any(), any(), any(), eq(finalizedBlockHeader)); + } + + @Test + public void shouldReturnAccessListWhenBlockNumberParamIsPresent() { + final JsonRpcRequestContext request = + ethCreateAccessListRequest(eip1559TransactionCallParameter(), "0x0"); + // Create a list with one access list entry + final List expectedAccessList = createAccessList(); + + // expect a list with the mocked access list + final JsonRpcResponse expectedResponse = + new JsonRpcSuccessResponse(null, new CreateAccessListResult(expectedAccessList, 1L)); + final AccessListOperationTracer tracer = createMockTracer(expectedAccessList); + + // Set TransactionSimulator.process response + mockTransactionSimulatorResult(true, false, 1L, genesisBlockHeader); + assertThat(responseWithMockTracer(request, tracer)) .usingRecursiveComparison() .isEqualTo(expectedResponse); - verify(transactionSimulator, times(2)).process(any(), any(), any(), anyLong()); + verify(transactionSimulator, times(2)).process(any(), any(), any(), eq(genesisBlockHeader)); } private JsonRpcResponse responseWithMockTracer( @@ -292,9 +329,12 @@ public class EthCreateAccessListTest { } private void mockTransactionSimulatorResult( - final boolean isSuccessful, final boolean isReverted, final long estimateGas) { + final boolean isSuccessful, + final boolean isReverted, + final long estimateGas, + final BlockHeader blockHeader) { final TransactionSimulatorResult mockTxSimResult = mock(TransactionSimulatorResult.class); - when(transactionSimulator.process(any(), any(), any(), anyLong())) + when(transactionSimulator.process(any(), any(), any(), eq(blockHeader))) .thenReturn(Optional.of(mockTxSimResult)); final TransactionProcessingResult mockResult = mock(TransactionProcessingResult.class); when(mockResult.getEstimateGasUsedByTransaction()).thenReturn(estimateGas); diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthEstimateGasTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthEstimateGasTest.java index a6f5008b29..f85a0813ef 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthEstimateGasTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthEstimateGasTest.java @@ -22,7 +22,6 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; @@ -66,7 +65,9 @@ public class EthEstimateGasTest { private EthEstimateGas method; - @Mock private BlockHeader blockHeader; + @Mock private BlockHeader latestBlockHeader; + @Mock private BlockHeader finalizedBlockHeader; + @Mock private BlockHeader genesisBlockHeader; @Mock private Blockchain blockchain; @Mock private BlockchainQueries blockchainQueries; @Mock private TransactionSimulator transactionSimulator; @@ -76,16 +77,18 @@ public class EthEstimateGasTest { public void setUp() { when(blockchainQueries.getBlockchain()).thenReturn(blockchain); when(blockchainQueries.getWorldStateArchive()).thenReturn(worldStateArchive); - when(blockchain.getChainHeadHash()) - .thenReturn( - Hash.fromHexString( - "0x3f07a9c83155594c000642e7d60e8a8a00038d03e9849171a05ed0e2d47acbb3")); - when(blockchain.getBlockHeader( - Hash.fromHexString( - "0x3f07a9c83155594c000642e7d60e8a8a00038d03e9849171a05ed0e2d47acbb3"))) - .thenReturn(Optional.of(blockHeader)); - when(blockHeader.getGasLimit()).thenReturn(Long.MAX_VALUE); - when(blockHeader.getNumber()).thenReturn(1L); + when(blockchainQueries.headBlockNumber()).thenReturn(2L); + when(blockchainQueries.getBlockHeaderByNumber(0L)).thenReturn(Optional.of(genesisBlockHeader)); + when(blockchainQueries.finalizedBlockHeader()).thenReturn(Optional.of(finalizedBlockHeader)); + when(blockchainQueries.getBlockHeaderByNumber(1L)) + .thenReturn(Optional.of(finalizedBlockHeader)); + when(genesisBlockHeader.getGasLimit()).thenReturn(Long.MAX_VALUE); + when(genesisBlockHeader.getNumber()).thenReturn(0L); + when(finalizedBlockHeader.getGasLimit()).thenReturn(Long.MAX_VALUE); + when(finalizedBlockHeader.getNumber()).thenReturn(1L); + when(blockchain.getChainHeadHeader()).thenReturn(latestBlockHeader); + when(latestBlockHeader.getGasLimit()).thenReturn(Long.MAX_VALUE); + when(latestBlockHeader.getNumber()).thenReturn(2L); when(worldStateArchive.isWorldStateAvailable(any(), any())).thenReturn(true); method = new EthEstimateGas(blockchainQueries, transactionSimulator); @@ -104,15 +107,13 @@ public class EthEstimateGasTest { eq(modifiedLegacyTransactionCallParameter(Wei.ZERO)), any(TransactionValidationParams.class), any(OperationTracer.class), - eq(1L))) + eq(latestBlockHeader))) .thenReturn(Optional.empty()); final JsonRpcResponse expectedResponse = new JsonRpcErrorResponse(null, RpcErrorType.INTERNAL_ERROR); - Assertions.assertThat(method.response(request)) - .usingRecursiveComparison() - .isEqualTo(expectedResponse); + assertThat(method.response(request)).usingRecursiveComparison().isEqualTo(expectedResponse); } @Test @@ -122,28 +123,24 @@ public class EthEstimateGasTest { eq(modifiedEip1559TransactionCallParameter()), any(TransactionValidationParams.class), any(OperationTracer.class), - eq(1L))) + eq(latestBlockHeader))) .thenReturn(Optional.empty()); final JsonRpcResponse expectedResponse = new JsonRpcErrorResponse(null, RpcErrorType.INTERNAL_ERROR); - Assertions.assertThat(method.response(request)) - .usingRecursiveComparison() - .isEqualTo(expectedResponse); + assertThat(method.response(request)).usingRecursiveComparison().isEqualTo(expectedResponse); } @Test public void shouldReturnGasEstimateWhenTransientLegacyTransactionProcessorReturnsResultSuccess() { final JsonRpcRequestContext request = ethEstimateGasRequest(defaultLegacyTransactionCallParameter(Wei.ZERO)); - mockTransientProcessorResultGasEstimate(1L, true, false); + mockTransientProcessorResultGasEstimate(1L, true, false, latestBlockHeader); final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse(null, Quantity.create(1L)); - Assertions.assertThat(method.response(request)) - .usingRecursiveComparison() - .isEqualTo(expectedResponse); + assertThat(method.response(request)).usingRecursiveComparison().isEqualTo(expectedResponse); } @Test @@ -151,20 +148,19 @@ public class EthEstimateGasTest { final Wei gasPrice = Wei.of(1000); final JsonRpcRequestContext request = ethEstimateGasRequest(defaultLegacyTransactionCallParameter(gasPrice)); - mockTransientProcessorResultGasEstimate(1L, true, gasPrice, Optional.empty()); + mockTransientProcessorResultGasEstimate( + 1L, true, gasPrice, Optional.empty(), latestBlockHeader); final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse(null, Quantity.create(1L)); - Assertions.assertThat(method.response(request)) - .usingRecursiveComparison() - .isEqualTo(expectedResponse); + assertThat(method.response(request)).usingRecursiveComparison().isEqualTo(expectedResponse); } @Test public void shouldReturnGasEstimateErrorWhenGasPricePresentForEip1559Transaction() { final JsonRpcRequestContext request = ethEstimateGasRequest(eip1559TransactionCallParameter(Optional.of(Wei.of(10)))); - mockTransientProcessorResultGasEstimate(1L, false, false); + mockTransientProcessorResultGasEstimate(1L, false, false, latestBlockHeader); Assertions.assertThatThrownBy(() -> method.response(request)) .isInstanceOf(InvalidJsonRpcParameters.class) .hasMessageContaining("gasPrice cannot be used with maxFeePerGas or maxPriorityFeePerGas"); @@ -174,12 +170,10 @@ public class EthEstimateGasTest { public void shouldReturnGasEstimateWhenTransientEip1559TransactionProcessorReturnsResultSuccess() { final JsonRpcRequestContext request = ethEstimateGasRequest(eip1559TransactionCallParameter()); - mockTransientProcessorResultGasEstimate(1L, true, false); + mockTransientProcessorResultGasEstimate(1L, true, false, latestBlockHeader); final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse(null, Quantity.create(1L)); - Assertions.assertThat(method.response(request)) - .usingRecursiveComparison() - .isEqualTo(expectedResponse); + assertThat(method.response(request)).usingRecursiveComparison().isEqualTo(expectedResponse); } @Test @@ -187,28 +181,24 @@ public class EthEstimateGasTest { shouldReturnGasEstimateErrorWhenTransientLegacyTransactionProcessorReturnsResultFailure() { final JsonRpcRequestContext request = ethEstimateGasRequest(defaultLegacyTransactionCallParameter(Wei.ZERO)); - mockTransientProcessorResultGasEstimate(1L, false, false); + mockTransientProcessorResultGasEstimate(1L, false, false, latestBlockHeader); final JsonRpcResponse expectedResponse = new JsonRpcErrorResponse(null, RpcErrorType.INTERNAL_ERROR); - Assertions.assertThat(method.response(request)) - .usingRecursiveComparison() - .isEqualTo(expectedResponse); + assertThat(method.response(request)).usingRecursiveComparison().isEqualTo(expectedResponse); } @Test public void shouldReturnGasEstimateErrorWhenTransientEip1559TransactionProcessorReturnsResultFailure() { final JsonRpcRequestContext request = ethEstimateGasRequest(eip1559TransactionCallParameter()); - mockTransientProcessorResultGasEstimate(1L, false, false); + mockTransientProcessorResultGasEstimate(1L, false, false, latestBlockHeader); final JsonRpcResponse expectedResponse = new JsonRpcErrorResponse(null, RpcErrorType.INTERNAL_ERROR); - Assertions.assertThat(method.response(request)) - .usingRecursiveComparison() - .isEqualTo(expectedResponse); + assertThat(method.response(request)).usingRecursiveComparison().isEqualTo(expectedResponse); } @Test @@ -217,7 +207,8 @@ public class EthEstimateGasTest { ethEstimateGasRequest(defaultLegacyTransactionCallParameter(Wei.ZERO)); mockTransientProcessorResultTxInvalidReason( TransactionInvalidReason.UPFRONT_COST_EXCEEDS_BALANCE, - "transaction up-front cost 10 exceeds transaction sender account balance 5"); + "transaction up-front cost 10 exceeds transaction sender account balance 5", + latestBlockHeader); final ValidationResult validationResult = ValidationResult.invalid( @@ -226,9 +217,7 @@ public class EthEstimateGasTest { final JsonRpcError rpcError = JsonRpcError.from(validationResult); final JsonRpcResponse expectedResponse = new JsonRpcErrorResponse(null, rpcError); - Assertions.assertThat(method.response(request)) - .usingRecursiveComparison() - .isEqualTo(expectedResponse); + assertThat(method.response(request)).usingRecursiveComparison().isEqualTo(expectedResponse); } @Test @@ -236,7 +225,8 @@ public class EthEstimateGasTest { final JsonRpcRequestContext request = ethEstimateGasRequest(eip1559TransactionCallParameter()); mockTransientProcessorResultTxInvalidReason( TransactionInvalidReason.UPFRONT_COST_EXCEEDS_BALANCE, - "transaction up-front cost 10 exceeds transaction sender account balance 5"); + "transaction up-front cost 10 exceeds transaction sender account balance 5", + latestBlockHeader); final ValidationResult validationResult = ValidationResult.invalid( TransactionInvalidReason.UPFRONT_COST_EXCEEDS_BALANCE, @@ -244,9 +234,7 @@ public class EthEstimateGasTest { final JsonRpcError rpcError = JsonRpcError.from(validationResult); final JsonRpcResponse expectedResponse = new JsonRpcErrorResponse(null, rpcError); - Assertions.assertThat(method.response(request)) - .usingRecursiveComparison() - .isEqualTo(expectedResponse); + assertThat(method.response(request)).usingRecursiveComparison().isEqualTo(expectedResponse); } @Test @@ -254,21 +242,21 @@ public class EthEstimateGasTest { when(worldStateArchive.isWorldStateAvailable(any(), any())).thenReturn(false); final JsonRpcRequestContext request = ethEstimateGasRequest(defaultLegacyTransactionCallParameter(Wei.ZERO)); - mockTransientProcessorResultGasEstimate(1L, false, false); + mockTransientProcessorResultGasEstimate(1L, false, false, latestBlockHeader); final JsonRpcResponse expectedResponse = new JsonRpcErrorResponse(null, RpcErrorType.WORLD_STATE_UNAVAILABLE); JsonRpcResponse theResponse = method.response(request); - Assertions.assertThat(theResponse).usingRecursiveComparison().isEqualTo(expectedResponse); + assertThat(theResponse).usingRecursiveComparison().isEqualTo(expectedResponse); } @Test public void shouldReturnErrorWhenTransactionReverted() { final JsonRpcRequestContext request = ethEstimateGasRequest(defaultLegacyTransactionCallParameter(Wei.ZERO)); - mockTransientProcessorResultGasEstimate(1L, false, true); + mockTransientProcessorResultGasEstimate(1L, false, true, latestBlockHeader); final JsonRpcResponse expectedResponse = new JsonRpcErrorResponse(null, new JsonRpcError(RpcErrorType.REVERT_ERROR, "0x00")); @@ -278,7 +266,7 @@ public class EthEstimateGasTest { final JsonRpcResponse actualResponse = method.response(request); - Assertions.assertThat(actualResponse).usingRecursiveComparison().isEqualTo(expectedResponse); + assertThat(actualResponse).usingRecursiveComparison().isEqualTo(expectedResponse); assertThat(((JsonRpcErrorResponse) actualResponse).getError().getMessage()) .isEqualTo("Execution reverted"); @@ -296,7 +284,8 @@ public class EthEstimateGasTest { + "00002545524332303a207472616e736665722066726f6d20746865207a65726f20" + "61646472657373000000000000000000000000000000000000000000000000000000"; - mockTransientProcessorTxReverted(1L, false, Bytes.fromHexString(executionRevertedReason)); + mockTransientProcessorTxReverted( + 1L, false, Bytes.fromHexString(executionRevertedReason), latestBlockHeader); final JsonRpcResponse expectedResponse = new JsonRpcErrorResponse( @@ -307,7 +296,7 @@ public class EthEstimateGasTest { final JsonRpcResponse actualResponse = method.response(request); - Assertions.assertThat(actualResponse).usingRecursiveComparison().isEqualTo(expectedResponse); + assertThat(actualResponse).usingRecursiveComparison().isEqualTo(expectedResponse); assertThat(((JsonRpcErrorResponse) actualResponse).getError().getMessage()) .isEqualTo("Execution reverted: ERC20: transfer from the zero address"); @@ -323,7 +312,8 @@ public class EthEstimateGasTest { "0x08c379a000000000000000000000000000000000000000000000000000000000" + "123451234512345123451234512345123451234512345123451234512345123451"; - mockTransientProcessorTxReverted(1L, false, Bytes.fromHexString(invalidRevertReason)); + mockTransientProcessorTxReverted( + 1L, false, Bytes.fromHexString(invalidRevertReason), latestBlockHeader); final JsonRpcResponse expectedResponse = new JsonRpcErrorResponse( @@ -334,7 +324,7 @@ public class EthEstimateGasTest { final JsonRpcResponse actualResponse = method.response(request); - Assertions.assertThat(actualResponse).usingRecursiveComparison().isEqualTo(expectedResponse); + assertThat(actualResponse).usingRecursiveComparison().isEqualTo(expectedResponse); assertThat(((JsonRpcErrorResponse) actualResponse).getError().getMessage()) .isEqualTo("Execution reverted: ABI decode error"); @@ -344,7 +334,7 @@ public class EthEstimateGasTest { public void shouldIgnoreSenderBalanceAccountWhenStrictModeDisabled() { final JsonRpcRequestContext request = ethEstimateGasRequest(defaultLegacyTransactionCallParameter(Wei.ZERO)); - mockTransientProcessorResultGasEstimate(1L, false, true); + mockTransientProcessorResultGasEstimate(1L, false, true, latestBlockHeader); method.response(request); @@ -357,14 +347,14 @@ public class EthEstimateGasTest { .isAllowExceedingBalance(true) .build()), any(OperationTracer.class), - eq(1L)); + eq(latestBlockHeader)); } @Test public void shouldNotIgnoreSenderBalanceAccountWhenStrictModeEnabled() { final JsonRpcRequestContext request = ethEstimateGasRequest(legacyTransactionCallParameter(Wei.ZERO, true)); - mockTransientProcessorResultGasEstimate(1L, false, true); + mockTransientProcessorResultGasEstimate(1L, false, true, latestBlockHeader); method.response(request); @@ -377,7 +367,7 @@ public class EthEstimateGasTest { .isAllowExceedingBalance(false) .build()), any(OperationTracer.class), - eq(1L)); + eq(latestBlockHeader)); } @Test @@ -385,22 +375,44 @@ public class EthEstimateGasTest { final JsonRpcRequestContext request = ethEstimateGasRequest(defaultLegacyTransactionCallParameter(Wei.ZERO)); mockTransientProcessorResultTxInvalidReason( - TransactionInvalidReason.EXECUTION_HALTED, "INVALID_OPERATION"); + TransactionInvalidReason.EXECUTION_HALTED, "INVALID_OPERATION", latestBlockHeader); final ValidationResult validationResult = ValidationResult.invalid(TransactionInvalidReason.EXECUTION_HALTED, "INVALID_OPERATION"); final JsonRpcError rpcError = JsonRpcError.from(validationResult); final JsonRpcResponse expectedResponse = new JsonRpcErrorResponse(null, rpcError); - Assertions.assertThat(method.response(request)) - .usingRecursiveComparison() - .isEqualTo(expectedResponse); + assertThat(method.response(request)).usingRecursiveComparison().isEqualTo(expectedResponse); + } + + @Test + public void shouldUseBlockTagParamWhenPresent() { + final JsonRpcRequestContext request = + ethEstimateGasRequest(eip1559TransactionCallParameter(), "finalized"); + mockTransientProcessorResultGasEstimate(1L, true, false, finalizedBlockHeader); + + final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse(null, Quantity.create(1L)); + + assertThat(method.response(request)).usingRecursiveComparison().isEqualTo(expectedResponse); + } + + @Test + public void shouldUseBlockNumberParamWhenPresent() { + final JsonRpcRequestContext request = + ethEstimateGasRequest(eip1559TransactionCallParameter(), "0x0"); + mockTransientProcessorResultGasEstimate(1L, true, false, genesisBlockHeader); + + final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse(null, Quantity.create(1L)); + + assertThat(method.response(request)).usingRecursiveComparison().isEqualTo(expectedResponse); } private void mockTransientProcessorResultTxInvalidReason( - final TransactionInvalidReason reason, final String validationFailedErrorMessage) { + final TransactionInvalidReason reason, + final String validationFailedErrorMessage, + final BlockHeader blockHeader) { final TransactionSimulatorResult mockTxSimResult = - getMockTransactionSimulatorResult(false, 0, Wei.ZERO, Optional.empty()); + getMockTransactionSimulatorResult(false, 0, Wei.ZERO, Optional.empty(), blockHeader); when(mockTxSimResult.getValidationResult()) .thenReturn( validationFailedErrorMessage == null @@ -409,45 +421,55 @@ public class EthEstimateGasTest { } private void mockTransientProcessorTxReverted( - final long estimateGas, final boolean isSuccessful, final Bytes revertReason) { + final long estimateGas, + final boolean isSuccessful, + final Bytes revertReason, + final BlockHeader blockHeader) { mockTransientProcessorResultGasEstimate( - estimateGas, isSuccessful, Wei.ZERO, Optional.of(revertReason)); + estimateGas, isSuccessful, Wei.ZERO, Optional.of(revertReason), blockHeader); } private void mockTransientProcessorResultGasEstimate( - final long estimateGas, final boolean isSuccessful, final boolean isReverted) { + final long estimateGas, + final boolean isSuccessful, + final boolean isReverted, + final BlockHeader blockHeader) { mockTransientProcessorResultGasEstimate( estimateGas, isSuccessful, Wei.ZERO, - isReverted ? Optional.of(Bytes.of(0)) : Optional.empty()); + isReverted ? Optional.of(Bytes.of(0)) : Optional.empty(), + blockHeader); } private void mockTransientProcessorResultGasEstimate( final long estimateGas, final boolean isSuccessful, final Wei gasPrice, - final Optional revertReason) { - getMockTransactionSimulatorResult(isSuccessful, estimateGas, gasPrice, revertReason); + final Optional revertReason, + final BlockHeader blockHeader) { + getMockTransactionSimulatorResult( + isSuccessful, estimateGas, gasPrice, revertReason, blockHeader); } private TransactionSimulatorResult getMockTransactionSimulatorResult( final boolean isSuccessful, final long estimateGas, final Wei gasPrice, - final Optional revertReason) { + final Optional revertReason, + final BlockHeader blockHeader) { final TransactionSimulatorResult mockTxSimResult = mock(TransactionSimulatorResult.class); when(transactionSimulator.process( eq(modifiedLegacyTransactionCallParameter(gasPrice)), any(TransactionValidationParams.class), any(OperationTracer.class), - eq(1L))) + eq(blockHeader))) .thenReturn(Optional.of(mockTxSimResult)); when(transactionSimulator.process( eq(modifiedEip1559TransactionCallParameter()), any(TransactionValidationParams.class), any(OperationTracer.class), - eq(1L))) + eq(blockHeader))) .thenReturn(Optional.of(mockTxSimResult)); final TransactionProcessingResult mockResult = mock(TransactionProcessingResult.class); @@ -523,4 +545,10 @@ public class EthEstimateGasTest { return new JsonRpcRequestContext( new JsonRpcRequest("2.0", "eth_estimateGas", new Object[] {callParameter})); } + + private JsonRpcRequestContext ethEstimateGasRequest( + final CallParameter callParameter, final String blockParam) { + return new JsonRpcRequestContext( + new JsonRpcRequest("2.0", "eth_estimateGas", new Object[] {callParameter, blockParam})); + } } diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_estimateGas_from_contract_withBlockNum.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_estimateGas_from_contract_withBlockNum.json new file mode 100644 index 0000000000..aa9731f74f --- /dev/null +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_estimateGas_from_contract_withBlockNum.json @@ -0,0 +1,21 @@ +{ + "request": { + "id": 3, + "jsonrpc": "2.0", + "method": "eth_estimateGas", + "params": [ + { + "to": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "from": "0x6295ee1b4f6dd65047762f924ecd367c17eabf8f", + "data": "0x123456" + }, + "0x1" + ] + }, + "response": { + "jsonrpc": "2.0", + "id": 3, + "result": "0x52d4" + }, + "statusCode": 200 +} diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_estimateGas_from_contract_withBlockTag.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_estimateGas_from_contract_withBlockTag.json new file mode 100644 index 0000000000..992a7d7728 --- /dev/null +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_estimateGas_from_contract_withBlockTag.json @@ -0,0 +1,21 @@ +{ + "request": { + "id": 3, + "jsonrpc": "2.0", + "method": "eth_estimateGas", + "params": [ + { + "to": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "from": "0x6295ee1b4f6dd65047762f924ecd367c17eabf8f", + "data": "0x123456" + }, + "latest" + ] + }, + "response": { + "jsonrpc": "2.0", + "id": 3, + "result": "0x5238" + }, + "statusCode": 200 +} diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_estimateGas_insufficientGas_withBlockNum.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_estimateGas_insufficientGas_withBlockNum.json new file mode 100644 index 0000000000..6dd337509e --- /dev/null +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_estimateGas_insufficientGas_withBlockNum.json @@ -0,0 +1,21 @@ +{ + "request": { + "id": 3, + "jsonrpc": "2.0", + "method": "eth_estimateGas", + "params": [ + { + "to": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "from": "0x6295ee1b4f6dd65047762f924ecd367c17eabf8f", + "gas": "0x1" + }, + "0xa" + ] + }, + "response": { + "jsonrpc": "2.0", + "id": 3, + "result": "0x5208" + }, + "statusCode": 200 +} \ No newline at end of file diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_estimateGas_transfer_withBlockTag.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_estimateGas_transfer_withBlockTag.json new file mode 100644 index 0000000000..d909af9eed --- /dev/null +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_estimateGas_transfer_withBlockTag.json @@ -0,0 +1,21 @@ +{ + "request": { + "id": 3, + "jsonrpc": "2.0", + "method": "eth_estimateGas", + "params": [ + { + "from": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "to": "0x8888f1f195afa192cfee860698584c030f4c9db1", + "value": "0x1" + }, + "earliest" + ] + }, + "response": { + "jsonrpc": "2.0", + "id": 3, + "result": "0x5208" + }, + "statusCode": 200 +} \ No newline at end of file From f0d2a665d77817719abf6b5f1eea01fecb8f57c4 Mon Sep 17 00:00:00 2001 From: Fabio Di Fabio Date: Thu, 5 Sep 2024 17:08:20 +0200 Subject: [PATCH 192/259] Remove tx from pool when its score is lower than a configured value (#7576) * Remove tx from pool when its score is lower than a configured value Signed-off-by: Fabio Di Fabio * Update besu/src/main/java/org/hyperledger/besu/cli/options/TransactionPoolOptions.java Co-authored-by: Stefan Pingel <16143240+pinges@users.noreply.github.com> Signed-off-by: Fabio Di Fabio * Check for below min score after the penalization Signed-off-by: Fabio Di Fabio --------- Signed-off-by: Fabio Di Fabio Co-authored-by: Stefan Pingel <16143240+pinges@users.noreply.github.com> --- CHANGELOG.md | 1 + .../cli/options/TransactionPoolOptions.java | 12 +++++++++ .../options/TransactionPoolOptionsTest.java | 18 +++++++++++++ .../src/test/resources/everything_config.toml | 1 + .../TransactionPoolConfiguration.java | 6 +++++ .../layered/AbstractTransactionsLayer.java | 4 +++ .../layered/LayeredPendingTransactions.java | 18 +++++-------- .../transactions/layered/RemovalReason.java | 25 +++++++++++-------- .../eth/transactions/layered/LayersTest.java | 15 ++++++++++- 9 files changed, 77 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c7c7a33e40..4e38dc1a38 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ ### Additions and Improvements - Update Java and Gradle dependecies [#7571](https://github.com/hyperledger/besu/pull/7571) +- Layered txpool: new options `--tx-pool-min-score` to remove a tx from pool when its score is lower than the specified value [#7576](https://github.com/hyperledger/besu/pull/7576) ### Bug fixes - Layered txpool: do not send notifications when moving tx between layers [#7539](https://github.com/hyperledger/besu/pull/7539) diff --git a/besu/src/main/java/org/hyperledger/besu/cli/options/TransactionPoolOptions.java b/besu/src/main/java/org/hyperledger/besu/cli/options/TransactionPoolOptions.java index 6f5381a968..6d1a6141ef 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/options/TransactionPoolOptions.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/options/TransactionPoolOptions.java @@ -160,6 +160,7 @@ public class TransactionPoolOptions implements CLIOptions assertThat(config.getMinScore()).isEqualTo(minScore), + "--tx-pool-min-score", + Byte.toString(minScore)); + } + + @Test + public void minScoreNonByteValueReturnError() { + final var overflowMinScore = Integer.toString(-300); + internalTestFailure( + "Invalid value for option '--tx-pool-min-score': '" + overflowMinScore + "' is not a byte", + "--tx-pool-min-score", + overflowMinScore); + } + @Override protected TransactionPoolConfiguration createDefaultDomainObject() { return TransactionPoolConfiguration.DEFAULT; diff --git a/besu/src/test/resources/everything_config.toml b/besu/src/test/resources/everything_config.toml index b489df9fa2..e3d7a3f28d 100644 --- a/besu/src/test/resources/everything_config.toml +++ b/besu/src/test/resources/everything_config.toml @@ -195,6 +195,7 @@ tx-pool-retention-hours=999 tx-pool-max-size=1234 tx-pool-limit-by-account-percentage=0.017 tx-pool-min-gas-price=1000 +tx-pool-min-score=100 # Revert Reason revert-reason-enabled=false diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolConfiguration.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolConfiguration.java index 18a8598ab8..2f823830fc 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolConfiguration.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolConfiguration.java @@ -80,6 +80,7 @@ public interface TransactionPoolConfiguration { Implementation DEFAULT_TX_POOL_IMPLEMENTATION = Implementation.LAYERED; Set
DEFAULT_PRIORITY_SENDERS = Set.of(); Wei DEFAULT_TX_POOL_MIN_GAS_PRICE = Wei.of(1000); + byte DEFAULT_TX_POOL_MIN_SCORE = -128; TransactionPoolConfiguration DEFAULT = ImmutableTransactionPoolConfiguration.builder().build(); @@ -173,6 +174,11 @@ public interface TransactionPoolConfiguration { return DEFAULT_TX_POOL_MIN_GAS_PRICE; } + @Value.Default + default byte getMinScore() { + return DEFAULT_TX_POOL_MIN_SCORE; + } + @Value.Default default TransactionPoolValidatorService getTransactionPoolValidatorService() { return new TransactionPoolValidatorService() { 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 b429de4a75..ca980b219d 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 @@ -21,6 +21,7 @@ import static org.hyperledger.besu.ethereum.eth.transactions.TransactionAddedRes 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; @@ -481,6 +482,9 @@ public abstract class AbstractTransactionsLayer implements TransactionsLayer { if (pendingTransactions.containsKey(penalizedTransaction.getHash())) { internalPenalize(penalizedTransaction); metrics.incrementPenalized(penalizedTransaction, name()); + if (penalizedTransaction.getScore() < poolConfig.getMinScore()) { + remove(penalizedTransaction, BELOW_MIN_SCORE); + } } else { nextLayer.penalize(penalizedTransaction); } 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 0209900eac..21c75b364a 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 @@ -42,7 +42,6 @@ import org.hyperledger.besu.evm.account.AccountState; import org.hyperledger.besu.plugin.data.TransactionSelectionResult; import java.util.ArrayDeque; -import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -316,7 +315,6 @@ public class LayeredPendingTransactions implements PendingTransactions { @Override public void selectTransactions(final PendingTransactions.TransactionSelector selector) { - final List penalizedTransactions = new ArrayList<>(); final Set
skipSenders = new HashSet<>(); final Map> candidateTxsByScore; @@ -356,7 +354,12 @@ public class LayeredPendingTransactions implements PendingTransactions { } if (selectionResult.penalize()) { - penalizedTransactions.add(candidatePendingTx); + ethScheduler.scheduleTxWorkerTask( + () -> { + synchronized (this) { + prioritizedTransactions.penalize(candidatePendingTx); + } + }); LOG.atTrace() .setMessage("Transaction {} penalized") .addArgument(candidatePendingTx::toTraceLog) @@ -379,15 +382,6 @@ public class LayeredPendingTransactions implements PendingTransactions { } } } - - ethScheduler.scheduleTxWorkerTask( - () -> - penalizedTransactions.forEach( - penalizedTx -> { - synchronized (this) { - prioritizedTransactions.penalize(penalizedTx); - } - })); } @Override 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/RemovalReason.java index 8b97861b88..8acd026b14 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/RemovalReason.java @@ -52,25 +52,30 @@ 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(), + CONFIRMED, /** Tx removed since it has been replaced by another one added in the same layer. */ - REPLACED(), + REPLACED, /** Tx removed since it has been replaced by another one added in another layer. */ - CROSS_LAYER_REPLACED(), + CROSS_LAYER_REPLACED, /** Tx removed when the pool is full, to make space for new incoming txs. */ - DROPPED(), + DROPPED, /** * Tx removed since found invalid after it was added to the pool, for example during txs * selection for a new block proposal. */ - INVALIDATED(), + INVALIDATED, /** * 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. */ - RECONCILED(); + RECONCILED, + /** + * 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. + */ + BELOW_MIN_SCORE; private final String label; @@ -95,22 +100,22 @@ public interface RemovalReason { * When the current layer is full, and this tx needs to be moved to the lower layer, in order to * free space. */ - EVICTED(), + EVICTED, /** * Specific to sequential layers, when a tx is removed because found invalid, then if the sender * has other txs with higher nonce, then a gap is created, and since sequential layers do not * permit gaps, txs following the invalid one need to be moved to lower layers. */ - FOLLOW_INVALIDATED(), + FOLLOW_INVALIDATED, /** * When a tx is moved to the upper layer, since it satisfies all the requirement to be promoted. */ - PROMOTED(), + PROMOTED, /** * When a tx is moved to the lower layer, since it, or a preceding one from the same sender, * does not respect anymore the requisites to stay in this layer. */ - DEMOTED(); + DEMOTED; private final String label; 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 2036e46d63..a7c6556e73 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 @@ -74,12 +74,14 @@ public class LayersTest extends BaseTransactionPoolTest { private static final int MAX_FUTURE_FOR_SENDER = 10; private static final Wei BASE_FEE = Wei.ONE; private static final Wei MIN_GAS_PRICE = BASE_FEE; + private static final byte MIN_SCORE = 125; private static final TransactionPoolConfiguration DEFAULT_TX_POOL_CONFIG = ImmutableTransactionPoolConfiguration.builder() .maxPrioritizedTransactions(MAX_PRIO_TRANSACTIONS) .maxPrioritizedTransactionsByType(Map.of(BLOB, 1)) .maxFutureBySender(MAX_FUTURE_FOR_SENDER) + .minScore(MIN_SCORE) .pendingTransactionsLayerMaxCapacityBytes( new PendingTransaction.Remote( new BaseTransactionPoolTest().createEIP1559Transaction(0, KEYS1, 1)) @@ -92,6 +94,7 @@ public class LayersTest extends BaseTransactionPoolTest { .maxPrioritizedTransactions(MAX_PRIO_TRANSACTIONS) .maxPrioritizedTransactionsByType(Map.of(BLOB, 1)) .maxFutureBySender(MAX_FUTURE_FOR_SENDER) + .minScore(MIN_SCORE) .pendingTransactionsLayerMaxCapacityBytes( new PendingTransaction.Remote( new BaseTransactionPoolTest().createEIP4844Transaction(0, KEYS1, 1, 1)) @@ -1293,7 +1296,17 @@ public class LayersTest extends BaseTransactionPoolTest { .penalizeForSender(S2, 1) .addForSender(S2, 2) .expectedReadyForSenders(S1, 0, S1, 1, S2, 1) - .expectedSparseForSender(S2, 2))); + .expectedSparseForSender(S2, 2)), + Arguments.of( + new Scenario("remove below min score") + .addForSender(S1, 0) // score 127 + .expectedPrioritizedForSender(S1, 0) + .penalizeForSender(S1, 0) // score 126 + .expectedPrioritizedForSender(S1, 0) + .penalizeForSender(S1, 0) // score 125 + .expectedPrioritizedForSender(S1, 0) + .penalizeForSender(S1, 0) // score 124, removed since decreased score < MIN_SCORE + .expectedPrioritizedForSenders())); } private static BlockHeader mockBlockHeader() { From cf592c48d1bae767ce5049b9197a4cda8e16ab22 Mon Sep 17 00:00:00 2001 From: Stefan Pingel <16143240+pinges@users.noreply.github.com> Date: Fri, 6 Sep 2024 17:37:36 +1000 Subject: [PATCH 193/259] implement engine_getBlobsV1 (#7553) * implement engine_getBlobsV1 Signed-off-by: stefan.pingel@consensys.net Signed-off-by: Stefan Pingel <16143240+pinges@users.noreply.github.com> Co-authored-by: Sally MacFarlane --- CHANGELOG.md | 3 +- .../blockcreation/CliqueBlockCreatorTest.java | 4 +- .../CliqueMinerExecutorTest.java | 4 +- .../ibft/support/TestContextBuilder.java | 4 +- .../blockcreation/BftBlockCreatorTest.java | 4 +- .../blockcreation/MergeCoordinatorTest.java | 4 +- .../qbft/support/TestContextBuilder.java | 4 +- .../EthGetFilterChangesIntegrationTest.java | 4 +- .../EthGetFilterChangesIntegrationTest.java | 4 +- .../besu/ethereum/api/jsonrpc/RpcMethod.java | 1 + .../methods/engine/EngineGetBlobsV1.java | 115 ++++++++ .../internal/response/RpcErrorType.java | 2 + .../internal/results/BlobAndProofV1.java | 42 +++ .../ExecutionEngineJsonRpcMethods.java | 11 +- .../methods/JsonRpcMethodsFactory.java | 3 +- .../methods/engine/EngineGetBlobsV1Test.java | 267 ++++++++++++++++++ .../AbstractBlockCreatorTest.java | 4 +- ...FeeMarketBlockTransactionSelectorTest.java | 4 +- ...FeeMarketBlockTransactionSelectorTest.java | 4 +- .../blockcreation/PoWBlockCreatorTest.java | 4 +- .../blockcreation/PoWMinerExecutorTest.java | 4 +- .../bonsai/AbstractIsolationTests.java | 3 +- .../ethereum/eth/transactions/BlobCache.java | 4 + .../eth/transactions/TransactionPool.java | 44 ++- .../transactions/TransactionPoolFactory.java | 3 +- .../AbstractTransactionPoolTest.java | 3 +- 26 files changed, 532 insertions(+), 21 deletions(-) create mode 100644 ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetBlobsV1.java create mode 100644 ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/BlobAndProofV1.java create mode 100644 ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetBlobsV1Test.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e38dc1a38..4e15113864 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ ### Additions and Improvements - Update Java and Gradle dependecies [#7571](https://github.com/hyperledger/besu/pull/7571) - Layered txpool: new options `--tx-pool-min-score` to remove a tx from pool when its score is lower than the specified value [#7576](https://github.com/hyperledger/besu/pull/7576) +- Add `engine_getBlobsV1` method to the Engine API [#7553](https://github.com/hyperledger/besu/pull/7553) ### Bug fixes - Layered txpool: do not send notifications when moving tx between layers [#7539](https://github.com/hyperledger/besu/pull/7539) @@ -39,7 +40,7 @@ - Correctly drops messages that exceeds local message size limit [#5455](https://github.com/hyperledger/besu/pull/7507) - **DebugMetrics**: Fixed a `ClassCastException` occurring in `DebugMetrics` when handling nested metric structures. Previously, `Double` values within these structures were incorrectly cast to `Map` objects, leading to errors. This update allows for proper handling of both direct values and nested structures at the same level. Issue# [#7383](https://github.com/hyperledger/besu/pull/7383) - `evmtool` was not respecting the `--genesis` setting, resulting in unexpected trace results. [#7433](https://github.com/hyperledger/besu/pull/7433) -- The genesis config override `contractSizeLimit` was not wired into code size limits [#7557](https://github.com/hyperledger/besu/pull/7557) +- The genesis config override `contractSizeLimit`q was not wired into code size limits [#7557](https://github.com/hyperledger/besu/pull/7557) - Fix incorrect key filtering in LayeredKeyValueStorage stream [#7535](https://github.com/hyperledger/besu/pull/7557) ## 24.8.0 diff --git a/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueBlockCreatorTest.java b/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueBlockCreatorTest.java index ec10630df9..9f2d848d45 100644 --- a/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueBlockCreatorTest.java +++ b/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueBlockCreatorTest.java @@ -55,6 +55,7 @@ import org.hyperledger.besu.ethereum.core.MiningParameters; import org.hyperledger.besu.ethereum.core.Util; import org.hyperledger.besu.ethereum.eth.manager.EthContext; import org.hyperledger.besu.ethereum.eth.manager.EthScheduler; +import org.hyperledger.besu.ethereum.eth.transactions.BlobCache; import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration; import org.hyperledger.besu.ethereum.eth.transactions.TransactionBroadcaster; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool; @@ -245,7 +246,8 @@ public class CliqueBlockCreatorTest { mock(TransactionBroadcaster.class), ethContext, new TransactionPoolMetrics(metricsSystem), - conf); + conf, + new BlobCache()); transactionPool.setEnabled(); return transactionPool; } diff --git a/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueMinerExecutorTest.java b/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueMinerExecutorTest.java index 9502d00a19..1aa2d75ef3 100644 --- a/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueMinerExecutorTest.java +++ b/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueMinerExecutorTest.java @@ -45,6 +45,7 @@ import org.hyperledger.besu.ethereum.core.MiningParameters; import org.hyperledger.besu.ethereum.core.Util; import org.hyperledger.besu.ethereum.eth.manager.EthContext; import org.hyperledger.besu.ethereum.eth.manager.EthScheduler; +import org.hyperledger.besu.ethereum.eth.transactions.BlobCache; import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration; import org.hyperledger.besu.ethereum.eth.transactions.TransactionBroadcaster; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool; @@ -233,7 +234,8 @@ public class CliqueMinerExecutorTest { mock(TransactionBroadcaster.class), cliqueEthContext, new TransactionPoolMetrics(metricsSystem), - conf); + conf, + new BlobCache()); transactionPool.setEnabled(); return transactionPool; diff --git a/consensus/ibft/src/integration-test/java/org/hyperledger/besu/consensus/ibft/support/TestContextBuilder.java b/consensus/ibft/src/integration-test/java/org/hyperledger/besu/consensus/ibft/support/TestContextBuilder.java index 2d620c5632..5d2b02b1a7 100644 --- a/consensus/ibft/src/integration-test/java/org/hyperledger/besu/consensus/ibft/support/TestContextBuilder.java +++ b/consensus/ibft/src/integration-test/java/org/hyperledger/besu/consensus/ibft/support/TestContextBuilder.java @@ -84,6 +84,7 @@ import org.hyperledger.besu.ethereum.core.MiningParameters; import org.hyperledger.besu.ethereum.core.Util; import org.hyperledger.besu.ethereum.eth.manager.EthContext; import org.hyperledger.besu.ethereum.eth.manager.EthScheduler; +import org.hyperledger.besu.ethereum.eth.transactions.BlobCache; import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration; import org.hyperledger.besu.ethereum.eth.transactions.TransactionBroadcaster; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool; @@ -371,7 +372,8 @@ public class TestContextBuilder { mock(TransactionBroadcaster.class), ethContext, new TransactionPoolMetrics(metricsSystem), - poolConf); + poolConf, + new BlobCache()); transactionPool.setEnabled(); diff --git a/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/blockcreation/BftBlockCreatorTest.java b/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/blockcreation/BftBlockCreatorTest.java index 1b86896f36..15844578cd 100644 --- a/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/blockcreation/BftBlockCreatorTest.java +++ b/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/blockcreation/BftBlockCreatorTest.java @@ -47,6 +47,7 @@ import org.hyperledger.besu.ethereum.core.ImmutableMiningParameters.MutableInitV import org.hyperledger.besu.ethereum.core.MiningParameters; import org.hyperledger.besu.ethereum.core.PrivacyParameters; import org.hyperledger.besu.ethereum.eth.manager.EthContext; +import org.hyperledger.besu.ethereum.eth.transactions.BlobCache; import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration; import org.hyperledger.besu.ethereum.eth.transactions.TransactionBroadcaster; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool; @@ -152,7 +153,8 @@ public class BftBlockCreatorTest { mock(TransactionBroadcaster.class), ethContext, new TransactionPoolMetrics(metricsSystem), - poolConf); + poolConf, + new BlobCache()); transactionPool.setEnabled(); 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 6ce8bcd8d0..a3dc6b6e0b 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 @@ -63,6 +63,7 @@ import org.hyperledger.besu.ethereum.core.TransactionTestFixture; import org.hyperledger.besu.ethereum.eth.manager.EthContext; import org.hyperledger.besu.ethereum.eth.manager.EthScheduler; import org.hyperledger.besu.ethereum.eth.sync.backwardsync.BackwardSyncContext; +import org.hyperledger.besu.ethereum.eth.transactions.BlobCache; import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration; import org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction; import org.hyperledger.besu.ethereum.eth.transactions.TransactionBroadcaster; @@ -214,7 +215,8 @@ public class MergeCoordinatorTest implements MergeGenesisConfigHelper { mock(TransactionBroadcaster.class), ethContext, new TransactionPoolMetrics(metricsSystem), - poolConf); + poolConf, + new BlobCache()); this.transactionPool.setEnabled(); diff --git a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/TestContextBuilder.java b/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/TestContextBuilder.java index 3467dce9fb..8906f0de7f 100644 --- a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/TestContextBuilder.java +++ b/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/TestContextBuilder.java @@ -98,6 +98,7 @@ import org.hyperledger.besu.ethereum.core.ProtocolScheduleFixture; import org.hyperledger.besu.ethereum.core.Util; import org.hyperledger.besu.ethereum.eth.manager.EthContext; import org.hyperledger.besu.ethereum.eth.manager.EthScheduler; +import org.hyperledger.besu.ethereum.eth.transactions.BlobCache; import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration; import org.hyperledger.besu.ethereum.eth.transactions.TransactionBroadcaster; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool; @@ -480,7 +481,8 @@ public class TestContextBuilder { mock(TransactionBroadcaster.class), ethContext, new TransactionPoolMetrics(metricsSystem), - poolConf); + poolConf, + new BlobCache()); transactionPool.setEnabled(); diff --git a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/frontier/EthGetFilterChangesIntegrationTest.java b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/frontier/EthGetFilterChangesIntegrationTest.java index 16a25d3500..d4de405305 100644 --- a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/frontier/EthGetFilterChangesIntegrationTest.java +++ b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/frontier/EthGetFilterChangesIntegrationTest.java @@ -50,6 +50,7 @@ import org.hyperledger.besu.ethereum.core.Transaction; import org.hyperledger.besu.ethereum.core.TransactionReceipt; import org.hyperledger.besu.ethereum.eth.manager.EthContext; import org.hyperledger.besu.ethereum.eth.manager.EthPeers; +import org.hyperledger.besu.ethereum.eth.transactions.BlobCache; import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration; import org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction; import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions; @@ -121,7 +122,8 @@ public class EthGetFilterChangesIntegrationTest { batchAddedListener, ethContext, new TransactionPoolMetrics(metricsSystem), - TransactionPoolConfiguration.DEFAULT); + TransactionPoolConfiguration.DEFAULT, + new BlobCache()); transactionPool.setEnabled(); final BlockchainQueries blockchainQueries = new BlockchainQueries( diff --git a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/london/EthGetFilterChangesIntegrationTest.java b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/london/EthGetFilterChangesIntegrationTest.java index e88d377f7f..0c194ad22f 100644 --- a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/london/EthGetFilterChangesIntegrationTest.java +++ b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/london/EthGetFilterChangesIntegrationTest.java @@ -50,6 +50,7 @@ import org.hyperledger.besu.ethereum.core.Transaction; import org.hyperledger.besu.ethereum.core.TransactionReceipt; import org.hyperledger.besu.ethereum.eth.manager.EthContext; import org.hyperledger.besu.ethereum.eth.manager.EthPeers; +import org.hyperledger.besu.ethereum.eth.transactions.BlobCache; import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration; import org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction; import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions; @@ -121,7 +122,8 @@ public class EthGetFilterChangesIntegrationTest { batchAddedListener, ethContext, new TransactionPoolMetrics(metricsSystem), - TransactionPoolConfiguration.DEFAULT); + TransactionPoolConfiguration.DEFAULT, + new BlobCache()); transactionPool.setEnabled(); final BlockchainQueries blockchainQueries = new BlockchainQueries( diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcMethod.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcMethod.java index 79d33ffbac..f8bc597ff7 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcMethod.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcMethod.java @@ -51,6 +51,7 @@ public enum RpcMethod { DEBUG_GET_RAW_BLOCK("debug_getRawBlock"), DEBUG_GET_RAW_RECEIPTS("debug_getRawReceipts"), DEBUG_GET_RAW_TRANSACTION("debug_getRawTransaction"), + ENGINE_GET_BLOBS_V1("engine_getBlobsV1"), ENGINE_GET_PAYLOAD_V1("engine_getPayloadV1"), ENGINE_GET_PAYLOAD_V2("engine_getPayloadV2"), ENGINE_GET_PAYLOAD_V3("engine_getPayloadV3"), diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetBlobsV1.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetBlobsV1.java new file mode 100644 index 0000000000..cc9ba2dce2 --- /dev/null +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetBlobsV1.java @@ -0,0 +1,115 @@ +/* + * 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.methods.engine; + +import org.hyperledger.besu.datatypes.BlobsWithCommitments; +import org.hyperledger.besu.datatypes.VersionedHash; +import org.hyperledger.besu.ethereum.ProtocolContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.BlobAndProofV1; +import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool; + +import java.util.Arrays; +import java.util.List; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import io.vertx.core.Vertx; + +/** + * #### Specification + * + *

1. Given an array of blob versioned hashes client software **MUST** respond with an array of + * `BlobAndProofV1` objects with matching versioned hashes, respecting the order of versioned hashes + * in the input array. + * + *

2. Client software **MUST** place responses in the order given in the request, using `null` + * for any missing blobs. For instance, if the request is `[A_versioned_hash, B_versioned_hash, + * C_versioned_hash]` and client software has data for blobs `A` and `C`, but doesn't have data for + * `B`, the response **MUST** be `[A, null, C]`. + * + *

3. Client software **MUST** support request sizes of at least 128 blob versioned hashes. The + * client **MUST** return `-38004: Too large request` error if the number of requested blobs is too + * large. + * + *

4. Client software **MAY** return an array of all `null` entries if syncing or otherwise + * unable to serve blob pool data. + * + *

5. Callers **MUST** consider that execution layer clients may prune old blobs from their pool, + * and will respond with `null` if a blob has been pruned. + */ +public class EngineGetBlobsV1 extends ExecutionEngineJsonRpcMethod { + + private final TransactionPool transactionPool; + + public EngineGetBlobsV1( + final Vertx vertx, + final ProtocolContext protocolContext, + final EngineCallListener engineCallListener, + final TransactionPool transactionPool) { + super(vertx, protocolContext, engineCallListener); + this.transactionPool = transactionPool; + } + + @Override + public String getName() { + return "engine_getBlobsV1"; + } + + @Override + public JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext) { + final VersionedHash[] versionedHashes; + try { + versionedHashes = requestContext.getRequiredParameter(0, VersionedHash[].class); + } catch (JsonRpcParameter.JsonRpcParameterException e) { + throw new InvalidJsonRpcParameters( + "Invalid versioned hashes parameter (index 0)", + RpcErrorType.INVALID_VERSIONED_HASHES_PARAMS, + e); + } + + if (versionedHashes.length > 128) { + return new JsonRpcErrorResponse( + requestContext.getRequest().getId(), + RpcErrorType.INVALID_ENGINE_GET_BLOBS_V1_TOO_LARGE_REQUEST); + } + + final List result = getBlobV1Result(versionedHashes); + + return new JsonRpcSuccessResponse(requestContext.getRequest().getId(), result); + } + + private @Nonnull List getBlobV1Result(final VersionedHash[] versionedHashes) { + return Arrays.stream(versionedHashes) + .map(transactionPool::getBlobQuad) + .map(this::getBlobAndProofV1) + .toList(); + } + + private @Nullable BlobAndProofV1 getBlobAndProofV1(final BlobsWithCommitments.BlobQuad bq) { + if (bq == null) { + return null; + } + return new BlobAndProofV1( + bq.blob().getData().toHexString(), bq.kzgProof().getData().toHexString()); + } +} 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 009fca38fc..875eab601b 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 @@ -58,6 +58,7 @@ public enum RpcErrorType implements RpcMethodError { INVALID_ENGINE_NEW_PAYLOAD_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid engine payload parameter"), INVALID_ENGINE_PREPARE_PAYLOAD_PARAMS( INVALID_PARAMS_ERROR_CODE, "Invalid engine prepare payload parameter"), + INVALID_ENGINE_GET_BLOBS_V1_TOO_LARGE_REQUEST(-38004, "Too large request"), 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)"), @@ -109,6 +110,7 @@ public enum RpcErrorType implements RpcMethodError { INVALID_TRANSACTION_LIMIT_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid transaction limit params"), INVALID_TRANSACTION_TRACE_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid transaction trace params"), INVALID_VERSIONED_HASH_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid versioned hash params"), + INVALID_VERSIONED_HASHES_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid versioned hashes params"), INVALID_VOTE_TYPE_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid vote type params"), INVALID_WITHDRAWALS_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid withdrawals"), diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/BlobAndProofV1.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/BlobAndProofV1.java new file mode 100644 index 0000000000..c8978e00c1 --- /dev/null +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/BlobAndProofV1.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.api.jsonrpc.internal.results; + +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +/** + * The result of the eth_getBlobAndProofV1 JSON-RPC method contains an array of BlobAndProofV1. + * BlobAndProofV1 contains the blob data and the kzg proof for the blob. + */ +@JsonPropertyOrder({"blob", "proof"}) +public class BlobAndProofV1 { + + private final String blob; + + private final String proof; + + public BlobAndProofV1(final String blob, final String proof) { + this.blob = blob; + this.proof = proof; + } + + public String getProof() { + return proof; + } + + public String getBlob() { + return blob; + } +} 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 6dda09bce9..d8d04027f6 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 @@ -23,6 +23,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineE import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineForkchoiceUpdatedV1; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineForkchoiceUpdatedV2; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineForkchoiceUpdatedV3; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineGetBlobsV1; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineGetClientVersionV1; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineGetPayloadBodiesByHashV1; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineGetPayloadBodiesByRangeV1; @@ -39,6 +40,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineQ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.BlockResultFactory; import org.hyperledger.besu.ethereum.blockcreation.MiningCoordinator; import org.hyperledger.besu.ethereum.eth.manager.EthPeers; +import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import java.util.ArrayList; @@ -60,6 +62,7 @@ public class ExecutionEngineJsonRpcMethods extends ApiGroupJsonRpcMethods { private final Vertx consensusEngineServer; private final String clientVersion; private final String commit; + private final TransactionPool transactionPool; ExecutionEngineJsonRpcMethods( final MiningCoordinator miningCoordinator, @@ -68,7 +71,8 @@ public class ExecutionEngineJsonRpcMethods extends ApiGroupJsonRpcMethods { final EthPeers ethPeers, final Vertx consensusEngineServer, final String clientVersion, - final String commit) { + final String commit, + final TransactionPool transactionPool) { this.mergeCoordinator = Optional.ofNullable(miningCoordinator) .filter(mc -> mc.isCompatibleWithEngineApi()) @@ -79,6 +83,7 @@ public class ExecutionEngineJsonRpcMethods extends ApiGroupJsonRpcMethods { this.consensusEngineServer = consensusEngineServer; this.clientVersion = clientVersion; this.commit = commit; + this.transactionPool = transactionPool; } @Override @@ -156,7 +161,9 @@ public class ExecutionEngineJsonRpcMethods extends ApiGroupJsonRpcMethods { new EnginePreparePayloadDebug( consensusEngineServer, protocolContext, engineQosTimer, mergeCoordinator.get()), new EngineGetClientVersionV1( - consensusEngineServer, protocolContext, engineQosTimer, clientVersion, commit))); + consensusEngineServer, protocolContext, engineQosTimer, clientVersion, commit), + new EngineGetBlobsV1( + consensusEngineServer, protocolContext, engineQosTimer, transactionPool))); if (protocolSchedule.anyMatch(p -> p.spec().getName().equalsIgnoreCase("cancun"))) { executionEngineApisSupported.add( diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/JsonRpcMethodsFactory.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/JsonRpcMethodsFactory.java index 41227c2ca8..55d9ef6029 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/JsonRpcMethodsFactory.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/JsonRpcMethodsFactory.java @@ -119,7 +119,8 @@ public class JsonRpcMethodsFactory { ethPeers, consensusEngineServer, clientVersion, - commit), + commit, + transactionPool), new EthJsonRpcMethods( blockchainQueries, synchronizer, diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetBlobsV1Test.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetBlobsV1Test.java new file mode 100644 index 0000000000..29c7ae82ed --- /dev/null +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetBlobsV1Test.java @@ -0,0 +1,267 @@ +/* + * 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.methods.engine; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; + +import org.hyperledger.besu.crypto.KeyPair; +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.BlobsWithCommitments; +import org.hyperledger.besu.datatypes.Hash; +import org.hyperledger.besu.datatypes.TransactionType; +import org.hyperledger.besu.datatypes.VersionedHash; +import org.hyperledger.besu.datatypes.Wei; +import org.hyperledger.besu.ethereum.ProtocolContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; +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.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.api.jsonrpc.internal.response.RpcErrorType; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.BlobAndProofV1; +import org.hyperledger.besu.ethereum.chain.MutableBlockchain; +import org.hyperledger.besu.ethereum.core.BlobTestFixture; +import org.hyperledger.besu.ethereum.core.Transaction; +import org.hyperledger.besu.ethereum.core.TransactionTestFixture; +import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool; +import org.hyperledger.besu.plugin.services.rpc.RpcResponseType; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.function.Supplier; + +import com.google.common.base.Suppliers; +import io.vertx.core.Vertx; +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; +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; +import org.mockito.junit.jupiter.MockitoSettings; +import org.mockito.quality.Strictness; + +@ExtendWith(MockitoExtension.class) +@MockitoSettings(strictness = Strictness.LENIENT) +public class EngineGetBlobsV1Test { + + private static final Supplier SIGNATURE_ALGORITHM = + Suppliers.memoize(SignatureAlgorithmFactory::getInstance); + private static final SECPPrivateKey PRIVATE_KEY1 = + SIGNATURE_ALGORITHM + .get() + .createPrivateKey( + Bytes32.fromHexString( + "8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63")); + private static final KeyPair KEYS1 = + new KeyPair(PRIVATE_KEY1, SIGNATURE_ALGORITHM.get().createPublicKey(PRIVATE_KEY1)); + public static final VersionedHash VERSIONED_HASH_ZERO = new VersionedHash((byte) 1, Hash.ZERO); + + @Mock private ProtocolContext protocolContext; + @Mock private EngineCallListener engineCallListener; + @Mock private MutableBlockchain blockchain; + @Mock private TransactionPool transactionPool; + + private EngineGetBlobsV1 method; + + private static final Vertx vertx = Vertx.vertx(); + + @BeforeEach + public void before() { + when(protocolContext.getBlockchain()).thenReturn(blockchain); + this.method = + spy(new EngineGetBlobsV1(vertx, protocolContext, engineCallListener, transactionPool)); + } + + @Test + public void shouldReturnExpectedMethodName() { + assertThat(method.getName()).isEqualTo("engine_getBlobsV1"); + } + + @Test + public void shouldReturnBlobsAndProofsForKnownVersionedHashesFromMap() { + final Transaction blobTransaction = createBlobTransaction(); + + final BlobsWithCommitments blobsWithCommitments = + blobTransaction.getBlobsWithCommitments().get(); + + mockTransactionPoolMethod(blobsWithCommitments); + + VersionedHash[] versionedHashes = + blobsWithCommitments.getVersionedHashes().toArray(new VersionedHash[0]); + + final JsonRpcResponse jsonRpcResponse = resp(versionedHashes); + + final List blobAndProofV1s = fromSuccessResp(jsonRpcResponse); + + assertThat(blobAndProofV1s.size()).isEqualTo(versionedHashes.length); + // for loop to check each blob and proof + for (int i = 0; i < versionedHashes.length; i++) { + assertThat(Bytes.fromHexString(blobAndProofV1s.get(i).getBlob())) + .isEqualTo(blobsWithCommitments.getBlobQuads().get(i).blob().getData()); + assertThat(Bytes.fromHexString(blobAndProofV1s.get(i).getProof())) + .isEqualTo(blobsWithCommitments.getBlobQuads().get(i).kzgProof().getData()); + } + } + + @Test + public void shouldReturnNullForBlobsAndProofsForUnknownVersionedHashes() { + final Transaction blobTransaction = createBlobTransaction(); + + final BlobsWithCommitments blobsWithCommitments = + blobTransaction.getBlobsWithCommitments().get(); + + mockTransactionPoolMethod(blobsWithCommitments); + + List versionedHashesList = + blobsWithCommitments.getVersionedHashes().stream().toList(); + + final VersionedHash[] hashes = versionedHashesList.toArray(new VersionedHash[0]); + hashes[1] = VERSIONED_HASH_ZERO; + + final JsonRpcResponse jsonRpcResponse = resp(hashes); + + final List blobAndProofV1s = fromSuccessResp(jsonRpcResponse); + + assertThat(blobAndProofV1s.size()).isEqualTo(versionedHashesList.size()); + // for loop to check each blob and proof + for (int i = 0; i < versionedHashesList.size(); i++) { + if (i != 1) { + assertThat(Bytes.fromHexString(blobAndProofV1s.get(i).getBlob())) + .isEqualTo(blobsWithCommitments.getBlobQuads().get(i).blob().getData()); + assertThat(Bytes.fromHexString(blobAndProofV1s.get(i).getProof())) + .isEqualTo(blobsWithCommitments.getBlobQuads().get(i).kzgProof().getData()); + } else { + assertThat(blobAndProofV1s.get(i)).isNull(); + } + } + } + + @Test + public void shouldReturnOnlyNullsForBlobsAndProofsIfAllVersionedHashesUnknown() { + final Transaction blobTransaction = createBlobTransaction(); + + final BlobsWithCommitments blobsWithCommitments = + blobTransaction.getBlobsWithCommitments().get(); + + mockTransactionPoolMethod(blobsWithCommitments); + + List versionedHashesList = + blobsWithCommitments.getVersionedHashes().stream().toList(); + + final VersionedHash[] versionedHashes = new VersionedHash[6]; + Arrays.fill(versionedHashes, VERSIONED_HASH_ZERO); + final JsonRpcResponse jsonRpcResponse = resp(versionedHashes); + + final List blobAndProofV1s = fromSuccessResp(jsonRpcResponse); + + assertThat(blobAndProofV1s.size()).isEqualTo(versionedHashesList.size()); + // for loop to check each blob and proof + for (int i = 0; i < versionedHashes.length; i++) { + assertThat(blobAndProofV1s.get(i)).isNull(); + } + } + + @Test + public void shouldReturnEmptyResponseForEmptyRequest() { + final VersionedHash[] versionedHashes = new VersionedHash[0]; + + final JsonRpcResponse jsonRpcResponse = resp(versionedHashes); + + assertThat(fromSuccessResp(jsonRpcResponse).size()).isEqualTo(0); + } + + @Test + public void shouldFailWhenRequestingMoreThan128() { + final VersionedHash[] versionedHashes = new VersionedHash[129]; + for (int i = 0; i < 129; i++) { + versionedHashes[i] = new VersionedHash((byte) 1, Hash.ZERO); + } + + final JsonRpcResponse jsonRpcResponse = resp(versionedHashes); + + assertThat(fromErrorResp(jsonRpcResponse).getCode()) + .isEqualTo(RpcErrorType.INVALID_ENGINE_GET_BLOBS_V1_TOO_LARGE_REQUEST.getCode()); + assertThat(fromErrorResp(jsonRpcResponse).getMessage()) + .isEqualTo(RpcErrorType.INVALID_ENGINE_GET_BLOBS_V1_TOO_LARGE_REQUEST.getMessage()); + } + + Transaction createBlobTransaction() { + BlobTestFixture blobTestFixture = new BlobTestFixture(); + BlobsWithCommitments bwc = blobTestFixture.createBlobsWithCommitments(6); + TransactionTestFixture ttf = new TransactionTestFixture(); + Transaction fullOfBlobs = + ttf.to(Optional.of(Address.ZERO)) + .type(TransactionType.BLOB) + .chainId(Optional.of(BigInteger.valueOf(42))) + .gasLimit(21000) + .maxFeePerGas(Optional.of(Wei.of(15))) + .maxFeePerBlobGas(Optional.of(Wei.of(128))) + .maxPriorityFeePerGas(Optional.of(Wei.of(1))) + .versionedHashes(Optional.of(bwc.getVersionedHashes())) + .blobsWithCommitments(Optional.of(bwc)) + .createTransaction(KEYS1); + return fullOfBlobs; + } + + private void mockTransactionPoolMethod(final BlobsWithCommitments blobsWithCommitments) { + blobsWithCommitments + .getBlobQuads() + .forEach( + blobQuad -> + when(transactionPool.getBlobQuad(blobQuad.versionedHash())).thenReturn(blobQuad)); + } + + private JsonRpcResponse resp(final VersionedHash[] versionedHashes) { + return method.response( + new JsonRpcRequestContext( + new JsonRpcRequest( + "2.0", + RpcMethod.ENGINE_GET_BLOBS_V1.getMethodName(), + new Object[] {versionedHashes}))); + } + + @SuppressWarnings({"unchecked", "rawtypes"}) + private List fromSuccessResp(final JsonRpcResponse resp) { + assertThat(resp.getType()).isEqualTo(RpcResponseType.SUCCESS); + final List list = + Optional.of(resp) + .map(JsonRpcSuccessResponse.class::cast) + .map(JsonRpcSuccessResponse::getResult) + .map(List.class::cast) + .get(); + final ArrayList blobAndProofV1s = new ArrayList<>(); + list.forEach(obj -> blobAndProofV1s.add((BlobAndProofV1) obj)); + return blobAndProofV1s; + } + + private RpcErrorType fromErrorResp(final JsonRpcResponse resp) { + assertThat(resp.getType()).isEqualTo(RpcResponseType.ERROR); + return Optional.of(resp) + .map(JsonRpcErrorResponse.class::cast) + .map(JsonRpcErrorResponse::getErrorType) + .get(); + } +} 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 946d4ab09d..88a39925b9 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 @@ -63,6 +63,7 @@ import org.hyperledger.besu.ethereum.core.TransactionTestFixture; import org.hyperledger.besu.ethereum.core.Withdrawal; import org.hyperledger.besu.ethereum.eth.manager.EthContext; import org.hyperledger.besu.ethereum.eth.manager.EthScheduler; +import org.hyperledger.besu.ethereum.eth.transactions.BlobCache; import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration; import org.hyperledger.besu.ethereum.eth.transactions.TransactionBroadcaster; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool; @@ -419,7 +420,8 @@ abstract class AbstractBlockCreatorTest { mock(TransactionBroadcaster.class), ethContext, new TransactionPoolMetrics(new NoOpMetricsSystem()), - poolConf); + poolConf, + new BlobCache()); transactionPool.setEnabled(); final MiningParameters miningParameters = diff --git a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/LegacyFeeMarketBlockTransactionSelectorTest.java b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/LegacyFeeMarketBlockTransactionSelectorTest.java index 416e5fd234..940d076bbc 100644 --- a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/LegacyFeeMarketBlockTransactionSelectorTest.java +++ b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/LegacyFeeMarketBlockTransactionSelectorTest.java @@ -25,6 +25,7 @@ import org.hyperledger.besu.ethereum.chain.BadBlockManager; import org.hyperledger.besu.ethereum.core.MiningParameters; import org.hyperledger.besu.ethereum.core.PrivacyParameters; import org.hyperledger.besu.ethereum.eth.manager.EthContext; +import org.hyperledger.besu.ethereum.eth.transactions.BlobCache; import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration; import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions; import org.hyperledger.besu.ethereum.eth.transactions.TransactionBroadcaster; @@ -94,7 +95,8 @@ public class LegacyFeeMarketBlockTransactionSelectorTest mock(TransactionBroadcaster.class), ethContext, new TransactionPoolMetrics(metricsSystem), - poolConf); + poolConf, + new BlobCache()); transactionPool.setEnabled(); return transactionPool; } diff --git a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/LondonFeeMarketBlockTransactionSelectorTest.java b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/LondonFeeMarketBlockTransactionSelectorTest.java index a59841d4f4..68d9a71de6 100644 --- a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/LondonFeeMarketBlockTransactionSelectorTest.java +++ b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/LondonFeeMarketBlockTransactionSelectorTest.java @@ -31,6 +31,7 @@ import org.hyperledger.besu.ethereum.core.MiningParameters; import org.hyperledger.besu.ethereum.core.PrivacyParameters; import org.hyperledger.besu.ethereum.core.ProcessableBlockHeader; import org.hyperledger.besu.ethereum.core.Transaction; +import org.hyperledger.besu.ethereum.eth.transactions.BlobCache; import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration; import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions; import org.hyperledger.besu.ethereum.eth.transactions.TransactionBroadcaster; @@ -101,7 +102,8 @@ public class LondonFeeMarketBlockTransactionSelectorTest mock(TransactionBroadcaster.class), ethContext, new TransactionPoolMetrics(metricsSystem), - poolConf); + poolConf, + new BlobCache()); transactionPool.setEnabled(); return transactionPool; } diff --git a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/PoWBlockCreatorTest.java b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/PoWBlockCreatorTest.java index 7e3c01200c..e9e727d99c 100644 --- a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/PoWBlockCreatorTest.java +++ b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/PoWBlockCreatorTest.java @@ -39,6 +39,7 @@ import org.hyperledger.besu.ethereum.core.PrivacyParameters; import org.hyperledger.besu.ethereum.core.ProcessableBlockHeader; import org.hyperledger.besu.ethereum.difficulty.fixed.FixedDifficultyCalculators; import org.hyperledger.besu.ethereum.eth.manager.EthContext; +import org.hyperledger.besu.ethereum.eth.transactions.BlobCache; import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration; import org.hyperledger.besu.ethereum.eth.transactions.TransactionBroadcaster; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool; @@ -371,7 +372,8 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest { mock(TransactionBroadcaster.class), ethContext, new TransactionPoolMetrics(metricsSystem), - poolConf); + poolConf, + new BlobCache()); transactionPool.setEnabled(); return transactionPool; diff --git a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/PoWMinerExecutorTest.java b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/PoWMinerExecutorTest.java index 6859409d49..8c1e217d75 100644 --- a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/PoWMinerExecutorTest.java +++ b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/PoWMinerExecutorTest.java @@ -25,6 +25,7 @@ import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.MiningParameters; import org.hyperledger.besu.ethereum.eth.manager.EthContext; import org.hyperledger.besu.ethereum.eth.manager.EthScheduler; +import org.hyperledger.besu.ethereum.eth.transactions.BlobCache; import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration; import org.hyperledger.besu.ethereum.eth.transactions.TransactionBroadcaster; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool; @@ -117,7 +118,8 @@ public class PoWMinerExecutorTest { mock(TransactionBroadcaster.class), ethContext, new TransactionPoolMetrics(new NoOpMetricsSystem()), - poolConf); + poolConf, + new BlobCache()); transactionPool.setEnabled(); return transactionPool; diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/AbstractIsolationTests.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/AbstractIsolationTests.java index 388a112699..939e3ec0cd 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/AbstractIsolationTests.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/AbstractIsolationTests.java @@ -181,7 +181,8 @@ public abstract class AbstractIsolationTests { mock(TransactionBroadcaster.class), ethContext, txPoolMetrics, - poolConfiguration); + poolConfiguration, + new BlobCache()); transactionPool.setEnabled(); } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/BlobCache.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/BlobCache.java index 50cc23977c..3d3a435f1f 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/BlobCache.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/BlobCache.java @@ -87,4 +87,8 @@ public class BlobCache { return Optional.empty(); } } + + public BlobsWithCommitments.BlobQuad get(final VersionedHash vh) { + return cache.getIfPresent(vh); + } } 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 6bb2029960..315f82921b 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 @@ -20,8 +20,10 @@ import static org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason import static org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason.TRANSACTION_ALREADY_KNOWN; import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.datatypes.BlobsWithCommitments; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.TransactionType; +import org.hyperledger.besu.datatypes.VersionedHash; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.chain.BlockAddedEvent; @@ -55,6 +57,7 @@ import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; +import java.util.HashMap; import java.util.IntSummaryStatistics; import java.util.List; import java.util.Map; @@ -89,6 +92,7 @@ public class TransactionPool implements BlockAddedObserver { private static final Logger LOG = LoggerFactory.getLogger(TransactionPool.class); private static final Logger LOG_FOR_REPLAY = LoggerFactory.getLogger("LOG_FOR_REPLAY"); private final Supplier pendingTransactionsSupplier; + private final BlobCache cacheForBlobsOfTransactionsAddedToABlock; private volatile PendingTransactions pendingTransactions = new DisabledPendingTransactions(); private final ProtocolSchedule protocolSchedule; private final ProtocolContext protocolContext; @@ -103,6 +107,8 @@ 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<>(); public TransactionPool( final Supplier pendingTransactionsSupplier, @@ -111,7 +117,8 @@ public class TransactionPool implements BlockAddedObserver { final TransactionBroadcaster transactionBroadcaster, final EthContext ethContext, final TransactionPoolMetrics metrics, - final TransactionPoolConfiguration configuration) { + final TransactionPoolConfiguration configuration, + final BlobCache blobCache) { this.pendingTransactionsSupplier = pendingTransactionsSupplier; this.protocolSchedule = protocolSchedule; this.protocolContext = protocolContext; @@ -121,7 +128,10 @@ public class TransactionPool implements BlockAddedObserver { this.configuration = configuration; this.blockAddedEventOrderedProcessor = ethContext.getScheduler().createOrderedProcessor(this::processBlockAddedEvent); + this.cacheForBlobsOfTransactionsAddedToABlock = blobCache; initLogForReplay(); + subscribePendingTransactions(this::mapBlobsOnTransactionAdded); + subscribeDroppedTransactions(this::unmapBlobsOnTransactionDropped); } private void initLogForReplay() { @@ -640,6 +650,38 @@ public class TransactionPool implements BlockAddedObserver { return CompletableFuture.completedFuture(null); } + private void mapBlobsOnTransactionAdded( + final org.hyperledger.besu.datatypes.Transaction transaction) { + final Optional maybeBlobsWithCommitments = + transaction.getBlobsWithCommitments(); + if (maybeBlobsWithCommitments.isEmpty()) { + return; + } + final List blobQuads = + maybeBlobsWithCommitments.get().getBlobQuads(); + blobQuads.forEach(bq -> mapOfBlobsInTransactionPool.put(bq.versionedHash(), bq)); + } + + private void unmapBlobsOnTransactionDropped( + final org.hyperledger.besu.datatypes.Transaction transaction) { + final Optional maybeBlobsWithCommitments = + transaction.getBlobsWithCommitments(); + if (maybeBlobsWithCommitments.isEmpty()) { + return; + } + final List blobQuads = + maybeBlobsWithCommitments.get().getBlobQuads(); + blobQuads.forEach(bq -> mapOfBlobsInTransactionPool.remove(bq.versionedHash())); + } + + public BlobsWithCommitments.BlobQuad getBlobQuad(final VersionedHash vh) { + BlobsWithCommitments.BlobQuad blobQuad = mapOfBlobsInTransactionPool.get(vh); + if (blobQuad == null) { + blobQuad = cacheForBlobsOfTransactionsAddedToABlock.get(vh); + } + return blobQuad; + } + public boolean isEnabled() { return isPoolEnabled.get(); } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolFactory.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolFactory.java index d32b7bafe8..79b1298d27 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolFactory.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolFactory.java @@ -118,7 +118,8 @@ public class TransactionPoolFactory { newPooledTransactionHashesMessageSender), ethContext, metrics, - transactionPoolConfiguration); + transactionPoolConfiguration, + blobCache); final TransactionsMessageHandler transactionsMessageHandler = new TransactionsMessageHandler( 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 cd780c2dc9..e5ec06fd35 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 @@ -293,7 +293,8 @@ public abstract class AbstractTransactionPoolTest { transactionBroadcaster, ethContext, new TransactionPoolMetrics(metricsSystem), - poolConfig); + poolConfig, + new BlobCache()); txPool.setEnabled(); return txPool; } From 8eee5698878af80a543362d136a01c51099d48d6 Mon Sep 17 00:00:00 2001 From: daniellehrner Date: Fri, 6 Sep 2024 12:04:41 +0200 Subject: [PATCH 194/259] 7702 for devenet-3 (#7444) * wrapped WorldUpdater into `EVMWorldupdater` to remove the authority code injection from the implementation of the actual world updaters Signed-off-by: Daniel Lehrner * add CHANGELOG entry Signed-off-by: Daniel Lehrner * first draft for 7702 v2 Signed-off-by: Daniel Lehrner * change return value of DelegatedCodeGasCostHelper Signed-off-by: Daniel Lehrner * fix upfront gas cost calculation, fix setting code multiple times in MutableDelegatedCodeAccount Signed-off-by: Daniel Lehrner * fix gas refund for delegated code when account already exists, added gas cost deduction for code delegation resolution to ExtCodeSizeOperation Signed-off-by: Daniel Lehrner * allow accounts with delegated code to send transactions Signed-off-by: Daniel Lehrner * add refund for already existing account after nonce check Signed-off-by: Daniel Lehrner * resolve delegated code only the first time to avoid delegation loops Signed-off-by: Daniel Lehrner * handle invalid authorization signatures properly Signed-off-by: Daniel Lehrner * refactored CodeDelegationProcessor to compute authorizer of a code delegation after the chain id check Signed-off-by: Daniel Lehrner * fix canSetDelegatedCode method by checking code how it is in the trie and not the resolved code Signed-off-by: Daniel Lehrner * optimize code hash calculation for empty code, fix check for empty code delegation list Signed-off-by: Daniel Lehrner * check the all code delegation signatures hava a valid s value Signed-off-by: Daniel Lehrner * rename encoder & decoder, handle invalid signature values in T8nExecutor Signed-off-by: Daniel Lehrner * create the signatures for code delegation authorizations in T8nExecutor without checking if they are valid to test them later during the tx execution Signed-off-by: Daniel Lehrner * check that recid is either 0 or 1 Signed-off-by: Daniel Lehrner * fixed acceptance tests, renamed the the remaining instances of set code to code delegation Signed-off-by: Daniel Lehrner * fix delegate encoder & encoder unit tests Signed-off-by: Daniel Lehrner * spotless Signed-off-by: Daniel Lehrner * changed empty check for delegated accounts, fixed test Signed-off-by: Daniel Lehrner * fix hasDelegatedCode method when code is null Signed-off-by: Daniel Lehrner * run acceptance tests without deamon Signed-off-by: Daniel Lehrner * disable CodeDelegationTransactionAcceptanceTest to check if it is causing the stuck ci pipeline Signed-off-by: Daniel Lehrner * check if shouldTransferAllEthOfAuthorizerToSponsor is causing pipeline to stall Signed-off-by: Daniel Lehrner * check if shouldCheckNonceAfterNonceIncreaseOfSender is causing pipeline to stall Signed-off-by: Daniel Lehrner * check if closing the cluster after every test is causing pipeline to stall Signed-off-by: Daniel Lehrner * spotless Signed-off-by: Daniel Lehrner --------- Signed-off-by: Daniel Lehrner Co-authored-by: Danno Ferrin --- ...eDelegationTransactionAcceptanceTest.java} | 66 +++++---- .../options/TransactionPoolOptionsTest.java | 2 +- .../besu/crypto/SECPSignature.java | 2 +- ...Authorization.java => CodeDelegation.java} | 15 +- .../besu/datatypes/Transaction.java | 8 +- .../besu/datatypes/TransactionType.java | 19 ++- .../results/TransactionCompleteResult.java | 10 +- ...Authorization.java => CodeDelegation.java} | 82 ++++++----- .../besu/ethereum/core/Transaction.java | 63 ++++---- ...ncoder.java => CodeDelegationEncoder.java} | 32 ++--- ... => CodeDelegationTransactionDecoder.java} | 43 ++---- .../core/encoding/TransactionDecoder.java | 4 +- .../core/encoding/TransactionEncoder.java | 4 +- .../ethereum/mainnet/AuthorityProcessor.java | 88 ------------ .../mainnet/CodeDelegationProcessor.java | 134 ++++++++++++++++++ .../mainnet/CodeDelegationResult.java | 41 ++++++ .../mainnet/MainnetProtocolSpecs.java | 4 +- .../mainnet/MainnetTransactionProcessor.java | 50 ++++--- .../mainnet/MainnetTransactionValidator.java | 51 ++++++- .../transaction/TransactionInvalidReason.java | 1 + .../ethereum/core/BlockDataGenerator.java | 2 +- .../ethereum/core/TransactionTestFixture.java | 2 +- ...st.java => CodeDelegationDecoderTest.java} | 44 ++---- ...st.java => CodeDelegationEncoderTest.java} | 41 +++--- .../MainnetTransactionProcessorTest.java | 2 +- .../eth/transactions/PendingTransaction.java | 2 +- .../layered/BaseTransactionPoolTest.java | 2 +- .../eth/transactions/layered/LayersTest.java | 2 +- .../hyperledger/besu/evmtool/T8nExecutor.java | 45 ++---- .../hyperledger/besu/evm/account/Account.java | 31 ++++ .../evm/account/BaseDelegatedCodeAccount.java | 92 ++++++++++++ ...Account.java => DelegatedCodeAccount.java} | 56 +++++--- ....java => MutableDelegatedCodeAccount.java} | 59 +++++--- .../besu/evm/gascalculator/GasCalculator.java | 27 +++- .../gascalculator/PragueGasCalculator.java | 25 ++-- .../evm/operation/AbstractCallOperation.java | 11 ++ .../operation/AbstractExtCallOperation.java | 13 ++ .../evm/operation/ExtCodeCopyOperation.java | 12 ++ .../evm/operation/ExtCodeHashOperation.java | 40 ++++-- .../evm/operation/ExtCodeSizeOperation.java | 13 ++ .../evm/worldstate/AuthorizedCodeService.java | 116 --------------- .../DelegatedCodeGasCostHelper.java | 80 +++++++++++ .../evm/worldstate/DelegatedCodeService.java | 97 +++++++++++++ .../besu/evm/worldstate/EVMWorldUpdater.java | 34 +++-- 44 files changed, 999 insertions(+), 568 deletions(-) rename acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/ethereum/{SetCodeTransactionAcceptanceTest.java => CodeDelegationTransactionAcceptanceTest.java} (76%) rename datatypes/src/main/java/org/hyperledger/besu/datatypes/{SetCodeAuthorization.java => CodeDelegation.java} (82%) rename ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/{SetCodeAuthorization.java => CodeDelegation.java} (76%) rename ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/{SetCodeTransactionEncoder.java => CodeDelegationEncoder.java} (75%) rename ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/{SetCodeTransactionDecoder.java => CodeDelegationTransactionDecoder.java} (73%) delete mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/AuthorityProcessor.java create mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/CodeDelegationProcessor.java create mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/CodeDelegationResult.java rename ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/{SetCodeTransactionDecoderTest.java => CodeDelegationDecoderTest.java} (67%) rename ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/{SetCodeTransactionEncoderTest.java => CodeDelegationEncoderTest.java} (75%) create mode 100644 evm/src/main/java/org/hyperledger/besu/evm/account/BaseDelegatedCodeAccount.java rename evm/src/main/java/org/hyperledger/besu/evm/account/{AuthorizedCodeAccount.java => DelegatedCodeAccount.java} (64%) rename evm/src/main/java/org/hyperledger/besu/evm/account/{MutableAuthorizedCodeAccount.java => MutableDelegatedCodeAccount.java} (69%) delete mode 100644 evm/src/main/java/org/hyperledger/besu/evm/worldstate/AuthorizedCodeService.java create mode 100644 evm/src/main/java/org/hyperledger/besu/evm/worldstate/DelegatedCodeGasCostHelper.java create mode 100644 evm/src/main/java/org/hyperledger/besu/evm/worldstate/DelegatedCodeService.java diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/ethereum/SetCodeTransactionAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/ethereum/CodeDelegationTransactionAcceptanceTest.java similarity index 76% rename from acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/ethereum/SetCodeTransactionAcceptanceTest.java rename to acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/ethereum/CodeDelegationTransactionAcceptanceTest.java index b134b1f5c0..6000915b44 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/ethereum/SetCodeTransactionAcceptanceTest.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/ethereum/CodeDelegationTransactionAcceptanceTest.java @@ -18,9 +18,9 @@ import static org.assertj.core.api.Assertions.assertThat; import org.hyperledger.besu.crypto.SECP256K1; import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.datatypes.CodeDelegation; import org.hyperledger.besu.datatypes.TransactionType; import org.hyperledger.besu.datatypes.Wei; -import org.hyperledger.besu.ethereum.core.SetCodeAuthorization; import org.hyperledger.besu.ethereum.core.Transaction; import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBase; import org.hyperledger.besu.tests.acceptance.dsl.account.Account; @@ -39,7 +39,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.web3j.protocol.core.methods.response.TransactionReceipt; -public class SetCodeTransactionAcceptanceTest extends AcceptanceTestBase { +public class CodeDelegationTransactionAcceptanceTest extends AcceptanceTestBase { private static final String GENESIS_FILE = "/dev/dev_prague.json"; private static final SECP256K1 secp256k1 = new SECP256K1(); @@ -74,7 +74,6 @@ public class SetCodeTransactionAcceptanceTest extends AcceptanceTestBase { @AfterEach void tearDown() { besuNode.close(); - cluster.close(); } /** @@ -88,17 +87,18 @@ public class SetCodeTransactionAcceptanceTest extends AcceptanceTestBase { public void shouldTransferAllEthOfAuthorizerToSponsor() throws IOException { // 7702 transaction - final org.hyperledger.besu.datatypes.SetCodeAuthorization authorization = - SetCodeAuthorization.builder() + final CodeDelegation authorization = + org.hyperledger.besu.ethereum.core.CodeDelegation.builder() .chainId(BigInteger.valueOf(20211)) .address(SEND_ALL_ETH_CONTRACT_ADDRESS) + .nonce(0) .signAndBuild( secp256k1.createKeyPair( secp256k1.createPrivateKey(AUTHORIZER_PRIVATE_KEY.toUnsignedBigInteger()))); final Transaction tx = Transaction.builder() - .type(TransactionType.SET_CODE) + .type(TransactionType.DELEGATE_CODE) .chainId(BigInteger.valueOf(20211)) .nonce(0) .maxPriorityFeePerGas(Wei.of(1000000000)) @@ -108,7 +108,7 @@ public class SetCodeTransactionAcceptanceTest extends AcceptanceTestBase { .value(Wei.ZERO) .payload(Bytes32.leftPad(Bytes.fromHexString(transactionSponsor.getAddress()))) .accessList(List.of()) - .setCodeTransactionPayloads(List.of(authorization)) + .codeDelegations(List.of(authorization)) .signAndBuild( secp256k1.createKeyPair( secp256k1.createPrivateKey( @@ -134,22 +134,21 @@ public class SetCodeTransactionAcceptanceTest extends AcceptanceTestBase { /** * The authorizer creates an authorization for a contract that sends all its ETH to any given - * address. But the nonce is 1 and the authorization list is processed before the nonce increase - * of the sender. Therefore, the authorization should be invalid and will be ignored. No balance - * change, except for a decrease for paying the transaction cost should occur. + * address. The nonce is 1 and the authorization list is processed after the nonce increase of the + * sender. Therefore, the authorization should be valid. The authorizer balance should be 0 and + * the transaction sponsor's * balance should be 180000 ETH minus the transaction costs. */ @Test - public void shouldCheckNonceBeforeNonceIncreaseOfSender() throws IOException { - + public void shouldCheckNonceAfterNonceIncreaseOfSender() throws IOException { + final long GAS_LIMIT = 1000000L; cluster.verify(authorizer.balanceEquals(Amount.ether(90000))); - final org.hyperledger.besu.datatypes.SetCodeAuthorization authorization = - SetCodeAuthorization.builder() + final CodeDelegation authorization = + org.hyperledger.besu.ethereum.core.CodeDelegation.builder() .chainId(BigInteger.valueOf(20211)) - .nonces( - Optional.of( - 1L)) // nonce is 1, but because it is validated before the nonce increase, it - // should be 0 + .nonce( + 1L) // nonce is 1, but because it is validated before the nonce increase, it should + // be 0 .address(SEND_ALL_ETH_CONTRACT_ADDRESS) .signAndBuild( secp256k1.createKeyPair( @@ -157,17 +156,17 @@ public class SetCodeTransactionAcceptanceTest extends AcceptanceTestBase { final Transaction tx = Transaction.builder() - .type(TransactionType.SET_CODE) + .type(TransactionType.DELEGATE_CODE) .chainId(BigInteger.valueOf(20211)) .nonce(0) .maxPriorityFeePerGas(Wei.of(1000000000)) .maxFeePerGas(Wei.fromHexString("0x02540BE400")) - .gasLimit(1000000) + .gasLimit(GAS_LIMIT) .to(Address.fromHexStringStrict(authorizer.getAddress())) .value(Wei.ZERO) .payload(Bytes32.leftPad(Bytes.fromHexString(otherAccount.getAddress()))) .accessList(List.of()) - .setCodeTransactionPayloads(List.of(authorization)) + .codeDelegations(List.of(authorization)) .signAndBuild( secp256k1.createKeyPair( secp256k1.createPrivateKey(AUTHORIZER_PRIVATE_KEY.toUnsignedBigInteger()))); @@ -180,14 +179,25 @@ public class SetCodeTransactionAcceptanceTest extends AcceptanceTestBase { besuNode.execute(ethTransactions.getTransactionReceipt(txHash)); assertThat(maybeTransactionReceipt).isPresent(); - // verify that the balance of the other account has not changed - cluster.verify(otherAccount.balanceEquals(0)); - final String gasPriceWithout0x = maybeTransactionReceipt.get().getEffectiveGasPrice().substring(2); - final BigInteger txCost = - maybeTransactionReceipt.get().getGasUsed().multiply(new BigInteger(gasPriceWithout0x, 16)); - BigInteger expectedSenderBalance = new BigInteger("90000000000000000000000").subtract(txCost); - cluster.verify(authorizer.balanceEquals(Amount.wei(expectedSenderBalance))); + final BigInteger gasPrice = new BigInteger(gasPriceWithout0x, 16); + final BigInteger txCost = maybeTransactionReceipt.get().getGasUsed().multiply(gasPrice); + + final BigInteger authorizerBalance = besuNode.execute(ethTransactions.getBalance(authorizer)); + + // The remaining balance of the authorizer should the gas limit multiplied by the gas price + // minus the transaction cost. + // The following executes this calculation in reverse. + assertThat(GAS_LIMIT).isEqualTo(authorizerBalance.add(txCost).divide(gasPrice).longValue()); + + // The other accounts balance should be the initial 9000 ETH balance from the authorizer minus + // the remaining balance of the authorizer and minus the transaction cost + cluster.verify( + otherAccount.balanceEquals( + Amount.wei( + new BigInteger("90000000000000000000000") + .subtract(authorizerBalance) + .subtract(txCost)))); } } diff --git a/besu/src/test/java/org/hyperledger/besu/cli/options/TransactionPoolOptionsTest.java b/besu/src/test/java/org/hyperledger/besu/cli/options/TransactionPoolOptionsTest.java index 8d23e7794a..eb48a3f2a5 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/options/TransactionPoolOptionsTest.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/options/TransactionPoolOptionsTest.java @@ -413,7 +413,7 @@ public class TransactionPoolOptionsTest @Test public void maxPrioritizedTxsPerTypeWrongTxType() { internalTestFailure( - "Invalid value for option '--tx-pool-max-prioritized-by-type' (MAP): expected one of [FRONTIER, ACCESS_LIST, EIP1559, BLOB, SET_CODE] (case-insensitive) but was 'WRONG_TYPE'", + "Invalid value for option '--tx-pool-max-prioritized-by-type' (MAP): expected one of [FRONTIER, ACCESS_LIST, EIP1559, BLOB, DELEGATE_CODE] (case-insensitive) but was 'WRONG_TYPE'", "--tx-pool-max-prioritized-by-type", "WRONG_TYPE=1"); } diff --git a/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/SECPSignature.java b/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/SECPSignature.java index 96f3ca6a93..5524faac3f 100644 --- a/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/SECPSignature.java +++ b/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/SECPSignature.java @@ -54,7 +54,7 @@ public class SECPSignature { * @param s the s * @param recId the rec id */ - SECPSignature(final BigInteger r, final BigInteger s, final byte recId) { + public SECPSignature(final BigInteger r, final BigInteger s, final byte recId) { this.r = r; this.s = s; this.recId = recId; diff --git a/datatypes/src/main/java/org/hyperledger/besu/datatypes/SetCodeAuthorization.java b/datatypes/src/main/java/org/hyperledger/besu/datatypes/CodeDelegation.java similarity index 82% rename from datatypes/src/main/java/org/hyperledger/besu/datatypes/SetCodeAuthorization.java rename to datatypes/src/main/java/org/hyperledger/besu/datatypes/CodeDelegation.java index b12e65de41..7b9e3d7d44 100644 --- a/datatypes/src/main/java/org/hyperledger/besu/datatypes/SetCodeAuthorization.java +++ b/datatypes/src/main/java/org/hyperledger/besu/datatypes/CodeDelegation.java @@ -20,10 +20,13 @@ import java.math.BigInteger; import java.util.Optional; /** - * SetCodeAuthorization is a data structure that represents the authorization to set code on a EOA - * account. + * CodeDelegation is a data structure that represents the authorization to delegate code of an EOA + * account to another account. */ -public interface SetCodeAuthorization { +public interface CodeDelegation { + /** The cost of delegating code on an existing account. */ + long PER_AUTH_BASE_COST = 2_500L; + /** * Return the chain id. * @@ -53,11 +56,11 @@ public interface SetCodeAuthorization { Optional
authorizer(); /** - * Return a valid nonce or empty otherwise. A nonce is valid if the size of the list is exactly 1 + * Return the nonce * - * @return all the optional nonce + * @return the nonce */ - Optional nonce(); + long nonce(); /** * Return the recovery id. diff --git a/datatypes/src/main/java/org/hyperledger/besu/datatypes/Transaction.java b/datatypes/src/main/java/org/hyperledger/besu/datatypes/Transaction.java index d6751852bc..e614901300 100644 --- a/datatypes/src/main/java/org/hyperledger/besu/datatypes/Transaction.java +++ b/datatypes/src/main/java/org/hyperledger/besu/datatypes/Transaction.java @@ -236,16 +236,16 @@ public interface Transaction { int getSize(); /** - * Returns the set code transaction payload if this transaction is a 7702 transaction. + * Returns the code delegations if this transaction is a 7702 transaction. * - * @return the set code transaction payloads + * @return the code delegations */ - Optional> getAuthorizationList(); + Optional> getCodeDelegationList(); /** * Returns the size of the authorization list. * * @return the size of the authorization list */ - int authorizationListSize(); + int codeDelegationListSize(); } diff --git a/datatypes/src/main/java/org/hyperledger/besu/datatypes/TransactionType.java b/datatypes/src/main/java/org/hyperledger/besu/datatypes/TransactionType.java index df4a07193b..bf1d4e7792 100644 --- a/datatypes/src/main/java/org/hyperledger/besu/datatypes/TransactionType.java +++ b/datatypes/src/main/java/org/hyperledger/besu/datatypes/TransactionType.java @@ -29,10 +29,10 @@ public enum TransactionType { /** Blob transaction type. */ BLOB(0x03), /** Eip7702 transaction type. */ - SET_CODE(0x04); + DELEGATE_CODE(0x04); private static final Set ACCESS_LIST_SUPPORTED_TRANSACTION_TYPES = - Set.of(ACCESS_LIST, EIP1559, BLOB, SET_CODE); + Set.of(ACCESS_LIST, EIP1559, BLOB, DELEGATE_CODE); private static final EnumSet LEGACY_FEE_MARKET_TRANSACTION_TYPES = EnumSet.of(TransactionType.FRONTIER, TransactionType.ACCESS_LIST); @@ -86,7 +86,7 @@ public enum TransactionType { TransactionType.ACCESS_LIST, TransactionType.EIP1559, TransactionType.BLOB, - TransactionType.SET_CODE + TransactionType.DELEGATE_CODE }) .filter(transactionType -> transactionType.typeValue == serializedTypeValue) .findFirst() @@ -132,12 +132,21 @@ public enum TransactionType { return this.equals(BLOB); } + /** + * Does transaction type support delegate code. + * + * @return the boolean + */ + public boolean supportsDelegateCode() { + return this.equals(DELEGATE_CODE); + } + /** * Does transaction type require code. * * @return the boolean */ - public boolean requiresSetCode() { - return this.equals(SET_CODE); + public boolean requiresCodeDelegation() { + return this.equals(DELEGATE_CODE); } } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/TransactionCompleteResult.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/TransactionCompleteResult.java index 05b323cacb..e8262021fd 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/TransactionCompleteResult.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/TransactionCompleteResult.java @@ -15,7 +15,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.results; import org.hyperledger.besu.datatypes.AccessListEntry; -import org.hyperledger.besu.datatypes.SetCodeAuthorization; +import org.hyperledger.besu.datatypes.CodeDelegation; import org.hyperledger.besu.datatypes.TransactionType; import org.hyperledger.besu.datatypes.VersionedHash; import org.hyperledger.besu.datatypes.Wei; @@ -94,7 +94,7 @@ public class TransactionCompleteResult implements TransactionResult { private final List versionedHashes; @JsonInclude(JsonInclude.Include.NON_NULL) - private final List authorizationList; + private final List authorizationList; public TransactionCompleteResult(final TransactionWithMetadata tx) { final Transaction transaction = tx.getTransaction(); @@ -131,7 +131,7 @@ public class TransactionCompleteResult implements TransactionResult { this.v = (transactionType == TransactionType.ACCESS_LIST || transactionType == TransactionType.EIP1559) - || transactionType == TransactionType.SET_CODE + || transactionType == TransactionType.DELEGATE_CODE ? Quantity.create(transaction.getYParity()) : null; } @@ -139,7 +139,7 @@ public class TransactionCompleteResult implements TransactionResult { this.r = Quantity.create(transaction.getR()); this.s = Quantity.create(transaction.getS()); this.versionedHashes = transaction.getVersionedHashes().orElse(null); - this.authorizationList = transaction.getAuthorizationList().orElse(null); + this.authorizationList = transaction.getCodeDelegationList().orElse(null); } @JsonGetter(value = "accessList") @@ -255,7 +255,7 @@ public class TransactionCompleteResult implements TransactionResult { } @JsonGetter(value = "authorizationList") - public List getAuthorizationList() { + public List getAuthorizationList() { return authorizationList; } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/SetCodeAuthorization.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/CodeDelegation.java similarity index 76% rename from ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/SetCodeAuthorization.java rename to ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/CodeDelegation.java index ea9cae2fcb..68fa958a8d 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/SetCodeAuthorization.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/CodeDelegation.java @@ -20,11 +20,10 @@ import org.hyperledger.besu.crypto.SignatureAlgorithm; import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.ethereum.core.encoding.SetCodeTransactionEncoder; +import org.hyperledger.besu.ethereum.core.encoding.CodeDelegationEncoder; import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; import java.math.BigInteger; -import java.util.List; import java.util.Optional; import java.util.function.Supplier; @@ -33,7 +32,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.google.common.base.Suppliers; import org.apache.tuweni.bytes.Bytes; -public class SetCodeAuthorization implements org.hyperledger.besu.datatypes.SetCodeAuthorization { +public class CodeDelegation implements org.hyperledger.besu.datatypes.CodeDelegation { private static final Supplier SIGNATURE_ALGORITHM = Suppliers.memoize(SignatureAlgorithmFactory::getInstance); @@ -41,7 +40,7 @@ public class SetCodeAuthorization implements org.hyperledger.besu.datatypes.SetC private final BigInteger chainId; private final Address address; - private final Optional nonce; + private final long nonce; private final SECPSignature signature; private Optional
authorizer = Optional.empty(); private boolean isAuthorityComputed = false; @@ -51,13 +50,13 @@ public class SetCodeAuthorization implements org.hyperledger.besu.datatypes.SetC * * @param chainId can be either the current chain id or zero * @param address the address from which the code will be set into the EOA account - * @param nonce an optional nonce after which this auth expires + * @param nonce the nonce after which this auth expires * @param signature the signature of the EOA account which will be used to set the code */ - public SetCodeAuthorization( + public CodeDelegation( final BigInteger chainId, final Address address, - final Optional nonce, + final long nonce, final SECPSignature signature) { this.chainId = chainId; this.address = address; @@ -66,29 +65,26 @@ public class SetCodeAuthorization implements org.hyperledger.besu.datatypes.SetC } /** - * Create access list entry. + * Create code delegation. * * @param chainId can be either the current chain id or zero * @param address the address from which the code will be set into the EOA account - * @param nonces the list of nonces + * @param nonce the nonce * @param v the recovery id * @param r the r value of the signature * @param s the s value of the signature - * @return SetCodeTransactionEntry + * @return CodeDelegation */ @JsonCreator - public static org.hyperledger.besu.datatypes.SetCodeAuthorization createSetCodeAuthorizationEntry( + public static org.hyperledger.besu.datatypes.CodeDelegation createCodeDelegation( @JsonProperty("chainId") final BigInteger chainId, @JsonProperty("address") final Address address, - @JsonProperty("nonce") final List nonces, + @JsonProperty("nonce") final long nonce, @JsonProperty("v") final byte v, @JsonProperty("r") final BigInteger r, @JsonProperty("s") final BigInteger s) { - return new SetCodeAuthorization( - chainId, - address, - Optional.ofNullable(nonces.get(0)), - SIGNATURE_ALGORITHM.get().createSignature(r, s, v)); + return new CodeDelegation( + chainId, address, nonce, SIGNATURE_ALGORITHM.get().createSignature(r, s, v)); } @JsonProperty("chainId") @@ -120,7 +116,7 @@ public class SetCodeAuthorization implements org.hyperledger.besu.datatypes.SetC } @Override - public Optional nonce() { + public long nonce() { return nonce; } @@ -144,30 +140,38 @@ public class SetCodeAuthorization implements org.hyperledger.besu.datatypes.SetC private Optional
computeAuthority() { BytesValueRLPOutput rlpOutput = new BytesValueRLPOutput(); - SetCodeTransactionEncoder.encodeSingleSetCodeWithoutSignature(this, rlpOutput); + CodeDelegationEncoder.encodeSingleCodeDelegationWithoutSignature(this, rlpOutput); final Hash hash = Hash.hash(Bytes.concatenate(MAGIC, rlpOutput.encoded())); - return SIGNATURE_ALGORITHM - .get() - .recoverPublicKeyFromSignature(hash, signature) - .map(Address::extract); + Optional
authorityAddress; + try { + authorityAddress = + SIGNATURE_ALGORITHM + .get() + .recoverPublicKeyFromSignature(hash, signature) + .map(Address::extract); + } catch (final IllegalArgumentException e) { + authorityAddress = Optional.empty(); + } + + return authorityAddress; } /** - * Create set code authorization with a builder. + * Create a code delegation authorization with a builder. * - * @return SetCodeAuthorization.Builder + * @return CodeDelegation.Builder */ public static Builder builder() { return new Builder(); } - /** Builder for SetCodeAuthorization. */ + /** Builder for CodeDelegation authorizations. */ public static class Builder { private BigInteger chainId = BigInteger.ZERO; private Address address; - private Optional nonce = Optional.empty(); + private Long nonce; private SECPSignature signature; /** Create a new builder. */ @@ -196,12 +200,12 @@ public class SetCodeAuthorization implements org.hyperledger.besu.datatypes.SetC } /** - * Set the optional nonce. + * Set the nonce. * - * @param nonce the optional nonce. + * @param nonce the nonce. * @return this builder */ - public Builder nonces(final Optional nonce) { + public Builder nonce(final long nonce) { this.nonce = nonce; return this; } @@ -221,16 +225,14 @@ public class SetCodeAuthorization implements org.hyperledger.besu.datatypes.SetC * Sign the authorization with the given key pair and return the authorization. * * @param keyPair the key pair - * @return SetCodeAuthorization + * @return CodeDelegation */ - public org.hyperledger.besu.datatypes.SetCodeAuthorization signAndBuild(final KeyPair keyPair) { + public org.hyperledger.besu.datatypes.CodeDelegation signAndBuild(final KeyPair keyPair) { final BytesValueRLPOutput output = new BytesValueRLPOutput(); output.startList(); output.writeBigIntegerScalar(chainId); output.writeBytes(address); - output.startList(); - nonce.ifPresent(output::writeLongScalar); - output.endList(); + output.writeLongScalar(nonce); output.endList(); signature( @@ -243,18 +245,22 @@ public class SetCodeAuthorization implements org.hyperledger.besu.datatypes.SetC /** * Build the authorization. * - * @return SetCodeAuthorization + * @return CodeDelegation */ - public org.hyperledger.besu.datatypes.SetCodeAuthorization build() { + public org.hyperledger.besu.datatypes.CodeDelegation build() { if (address == null) { throw new IllegalStateException("Address must be set"); } + if (nonce == null) { + throw new IllegalStateException("Nonce must be set"); + } + if (signature == null) { throw new IllegalStateException("Signature must be set"); } - return new SetCodeAuthorization(chainId, address, nonce, signature); + return new CodeDelegation(chainId, address, nonce, signature); } } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Transaction.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Transaction.java index 513cfb8319..0da8f8f28a 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Transaction.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Transaction.java @@ -28,18 +28,18 @@ import org.hyperledger.besu.datatypes.AccessListEntry; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Blob; import org.hyperledger.besu.datatypes.BlobsWithCommitments; +import org.hyperledger.besu.datatypes.CodeDelegation; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.KZGCommitment; import org.hyperledger.besu.datatypes.KZGProof; -import org.hyperledger.besu.datatypes.SetCodeAuthorization; import org.hyperledger.besu.datatypes.Sha256Hash; import org.hyperledger.besu.datatypes.TransactionType; import org.hyperledger.besu.datatypes.VersionedHash; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.core.encoding.AccessListTransactionEncoder; import org.hyperledger.besu.ethereum.core.encoding.BlobTransactionEncoder; +import org.hyperledger.besu.ethereum.core.encoding.CodeDelegationEncoder; import org.hyperledger.besu.ethereum.core.encoding.EncodingContext; -import org.hyperledger.besu.ethereum.core.encoding.SetCodeTransactionEncoder; import org.hyperledger.besu.ethereum.core.encoding.TransactionDecoder; import org.hyperledger.besu.ethereum.core.encoding.TransactionEncoder; import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; @@ -124,7 +124,7 @@ public class Transaction private final Optional> versionedHashes; private final Optional blobsWithCommitments; - private final Optional> maybeAuthorizationList; + private final Optional> maybeCodeDelegationList; public static Builder builder() { return new Builder(); @@ -181,7 +181,7 @@ public class Transaction final Optional chainId, final Optional> versionedHashes, final Optional blobsWithCommitments, - final Optional> maybeAuthorizationList) { + final Optional> maybeCodeDelegationList) { if (!forCopy) { if (transactionType.requiresChainId()) { @@ -218,10 +218,10 @@ public class Transaction maxFeePerBlobGas.isPresent(), "Must specify max fee per blob gas for blob transaction"); } - if (transactionType.requiresSetCode()) { + if (transactionType.requiresCodeDelegation()) { checkArgument( - maybeAuthorizationList.isPresent(), - "Must specify set code transaction payload for set code transaction"); + maybeCodeDelegationList.isPresent(), + "Must specify code delegation authorizations for code delegation transaction"); } } @@ -241,7 +241,7 @@ public class Transaction this.chainId = chainId; this.versionedHashes = versionedHashes; this.blobsWithCommitments = blobsWithCommitments; - this.maybeAuthorizationList = maybeAuthorizationList; + this.maybeCodeDelegationList = maybeCodeDelegationList; } /** @@ -473,7 +473,7 @@ public class Transaction payload, maybeAccessList, versionedHashes.orElse(null), - maybeAuthorizationList, + maybeCodeDelegationList, chainId); } return hashNoSignature; @@ -681,13 +681,13 @@ public class Transaction } @Override - public Optional> getAuthorizationList() { - return maybeAuthorizationList; + public Optional> getCodeDelegationList() { + return maybeCodeDelegationList; } @Override - public int authorizationListSize() { - return maybeAuthorizationList.map(List::size).orElse(0); + public int codeDelegationListSize() { + return maybeCodeDelegationList.map(List::size).orElse(0); } /** @@ -714,7 +714,7 @@ public class Transaction final Bytes payload, final Optional> accessList, final List versionedHashes, - final Optional> authorizationList, + final Optional> codeDelegationList, final Optional chainId) { if (transactionType.requiresChainId()) { checkArgument(chainId.isPresent(), "Transaction type %s requires chainId", transactionType); @@ -759,8 +759,8 @@ public class Transaction new IllegalStateException( "Developer error: the transaction should be guaranteed to have an access list here")), chainId); - case SET_CODE -> - setCodePreimage( + case DELEGATE_CODE -> + codeDelegationPreimage( nonce, maxPriorityFeePerGas, maxFeePerGas, @@ -770,10 +770,10 @@ public class Transaction payload, chainId, accessList, - authorizationList.orElseThrow( + codeDelegationList.orElseThrow( () -> new IllegalStateException( - "Developer error: the transaction should be guaranteed to have a set code payload here"))); + "Developer error: the transaction should be guaranteed to have a code delegations here"))); }; return keccak256(preimage); } @@ -911,7 +911,7 @@ public class Transaction return Bytes.concatenate(Bytes.of(TransactionType.ACCESS_LIST.getSerializedType()), encode); } - private static Bytes setCodePreimage( + private static Bytes codeDelegationPreimage( final long nonce, final Wei maxPriorityFeePerGas, final Wei maxFeePerGas, @@ -921,7 +921,7 @@ public class Transaction final Bytes payload, final Optional chainId, final Optional> accessList, - final List authorizationList) { + final List authorizationList) { final Bytes encoded = RLP.encode( rlpOutput -> { @@ -937,10 +937,10 @@ public class Transaction chainId, accessList, rlpOutput); - SetCodeTransactionEncoder.encodeSetCodeInner(authorizationList, rlpOutput); + CodeDelegationEncoder.encodeCodeDelegationInner(authorizationList, rlpOutput); rlpOutput.endList(); }); - return Bytes.concatenate(Bytes.of(TransactionType.SET_CODE.getSerializedType()), encoded); + return Bytes.concatenate(Bytes.of(TransactionType.DELEGATE_CODE.getSerializedType()), encoded); } @Override @@ -1111,7 +1111,7 @@ public class Transaction chainId, detachedVersionedHashes, detachedBlobsWithCommitments, - maybeAuthorizationList); + maybeCodeDelegationList); // copy also the computed fields, to avoid to recompute them copiedTx.sender = this.sender; @@ -1179,7 +1179,7 @@ public class Transaction protected Optional v = Optional.empty(); protected List versionedHashes = null; private BlobsWithCommitments blobsWithCommitments; - protected Optional> setCodeTransactionPayloads = Optional.empty(); + protected Optional> codeDelegationAuthorizations = Optional.empty(); public Builder copiedFrom(final Transaction toCopy) { this.transactionType = toCopy.transactionType; @@ -1198,7 +1198,7 @@ public class Transaction this.chainId = toCopy.chainId; this.versionedHashes = toCopy.versionedHashes.orElse(null); this.blobsWithCommitments = toCopy.blobsWithCommitments.orElse(null); - this.setCodeTransactionPayloads = toCopy.maybeAuthorizationList; + this.codeDelegationAuthorizations = toCopy.maybeCodeDelegationList; return this; } @@ -1292,8 +1292,8 @@ public class Transaction transactionType = TransactionType.EIP1559; } else if (accessList.isPresent()) { transactionType = TransactionType.ACCESS_LIST; - } else if (setCodeTransactionPayloads.isPresent()) { - transactionType = TransactionType.SET_CODE; + } else if (codeDelegationAuthorizations.isPresent()) { + transactionType = TransactionType.DELEGATE_CODE; } else { transactionType = TransactionType.FRONTIER; } @@ -1324,7 +1324,7 @@ public class Transaction chainId, Optional.ofNullable(versionedHashes), Optional.ofNullable(blobsWithCommitments), - setCodeTransactionPayloads); + codeDelegationAuthorizations); } public Transaction signAndBuild(final KeyPair keys) { @@ -1351,7 +1351,7 @@ public class Transaction payload, accessList, versionedHashes, - setCodeTransactionPayloads, + codeDelegationAuthorizations, chainId), keys); } @@ -1376,9 +1376,8 @@ public class Transaction return this; } - public Builder setCodeTransactionPayloads( - final List setCodeTransactionEntries) { - this.setCodeTransactionPayloads = Optional.ofNullable(setCodeTransactionEntries); + public Builder codeDelegations(final List codeDelegations) { + this.codeDelegationAuthorizations = Optional.ofNullable(codeDelegations); return this; } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/SetCodeTransactionEncoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/CodeDelegationEncoder.java similarity index 75% rename from ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/SetCodeTransactionEncoder.java rename to ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/CodeDelegationEncoder.java index 05808f3129..4cedf93adc 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/SetCodeTransactionEncoder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/CodeDelegationEncoder.java @@ -17,7 +17,7 @@ package org.hyperledger.besu.ethereum.core.encoding; import static org.hyperledger.besu.ethereum.core.encoding.AccessListTransactionEncoder.writeAccessList; import static org.hyperledger.besu.ethereum.core.encoding.TransactionEncoder.writeSignatureAndRecoveryId; -import org.hyperledger.besu.datatypes.SetCodeAuthorization; +import org.hyperledger.besu.datatypes.CodeDelegation; import org.hyperledger.besu.ethereum.core.Transaction; import org.hyperledger.besu.ethereum.rlp.RLPOutput; @@ -25,28 +25,28 @@ import java.util.List; import org.apache.tuweni.bytes.Bytes; -public class SetCodeTransactionEncoder { +public class CodeDelegationEncoder { - private SetCodeTransactionEncoder() { + private CodeDelegationEncoder() { // private constructor } - public static void encodeSetCodeInner( - final List payloads, final RLPOutput rlpOutput) { + public static void encodeCodeDelegationInner( + final List payloads, final RLPOutput rlpOutput) { rlpOutput.startList(); - payloads.forEach(payload -> encodeSingleSetCode(payload, rlpOutput)); + payloads.forEach(payload -> encodeSingleCodeDelegation(payload, rlpOutput)); rlpOutput.endList(); } - public static void encodeSingleSetCodeWithoutSignature( - final SetCodeAuthorization payload, final RLPOutput rlpOutput) { + public static void encodeSingleCodeDelegationWithoutSignature( + final CodeDelegation payload, final RLPOutput rlpOutput) { rlpOutput.startList(); encodeAuthorizationDetails(payload, rlpOutput); rlpOutput.endList(); } - public static void encodeSingleSetCode( - final SetCodeAuthorization payload, final RLPOutput rlpOutput) { + public static void encodeSingleCodeDelegation( + final CodeDelegation payload, final RLPOutput rlpOutput) { rlpOutput.startList(); encodeAuthorizationDetails(payload, rlpOutput); rlpOutput.writeIntScalar(payload.signature().getRecId()); @@ -56,12 +56,10 @@ public class SetCodeTransactionEncoder { } private static void encodeAuthorizationDetails( - final SetCodeAuthorization payload, final RLPOutput rlpOutput) { + final CodeDelegation payload, final RLPOutput rlpOutput) { rlpOutput.writeBigIntegerScalar(payload.chainId()); rlpOutput.writeBytes(payload.address().copy()); - rlpOutput.startList(); - payload.nonce().ifPresent(rlpOutput::writeLongScalar); - rlpOutput.endList(); + rlpOutput.writeLongScalar(payload.nonce()); } public static void encode(final Transaction transaction, final RLPOutput out) { @@ -75,13 +73,13 @@ public class SetCodeTransactionEncoder { out.writeUInt256Scalar(transaction.getValue()); out.writeBytes(transaction.getPayload()); writeAccessList(out, transaction.getAccessList()); - encodeSetCodeInner( + encodeCodeDelegationInner( transaction - .getAuthorizationList() + .getCodeDelegationList() .orElseThrow( () -> new IllegalStateException( - "Developer error: the transaction should be guaranteed to have a set code payload here")), + "Developer error: the transaction should be guaranteed to have a code delegation authorizations here")), out); writeSignatureAndRecoveryId(transaction, out); out.endList(); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/SetCodeTransactionDecoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/CodeDelegationTransactionDecoder.java similarity index 73% rename from ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/SetCodeTransactionDecoder.java rename to ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/CodeDelegationTransactionDecoder.java index 80d59de83b..8961431c9c 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/SetCodeTransactionDecoder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/CodeDelegationTransactionDecoder.java @@ -19,23 +19,22 @@ import org.hyperledger.besu.crypto.SignatureAlgorithm; import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; import org.hyperledger.besu.datatypes.AccessListEntry; import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.datatypes.CodeDelegation; import org.hyperledger.besu.datatypes.TransactionType; import org.hyperledger.besu.datatypes.Wei; -import org.hyperledger.besu.ethereum.core.SetCodeAuthorization; import org.hyperledger.besu.ethereum.core.Transaction; import org.hyperledger.besu.ethereum.rlp.RLPInput; import java.math.BigInteger; -import java.util.Optional; import java.util.function.Supplier; import com.google.common.base.Suppliers; -public class SetCodeTransactionDecoder { +public class CodeDelegationTransactionDecoder { private static final Supplier SIGNATURE_ALGORITHM = Suppliers.memoize(SignatureAlgorithmFactory::getInstance); - private SetCodeTransactionDecoder() { + private CodeDelegationTransactionDecoder() { // private constructor } @@ -44,7 +43,7 @@ public class SetCodeTransactionDecoder { final BigInteger chainId = input.readBigIntegerScalar(); final Transaction.Builder builder = Transaction.builder() - .type(TransactionType.SET_CODE) + .type(TransactionType.DELEGATE_CODE) .chainId(chainId) .nonce(input.readLongScalar()) .maxPriorityFeePerGas(Wei.of(input.readUInt256Scalar())) @@ -64,10 +63,7 @@ public class SetCodeTransactionDecoder { accessListEntryRLPInput.leaveList(); return accessListEntry; })) - .setCodeTransactionPayloads( - input.readList( - setCodeTransactionPayloadsRLPInput -> - decodeInnerPayload(setCodeTransactionPayloadsRLPInput))); + .codeDelegations(input.readList(CodeDelegationTransactionDecoder::decodeInnerPayload)); final byte recId = (byte) input.readUnsignedByteScalar(); final BigInteger r = input.readUInt256Scalar().toUnsignedBigInteger(); @@ -75,33 +71,15 @@ public class SetCodeTransactionDecoder { input.leaveList(); - final Transaction transaction = - builder.signature(SIGNATURE_ALGORITHM.get().createSignature(r, s, recId)).build(); - - return transaction; + return builder.signature(SIGNATURE_ALGORITHM.get().createSignature(r, s, recId)).build(); } - public static org.hyperledger.besu.datatypes.SetCodeAuthorization decodeInnerPayload( - final RLPInput input) { + public static CodeDelegation decodeInnerPayload(final RLPInput input) { input.enterList(); + final BigInteger chainId = input.readBigIntegerScalar(); final Address address = Address.wrap(input.readBytes()); - - Optional nonce = Optional.empty(); - - if (!input.nextIsList()) { - throw new IllegalArgumentException("Optional nonce must be an list, but isn't"); - } - - final long noncesSize = input.nextSize(); - - input.enterList(); - if (noncesSize == 1) { - nonce = Optional.ofNullable(input.readLongScalar()); - } else if (noncesSize > 1) { - throw new IllegalArgumentException("Nonce list may only have 1 member, if any"); - } - input.leaveList(); + final long nonce = input.readLongScalar(); final byte yParity = (byte) input.readUnsignedByteScalar(); final BigInteger r = input.readUInt256Scalar().toUnsignedBigInteger(); @@ -111,6 +89,7 @@ public class SetCodeTransactionDecoder { final SECPSignature signature = SIGNATURE_ALGORITHM.get().createSignature(r, s, yParity); - return new SetCodeAuthorization(chainId, address, nonce, signature); + return new org.hyperledger.besu.ethereum.core.CodeDelegation( + chainId, address, nonce, signature); } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/TransactionDecoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/TransactionDecoder.java index 2a63d8f24b..7261aecbea 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/TransactionDecoder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/TransactionDecoder.java @@ -41,8 +41,8 @@ public class TransactionDecoder { EIP1559TransactionDecoder::decode, TransactionType.BLOB, BlobTransactionDecoder::decode, - TransactionType.SET_CODE, - SetCodeTransactionDecoder::decode); + TransactionType.DELEGATE_CODE, + CodeDelegationTransactionDecoder::decode); private static final ImmutableMap POOLED_TRANSACTION_DECODERS = ImmutableMap.of(TransactionType.BLOB, BlobPooledTransactionDecoder::decode); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/TransactionEncoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/TransactionEncoder.java index 4995975621..26bad56c6d 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/TransactionEncoder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/TransactionEncoder.java @@ -40,8 +40,8 @@ public class TransactionEncoder { EIP1559TransactionEncoder::encode, TransactionType.BLOB, BlobTransactionEncoder::encode, - TransactionType.SET_CODE, - SetCodeTransactionEncoder::encode); + TransactionType.DELEGATE_CODE, + CodeDelegationEncoder::encode); private static final ImmutableMap POOLED_TRANSACTION_ENCODERS = ImmutableMap.of(TransactionType.BLOB, BlobPooledTransactionEncoder::encode); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/AuthorityProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/AuthorityProcessor.java deleted file mode 100644 index 1d25d2d34f..0000000000 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/AuthorityProcessor.java +++ /dev/null @@ -1,88 +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 org.hyperledger.besu.ethereum.core.Transaction; -import org.hyperledger.besu.evm.account.Account; -import org.hyperledger.besu.evm.account.AccountState; -import org.hyperledger.besu.evm.account.MutableAccount; -import org.hyperledger.besu.evm.worldstate.EVMWorldUpdater; - -import java.math.BigInteger; -import java.util.Optional; - -import org.apache.tuweni.bytes.Bytes; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class AuthorityProcessor { - private static final Logger LOG = LoggerFactory.getLogger(AuthorityProcessor.class); - - private final Optional maybeChainId; - - public AuthorityProcessor(final Optional maybeChainId) { - this.maybeChainId = maybeChainId; - } - - public void addContractToAuthority( - final EVMWorldUpdater evmWorldUpdater, final Transaction transaction) { - transaction - .getAuthorizationList() - .get() - .forEach( - payload -> - payload - .authorizer() - .ifPresent( - authorityAddress -> { - LOG.trace("Set code authority: {}", authorityAddress); - - if (maybeChainId.isPresent() - && !payload.chainId().equals(BigInteger.ZERO) - && !maybeChainId.get().equals(payload.chainId())) { - return; - } - - final Optional maybeAccount = - Optional.ofNullable(evmWorldUpdater.getAccount(authorityAddress)); - final long accountNonce = - maybeAccount.map(AccountState::getNonce).orElse(0L); - - if (payload.nonce().isPresent() - && !payload.nonce().get().equals(accountNonce)) { - return; - } - - if (evmWorldUpdater - .authorizedCodeService() - .hasAuthorizedCode(authorityAddress)) { - return; - } - - Optional codeAccount = - Optional.ofNullable(evmWorldUpdater.get(payload.address())); - final Bytes code; - if (codeAccount.isPresent()) { - code = codeAccount.get().getCode(); - } else { - code = Bytes.EMPTY; - } - - evmWorldUpdater - .authorizedCodeService() - .addAuthorizedCode(authorityAddress, code); - })); - } -} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/CodeDelegationProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/CodeDelegationProcessor.java new file mode 100644 index 0000000000..58f66b6afb --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/CodeDelegationProcessor.java @@ -0,0 +1,134 @@ +/* + * 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 org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.ethereum.core.CodeDelegation; +import org.hyperledger.besu.ethereum.core.Transaction; +import org.hyperledger.besu.evm.account.MutableAccount; +import org.hyperledger.besu.evm.worldstate.EVMWorldUpdater; + +import java.math.BigInteger; +import java.util.Optional; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class CodeDelegationProcessor { + private static final Logger LOG = LoggerFactory.getLogger(CodeDelegationProcessor.class); + + private final Optional maybeChainId; + + public CodeDelegationProcessor(final Optional maybeChainId) { + this.maybeChainId = maybeChainId; + } + + /** + * At the start of executing the transaction, after incrementing the sender’s nonce, for each + * authorization we do the following: + * + *
    + *
  1. Verify the chain id is either 0 or the chain's current ID. + *
  2. `authority = ecrecover(keccak(MAGIC || rlp([chain_id, address, nonce])), y_parity, r, s]` + *
  3. Add `authority` to `accessed_addresses` (as defined in [EIP-2929](./eip-2929.md).) + *
  4. Verify the code of `authority` is either empty or already delegated. + *
  5. Verify the nonce of `authority` is equal to `nonce`. + *
  6. Add `PER_EMPTY_ACCOUNT_COST - PER_AUTH_BASE_COST` gas to the global refund counter if + * `authority` exists in the trie. + *
  7. Set the code of `authority` to be `0xef0100 || address`. This is a delegation + * designation. + *
  8. Increase the nonce of `authority` by one. + *
+ * + * @param evmWorldUpdater The world state updater which is aware of code delegation. + * @param transaction The transaction being processed. + * @return The result of the code delegation processing. + */ + public CodeDelegationResult process( + final EVMWorldUpdater evmWorldUpdater, final Transaction transaction) { + final CodeDelegationResult result = new CodeDelegationResult(); + + transaction + .getCodeDelegationList() + .get() + .forEach( + codeDelegation -> + processAuthorization( + evmWorldUpdater, + (org.hyperledger.besu.ethereum.core.CodeDelegation) codeDelegation, + result)); + + return result; + } + + private void processAuthorization( + final EVMWorldUpdater evmWorldUpdater, + final CodeDelegation codeDelegation, + final CodeDelegationResult result) { + LOG.trace("Processing code delegation: {}", codeDelegation); + + if (maybeChainId.isPresent() + && !codeDelegation.chainId().equals(BigInteger.ZERO) + && !maybeChainId.get().equals(codeDelegation.chainId())) { + LOG.trace( + "Invalid chain id for code delegation. Expected: {}, Actual: {}", + maybeChainId.get(), + codeDelegation.chainId()); + return; + } + + final Optional
authorizer = codeDelegation.authorizer(); + if (authorizer.isEmpty()) { + LOG.trace("Invalid signature for code delegation"); + return; + } + + LOG.trace("Set code delegation for authority: {}", authorizer.get()); + + final Optional maybeAuthorityAccount = + Optional.ofNullable(evmWorldUpdater.getAccount(authorizer.get())); + + result.addAccessedDelegatorAddress(authorizer.get()); + + MutableAccount authority; + boolean authorityDoesAlreadyExist = false; + if (maybeAuthorityAccount.isEmpty()) { + authority = evmWorldUpdater.createAccount(authorizer.get()); + } else { + authority = maybeAuthorityAccount.get(); + + if (!evmWorldUpdater.authorizedCodeService().canSetDelegatedCode(authority)) { + return; + } + + authorityDoesAlreadyExist = true; + } + + if (codeDelegation.nonce() != authority.getNonce()) { + LOG.trace( + "Invalid nonce for code delegation. Expected: {}, Actual: {}", + authority.getNonce(), + codeDelegation.nonce()); + return; + } + + if (authorityDoesAlreadyExist) { + result.incremenentAlreadyExistingDelegators(); + } + + evmWorldUpdater.authorizedCodeService().addDelegatedCode(authority, codeDelegation.address()); + authority.incrementNonce(); + } +} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/CodeDelegationResult.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/CodeDelegationResult.java new file mode 100644 index 0000000000..20d75a6757 --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/CodeDelegationResult.java @@ -0,0 +1,41 @@ +/* + * 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 org.hyperledger.besu.collections.trie.BytesTrieSet; +import org.hyperledger.besu.datatypes.Address; + +import java.util.Set; + +public class CodeDelegationResult { + private final Set
accessedDelegatorAddresses = new BytesTrieSet<>(Address.SIZE); + private long alreadyExistingDelegators = 0L; + + public void addAccessedDelegatorAddress(final Address address) { + accessedDelegatorAddresses.add(address); + } + + public void incremenentAlreadyExistingDelegators() { + alreadyExistingDelegators += 1; + } + + public Set
accessedDelegatorAddresses() { + return accessedDelegatorAddresses; + } + + public long alreadyExistingDelegators() { + return alreadyExistingDelegators; + } +} 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 ddc8b49b4f..e6d7a88cbd 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 @@ -715,7 +715,7 @@ public abstract class MainnetProtocolSpecs { evmConfiguration.evmStackSize(), feeMarket, CoinbaseFeePriceCalculator.eip1559(), - new AuthorityProcessor(chainId))) + new CodeDelegationProcessor(chainId))) // change to check for max blob gas per block for EIP-4844 .transactionValidatorFactoryBuilder( (evm, gasLimitCalculator, feeMarket) -> @@ -813,7 +813,7 @@ public abstract class MainnetProtocolSpecs { TransactionType.ACCESS_LIST, TransactionType.EIP1559, TransactionType.BLOB, - TransactionType.SET_CODE), + TransactionType.DELEGATE_CODE), evm.getMaxInitcodeSize())) // EIP-2935 Blockhash processor diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java index b008a8d5f6..91c964525e 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java @@ -81,7 +81,7 @@ public class MainnetTransactionProcessor { protected final FeeMarket feeMarket; private final CoinbaseFeePriceCalculator coinbaseFeePriceCalculator; - private final Optional maybeAuthorityProcessor; + private final Optional maybeCodeDelegationProcessor; public MainnetTransactionProcessor( final GasCalculator gasCalculator, @@ -116,7 +116,7 @@ public class MainnetTransactionProcessor { final int maxStackSize, final FeeMarket feeMarket, final CoinbaseFeePriceCalculator coinbaseFeePriceCalculator, - final AuthorityProcessor maybeAuthorityProcessor) { + final CodeDelegationProcessor maybeCodeDelegationProcessor) { this.gasCalculator = gasCalculator; this.transactionValidatorFactory = transactionValidatorFactory; this.contractCreationProcessor = contractCreationProcessor; @@ -126,7 +126,7 @@ public class MainnetTransactionProcessor { this.maxStackSize = maxStackSize; this.feeMarket = feeMarket; this.coinbaseFeePriceCalculator = coinbaseFeePriceCalculator; - this.maybeAuthorityProcessor = Optional.ofNullable(maybeAuthorityProcessor); + this.maybeCodeDelegationProcessor = Optional.ofNullable(maybeCodeDelegationProcessor); } /** @@ -316,16 +316,7 @@ public class MainnetTransactionProcessor { operationTracer.tracePrepareTransaction(evmWorldUpdater, transaction); - final Set
addressList = new BytesTrieSet<>(Address.SIZE); - - if (transaction.getAuthorizationList().isPresent()) { - if (maybeAuthorityProcessor.isEmpty()) { - throw new RuntimeException("Authority processor is required for 7702 transactions"); - } - - maybeAuthorityProcessor.get().addContractToAuthority(evmWorldUpdater, transaction); - addressList.addAll(evmWorldUpdater.authorizedCodeService().getAuthorities()); - } + final Set
warmAddressList = new BytesTrieSet<>(Address.SIZE); final long previousNonce = sender.incrementNonce(); LOG.trace( @@ -349,6 +340,20 @@ public class MainnetTransactionProcessor { previousBalance, sender.getBalance()); + long codeDelegationRefund = 0L; + if (transaction.getCodeDelegationList().isPresent()) { + if (maybeCodeDelegationProcessor.isEmpty()) { + throw new RuntimeException("Code delegation processor is required for 7702 transactions"); + } + + final CodeDelegationResult codeDelegationResult = + maybeCodeDelegationProcessor.get().process(evmWorldUpdater, transaction); + warmAddressList.addAll(codeDelegationResult.accessedDelegatorAddresses()); + codeDelegationRefund = + gasCalculator.calculateDelegateCodeGasRefund( + (codeDelegationResult.alreadyExistingDelegators())); + } + final List accessListEntries = transaction.getAccessList().orElse(List.of()); // we need to keep a separate hash set of addresses in case they specify no storage. // No-storage is a common pattern, especially for Externally Owned Accounts @@ -356,13 +361,13 @@ public class MainnetTransactionProcessor { int accessListStorageCount = 0; for (final var entry : accessListEntries) { final Address address = entry.address(); - addressList.add(address); + warmAddressList.add(address); final List storageKeys = entry.storageKeys(); storageList.putAll(address, storageKeys); accessListStorageCount += storageKeys.size(); } if (warmCoinbase) { - addressList.add(miningBeneficiary); + warmAddressList.add(miningBeneficiary); } final long intrinsicGas = @@ -370,16 +375,17 @@ public class MainnetTransactionProcessor { transaction.getPayload(), transaction.isContractCreation()); final long accessListGas = gasCalculator.accessListGasCost(accessListEntries.size(), accessListStorageCount); - final long setCodeGas = gasCalculator.setCodeListGasCost(transaction.authorizationListSize()); + final long codeDelegationGas = + gasCalculator.delegateCodeGasCost(transaction.codeDelegationListSize()); final long gasAvailable = - transaction.getGasLimit() - intrinsicGas - accessListGas - setCodeGas; + transaction.getGasLimit() - intrinsicGas - accessListGas - codeDelegationGas; LOG.trace( - "Gas available for execution {} = {} - {} - {} - {} (limit - intrinsic - accessList - setCode)", + "Gas available for execution {} = {} - {} - {} - {} (limit - intrinsic - accessList - codeDelegation)", gasAvailable, transaction.getGasLimit(), intrinsicGas, accessListGas, - setCodeGas); + codeDelegationGas); final WorldUpdater worldUpdater = evmWorldUpdater.updater(); final ImmutableMap.Builder contextVariablesBuilder = @@ -409,7 +415,7 @@ public class MainnetTransactionProcessor { .miningBeneficiary(miningBeneficiary) .blockHashLookup(blockHashLookup) .contextVariables(contextVariablesBuilder.build()) - .accessListWarmAddresses(addressList) + .accessListWarmAddresses(warmAddressList) .accessListWarmStorage(storageList); if (transaction.getVersionedHashes().isPresent()) { @@ -488,7 +494,8 @@ public class MainnetTransactionProcessor { // after the other so that if it is the same account somehow, we end up with the right result) final long selfDestructRefund = gasCalculator.getSelfDestructRefundAmount() * initialFrame.getSelfDestructs().size(); - final long baseRefundGas = initialFrame.getGasRefund() + selfDestructRefund; + final long baseRefundGas = + initialFrame.getGasRefund() + selfDestructRefund + codeDelegationRefund; final long refundedGas = refunded(transaction, initialFrame.getRemainingGas(), baseRefundGas); final Wei refundedWei = transactionGasPrice.multiply(refundedGas); final Wei balancePriorToRefund = sender.getBalance(); @@ -528,7 +535,6 @@ public class MainnetTransactionProcessor { final var coinbase = evmWorldUpdater.getOrCreate(miningBeneficiary); coinbase.incrementBalance(coinbaseWeiDelta); - evmWorldUpdater.authorizedCodeService().resetAuthorities(); operationTracer.traceEndTransaction( worldUpdater, diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionValidator.java index 481ce70e05..4f4c554f3f 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionValidator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionValidator.java @@ -20,6 +20,7 @@ import org.hyperledger.besu.crypto.SECPSignature; import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; import org.hyperledger.besu.datatypes.Blob; import org.hyperledger.besu.datatypes.BlobsWithCommitments; +import org.hyperledger.besu.datatypes.CodeDelegation; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.KZGCommitment; import org.hyperledger.besu.datatypes.TransactionType; @@ -129,9 +130,50 @@ public class MainnetTransactionValidator implements TransactionValidator { transaction.getPayload().size(), maxInitcodeSize)); } + if (transactionType == TransactionType.DELEGATE_CODE) { + if (isDelegateCodeEmpty(transaction)) { + return ValidationResult.invalid( + TransactionInvalidReason.EMPTY_CODE_DELEGATION, + "transaction code delegation transactions must have a non-empty code delegation list"); + } + + final BigInteger halfCurveOrder = SignatureAlgorithmFactory.getInstance().getHalfCurveOrder(); + final Optional> validationResult = + transaction + .getCodeDelegationList() + .map( + codeDelegations -> { + for (CodeDelegation codeDelegation : codeDelegations) { + if (codeDelegation.signature().getS().compareTo(halfCurveOrder) > 0) { + return ValidationResult.invalid( + TransactionInvalidReason.INVALID_SIGNATURE, + "Invalid signature for code delegation. S value must be less or equal than the half curve order."); + } + + if (codeDelegation.signature().getRecId() != 0 + && codeDelegation.signature().getRecId() != 1) { + return ValidationResult.invalid( + TransactionInvalidReason.INVALID_SIGNATURE, + "Invalid signature for code delegation. RecId value must be 0 or 1."); + } + } + + return ValidationResult.valid(); + }); + + if (validationResult.isPresent() && !validationResult.get().isValid()) { + return validationResult.get(); + } + } + return validateCostAndFee(transaction, baseFee, blobFee, transactionValidationParams); } + private static boolean isDelegateCodeEmpty(final Transaction transaction) { + return transaction.getCodeDelegationList().isEmpty() + || transaction.getCodeDelegationList().get().isEmpty(); + } + private ValidationResult validateCostAndFee( final Transaction transaction, final Optional maybeBaseFee, @@ -190,7 +232,7 @@ public class MainnetTransactionValidator implements TransactionValidator { gasCalculator.transactionIntrinsicGasCost( transaction.getPayload(), transaction.isContractCreation()) + (transaction.getAccessList().map(gasCalculator::accessListGasCost).orElse(0L)) - + gasCalculator.setCodeListGasCost(transaction.authorizationListSize()); + + gasCalculator.delegateCodeGasCost(transaction.codeDelegationListSize()); if (Long.compareUnsigned(intrinsicGasCost, transaction.getGasLimit()) > 0) { return ValidationResult.invalid( TransactionInvalidReason.INTRINSIC_GAS_EXCEEDS_GAS_LIMIT, @@ -250,7 +292,8 @@ public class MainnetTransactionValidator implements TransactionValidator { transaction.getNonce(), senderNonce)); } - if (!validationParams.isAllowContractAddressAsSender() && !codeHash.equals(Hash.EMPTY)) { + if (!validationParams.isAllowContractAddressAsSender() + && !canSendTransaction(sender, codeHash)) { return ValidationResult.invalid( TransactionInvalidReason.TX_SENDER_NOT_AUTHORIZED, String.format( @@ -261,6 +304,10 @@ public class MainnetTransactionValidator implements TransactionValidator { return ValidationResult.valid(); } + private static boolean canSendTransaction(final Account sender, final Hash codeHash) { + return codeHash.equals(Hash.EMPTY) || sender.hasDelegatedCode(); + } + private ValidationResult validateTransactionSignature( final Transaction transaction) { if (chainId.isPresent() diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/TransactionInvalidReason.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/TransactionInvalidReason.java index a6c2cb69b2..8273c556d9 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/TransactionInvalidReason.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/TransactionInvalidReason.java @@ -50,6 +50,7 @@ public enum TransactionInvalidReason { PLUGIN_TX_POOL_VALIDATOR, EXECUTION_HALTED, EOF_CODE_INVALID, + EMPTY_CODE_DELEGATION, // Private Transaction Invalid Reasons PRIVATE_TRANSACTION_INVALID, PRIVATE_TRANSACTION_FAILED, 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 2709b94e29..ea62d7f1fa 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 @@ -376,7 +376,7 @@ public class BlockDataGenerator { case EIP1559 -> eip1559Transaction(payload, to); case ACCESS_LIST -> accessListTransaction(payload, to); case BLOB -> blobTransaction(payload, to); - case SET_CODE -> null; + case DELEGATE_CODE -> null; // no default, all types accounted for. }; } diff --git a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/TransactionTestFixture.java b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/TransactionTestFixture.java index 3f7049be39..602116749b 100644 --- a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/TransactionTestFixture.java +++ b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/TransactionTestFixture.java @@ -92,7 +92,7 @@ public class TransactionTestFixture { builder.versionedHashes(versionedHashes.get()); } break; - case SET_CODE: + case DELEGATE_CODE: break; } diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/SetCodeTransactionDecoderTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/CodeDelegationDecoderTest.java similarity index 67% rename from ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/SetCodeTransactionDecoderTest.java rename to ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/CodeDelegationDecoderTest.java index 610b5906f5..d6ff585b4f 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/SetCodeTransactionDecoderTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/CodeDelegationDecoderTest.java @@ -15,11 +15,10 @@ package org.hyperledger.besu.ethereum.core.encoding; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; -import static org.junit.jupiter.api.Assertions.assertThrows; import org.hyperledger.besu.crypto.SECPSignature; import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.SetCodeAuthorization; +import org.hyperledger.besu.datatypes.CodeDelegation; import org.hyperledger.besu.ethereum.rlp.BytesValueRLPInput; import java.math.BigInteger; @@ -27,7 +26,7 @@ import java.math.BigInteger; import org.apache.tuweni.bytes.Bytes; import org.junit.jupiter.api.Test; -class SetCodeTransactionDecoderTest { +class CodeDelegationDecoderTest { @Test void shouldDecodeInnerPayloadWithNonce() { @@ -36,14 +35,14 @@ class SetCodeTransactionDecoderTest { final BytesValueRLPInput input = new BytesValueRLPInput( Bytes.fromHexString( - "0xf85b0194633688abc3ccf8b0c03088d2d1c6ae4958c2fa56c18080a0840798fa67118e034c1eb7e42fe89e28d7cd5006dc813d5729e5f75b0d1a7ec5a03b1dbace38ceb862a65bf2eac0637693b5c3493bcb2a022dd614c0a74cce0b99"), + "0xf85a0194633688abc3ccf8b0c03088d2d1c6ae4958c2fa562a80a0840798fa67118e034c1eb7e42fe89e28d7cd5006dc813d5729e5f75b0d1a7ec5a03b1dbace38ceb862a65bf2eac0637693b5c3493bcb2a022dd614c0a74cce0b99"), true); - final SetCodeAuthorization authorization = SetCodeTransactionDecoder.decodeInnerPayload(input); + final CodeDelegation authorization = CodeDelegationTransactionDecoder.decodeInnerPayload(input); assertThat(authorization.chainId()).isEqualTo(BigInteger.ONE); assertThat(authorization.address()) .isEqualTo(Address.fromHexStringStrict("0x633688abc3cCf8B0C03088D2d1C6ae4958c2fA56")); - assertThat(authorization.nonce().get()).isEqualTo(0L); + assertThat(authorization.nonce()).isEqualTo(42); final SECPSignature signature = authorization.signature(); assertThat(signature.getRecId()).isEqualTo((byte) 0); @@ -54,20 +53,20 @@ class SetCodeTransactionDecoderTest { } @Test - void shouldDecodeInnerPayloadWithoutNonce() { + void shouldDecodeInnerPayloadWithNonceZero() { // "0xd70194633688abc3ccf8b0c03088d2d1c6ae4958c2fa56c5" final BytesValueRLPInput input = new BytesValueRLPInput( Bytes.fromHexString( - "0xf85a0194633688abc3ccf8b0c03088d2d1c6ae4958c2fa56c001a0dd6b24048be1b7d7fe5bbbb73ffc37eb2ce1997ecb4ae5b6096532ef19363148a025b58a1ff8ad00bddbbfa1d5c2411961cbb6d08dcdc8ae88303db3c6cf983031"), + "0xf85a0194633688abc3ccf8b0c03088d2d1c6ae4958c2fa568001a0dd6b24048be1b7d7fe5bbbb73ffc37eb2ce1997ecb4ae5b6096532ef19363148a025b58a1ff8ad00bddbbfa1d5c2411961cbb6d08dcdc8ae88303db3c6cf983031"), true); - final SetCodeAuthorization authorization = SetCodeTransactionDecoder.decodeInnerPayload(input); + final CodeDelegation authorization = CodeDelegationTransactionDecoder.decodeInnerPayload(input); assertThat(authorization.chainId()).isEqualTo(BigInteger.ONE); assertThat(authorization.address()) .isEqualTo(Address.fromHexStringStrict("0x633688abc3cCf8B0C03088D2d1C6ae4958c2fA56")); - assertThat(authorization.nonce()).isEmpty(); + assertThat(authorization.nonce()).isEqualTo(0); final SECPSignature signature = authorization.signature(); assertThat(signature.getRecId()).isEqualTo((byte) 1); @@ -78,37 +77,20 @@ class SetCodeTransactionDecoderTest { } @Test - void shouldThrowInnerPayloadWithMultipleNonces() { - // "d90194633688abc3ccf8b0c03088d2d1c6ae4958c2fa56c20107" - - final BytesValueRLPInput input = - new BytesValueRLPInput( - Bytes.fromHexString( - "0xf85c0194633688abc3ccf8b0c03088d2d1c6ae4958c2fa56c2010201a0401b5d4ebe88306448115d1a46a30e5ad1136f2818b4ebb0733d9c4efffd135aa0753ff1dbce6db504ecb9635a64d8c4506ff887e2d2a0d2b7175baf94c849eccc"), - true); - - assertThrows( - IllegalArgumentException.class, - () -> { - SetCodeTransactionDecoder.decodeInnerPayload(input); - }); - } - - @Test - void shouldDecodeInnerPayloadWithoutNonceAndChainIdZero() { + void shouldDecodeInnerPayloadWithChainIdZero() { // "d70094633688abc3ccf8b0c03088d2d1c6ae4958c2fa56c5" final BytesValueRLPInput input = new BytesValueRLPInput( Bytes.fromHexString( - "0xf85a0094633688abc3ccf8b0c03088d2d1c6ae4958c2fa56c001a0025c1240d7ffec0daeedb752d3357aff2e3cd58468f0c2d43ee0ee999e02ace2a03c8a25b2becd6e666f69803d1ae3322f2e137b7745c2c7f19da80f993ffde4df"), + "0xf85a8094633688abc3ccf8b0c03088d2d1c6ae4958c2fa560501a0025c1240d7ffec0daeedb752d3357aff2e3cd58468f0c2d43ee0ee999e02ace2a03c8a25b2becd6e666f69803d1ae3322f2e137b7745c2c7f19da80f993ffde4df"), true); - final SetCodeAuthorization authorization = SetCodeTransactionDecoder.decodeInnerPayload(input); + final CodeDelegation authorization = CodeDelegationTransactionDecoder.decodeInnerPayload(input); assertThat(authorization.chainId()).isEqualTo(BigInteger.ZERO); assertThat(authorization.address()) .isEqualTo(Address.fromHexStringStrict("0x633688abc3cCf8B0C03088D2d1C6ae4958c2fA56")); - assertThat(authorization.nonce().isEmpty()).isTrue(); + assertThat(authorization.nonce()).isEqualTo(5); final SECPSignature signature = authorization.signature(); assertThat(signature.getRecId()).isEqualTo((byte) 1); diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/SetCodeTransactionEncoderTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/CodeDelegationEncoderTest.java similarity index 75% rename from ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/SetCodeTransactionEncoderTest.java rename to ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/CodeDelegationEncoderTest.java index 89211f4ba3..34b7c6d449 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/SetCodeTransactionEncoderTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/CodeDelegationEncoderTest.java @@ -19,11 +19,10 @@ import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import org.hyperledger.besu.crypto.SignatureAlgorithm; import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.ethereum.core.SetCodeAuthorization; +import org.hyperledger.besu.ethereum.core.CodeDelegation; import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; import java.math.BigInteger; -import java.util.Optional; import java.util.function.Supplier; import com.google.common.base.Suppliers; @@ -31,7 +30,7 @@ import org.apache.tuweni.bytes.Bytes; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -class SetCodeTransactionEncoderTest { +class CodeDelegationEncoderTest { private static final Supplier SIGNATURE_ALGORITHM = Suppliers.memoize(SignatureAlgorithmFactory::getInstance); @@ -43,14 +42,14 @@ class SetCodeTransactionEncoderTest { } @Test - void shouldEncodeSingleSetCodeWithNonce() { + void shouldEncodeSingleCodeDelegationWithNonceAndChainId() { // "0xd80194633688abc3ccf8b0c03088d2d1c6ae4958c2fa56c105" - final SetCodeAuthorization authorization = - new SetCodeAuthorization( + final CodeDelegation authorization = + new CodeDelegation( BigInteger.ONE, Address.fromHexString("0x633688abc3cCf8B0C03088D2d1C6ae4958c2fA56"), - Optional.of(0L), + 42, SIGNATURE_ALGORITHM .get() .createSignature( @@ -60,23 +59,23 @@ class SetCodeTransactionEncoderTest { "3b1dbace38ceb862a65bf2eac0637693b5c3493bcb2a022dd614c0a74cce0b99", 16), (byte) 0)); - SetCodeTransactionEncoder.encodeSingleSetCode(authorization, output); + CodeDelegationEncoder.encodeSingleCodeDelegation(authorization, output); assertThat(output.encoded()) .isEqualTo( Bytes.fromHexString( - "0xf85b0194633688abc3ccf8b0c03088d2d1c6ae4958c2fa56c18080a0840798fa67118e034c1eb7e42fe89e28d7cd5006dc813d5729e5f75b0d1a7ec5a03b1dbace38ceb862a65bf2eac0637693b5c3493bcb2a022dd614c0a74cce0b99")); + "0xf85a0194633688abc3ccf8b0c03088d2d1c6ae4958c2fa562a80a0840798fa67118e034c1eb7e42fe89e28d7cd5006dc813d5729e5f75b0d1a7ec5a03b1dbace38ceb862a65bf2eac0637693b5c3493bcb2a022dd614c0a74cce0b99")); } @Test - void shouldEncodeSingleSetCodeWithoutNonce() { + void shouldEncodeSingleCodeDelegationWithNonceZero() { // "0xd70194633688abc3ccf8b0c03088d2d1c6ae4958c2fa56c5" - final SetCodeAuthorization authorization = - new SetCodeAuthorization( + final CodeDelegation authorization = + new CodeDelegation( BigInteger.ONE, Address.fromHexString("0x633688abc3cCf8B0C03088D2d1C6ae4958c2fA56"), - Optional.empty(), + 0, SIGNATURE_ALGORITHM .get() .createSignature( @@ -86,23 +85,23 @@ class SetCodeTransactionEncoderTest { "25b58a1ff8ad00bddbbfa1d5c2411961cbb6d08dcdc8ae88303db3c6cf983031", 16), (byte) 1)); - SetCodeTransactionEncoder.encodeSingleSetCode(authorization, output); + CodeDelegationEncoder.encodeSingleCodeDelegation(authorization, output); assertThat(output.encoded()) .isEqualTo( Bytes.fromHexString( - "0xf85a0194633688abc3ccf8b0c03088d2d1c6ae4958c2fa56c001a0dd6b24048be1b7d7fe5bbbb73ffc37eb2ce1997ecb4ae5b6096532ef19363148a025b58a1ff8ad00bddbbfa1d5c2411961cbb6d08dcdc8ae88303db3c6cf983031")); + "0xf85a0194633688abc3ccf8b0c03088d2d1c6ae4958c2fa568001a0dd6b24048be1b7d7fe5bbbb73ffc37eb2ce1997ecb4ae5b6096532ef19363148a025b58a1ff8ad00bddbbfa1d5c2411961cbb6d08dcdc8ae88303db3c6cf983031")); } @Test - void shouldEncodeSingleSetCodeWithoutNonceAndChainIdZero() { + void shouldEncodeSingleCodeDelegationWithChainIdZero() { // "d70094633688abc3ccf8b0c03088d2d1c6ae4958c2fa56c5" - final SetCodeAuthorization authorization = - new SetCodeAuthorization( + final CodeDelegation authorization = + new CodeDelegation( BigInteger.ZERO, Address.fromHexString("0x633688abc3cCf8B0C03088D2d1C6ae4958c2fA56"), - Optional.empty(), + 5, SIGNATURE_ALGORITHM .get() .createSignature( @@ -112,11 +111,11 @@ class SetCodeTransactionEncoderTest { "3c8a25b2becd6e666f69803d1ae3322f2e137b7745c2c7f19da80f993ffde4df", 16), (byte) 1)); - SetCodeTransactionEncoder.encodeSingleSetCode(authorization, output); + CodeDelegationEncoder.encodeSingleCodeDelegation(authorization, output); assertThat(output.encoded()) .isEqualTo( Bytes.fromHexString( - "0xf85a8094633688abc3ccf8b0c03088d2d1c6ae4958c2fa56c001a0025c1240d7ffec0daeedb752d3357aff2e3cd58468f0c2d43ee0ee999e02ace2a03c8a25b2becd6e666f69803d1ae3322f2e137b7745c2c7f19da80f993ffde4df")); + "0xf85a8094633688abc3ccf8b0c03088d2d1c6ae4958c2fa560501a0025c1240d7ffec0daeedb752d3357aff2e3cd58468f0c2d43ee0ee999e02ace2a03c8a25b2becd6e666f69803d1ae3322f2e137b7745c2c7f19da80f993ffde4df")); } } diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessorTest.java index b2f5718dad..d8d9f3777e 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessorTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessorTest.java @@ -89,7 +89,7 @@ class MainnetTransactionProcessorTest { MAX_STACK_SIZE, FeeMarket.legacy(), CoinbaseFeePriceCalculator.frontier(), - new AuthorityProcessor(Optional.of(BigInteger.ONE))); + new CodeDelegationProcessor(Optional.of(BigInteger.ONE))); } @Test diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/PendingTransaction.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/PendingTransaction.java index e15fe417a8..91b4efd7b2 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/PendingTransaction.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/PendingTransaction.java @@ -147,7 +147,7 @@ public abstract class PendingTransaction case ACCESS_LIST -> computeAccessListMemorySize(); case EIP1559 -> computeEIP1559MemorySize(); case BLOB -> computeBlobMemorySize(); - case SET_CODE -> computeSetCodeMemorySize(); + case DELEGATE_CODE -> computeSetCodeMemorySize(); } + PENDING_TRANSACTION_MEMORY_SIZE; } diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/BaseTransactionPoolTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/BaseTransactionPoolTest.java index 864c8c9181..690ab02a95 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/BaseTransactionPoolTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/layered/BaseTransactionPoolTest.java @@ -128,7 +128,7 @@ public class BaseTransactionPoolTest { final TransactionType txType = TransactionType.values()[randomizeTxType.nextInt(4)]; return switch (txType) { - case FRONTIER, ACCESS_LIST, EIP1559, SET_CODE -> + case FRONTIER, ACCESS_LIST, EIP1559, DELEGATE_CODE -> createTransaction(txType, nonce, maxGasPrice, payloadSize, keys); case BLOB -> createTransaction( 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 a7c6556e73..b5503ba81c 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 @@ -1598,7 +1598,7 @@ public class LayersTest extends BaseTransactionPoolTest { case ACCESS_LIST -> createAccessListPendingTransaction(sender, nonce); case EIP1559 -> createEIP1559PendingTransaction(sender, nonce); case BLOB -> createBlobPendingTransaction(sender, nonce); - case SET_CODE -> throw new UnsupportedOperationException(); + case DELEGATE_CODE -> throw new UnsupportedOperationException(); }; liveTxsBySender.get(sender).put(nonce, newPendingTx); return newPendingTx; 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 6f222166b3..fb0ccf4912 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 @@ -22,10 +22,12 @@ import static org.hyperledger.besu.ethereum.referencetests.ReferenceTestProtocol import org.hyperledger.besu.config.StubGenesisConfigOptions; import org.hyperledger.besu.crypto.KeyPair; +import org.hyperledger.besu.crypto.SECPSignature; import org.hyperledger.besu.crypto.SignatureAlgorithm; import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; import org.hyperledger.besu.datatypes.AccessListEntry; import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.datatypes.CodeDelegation; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.TransactionType; import org.hyperledger.besu.datatypes.VersionedHash; @@ -35,7 +37,6 @@ 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.SetCodeAuthorization; import org.hyperledger.besu.ethereum.core.Transaction; import org.hyperledger.besu.ethereum.core.TransactionReceipt; import org.hyperledger.besu.ethereum.core.WithdrawalRequest; @@ -223,8 +224,7 @@ public class T8nExecutor { continue; } - List authorizations = - new ArrayList<>(authorizationList.size()); + List authorizations = new ArrayList<>(authorizationList.size()); for (JsonNode entryAsJson : authorizationList) { final BigInteger authorizationChainId = Bytes.fromHexStringLenient(entryAsJson.get("chainId").textValue()) @@ -232,26 +232,8 @@ public class T8nExecutor { final Address authorizationAddress = Address.fromHexString(entryAsJson.get("address").textValue()); - JsonNode nonces = entryAsJson.get("nonce"); - - if (nonces == null) { - out.printf( - "TX json node unparseable: expected nonce field to be provided - %s%n", - txNode); - continue; - } - - List authorizationNonces; - if (nonces.isArray()) { - authorizationNonces = new ArrayList<>(nonces.size()); - for (JsonNode nonceAsJson : nonces) { - authorizationNonces.add( - Bytes.fromHexStringLenient(nonceAsJson.textValue()).toLong()); - } - } else { - authorizationNonces = - List.of(Bytes.fromHexStringLenient(nonces.textValue()).toLong()); - } + final long authorizationNonce = + Bytes.fromHexStringLenient(entryAsJson.get("nonce").textValue()).toLong(); final byte authorizationV = Bytes.fromHexStringLenient(entryAsJson.get("v").textValue()) @@ -264,16 +246,17 @@ public class T8nExecutor { Bytes.fromHexStringLenient(entryAsJson.get("s").textValue()) .toUnsignedBigInteger(); + final SECPSignature authorizationSignature = + new SECPSignature(authorizationR, authorizationS, authorizationV); + authorizations.add( - SetCodeAuthorization.createSetCodeAuthorizationEntry( + new org.hyperledger.besu.ethereum.core.CodeDelegation( authorizationChainId, authorizationAddress, - authorizationNonces, - authorizationV, - authorizationR, - authorizationS)); + authorizationNonce, + authorizationSignature)); } - builder.setCodeTransactionPayloads(authorizations); + builder.codeDelegations(authorizations); } if (txNode.has("blobVersionedHashes")) { @@ -328,8 +311,8 @@ public class T8nExecutor { } else { out.printf("TX json node unparseable: %s%n", txNode); } - } catch (IllegalArgumentException iae) { - rejections.add(new RejectedTransaction(i, iae.getMessage())); + } catch (IllegalArgumentException | ArithmeticException e) { + rejections.add(new RejectedTransaction(i, e.getMessage())); } i++; } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/account/Account.java b/evm/src/main/java/org/hyperledger/besu/evm/account/Account.java index 8f20eba628..8a65adf617 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/account/Account.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/account/Account.java @@ -17,6 +17,10 @@ package org.hyperledger.besu.evm.account; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Wei; +import java.util.Optional; + +import org.apache.tuweni.bytes.Bytes; + /** * A world state account. * @@ -49,4 +53,31 @@ public interface Account extends AccountState { * is set. */ boolean isStorageEmpty(); + + /** + * Returns the address of the delegated code account if it has one. + * + * @return the address of the delegated code account if it has one otherwise empty. + */ + default Optional
delegatedCodeAddress() { + return Optional.empty(); + } + + /** + * Returns a boolean to indicate if the account has delegated code. + * + * @return true if the account has delegated code otherwise false. + */ + default boolean hasDelegatedCode() { + return false; + } + + /** + * Returns the code as it is stored in the trie even if it's a delegated code account. + * + * @return the code as it is stored in the trie. + */ + default Bytes getUnprocessedCode() { + return getCode(); + } } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/account/BaseDelegatedCodeAccount.java b/evm/src/main/java/org/hyperledger/besu/evm/account/BaseDelegatedCodeAccount.java new file mode 100644 index 0000000000..0e5219d835 --- /dev/null +++ b/evm/src/main/java/org/hyperledger/besu/evm/account/BaseDelegatedCodeAccount.java @@ -0,0 +1,92 @@ +/* + * Copyright contributors to Hyperledger Besu. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.evm.account; + +import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.datatypes.Hash; +import org.hyperledger.besu.datatypes.Wei; +import org.hyperledger.besu.evm.worldstate.WorldUpdater; + +import java.util.Optional; + +import org.apache.tuweni.bytes.Bytes; + +class BaseDelegatedCodeAccount { + private final WorldUpdater worldUpdater; + + /** The address of the account that has delegated code to be loaded into it. */ + protected final Address delegatedCodeAddress; + + protected BaseDelegatedCodeAccount( + final WorldUpdater worldUpdater, final Address delegatedCodeAddress) { + this.worldUpdater = worldUpdater; + this.delegatedCodeAddress = delegatedCodeAddress; + } + + /** + * Returns the delegated code. + * + * @return the delegated code. + */ + protected Bytes getCode() { + return resolveDelegatedCode(); + } + + /** + * Returns the hash of the delegated code. + * + * @return the hash of the delegated code. + */ + protected Hash getCodeHash() { + final Bytes code = getCode(); + return (code == null || code.isEmpty()) ? Hash.EMPTY : Hash.hash(code); + } + + /** + * Returns the balance of the delegated account. + * + * @return the balance of the delegated account. + */ + protected Wei getDelegatedBalance() { + return getDelegatedAccount().map(Account::getBalance).orElse(Wei.ZERO); + } + + /** + * Returns the nonce of the delegated account. + * + * @return the nonce of the delegated account. + */ + protected long getDelegatedNonce() { + return getDelegatedAccount().map(Account::getNonce).orElse(Account.DEFAULT_NONCE); + } + + /** + * Returns the address of the delegated code. + * + * @return the address of the delegated code. + */ + protected Optional
delegatedCodeAddress() { + return Optional.of(delegatedCodeAddress); + } + + private Optional getDelegatedAccount() { + return Optional.ofNullable(worldUpdater.getAccount(delegatedCodeAddress)); + } + + private Bytes resolveDelegatedCode() { + + return getDelegatedAccount().map(Account::getUnprocessedCode).orElse(Bytes.EMPTY); + } +} diff --git a/evm/src/main/java/org/hyperledger/besu/evm/account/AuthorizedCodeAccount.java b/evm/src/main/java/org/hyperledger/besu/evm/account/DelegatedCodeAccount.java similarity index 64% rename from evm/src/main/java/org/hyperledger/besu/evm/account/AuthorizedCodeAccount.java rename to evm/src/main/java/org/hyperledger/besu/evm/account/DelegatedCodeAccount.java index 46acac74f9..1eba364c19 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/account/AuthorizedCodeAccount.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/account/DelegatedCodeAccount.java @@ -17,30 +17,33 @@ package org.hyperledger.besu.evm.account; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.Wei; +import org.hyperledger.besu.evm.worldstate.WorldUpdater; import java.util.NavigableMap; +import java.util.Optional; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; import org.apache.tuweni.units.bigints.UInt256; -/** Wraps an EOA account and includes authorized code to be run on behalf of it. */ -public class AuthorizedCodeAccount implements Account { - private final Account wrappedAccount; - private final Bytes authorizedCode; +/** Wraps an EOA account and includes delegated code to be run on behalf of it. */ +public class DelegatedCodeAccount extends BaseDelegatedCodeAccount implements Account { - /** The hash of the authorized code. */ - protected Hash codeHash = null; + private final Account wrappedAccount; /** * Creates a new AuthorizedCodeAccount. * - * @param wrappedAccount the account that has authorized code to be loaded into it. - * @param authorizedCode the authorized code. + * @param worldUpdater the world updater. + * @param wrappedAccount the account that has delegated code to be loaded into it. + * @param codeDelegationAddress the address of the delegated code. */ - public AuthorizedCodeAccount(final Account wrappedAccount, final Bytes authorizedCode) { + public DelegatedCodeAccount( + final WorldUpdater worldUpdater, + final Account wrappedAccount, + final Address codeDelegationAddress) { + super(worldUpdater, codeDelegationAddress); this.wrappedAccount = wrappedAccount; - this.authorizedCode = authorizedCode; } @Override @@ -53,6 +56,11 @@ public class AuthorizedCodeAccount implements Account { return wrappedAccount.isStorageEmpty(); } + @Override + public Optional
delegatedCodeAddress() { + return super.delegatedCodeAddress(); + } + @Override public Hash getAddressHash() { return wrappedAccount.getAddressHash(); @@ -70,16 +78,17 @@ public class AuthorizedCodeAccount implements Account { @Override public Bytes getCode() { - return authorizedCode; + return super.getCode(); } @Override - public Hash getCodeHash() { - if (codeHash == null) { - codeHash = authorizedCode.equals(Bytes.EMPTY) ? Hash.EMPTY : Hash.hash(authorizedCode); - } + public Bytes getUnprocessedCode() { + return wrappedAccount.getCode(); + } - return codeHash; + @Override + public Hash getCodeHash() { + return super.getCodeHash(); } @Override @@ -92,9 +101,24 @@ public class AuthorizedCodeAccount implements Account { return wrappedAccount.getOriginalStorageValue(key); } + @Override + public boolean isEmpty() { + return getDelegatedNonce() == 0 && getDelegatedBalance().isZero() && !hasCode(); + } + + @Override + public boolean hasCode() { + return !getCode().isEmpty(); + } + @Override public NavigableMap storageEntriesFrom( final Bytes32 startKeyHash, final int limit) { return wrappedAccount.storageEntriesFrom(startKeyHash, limit); } + + @Override + public boolean hasDelegatedCode() { + return true; + } } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/account/MutableAuthorizedCodeAccount.java b/evm/src/main/java/org/hyperledger/besu/evm/account/MutableDelegatedCodeAccount.java similarity index 69% rename from evm/src/main/java/org/hyperledger/besu/evm/account/MutableAuthorizedCodeAccount.java rename to evm/src/main/java/org/hyperledger/besu/evm/account/MutableDelegatedCodeAccount.java index 6d4e30a9c2..0e1e1145dd 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/account/MutableAuthorizedCodeAccount.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/account/MutableDelegatedCodeAccount.java @@ -17,33 +17,35 @@ package org.hyperledger.besu.evm.account; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.Wei; +import org.hyperledger.besu.evm.worldstate.WorldUpdater; import java.util.Map; import java.util.NavigableMap; +import java.util.Optional; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; import org.apache.tuweni.units.bigints.UInt256; -/** Wraps a mutable EOA account and includes authorized code to be run on behalf of it. */ -public class MutableAuthorizedCodeAccount implements MutableAccount { +/** Wraps an EOA account and includes delegated code to be run on behalf of it. */ +public class MutableDelegatedCodeAccount extends BaseDelegatedCodeAccount + implements MutableAccount { private final MutableAccount wrappedAccount; - private final Bytes authorizedCode; - - /** The hash of the authorized code. */ - protected Hash codeHash = null; /** * Creates a new MutableAuthorizedCodeAccount. * - * @param wrappedAccount the account that has authorized code to be loaded into it. - * @param authorizedCode the authorized code. + * @param worldUpdater the world updater. + * @param wrappedAccount the account that has delegated code to be loaded into it. + * @param codeDelegationAddress the address of the delegated code. */ - public MutableAuthorizedCodeAccount( - final MutableAccount wrappedAccount, final Bytes authorizedCode) { + public MutableDelegatedCodeAccount( + final WorldUpdater worldUpdater, + final MutableAccount wrappedAccount, + final Address codeDelegationAddress) { + super(worldUpdater, codeDelegationAddress); this.wrappedAccount = wrappedAccount; - this.authorizedCode = authorizedCode; } @Override @@ -56,6 +58,11 @@ public class MutableAuthorizedCodeAccount implements MutableAccount { return wrappedAccount.isStorageEmpty(); } + @Override + public Optional
delegatedCodeAddress() { + return super.delegatedCodeAddress(); + } + @Override public Hash getAddressHash() { return wrappedAccount.getAddressHash(); @@ -73,16 +80,17 @@ public class MutableAuthorizedCodeAccount implements MutableAccount { @Override public Bytes getCode() { - return authorizedCode; + return super.getCode(); } @Override - public Hash getCodeHash() { - if (codeHash == null) { - codeHash = authorizedCode.equals(Bytes.EMPTY) ? Hash.EMPTY : Hash.hash(authorizedCode); - } + public Bytes getUnprocessedCode() { + return wrappedAccount.getCode(); + } - return codeHash; + @Override + public Hash getCodeHash() { + return super.getCodeHash(); } @Override @@ -95,6 +103,16 @@ public class MutableAuthorizedCodeAccount implements MutableAccount { return wrappedAccount.getOriginalStorageValue(key); } + @Override + public boolean isEmpty() { + return getDelegatedNonce() == 0 && getDelegatedBalance().isZero() && !hasCode(); + } + + @Override + public boolean hasCode() { + return !getCode().isEmpty(); + } + @Override public NavigableMap storageEntriesFrom( final Bytes32 startKeyHash, final int limit) { @@ -113,7 +131,7 @@ public class MutableAuthorizedCodeAccount implements MutableAccount { @Override public void setCode(final Bytes code) { - throw new RuntimeException("Cannot set code on an AuthorizedCodeAccount"); + wrappedAccount.setCode(code); } @Override @@ -135,4 +153,9 @@ public class MutableAuthorizedCodeAccount implements MutableAccount { public void becomeImmutable() { wrappedAccount.becomeImmutable(); } + + @Override + public boolean hasDelegatedCode() { + return true; + } } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/GasCalculator.java b/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/GasCalculator.java index 0af023851c..fd453deac5 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/GasCalculator.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/GasCalculator.java @@ -647,12 +647,33 @@ public interface GasCalculator { } /** - * Returns the upfront gas cost for EIP 7702 operation. + * Returns the upfront gas cost for EIP 7702 authorization processing. * - * @param authorizationListLength The length of the authorization list + * @param delegateCodeListLength The length of the code delegation list * @return the gas cost */ - default long setCodeListGasCost(final int authorizationListLength) { + default long delegateCodeGasCost(final int delegateCodeListLength) { + return 0L; + } + + /** + * Calculates the refund for proessing the 7702 code delegation list if an delegater account + * already exist in the trie. + * + * @param alreadyExistingAccountSize The number of accounts already in the trie + * @return the gas refund + */ + default long calculateDelegateCodeGasRefund(final long alreadyExistingAccountSize) { + return 0L; + } + + /** + * Returns the gas cost for resolving the code of a delegate account. + * + * @param isWarm whether the account is warm + * @return the gas cost + */ + default long delegatedCodeResolutionGasCost(final boolean isWarm) { return 0L; } } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/PragueGasCalculator.java b/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/PragueGasCalculator.java index 0c223d780b..33fe98b996 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/PragueGasCalculator.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/PragueGasCalculator.java @@ -16,19 +16,17 @@ package org.hyperledger.besu.evm.gascalculator; import static org.hyperledger.besu.datatypes.Address.BLS12_MAP_FP2_TO_G2; +import org.hyperledger.besu.datatypes.CodeDelegation; + /** * Gas Calculator for Prague * - *

Placeholder for new gas schedule items. If Prague finalzies without changes this can be - * removed - * *

    - *
  • TBD + *
  • Gas costs for EIP-7702 (Code Delegation) *
*/ public class PragueGasCalculator extends CancunGasCalculator { - - static final long PER_CONTRACT_CODE_BASE_COST = 2500L; + final long existingAccountGasRefund; /** Instantiates a new Prague Gas Calculator. */ public PragueGasCalculator() { @@ -42,10 +40,21 @@ public class PragueGasCalculator extends CancunGasCalculator { */ protected PragueGasCalculator(final int maxPrecompile) { super(maxPrecompile); + this.existingAccountGasRefund = newAccountGasCost() - CodeDelegation.PER_AUTH_BASE_COST; + } + + @Override + public long delegateCodeGasCost(final int delegateCodeListLength) { + return newAccountGasCost() * delegateCodeListLength; + } + + @Override + public long calculateDelegateCodeGasRefund(final long alreadyExistingAccounts) { + return existingAccountGasRefund * alreadyExistingAccounts; } @Override - public long setCodeListGasCost(final int authorizationListLength) { - return PER_CONTRACT_CODE_BASE_COST * authorizationListLength; + public long delegatedCodeResolutionGasCost(final boolean isWarm) { + return isWarm ? getWarmStorageReadCost() : getColdAccountAccessCost(); } } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCallOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCallOperation.java index 12cb06eaa6..932bb4c391 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCallOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCallOperation.java @@ -15,6 +15,7 @@ package org.hyperledger.besu.evm.operation; import static org.hyperledger.besu.evm.internal.Words.clampedToLong; +import static org.hyperledger.besu.evm.worldstate.DelegatedCodeGasCostHelper.deductDelegatedCodeGasCost; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Wei; @@ -26,6 +27,7 @@ import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.frame.MessageFrame.State; import org.hyperledger.besu.evm.gascalculator.GasCalculator; +import org.hyperledger.besu.evm.worldstate.DelegatedCodeGasCostHelper; import org.apache.tuweni.bytes.Bytes; @@ -190,6 +192,15 @@ public abstract class AbstractCallOperation extends AbstractOperation { final Account contract = frame.getWorldUpdater().get(to); + if (contract != null) { + final DelegatedCodeGasCostHelper.Result result = + deductDelegatedCodeGasCost(frame, gasCalculator(), contract); + if (result.status() != DelegatedCodeGasCostHelper.Status.SUCCESS) { + return new Operation.OperationResult( + result.gasCost(), ExceptionalHaltReason.INSUFFICIENT_GAS); + } + } + final Account account = frame.getWorldUpdater().get(frame.getRecipientAddress()); final Wei balance = account == null ? Wei.ZERO : account.getBalance(); // If the call is sending more value than the account has or the message frame is to deep 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 7b58e956f5..c82e8c1633 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 @@ -14,6 +14,8 @@ */ package org.hyperledger.besu.evm.operation; +import static org.hyperledger.besu.evm.worldstate.DelegatedCodeGasCostHelper.deductDelegatedCodeGasCost; + import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.evm.Code; @@ -24,6 +26,7 @@ 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.Words; +import org.hyperledger.besu.evm.worldstate.DelegatedCodeGasCostHelper; import javax.annotation.Nonnull; @@ -119,6 +122,16 @@ public abstract class AbstractExtCallOperation extends AbstractCallOperation { } Address to = Words.toAddress(toBytes); final Account contract = frame.getWorldUpdater().get(to); + + if (contract != null) { + final DelegatedCodeGasCostHelper.Result result = + deductDelegatedCodeGasCost(frame, gasCalculator(), contract); + if (result.status() != DelegatedCodeGasCostHelper.Status.SUCCESS) { + return new Operation.OperationResult( + result.gasCost(), ExceptionalHaltReason.INSUFFICIENT_GAS); + } + } + boolean accountCreation = contract == null && !zeroValue; long cost = gasCalculator().memoryExpansionGasCost(frame, inputOffset, inputLength) diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtCodeCopyOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtCodeCopyOperation.java index 2f1c139182..ed1e469777 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtCodeCopyOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtCodeCopyOperation.java @@ -16,6 +16,7 @@ package org.hyperledger.besu.evm.operation; import static org.hyperledger.besu.evm.internal.Words.clampedAdd; import static org.hyperledger.besu.evm.internal.Words.clampedToLong; +import static org.hyperledger.besu.evm.worldstate.DelegatedCodeGasCostHelper.deductDelegatedCodeGasCost; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.evm.EVM; @@ -25,6 +26,7 @@ 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.Words; +import org.hyperledger.besu.evm.worldstate.DelegatedCodeGasCostHelper; import org.apache.tuweni.bytes.Bytes; @@ -93,6 +95,16 @@ public class ExtCodeCopyOperation extends AbstractOperation { } final Account account = frame.getWorldUpdater().get(address); + + if (account != null) { + final DelegatedCodeGasCostHelper.Result result = + deductDelegatedCodeGasCost(frame, gasCalculator(), account); + if (result.status() != DelegatedCodeGasCostHelper.Status.SUCCESS) { + return new Operation.OperationResult( + result.gasCost(), ExceptionalHaltReason.INSUFFICIENT_GAS); + } + } + final Bytes code = account != null ? account.getCode() : Bytes.EMPTY; if (enableEIP3540 diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtCodeHashOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtCodeHashOperation.java index c08331b006..9a8cfe8386 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtCodeHashOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtCodeHashOperation.java @@ -14,6 +14,8 @@ */ package org.hyperledger.besu.evm.operation; +import static org.hyperledger.besu.evm.worldstate.DelegatedCodeGasCostHelper.deductDelegatedCodeGasCost; + import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.evm.EVM; @@ -25,6 +27,7 @@ import org.hyperledger.besu.evm.gascalculator.GasCalculator; import org.hyperledger.besu.evm.internal.OverflowException; import org.hyperledger.besu.evm.internal.UnderflowException; import org.hyperledger.besu.evm.internal.Words; +import org.hyperledger.besu.evm.worldstate.DelegatedCodeGasCostHelper; import org.apache.tuweni.bytes.Bytes; @@ -78,23 +81,34 @@ public class ExtCodeHashOperation extends AbstractOperation { final long cost = cost(accountIsWarm); if (frame.getRemainingGas() < cost) { return new OperationResult(cost, ExceptionalHaltReason.INSUFFICIENT_GAS); + } + + final Account account = frame.getWorldUpdater().get(address); + + if (account != null) { + final DelegatedCodeGasCostHelper.Result result = + deductDelegatedCodeGasCost(frame, gasCalculator(), account); + if (result.status() != DelegatedCodeGasCostHelper.Status.SUCCESS) { + return new Operation.OperationResult( + result.gasCost(), ExceptionalHaltReason.INSUFFICIENT_GAS); + } + } + + if (account == null || account.isEmpty()) { + frame.pushStackItem(Bytes.EMPTY); } else { - final Account account = frame.getWorldUpdater().get(address); - if (account == null || account.isEmpty()) { - frame.pushStackItem(Bytes.EMPTY); + final Bytes code = account.getCode(); + if (enableEIP3540 + && code.size() >= 2 + && code.get(0) == EOFLayout.EOF_PREFIX_BYTE + && code.get(1) == 0) { + frame.pushStackItem(EOF_REPLACEMENT_HASH); } else { - final Bytes code = account.getCode(); - if (enableEIP3540 - && code.size() >= 2 - && code.get(0) == EOFLayout.EOF_PREFIX_BYTE - && code.get(1) == 0) { - frame.pushStackItem(EOF_REPLACEMENT_HASH); - } else { - frame.pushStackItem(account.getCodeHash()); - } + frame.pushStackItem(account.getCodeHash()); } - return new OperationResult(cost, null); } + return new OperationResult(cost, null); + } catch (final UnderflowException ufe) { return new OperationResult(cost(true), ExceptionalHaltReason.INSUFFICIENT_STACK_ITEMS); } catch (final OverflowException ofe) { diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtCodeSizeOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtCodeSizeOperation.java index 1779175f15..c2795f364b 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtCodeSizeOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtCodeSizeOperation.java @@ -14,6 +14,8 @@ */ package org.hyperledger.besu.evm.operation; +import static org.hyperledger.besu.evm.worldstate.DelegatedCodeGasCostHelper.deductDelegatedCodeGasCost; + import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.evm.EVM; import org.hyperledger.besu.evm.account.Account; @@ -24,6 +26,7 @@ import org.hyperledger.besu.evm.gascalculator.GasCalculator; import org.hyperledger.besu.evm.internal.OverflowException; import org.hyperledger.besu.evm.internal.UnderflowException; import org.hyperledger.besu.evm.internal.Words; +import org.hyperledger.besu.evm.worldstate.DelegatedCodeGasCostHelper; import org.apache.tuweni.bytes.Bytes; @@ -78,6 +81,16 @@ public class ExtCodeSizeOperation extends AbstractOperation { return new OperationResult(cost, ExceptionalHaltReason.INSUFFICIENT_GAS); } else { final Account account = frame.getWorldUpdater().get(address); + + if (account != null) { + final DelegatedCodeGasCostHelper.Result result = + deductDelegatedCodeGasCost(frame, gasCalculator(), account); + if (result.status() != DelegatedCodeGasCostHelper.Status.SUCCESS) { + return new Operation.OperationResult( + result.gasCost(), ExceptionalHaltReason.INSUFFICIENT_GAS); + } + } + Bytes codeSize; if (account == null) { codeSize = Bytes.EMPTY; diff --git a/evm/src/main/java/org/hyperledger/besu/evm/worldstate/AuthorizedCodeService.java b/evm/src/main/java/org/hyperledger/besu/evm/worldstate/AuthorizedCodeService.java deleted file mode 100644 index ff5d94343b..0000000000 --- a/evm/src/main/java/org/hyperledger/besu/evm/worldstate/AuthorizedCodeService.java +++ /dev/null @@ -1,116 +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.evm.worldstate; - -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.evm.account.Account; -import org.hyperledger.besu.evm.account.AuthorizedCodeAccount; -import org.hyperledger.besu.evm.account.MutableAccount; -import org.hyperledger.besu.evm.account.MutableAuthorizedCodeAccount; - -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -import org.apache.tuweni.bytes.Bytes; - -/** A service that manages the code injection of authorized code. */ -public class AuthorizedCodeService { - private final Map authorizedCode = new HashMap<>(); - - /** Creates a new AuthorizedCodeService. */ - public AuthorizedCodeService() {} - - /** - * Authorizes to load the code of authorizedCode into the authorizer account. - * - * @param authorizer the address that gives the authorization. - * @param authorizedCode the code which will be loaded. - */ - public void addAuthorizedCode(final Address authorizer, final Bytes authorizedCode) { - this.authorizedCode.put(authorizer, authorizedCode); - } - - /** - * Return all the authorities that have given their authorization to load the code of another - * account. - * - * @return the set of authorities. - */ - public Set
getAuthorities() { - return authorizedCode.keySet(); - } - - /** Resets all the authorized accounts. */ - public void resetAuthorities() { - authorizedCode.clear(); - } - - /** - * Checks if the provided address has set an authorized to load code into an EOA account. - * - * @param authority the address to check. - * @return {@code true} if the address has been authorized, {@code false} otherwise. - */ - public boolean hasAuthorizedCode(final Address authority) { - return authorizedCode.containsKey(authority); - } - - /** - * Processes the provided account, injecting the authorized code if authorized. - * - * @param worldUpdater the world updater to retrieve the code account. - * @param originalAccount the account to process. - * @param address the address of the account in case the provided account is null - * @return the processed account, containing the authorized code if authorized. - */ - public Account processAccount( - final WorldUpdater worldUpdater, final Account originalAccount, final Address address) { - if (!authorizedCode.containsKey(address)) { - return originalAccount; - } - - Account account = originalAccount; - if (account == null) { - account = worldUpdater.createAccount(address); - } - - return new AuthorizedCodeAccount(account, authorizedCode.get(address)); - } - - /** - * Processes the provided mutable account, injecting the authorized code if authorized. - * - * @param worldUpdater the world updater to retrieve the code account. - * @param originalAccount the mutable account to process. - * @param address the address of the account in case the provided account is null - * @return the processed mutable account, containing the authorized code if authorized. - */ - public MutableAccount processMutableAccount( - final WorldUpdater worldUpdater, - final MutableAccount originalAccount, - final Address address) { - if (!authorizedCode.containsKey(address)) { - return originalAccount; - } - - MutableAccount account = originalAccount; - if (account == null) { - account = worldUpdater.createAccount(address); - } - - return new MutableAuthorizedCodeAccount(account, authorizedCode.get(address)); - } -} diff --git a/evm/src/main/java/org/hyperledger/besu/evm/worldstate/DelegatedCodeGasCostHelper.java b/evm/src/main/java/org/hyperledger/besu/evm/worldstate/DelegatedCodeGasCostHelper.java new file mode 100644 index 0000000000..fc67770314 --- /dev/null +++ b/evm/src/main/java/org/hyperledger/besu/evm/worldstate/DelegatedCodeGasCostHelper.java @@ -0,0 +1,80 @@ +/* + * Copyright contributors to Hyperledger Besu. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.evm.worldstate; + +import org.hyperledger.besu.evm.account.Account; +import org.hyperledger.besu.evm.frame.MessageFrame; +import org.hyperledger.besu.evm.gascalculator.GasCalculator; + +/** + * Helper class to deduct gas cost for delegated code resolution. + * + *

Delegated code resolution is the process of determining the address of the contract that will + * be executed when a contract has delegated code. This process is necessary to determine the + * contract that will be executed and to ensure that the contract is warm in the cache. + */ +public class DelegatedCodeGasCostHelper { + + /** Private constructor to prevent instantiation. */ + private DelegatedCodeGasCostHelper() { + // empty constructor + } + + /** The status of the operation. */ + public enum Status { + /** The operation failed due to insufficient gas. */ + INSUFFICIENT_GAS, + /** The operation was successful. */ + SUCCESS + } + + /** + * The result of the operation. + * + * @param gasCost the gas cost + * @param status of the operation + */ + public record Result(long gasCost, Status status) {} + + /** + * Deducts the gas cost for delegated code resolution. + * + * @param frame the message frame + * @param gasCalculator the gas calculator + * @param account the account + * @return the gas cost and result of the operation + */ + public static Result deductDelegatedCodeGasCost( + final MessageFrame frame, final GasCalculator gasCalculator, final Account account) { + if (!account.hasDelegatedCode()) { + return new Result(0, Status.SUCCESS); + } + + if (account.delegatedCodeAddress().isEmpty()) { + throw new RuntimeException("A delegated code account must have a delegated code address"); + } + + final boolean delegatedCodeIsWarm = frame.warmUpAddress(account.delegatedCodeAddress().get()); + final long delegatedCodeResolutionGas = + gasCalculator.delegatedCodeResolutionGasCost(delegatedCodeIsWarm); + + if (frame.getRemainingGas() < delegatedCodeResolutionGas) { + return new Result(delegatedCodeResolutionGas, Status.INSUFFICIENT_GAS); + } + + frame.decrementRemainingGas(delegatedCodeResolutionGas); + return new Result(delegatedCodeResolutionGas, Status.SUCCESS); + } +} diff --git a/evm/src/main/java/org/hyperledger/besu/evm/worldstate/DelegatedCodeService.java b/evm/src/main/java/org/hyperledger/besu/evm/worldstate/DelegatedCodeService.java new file mode 100644 index 0000000000..1c89fad8bc --- /dev/null +++ b/evm/src/main/java/org/hyperledger/besu/evm/worldstate/DelegatedCodeService.java @@ -0,0 +1,97 @@ +/* + * Copyright contributors to Hyperledger Besu. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.evm.worldstate; + +import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.evm.account.Account; +import org.hyperledger.besu.evm.account.DelegatedCodeAccount; +import org.hyperledger.besu.evm.account.MutableAccount; +import org.hyperledger.besu.evm.account.MutableDelegatedCodeAccount; + +import org.apache.tuweni.bytes.Bytes; + +/** A service that manages the code injection of delegated code. */ +public class DelegatedCodeService { + private static final Bytes DELEGATED_CODE_PREFIX = Bytes.fromHexString("ef0100"); + private static final int DELEGATED_CODE_SIZE = DELEGATED_CODE_PREFIX.size() + Address.SIZE; + + /** Creates a new DelegatedCodeService. */ + public DelegatedCodeService() {} + + /** + * Add the delegated code to the given account. + * + * @param account the account to which the delegated code is added. + * @param delegatedCodeAddress the address of the delegated code. + */ + public void addDelegatedCode(final MutableAccount account, final Address delegatedCodeAddress) { + account.setCode(Bytes.concatenate(DELEGATED_CODE_PREFIX, delegatedCodeAddress)); + } + + /** + * Returns if the provided account has either no code set or has already delegated code. + * + * @param account the account to check. + * @return {@code true} if the account can set delegated code, {@code false} otherwise. + */ + public boolean canSetDelegatedCode(final Account account) { + return account.getCode().isEmpty() || hasDelegatedCode(account.getUnprocessedCode()); + } + + /** + * Processes the provided account, resolving the code if delegated. + * + * @param worldUpdater the world updater to retrieve the delegated code. + * @param account the account to process. + * @return the processed account, containing the delegated code if set, the unmodified account + * otherwise. + */ + public Account processAccount(final WorldUpdater worldUpdater, final Account account) { + if (account == null || !hasDelegatedCode(account.getCode())) { + return account; + } + + return new DelegatedCodeAccount( + worldUpdater, account, resolveDelegatedAddress(account.getCode())); + } + + /** + * Processes the provided mutable account, resolving the code if delegated. + * + * @param worldUpdater the world updater to retrieve the delegated code. + * @param account the mutable account to process. + * @return the processed mutable account, containing the delegated code if set, the unmodified + * mutable account otherwise. + */ + public MutableAccount processMutableAccount( + final WorldUpdater worldUpdater, final MutableAccount account) { + if (account == null || !hasDelegatedCode(account.getCode())) { + return account; + } + + return new MutableDelegatedCodeAccount( + worldUpdater, account, resolveDelegatedAddress(account.getCode())); + } + + private Address resolveDelegatedAddress(final Bytes code) { + return Address.wrap(code.slice(DELEGATED_CODE_PREFIX.size())); + } + + private boolean hasDelegatedCode(final Bytes code) { + return code != null + && code.size() == DELEGATED_CODE_SIZE + && code.slice(0, DELEGATED_CODE_PREFIX.size()).equals(DELEGATED_CODE_PREFIX); + } +} diff --git a/evm/src/main/java/org/hyperledger/besu/evm/worldstate/EVMWorldUpdater.java b/evm/src/main/java/org/hyperledger/besu/evm/worldstate/EVMWorldUpdater.java index bac21e73fc..928118acfe 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/worldstate/EVMWorldUpdater.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/worldstate/EVMWorldUpdater.java @@ -29,7 +29,7 @@ import java.util.Optional; */ public class EVMWorldUpdater implements WorldUpdater { private final WorldUpdater rootWorldUpdater; - private final AuthorizedCodeService authorizedCodeService; + private final DelegatedCodeService delegatedCodeService; /** * Instantiates a new EVM world updater. @@ -37,13 +37,13 @@ public class EVMWorldUpdater implements WorldUpdater { * @param rootWorldUpdater the root world updater */ public EVMWorldUpdater(final WorldUpdater rootWorldUpdater) { - this(rootWorldUpdater, new AuthorizedCodeService()); + this(rootWorldUpdater, new DelegatedCodeService()); } private EVMWorldUpdater( - final WorldUpdater rootWorldUpdater, final AuthorizedCodeService authorizedCodeService) { + final WorldUpdater rootWorldUpdater, final DelegatedCodeService delegatedCodeService) { this.rootWorldUpdater = rootWorldUpdater; - this.authorizedCodeService = authorizedCodeService; + this.delegatedCodeService = delegatedCodeService; } /** @@ -51,38 +51,36 @@ public class EVMWorldUpdater implements WorldUpdater { * * @return the authorized code service */ - public AuthorizedCodeService authorizedCodeService() { - return authorizedCodeService; + public DelegatedCodeService authorizedCodeService() { + return delegatedCodeService; } @Override public MutableAccount createAccount(final Address address, final long nonce, final Wei balance) { - return authorizedCodeService.processMutableAccount( - this, rootWorldUpdater.createAccount(address, nonce, balance), address); + return delegatedCodeService.processMutableAccount( + this, rootWorldUpdater.createAccount(address, nonce, balance)); } @Override public MutableAccount getAccount(final Address address) { - return authorizedCodeService.processMutableAccount( - this, rootWorldUpdater.getAccount(address), address); + return delegatedCodeService.processMutableAccount(this, rootWorldUpdater.getAccount(address)); } @Override public MutableAccount getOrCreate(final Address address) { - return authorizedCodeService.processMutableAccount( - this, rootWorldUpdater.getOrCreate(address), address); + return delegatedCodeService.processMutableAccount(this, rootWorldUpdater.getOrCreate(address)); } @Override public MutableAccount getOrCreateSenderAccount(final Address address) { - return authorizedCodeService.processMutableAccount( - this, rootWorldUpdater.getOrCreateSenderAccount(address), address); + return delegatedCodeService.processMutableAccount( + this, rootWorldUpdater.getOrCreateSenderAccount(address)); } @Override public MutableAccount getSenderAccount(final MessageFrame frame) { - return authorizedCodeService.processMutableAccount( - this, rootWorldUpdater.getSenderAccount(frame), frame.getSenderAddress()); + return delegatedCodeService.processMutableAccount( + this, rootWorldUpdater.getSenderAccount(frame)); } @Override @@ -117,11 +115,11 @@ public class EVMWorldUpdater implements WorldUpdater { @Override public WorldUpdater updater() { - return new EVMWorldUpdater(rootWorldUpdater.updater(), authorizedCodeService); + return new EVMWorldUpdater(rootWorldUpdater.updater(), delegatedCodeService); } @Override public Account get(final Address address) { - return authorizedCodeService.processAccount(this, rootWorldUpdater.get(address), address); + return delegatedCodeService.processAccount(this, rootWorldUpdater.get(address)); } } From 2a52b0278b56eab556a8b20c34e9034d609723f2 Mon Sep 17 00:00:00 2001 From: Stefan Pingel <16143240+pinges@users.noreply.github.com> Date: Mon, 9 Sep 2024 13:47:20 +1000 Subject: [PATCH 195/259] remove character accidentally added in CHANGELOG (#7586) Signed-off-by: stefan.pingel@consensys.net --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e15113864..aa6250508e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,7 +40,7 @@ - Correctly drops messages that exceeds local message size limit [#5455](https://github.com/hyperledger/besu/pull/7507) - **DebugMetrics**: Fixed a `ClassCastException` occurring in `DebugMetrics` when handling nested metric structures. Previously, `Double` values within these structures were incorrectly cast to `Map` objects, leading to errors. This update allows for proper handling of both direct values and nested structures at the same level. Issue# [#7383](https://github.com/hyperledger/besu/pull/7383) - `evmtool` was not respecting the `--genesis` setting, resulting in unexpected trace results. [#7433](https://github.com/hyperledger/besu/pull/7433) -- The genesis config override `contractSizeLimit`q was not wired into code size limits [#7557](https://github.com/hyperledger/besu/pull/7557) +- The genesis config override `contractSizeLimit` was not wired into code size limits [#7557](https://github.com/hyperledger/besu/pull/7557) - Fix incorrect key filtering in LayeredKeyValueStorage stream [#7535](https://github.com/hyperledger/besu/pull/7557) ## 24.8.0 From 9a570d415ec05c94473b8a8d92bfa3a4e914e48b Mon Sep 17 00:00:00 2001 From: Justin Florentine Date: Mon, 9 Sep 2024 09:25:37 -0400 Subject: [PATCH 196/259] Decouple block creators (#7468) * wip decoupled parent block header from block creators --------- Signed-off-by: Justin Florentine --- .../blockcreation/CliqueBlockCreator.java | 5 +- .../blockcreation/CliqueMinerExecutor.java | 1 - .../blockcreation/CliqueBlockCreatorTest.java | 12 +- .../blockcreation/CliqueBlockMinerTest.java | 4 +- .../bft/blockcreation/BftBlockCreator.java | 18 ++- .../blockcreation/BftBlockCreatorFactory.java | 4 +- .../consensus/ibft/support/TestContext.java | 4 +- .../tests/round/IbftRoundIntegrationTest.java | 7 +- .../ibft/statemachine/IbftRound.java | 11 +- .../ibft/statemachine/IbftRoundFactory.java | 5 +- .../blockcreation/BftBlockCreatorTest.java | 4 +- .../IbftBlockHeightManagerTest.java | 9 +- .../ibft/statemachine/IbftRoundTest.java | 42 +++-- .../blockcreation/MergeBlockCreator.java | 10 +- .../merge/blockcreation/MergeCoordinator.java | 16 +- .../blockcreation/MergeCoordinatorTest.java | 7 +- .../consensus/qbft/support/TestContext.java | 2 +- .../test/round/QbftRoundIntegrationTest.java | 7 +- .../qbft/statemachine/QbftRound.java | 13 +- .../qbft/statemachine/QbftRoundFactory.java | 5 +- .../QbftBlockHeightManagerTest.java | 9 +- .../qbft/statemachine/QbftRoundTest.java | 39 +++-- .../blockcreation/AbstractBlockCreator.java | 58 ++++--- .../ethereum/blockcreation/BlockCreator.java | 13 +- .../ethereum/blockcreation/BlockMiner.java | 6 +- .../blockcreation/PoWBlockCreator.java | 2 - .../blockcreation/PoWMinerExecutor.java | 1 - .../AbstractBlockCreatorTest.java | 144 ++++++++++-------- .../blockcreation/BlockMinerTest.java | 6 +- .../blockcreation/PoWBlockCreatorTest.java | 14 +- .../bonsai/AbstractIsolationTests.java | 8 +- .../retesteth/methods/TestMineBlocks.java | 5 +- 32 files changed, 295 insertions(+), 196 deletions(-) diff --git a/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueBlockCreator.java b/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueBlockCreator.java index 099d66dc9f..ed17529a9f 100644 --- a/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueBlockCreator.java +++ b/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueBlockCreator.java @@ -54,7 +54,6 @@ public class CliqueBlockCreator extends AbstractBlockCreator { * @param protocolContext the protocol context * @param protocolSchedule the protocol schedule * @param nodeKey the node key - * @param parentHeader the parent header * @param epochManager the epoch manager * @param ethScheduler the scheduler for asynchronous block creation tasks */ @@ -65,7 +64,6 @@ public class CliqueBlockCreator extends AbstractBlockCreator { final ProtocolContext protocolContext, final ProtocolSchedule protocolSchedule, final NodeKey nodeKey, - final BlockHeader parentHeader, final EpochManager epochManager, final EthScheduler ethScheduler) { super( @@ -75,7 +73,6 @@ public class CliqueBlockCreator extends AbstractBlockCreator { transactionPool, protocolContext, protocolSchedule, - parentHeader, ethScheduler); this.nodeKey = nodeKey; this.epochManager = epochManager; @@ -112,6 +109,8 @@ public class CliqueBlockCreator extends AbstractBlockCreator { private Optional determineCliqueVote( final SealableBlockHeader sealableBlockHeader) { + BlockHeader parentHeader = + protocolContext.getBlockchain().getBlockHeader(sealableBlockHeader.getParentHash()).get(); if (epochManager.isEpochBlock(sealableBlockHeader.getNumber())) { return Optional.empty(); } else { diff --git a/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueMinerExecutor.java b/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueMinerExecutor.java index 69b1fe70dd..ef3d58fbff 100644 --- a/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueMinerExecutor.java +++ b/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueMinerExecutor.java @@ -103,7 +103,6 @@ public class CliqueMinerExecutor extends AbstractMinerExecutor protocolContext, protocolSchedule, nodeKey, - header, epochManager, ethScheduler); diff --git a/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueBlockCreatorTest.java b/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueBlockCreatorTest.java index 9f2d848d45..ca76517c62 100644 --- a/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueBlockCreatorTest.java +++ b/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueBlockCreatorTest.java @@ -156,11 +156,11 @@ public class CliqueBlockCreatorTest { protocolContext, protocolSchedule, proposerNodeKey, - blockchain.getChainHeadHeader(), epochManager, ethScheduler); - final Block createdBlock = blockCreator.createBlock(5L).getBlock(); + final Block createdBlock = + blockCreator.createBlock(5L, blockchain.getChainHeadHeader()).getBlock(); assertThat(CliqueHelpers.getProposerOfBlock(createdBlock.getHeader())) .isEqualTo(proposerAddress); @@ -185,11 +185,11 @@ public class CliqueBlockCreatorTest { protocolContext, protocolSchedule, proposerNodeKey, - blockchain.getChainHeadHeader(), epochManager, ethScheduler); - final Block createdBlock = blockCreator.createBlock(0L).getBlock(); + final Block createdBlock = + blockCreator.createBlock(0L, blockchain.getChainHeadHeader()).getBlock(); assertThat(createdBlock.getHeader().getNonce()).isEqualTo(CliqueBlockInterface.ADD_NONCE); assertThat(createdBlock.getHeader().getCoinbase()).isEqualTo(a1); } @@ -219,11 +219,11 @@ public class CliqueBlockCreatorTest { protocolContext, protocolSchedule, proposerNodeKey, - blockchain.getChainHeadHeader(), epochManager, ethScheduler); - final Block createdBlock = blockCreator.createBlock(0L).getBlock(); + final Block createdBlock = + blockCreator.createBlock(0L, blockchain.getChainHeadHeader()).getBlock(); assertThat(createdBlock.getHeader().getNonce()).isEqualTo(CliqueBlockInterface.DROP_NONCE); assertThat(createdBlock.getHeader().getCoinbase()).isEqualTo(Address.fromHexString("0")); } diff --git a/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueBlockMinerTest.java b/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueBlockMinerTest.java index 9dd3f2e03c..8aca4713cd 100644 --- a/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueBlockMinerTest.java +++ b/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueBlockMinerTest.java @@ -91,7 +91,7 @@ class CliqueBlockMinerTest { final CliqueBlockCreator blockCreator = mock(CliqueBlockCreator.class); final Function blockCreatorSupplier = (parentHeader) -> blockCreator; - when(blockCreator.createBlock(anyLong())) + when(blockCreator.createBlock(anyLong(), any())) .thenReturn( new BlockCreator.BlockCreationResult( blockToCreate, new TransactionSelectionResults(), new BlockCreationTiming())); @@ -147,7 +147,7 @@ class CliqueBlockMinerTest { final CliqueBlockCreator blockCreator = mock(CliqueBlockCreator.class); final Function blockCreatorSupplier = (parentHeader) -> blockCreator; - when(blockCreator.createBlock(anyLong())) + when(blockCreator.createBlock(anyLong(), any())) .thenReturn( new BlockCreator.BlockCreationResult( blockToCreate, new TransactionSelectionResults(), new BlockCreationTiming())); diff --git a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftBlockCreator.java b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftBlockCreator.java index f461a77913..6bc0254b69 100644 --- a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftBlockCreator.java +++ b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftBlockCreator.java @@ -53,7 +53,6 @@ public class BftBlockCreator extends AbstractBlockCreator { * @param transactionPool the pending transactions * @param protocolContext the protocol context * @param protocolSchedule the protocol schedule - * @param parentHeader the parent header * @param bftExtraDataCodec the bft extra data codec * @param ethScheduler the scheduler for asynchronous block creation tasks */ @@ -65,7 +64,6 @@ public class BftBlockCreator extends AbstractBlockCreator { final TransactionPool transactionPool, final ProtocolContext protocolContext, final ProtocolSchedule protocolSchedule, - final BlockHeader parentHeader, final BftExtraDataCodec bftExtraDataCodec, final EthScheduler ethScheduler) { super( @@ -75,21 +73,20 @@ public class BftBlockCreator extends AbstractBlockCreator { transactionPool, protocolContext, protocolSchedule, - parentHeader, ethScheduler); this.bftExtraDataCodec = bftExtraDataCodec; } @Override - public BlockCreationResult createBlock(final long timestamp) { + public BlockCreationResult createBlock(final long timestamp, final BlockHeader parentHeader) { ProtocolSpec protocolSpec = ((BftProtocolSchedule) protocolSchedule) .getByBlockNumberOrTimestamp(parentHeader.getNumber() + 1, timestamp); if (protocolSpec.getWithdrawalsValidator() instanceof WithdrawalsValidator.AllowedWithdrawals) { - return createEmptyWithdrawalsBlock(timestamp); + return createEmptyWithdrawalsBlock(timestamp, parentHeader); } else { - return createBlock(Optional.empty(), Optional.empty(), timestamp); + return createBlock(Optional.empty(), Optional.empty(), timestamp, parentHeader); } } @@ -100,9 +97,14 @@ public class BftBlockCreator extends AbstractBlockCreator { } @Override - public BlockCreationResult createEmptyWithdrawalsBlock(final long timestamp) { + public BlockCreationResult createEmptyWithdrawalsBlock( + final long timestamp, final BlockHeader parentHeader) { return createBlock( - Optional.empty(), Optional.empty(), Optional.of(Collections.emptyList()), timestamp); + Optional.empty(), + Optional.empty(), + Optional.of(Collections.emptyList()), + timestamp, + parentHeader); } @Override diff --git a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftBlockCreatorFactory.java b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftBlockCreatorFactory.java index 64f7eef27d..7c679763b6 100644 --- a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftBlockCreatorFactory.java +++ b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftBlockCreatorFactory.java @@ -106,11 +106,10 @@ public class BftBlockCreatorFactory { /** * Create block creator. * - * @param parentHeader the parent header * @param round the round * @return the block creator */ - public BlockCreator create(final BlockHeader parentHeader, final int round) { + public BlockCreator create(final int round) { return new BftBlockCreator( miningParameters, forksSchedule, @@ -119,7 +118,6 @@ public class BftBlockCreatorFactory { transactionPool, protocolContext, protocolSchedule, - parentHeader, bftExtraDataCodec, ethScheduler); } diff --git a/consensus/ibft/src/integration-test/java/org/hyperledger/besu/consensus/ibft/support/TestContext.java b/consensus/ibft/src/integration-test/java/org/hyperledger/besu/consensus/ibft/support/TestContext.java index fdd229c13e..acf2507681 100644 --- a/consensus/ibft/src/integration-test/java/org/hyperledger/besu/consensus/ibft/support/TestContext.java +++ b/consensus/ibft/src/integration-test/java/org/hyperledger/besu/consensus/ibft/support/TestContext.java @@ -90,8 +90,8 @@ public class TestContext { final BlockHeader parent, final int round, final long timestamp) { return finalState .getBlockCreatorFactory() - .create(parent, round) - .createBlock(timestamp) + .create(round) + .createBlock(timestamp, parent) .getBlock(); } diff --git a/consensus/ibft/src/integration-test/java/org/hyperledger/besu/consensus/ibft/tests/round/IbftRoundIntegrationTest.java b/consensus/ibft/src/integration-test/java/org/hyperledger/besu/consensus/ibft/tests/round/IbftRoundIntegrationTest.java index 5c43e086fb..6a2199f713 100644 --- a/consensus/ibft/src/integration-test/java/org/hyperledger/besu/consensus/ibft/tests/round/IbftRoundIntegrationTest.java +++ b/consensus/ibft/src/integration-test/java/org/hyperledger/besu/consensus/ibft/tests/round/IbftRoundIntegrationTest.java @@ -90,6 +90,7 @@ public class IbftRoundIntegrationTest { private MessageFactory throwingMessageFactory; private IbftMessageTransmitter transmitter; @Mock private StubValidatorMulticaster multicaster; + @Mock BlockHeader parentHeader; private Block proposedBlock; @@ -145,7 +146,8 @@ public class IbftRoundIntegrationTest { throwingMessageFactory, transmitter, roundTimer, - bftExtraDataEncoder); + bftExtraDataEncoder, + parentHeader); round.handleProposalMessage( peerMessageFactory.createProposal(roundIdentifier, proposedBlock, Optional.empty())); @@ -172,7 +174,8 @@ public class IbftRoundIntegrationTest { throwingMessageFactory, transmitter, roundTimer, - bftExtraDataEncoder); + bftExtraDataEncoder, + parentHeader); // inject a block first, then a prepare on it. round.handleProposalMessage( diff --git a/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/statemachine/IbftRound.java b/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/statemachine/IbftRound.java index 460213fa43..bff32dbf3c 100644 --- a/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/statemachine/IbftRound.java +++ b/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/statemachine/IbftRound.java @@ -66,6 +66,7 @@ public class IbftRound { private final MessageFactory messageFactory; // used only to create stored local msgs private final IbftMessageTransmitter transmitter; private final BftExtraDataCodec bftExtraDataCodec; + private final BlockHeader parentHeader; /** * Instantiates a new Ibft round. @@ -80,6 +81,7 @@ public class IbftRound { * @param transmitter the transmitter * @param roundTimer the round timer * @param bftExtraDataCodec the bft extra data codec + * @param parentHeader the parent header */ public IbftRound( final RoundState roundState, @@ -91,7 +93,8 @@ public class IbftRound { final MessageFactory messageFactory, final IbftMessageTransmitter transmitter, final RoundTimer roundTimer, - final BftExtraDataCodec bftExtraDataCodec) { + final BftExtraDataCodec bftExtraDataCodec, + final BlockHeader parentHeader) { this.roundState = roundState; this.blockCreator = blockCreator; this.protocolContext = protocolContext; @@ -101,6 +104,7 @@ public class IbftRound { this.messageFactory = messageFactory; this.transmitter = transmitter; this.bftExtraDataCodec = bftExtraDataCodec; + this.parentHeader = parentHeader; roundTimer.startTimer(getRoundIdentifier()); } @@ -119,7 +123,8 @@ public class IbftRound { * @param headerTimeStampSeconds the header time stamp seconds */ public void createAndSendProposalMessage(final long headerTimeStampSeconds) { - final Block block = blockCreator.createBlock(headerTimeStampSeconds).getBlock(); + final Block block = + blockCreator.createBlock(headerTimeStampSeconds, this.parentHeader).getBlock(); final BftExtraData extraData = bftExtraDataCodec.decode(block.getHeader()); LOG.debug("Creating proposed block. round={}", roundState.getRoundIdentifier()); LOG.trace( @@ -142,7 +147,7 @@ public class IbftRound { final Block blockToPublish; if (!bestBlockFromRoundChange.isPresent()) { LOG.debug("Sending proposal with new block. round={}", roundState.getRoundIdentifier()); - blockToPublish = blockCreator.createBlock(headerTimestamp).getBlock(); + blockToPublish = blockCreator.createBlock(headerTimestamp, this.parentHeader).getBlock(); } else { LOG.debug( "Sending proposal from PreparedCertificate. round={}", roundState.getRoundIdentifier()); diff --git a/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/statemachine/IbftRoundFactory.java b/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/statemachine/IbftRoundFactory.java index 3c038fe01e..489e23b58a 100644 --- a/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/statemachine/IbftRoundFactory.java +++ b/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/statemachine/IbftRoundFactory.java @@ -100,7 +100,7 @@ public class IbftRoundFactory { public IbftRound createNewRoundWithState( final BlockHeader parentHeader, final RoundState roundState) { final BlockCreator blockCreator = - blockCreatorFactory.create(parentHeader, roundState.getRoundIdentifier().getRoundNumber()); + blockCreatorFactory.create(roundState.getRoundIdentifier().getRoundNumber()); final IbftMessageTransmitter messageTransmitter = new IbftMessageTransmitter(messageFactory, finalState.getValidatorMulticaster()); @@ -115,6 +115,7 @@ public class IbftRoundFactory { messageFactory, messageTransmitter, finalState.getRoundTimer(), - bftExtraDataCodec); + bftExtraDataCodec, + parentHeader); } } diff --git a/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/blockcreation/BftBlockCreatorTest.java b/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/blockcreation/BftBlockCreatorTest.java index 15844578cd..8b8406b638 100644 --- a/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/blockcreation/BftBlockCreatorTest.java +++ b/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/blockcreation/BftBlockCreatorTest.java @@ -191,12 +191,12 @@ public class BftBlockCreatorTest { transactionPool, protContext, protocolSchedule, - parentHeader, bftExtraDataEncoder, new DeterministicEthScheduler()); final int secondsBetweenBlocks = 1; - final Block block = blockCreator.createBlock(parentHeader.getTimestamp() + 1).getBlock(); + final Block block = + blockCreator.createBlock(parentHeader.getTimestamp() + 1, parentHeader).getBlock(); final BlockHeaderValidator rules = IbftBlockHeaderValidationRulesetFactory.blockHeaderValidator( diff --git a/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/statemachine/IbftBlockHeightManagerTest.java b/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/statemachine/IbftBlockHeightManagerTest.java index b388b80a3f..b9f57debb6 100644 --- a/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/statemachine/IbftBlockHeightManagerTest.java +++ b/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/statemachine/IbftBlockHeightManagerTest.java @@ -119,6 +119,7 @@ public class IbftBlockHeightManagerTest { @Mock private RoundTimer roundTimer; @Mock private FutureRoundProposalMessageValidator futureRoundProposalMessageValidator; @Mock private ValidatorMulticaster validatorMulticaster; + @Mock private BlockHeader parentHeader; @Captor private ArgumentCaptor sentMessageArgCaptor; @@ -158,7 +159,7 @@ public class IbftBlockHeightManagerTest { lenient().when(finalState.getQuorum()).thenReturn(3); when(finalState.getValidatorMulticaster()).thenReturn(validatorMulticaster); lenient() - .when(blockCreator.createBlock(anyLong())) + .when(blockCreator.createBlock(anyLong(), any())) .thenReturn( new BlockCreationResult( createdBlock, new TransactionSelectionResults(), new BlockCreationTiming())); @@ -210,7 +211,8 @@ public class IbftBlockHeightManagerTest { messageFactory, messageTransmitter, roundTimer, - bftExtraDataCodec); + bftExtraDataCodec, + parentHeader); }); lenient() @@ -228,7 +230,8 @@ public class IbftBlockHeightManagerTest { messageFactory, messageTransmitter, roundTimer, - bftExtraDataCodec); + bftExtraDataCodec, + parentHeader); }); } diff --git a/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/statemachine/IbftRoundTest.java b/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/statemachine/IbftRoundTest.java index e948f43f3b..f4ee852a04 100644 --- a/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/statemachine/IbftRoundTest.java +++ b/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/statemachine/IbftRoundTest.java @@ -98,6 +98,7 @@ public class IbftRoundTest { @Mock private RoundTimer roundTimer; @Mock private ProtocolSpec protocolSpec; @Mock private BlockImporter blockImporter; + @Mock private BlockHeader parentHeader; @Captor private ArgumentCaptor blockCaptor; @@ -131,7 +132,7 @@ public class IbftRoundTest { proposedBlock = new Block(header, new BlockBody(emptyList(), emptyList())); lenient() - .when(blockCreator.createBlock(anyLong())) + .when(blockCreator.createBlock(anyLong(), any())) .thenReturn( new BlockCreationResult( proposedBlock, new TransactionSelectionResults(), new BlockCreationTiming())); @@ -159,7 +160,8 @@ public class IbftRoundTest { messageFactory, transmitter, roundTimer, - bftExtraDataCodec); + bftExtraDataCodec, + parentHeader); verify(roundTimer, times(1)).startTimer(roundIdentifier); } @@ -177,7 +179,8 @@ public class IbftRoundTest { messageFactory, transmitter, roundTimer, - bftExtraDataCodec); + bftExtraDataCodec, + parentHeader); round.handleProposalMessage( messageFactory.createProposal(roundIdentifier, proposedBlock, Optional.empty())); @@ -199,7 +202,8 @@ public class IbftRoundTest { messageFactory, transmitter, roundTimer, - bftExtraDataCodec); + bftExtraDataCodec, + parentHeader); round.createAndSendProposalMessage(15); verify(transmitter, times(1)) @@ -222,7 +226,8 @@ public class IbftRoundTest { messageFactory, transmitter, roundTimer, - bftExtraDataCodec); + bftExtraDataCodec, + parentHeader); round.createAndSendProposalMessage(15); verify(transmitter, times(1)) .multicastProposal(roundIdentifier, proposedBlock, Optional.empty()); @@ -245,7 +250,8 @@ public class IbftRoundTest { messageFactory, transmitter, roundTimer, - bftExtraDataCodec); + bftExtraDataCodec, + parentHeader); final Hash commitSealHash = new BftBlockHashing(new IbftExtraDataCodec()) @@ -292,7 +298,8 @@ public class IbftRoundTest { messageFactory, transmitter, roundTimer, - bftExtraDataCodec); + bftExtraDataCodec, + parentHeader); final Hash commitSealHash = new BftBlockHashing(new IbftExtraDataCodec()) @@ -329,7 +336,8 @@ public class IbftRoundTest { messageFactory, transmitter, roundTimer, - bftExtraDataCodec); + bftExtraDataCodec, + parentHeader); final RoundChangeCertificate roundChangeCertificate = new RoundChangeCertificate(emptyList()); @@ -353,7 +361,8 @@ public class IbftRoundTest { messageFactory, transmitter, roundTimer, - bftExtraDataCodec); + bftExtraDataCodec, + parentHeader); final RoundChangeArtifacts roundChangeArtifacts = RoundChangeArtifacts.create( @@ -400,7 +409,8 @@ public class IbftRoundTest { messageFactory, transmitter, roundTimer, - bftExtraDataCodec); + bftExtraDataCodec, + parentHeader); final RoundChangeArtifacts roundChangeArtifacts = RoundChangeArtifacts.create( @@ -434,7 +444,8 @@ public class IbftRoundTest { messageFactory, transmitter, roundTimer, - bftExtraDataCodec); + bftExtraDataCodec, + parentHeader); round.createAndSendProposalMessage(15); verify(minedBlockObserver).blockMined(any()); } @@ -455,7 +466,8 @@ public class IbftRoundTest { messageFactory, transmitter, roundTimer, - bftExtraDataCodec); + bftExtraDataCodec, + parentHeader); round.handleCommitMessage( messageFactory.createCommit(roundIdentifier, proposedBlock.getHash(), remoteCommitSeal)); @@ -481,7 +493,8 @@ public class IbftRoundTest { messageFactory, transmitter, roundTimer, - bftExtraDataCodec); + bftExtraDataCodec, + parentHeader); round.handleCommitMessage( messageFactory.createCommit(roundIdentifier, proposedBlock.getHash(), remoteCommitSeal)); @@ -511,7 +524,8 @@ public class IbftRoundTest { throwingMessageFactory, transmitter, roundTimer, - bftExtraDataCodec); + bftExtraDataCodec, + parentHeader); round.handleProposalMessage( messageFactory.createProposal(roundIdentifier, proposedBlock, Optional.empty())); diff --git a/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeBlockCreator.java b/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeBlockCreator.java index 10c21384ad..c56c62d80d 100644 --- a/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeBlockCreator.java +++ b/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeBlockCreator.java @@ -61,7 +61,6 @@ class MergeBlockCreator extends AbstractBlockCreator { transactionPool, protocolContext, protocolSchedule, - parentHeader, ethScheduler); } @@ -80,7 +79,8 @@ class MergeBlockCreator extends AbstractBlockCreator { final Bytes32 random, final long timestamp, final Optional> withdrawals, - final Optional parentBeaconBlockRoot) { + final Optional parentBeaconBlockRoot, + final BlockHeader parentHeader) { return createBlock( maybeTransactions, @@ -89,14 +89,16 @@ class MergeBlockCreator extends AbstractBlockCreator { Optional.of(random), parentBeaconBlockRoot, timestamp, - false); + false, + parentHeader); } @Override public BlockCreationResult createBlock( final Optional> maybeTransactions, final Optional> maybeOmmers, - final long timestamp) { + final long timestamp, + final BlockHeader parentHeader) { throw new UnsupportedOperationException("random is required"); } 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 4d4ca0638d..c62b6e0de8 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 @@ -294,7 +294,8 @@ public class MergeCoordinator implements MergeMiningCoordinator, BadChainListene prevRandao, timestamp, withdrawals, - parentBeaconBlockRoot) + parentBeaconBlockRoot, + parentHeader) .getBlock(); BlockProcessingResult result = validateProposedBlock(emptyBlock); @@ -322,7 +323,8 @@ public class MergeCoordinator implements MergeMiningCoordinator, BadChainListene payloadIdentifier, mergeBlockCreator, withdrawals, - parentBeaconBlockRoot); + parentBeaconBlockRoot, + parentHeader); return payloadIdentifier; } @@ -363,12 +365,18 @@ public class MergeCoordinator implements MergeMiningCoordinator, BadChainListene final PayloadIdentifier payloadIdentifier, final MergeBlockCreator mergeBlockCreator, final Optional> withdrawals, - final Optional parentBeaconBlockRoot) { + final Optional parentBeaconBlockRoot, + final BlockHeader parentHeader) { final Supplier blockCreator = () -> mergeBlockCreator.createBlock( - Optional.empty(), random, timestamp, withdrawals, parentBeaconBlockRoot); + Optional.empty(), + random, + timestamp, + withdrawals, + parentBeaconBlockRoot, + parentHeader); LOG.debug( "Block creation started for payload id {}, remaining time is {}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 a3dc6b6e0b..9c1a3df075 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 @@ -285,7 +285,12 @@ public class MergeCoordinatorTest implements MergeGenesisConfigHelper { .doCallRealMethod() .when(beingSpiedOn) .createBlock( - any(), any(Bytes32.class), anyLong(), eq(Optional.empty()), eq(Optional.empty())); + any(), + any(Bytes32.class), + anyLong(), + eq(Optional.empty()), + eq(Optional.empty()), + any()); return beingSpiedOn; }; diff --git a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/TestContext.java b/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/TestContext.java index cbce344efc..10cdfa9150 100644 --- a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/TestContext.java +++ b/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/TestContext.java @@ -103,7 +103,7 @@ public class TestContext { public Block createBlockForProposal( final BlockHeader parent, final long timestamp, final Address proposer) { final Block block = - finalState.getBlockCreatorFactory().create(parent, 0).createBlock(timestamp).getBlock(); + finalState.getBlockCreatorFactory().create(0).createBlock(timestamp, parent).getBlock(); final BlockHeaderBuilder headerBuilder = BlockHeaderBuilder.fromHeader(block.getHeader()); headerBuilder diff --git a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/test/round/QbftRoundIntegrationTest.java b/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/test/round/QbftRoundIntegrationTest.java index 7d57942655..7dcca442a7 100644 --- a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/test/round/QbftRoundIntegrationTest.java +++ b/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/test/round/QbftRoundIntegrationTest.java @@ -92,6 +92,7 @@ public class QbftRoundIntegrationTest { private MessageFactory throwingMessageFactory; private QbftMessageTransmitter transmitter; @Mock private StubValidatorMulticaster multicaster; + @Mock private BlockHeader parentHeader; private Block proposedBlock; @@ -148,7 +149,8 @@ public class QbftRoundIntegrationTest { throwingMessageFactory, transmitter, roundTimer, - bftExtraDataCodec); + bftExtraDataCodec, + parentHeader); round.handleProposalMessage( peerMessageFactory.createProposal( @@ -176,7 +178,8 @@ public class QbftRoundIntegrationTest { throwingMessageFactory, transmitter, roundTimer, - bftExtraDataCodec); + bftExtraDataCodec, + parentHeader); // inject a block first, then a prepare on it. round.handleProposalMessage( diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftRound.java b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftRound.java index 47db570acc..f7c43ef43d 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftRound.java +++ b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftRound.java @@ -80,6 +80,8 @@ public class QbftRound { /** The Bft extra data codec. */ protected final BftExtraDataCodec bftExtraDataCodec; + private final BlockHeader parentHeader; + /** * Instantiates a new Qbft round. * @@ -93,6 +95,7 @@ public class QbftRound { * @param transmitter the transmitter * @param roundTimer the round timer * @param bftExtraDataCodec the bft extra data codec + * @param parentHeader the parent header */ public QbftRound( final RoundState roundState, @@ -104,7 +107,8 @@ public class QbftRound { final MessageFactory messageFactory, final QbftMessageTransmitter transmitter, final RoundTimer roundTimer, - final BftExtraDataCodec bftExtraDataCodec) { + final BftExtraDataCodec bftExtraDataCodec, + final BlockHeader parentHeader) { this.roundState = roundState; this.blockCreator = blockCreator; this.protocolContext = protocolContext; @@ -114,7 +118,7 @@ public class QbftRound { this.messageFactory = messageFactory; this.transmitter = transmitter; this.bftExtraDataCodec = bftExtraDataCodec; - + this.parentHeader = parentHeader; roundTimer.startTimer(getRoundIdentifier()); } @@ -134,7 +138,8 @@ public class QbftRound { */ public void createAndSendProposalMessage(final long headerTimeStampSeconds) { LOG.debug("Creating proposed block. round={}", roundState.getRoundIdentifier()); - final Block block = blockCreator.createBlock(headerTimeStampSeconds).getBlock(); + final Block block = + blockCreator.createBlock(headerTimeStampSeconds, this.parentHeader).getBlock(); LOG.trace("Creating proposed block blockHeader={}", block.getHeader()); updateStateWithProposalAndTransmit(block, emptyList(), emptyList()); @@ -154,7 +159,7 @@ public class QbftRound { final Block blockToPublish; if (bestPreparedCertificate.isEmpty()) { LOG.debug("Sending proposal with new block. round={}", roundState.getRoundIdentifier()); - blockToPublish = blockCreator.createBlock(headerTimestamp).getBlock(); + blockToPublish = blockCreator.createBlock(headerTimestamp, this.parentHeader).getBlock(); } else { LOG.debug( "Sending proposal from PreparedCertificate. round={}", roundState.getRoundIdentifier()); diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftRoundFactory.java b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftRoundFactory.java index 7c1c9200f9..3025330009 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftRoundFactory.java +++ b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftRoundFactory.java @@ -99,7 +99,7 @@ public class QbftRoundFactory { */ public QbftRound createNewRoundWithState( final BlockHeader parentHeader, final RoundState roundState) { - final BlockCreator blockCreator = blockCreatorFactory.create(parentHeader, 0); + final BlockCreator blockCreator = blockCreatorFactory.create(0); // TODO(tmm): Why is this created everytime?! final QbftMessageTransmitter messageTransmitter = @@ -115,6 +115,7 @@ public class QbftRoundFactory { messageFactory, messageTransmitter, finalState.getRoundTimer(), - bftExtraDataCodec); + bftExtraDataCodec, + parentHeader); } } diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftBlockHeightManagerTest.java b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftBlockHeightManagerTest.java index 71ea4131a3..171b1607f3 100644 --- a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftBlockHeightManagerTest.java +++ b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftBlockHeightManagerTest.java @@ -121,6 +121,7 @@ public class QbftBlockHeightManagerTest { @Mock private DefaultBlockchain blockchain; @Mock private FutureRoundProposalMessageValidator futureRoundProposalMessageValidator; @Mock private ValidatorMulticaster validatorMulticaster; + @Mock private BlockHeader parentHeader; @Captor private ArgumentCaptor sentMessageArgCaptor; @@ -158,7 +159,7 @@ public class QbftBlockHeightManagerTest { when(finalState.getBlockTimer()).thenReturn(blockTimer); when(finalState.getQuorum()).thenReturn(3); when(finalState.getValidatorMulticaster()).thenReturn(validatorMulticaster); - when(blockCreator.createBlock(anyLong())) + when(blockCreator.createBlock(anyLong(), any())) .thenReturn( new BlockCreationResult( createdBlock, new TransactionSelectionResults(), new BlockCreationTiming())); @@ -210,7 +211,8 @@ public class QbftBlockHeightManagerTest { messageFactory, messageTransmitter, roundTimer, - bftExtraDataCodec); + bftExtraDataCodec, + parentHeader); }); when(roundFactory.createNewRoundWithState(any(), any())) @@ -227,7 +229,8 @@ public class QbftBlockHeightManagerTest { messageFactory, messageTransmitter, roundTimer, - bftExtraDataCodec); + bftExtraDataCodec, + parentHeader); }); } diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftRoundTest.java b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftRoundTest.java index 92e7131476..514fd653a1 100644 --- a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftRoundTest.java +++ b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftRoundTest.java @@ -106,6 +106,7 @@ public class QbftRoundTest { @Mock private RoundTimer roundTimer; @Mock private ProtocolSpec protocolSpec; @Mock private BlockImporter blockImporter; + @Mock private BlockHeader parentHeader; @Captor private ArgumentCaptor blockCaptor; @@ -139,7 +140,7 @@ public class QbftRoundTest { final BlockHeader header = headerTestFixture.buildHeader(); proposedBlock = new Block(header, new BlockBody(emptyList(), emptyList())); - when(blockCreator.createBlock(anyLong())) + when(blockCreator.createBlock(anyLong(), any())) .thenReturn( new BlockCreationResult( proposedBlock, new TransactionSelectionResults(), new BlockCreationTiming())); @@ -166,7 +167,8 @@ public class QbftRoundTest { messageFactory, transmitter, roundTimer, - bftExtraDataCodec); + bftExtraDataCodec, + parentHeader); verify(roundTimer, times(1)).startTimer(roundIdentifier); } @@ -184,7 +186,8 @@ public class QbftRoundTest { messageFactory, transmitter, roundTimer, - bftExtraDataCodec); + bftExtraDataCodec, + parentHeader); round.handleProposalMessage( messageFactory.createProposal( @@ -207,7 +210,8 @@ public class QbftRoundTest { messageFactory, transmitter, roundTimer, - bftExtraDataCodec); + bftExtraDataCodec, + parentHeader); round.createAndSendProposalMessage(15); verify(transmitter, times(1)) @@ -231,7 +235,8 @@ public class QbftRoundTest { messageFactory, transmitter, roundTimer, - bftExtraDataCodec); + bftExtraDataCodec, + parentHeader); round.createAndSendProposalMessage(15); verify(transmitter, times(1)) .multicastProposal( @@ -254,7 +259,8 @@ public class QbftRoundTest { messageFactory, transmitter, roundTimer, - bftExtraDataCodec); + bftExtraDataCodec, + parentHeader); final Hash commitSealHash = new BftBlockHashing(new QbftExtraDataCodec()) @@ -288,7 +294,8 @@ public class QbftRoundTest { messageFactory, transmitter, roundTimer, - bftExtraDataCodec); + bftExtraDataCodec, + parentHeader); round.startRoundWith(new RoundChangeArtifacts(emptyList(), Optional.empty()), 15); verify(transmitter, times(1)) @@ -311,7 +318,8 @@ public class QbftRoundTest { messageFactory, transmitter, roundTimer, - bftExtraDataCodec); + bftExtraDataCodec, + parentHeader); final SignedData preparedPayload = messageFactory.createPrepare(priorRoundChange, proposedBlock.getHash()).getSignedPayload(); @@ -359,7 +367,8 @@ public class QbftRoundTest { messageFactory, transmitter, roundTimer, - bftExtraDataCodec); + bftExtraDataCodec, + parentHeader); final RoundChange roundChange = messageFactory.createRoundChange(roundIdentifier, Optional.empty()); @@ -398,7 +407,8 @@ public class QbftRoundTest { messageFactory, transmitter, roundTimer, - bftExtraDataCodec); + bftExtraDataCodec, + parentHeader); round.createAndSendProposalMessage(15); verify(minedBlockObserver).blockMined(any()); } @@ -419,7 +429,8 @@ public class QbftRoundTest { messageFactory, transmitter, roundTimer, - bftExtraDataCodec); + bftExtraDataCodec, + parentHeader); round.handleCommitMessage( messageFactory.createCommit(roundIdentifier, proposedBlock.getHash(), remoteCommitSeal)); @@ -444,7 +455,8 @@ public class QbftRoundTest { messageFactory, transmitter, roundTimer, - bftExtraDataCodec); + bftExtraDataCodec, + parentHeader); round.handleCommitMessage( messageFactory.createCommit(roundIdentifier, proposedBlock.getHash(), remoteCommitSeal)); @@ -473,7 +485,8 @@ public class QbftRoundTest { throwingMessageFactory, transmitter, roundTimer, - bftExtraDataCodec); + bftExtraDataCodec, + parentHeader); round.handleProposalMessage( messageFactory.createProposal( 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 78c32842ff..b843389c0d 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 @@ -88,7 +88,6 @@ public abstract class AbstractBlockCreator implements AsyncBlockCreator { protected final ProtocolContext protocolContext; protected final ProtocolSchedule protocolSchedule; protected final BlockHeaderFunctions blockHeaderFunctions; - protected final BlockHeader parentHeader; private final EthScheduler ethScheduler; private final AtomicBoolean isCancelled = new AtomicBoolean(false); @@ -99,7 +98,6 @@ public abstract class AbstractBlockCreator implements AsyncBlockCreator { final TransactionPool transactionPool, final ProtocolContext protocolContext, final ProtocolSchedule protocolSchedule, - final BlockHeader parentHeader, final EthScheduler ethScheduler) { this.miningParameters = miningParameters; this.miningBeneficiaryCalculator = miningBeneficiaryCalculator; @@ -107,7 +105,6 @@ public abstract class AbstractBlockCreator implements AsyncBlockCreator { this.transactionPool = transactionPool; this.protocolContext = protocolContext; this.protocolSchedule = protocolSchedule; - this.parentHeader = parentHeader; this.ethScheduler = ethScheduler; blockHeaderFunctions = ScheduleBasedBlockHeaderFunctions.create(protocolSchedule); } @@ -130,21 +127,25 @@ public abstract class AbstractBlockCreator implements AsyncBlockCreator { * @return a block with appropriately selected transactions, seals and ommers. */ @Override - public BlockCreationResult createBlock(final long timestamp) { - return createBlock(Optional.empty(), Optional.empty(), timestamp); + public BlockCreationResult createBlock(final long timestamp, final BlockHeader parentHeader) { + return createBlock(Optional.empty(), Optional.empty(), timestamp, parentHeader); } @Override public BlockCreationResult createBlock( - final List transactions, final List ommers, final long timestamp) { - return createBlock(Optional.of(transactions), Optional.of(ommers), timestamp); + final List transactions, + final List ommers, + final long timestamp, + final BlockHeader parentHeader) { + return createBlock(Optional.of(transactions), Optional.of(ommers), timestamp, parentHeader); } @Override public BlockCreationResult createBlock( final Optional> maybeTransactions, final Optional> maybeOmmers, - final long timestamp) { + final long timestamp, + final BlockHeader parentHeader) { return createBlock( maybeTransactions, maybeOmmers, @@ -152,11 +153,13 @@ public abstract class AbstractBlockCreator implements AsyncBlockCreator { Optional.empty(), Optional.empty(), timestamp, - true); + true, + parentHeader); } @Override - public BlockCreationResult createEmptyWithdrawalsBlock(final long timestamp) { + public BlockCreationResult createEmptyWithdrawalsBlock( + final long timestamp, final BlockHeader parentHeader) { throw new UnsupportedOperationException("Only used by BFT block creators"); } @@ -164,7 +167,8 @@ public abstract class AbstractBlockCreator implements AsyncBlockCreator { final Optional> maybeTransactions, final Optional> maybeOmmers, final Optional> maybeWithdrawals, - final long timestamp) { + final long timestamp, + final BlockHeader parentHeader) { return createBlock( maybeTransactions, maybeOmmers, @@ -172,7 +176,8 @@ public abstract class AbstractBlockCreator implements AsyncBlockCreator { Optional.empty(), Optional.empty(), timestamp, - true); + true, + parentHeader); } protected BlockCreationResult createBlock( @@ -182,18 +187,23 @@ public abstract class AbstractBlockCreator implements AsyncBlockCreator { final Optional maybePrevRandao, final Optional maybeParentBeaconBlockRoot, final long timestamp, - boolean rewardCoinbase) { + boolean rewardCoinbase, + final BlockHeader parentHeader) { final var timings = new BlockCreationTiming(); - try (final MutableWorldState disposableWorldState = duplicateWorldStateAtParent()) { + try (final MutableWorldState disposableWorldState = duplicateWorldStateAtParent(parentHeader)) { timings.register("duplicateWorldState"); final ProtocolSpec newProtocolSpec = protocolSchedule.getForNextBlockHeader(parentHeader, timestamp); final ProcessableBlockHeader processableBlockHeader = createPendingBlockHeader( - timestamp, maybePrevRandao, maybeParentBeaconBlockRoot, newProtocolSpec); + timestamp, + maybePrevRandao, + maybeParentBeaconBlockRoot, + newProtocolSpec, + parentHeader); final Address miningBeneficiary = miningBeneficiaryCalculator.getMiningBeneficiary(processableBlockHeader.getNumber()); @@ -223,7 +233,8 @@ public abstract class AbstractBlockCreator implements AsyncBlockCreator { maybeTransactions, miningBeneficiary, newProtocolSpec, - pluginTransactionSelector); + pluginTransactionSelector, + parentHeader); transactionResults.logSelectionStats(); timings.register("txsSelection"); throwIfStopped(); @@ -273,7 +284,8 @@ public abstract class AbstractBlockCreator implements AsyncBlockCreator { throwIfStopped(); - final GasUsage usage = computeExcessBlobGas(transactionResults, newProtocolSpec); + final GasUsage usage = + computeExcessBlobGas(transactionResults, newProtocolSpec, parentHeader); throwIfStopped(); @@ -324,7 +336,9 @@ public abstract class AbstractBlockCreator implements AsyncBlockCreator { record GasUsage(BlobGas excessBlobGas, BlobGas used) {} private GasUsage computeExcessBlobGas( - final TransactionSelectionResults transactionResults, final ProtocolSpec newProtocolSpec) { + final TransactionSelectionResults transactionResults, + final ProtocolSpec newProtocolSpec, + final BlockHeader parentHeader) { if (newProtocolSpec.getFeeMarket().implementsDataFee()) { final var gasCalculator = newProtocolSpec.getGasCalculator(); @@ -349,7 +363,8 @@ public abstract class AbstractBlockCreator implements AsyncBlockCreator { final Optional> transactions, final Address miningBeneficiary, final ProtocolSpec protocolSpec, - final PluginTransactionSelector pluginTransactionSelector) + final PluginTransactionSelector pluginTransactionSelector, + final BlockHeader parentHeader) throws RuntimeException { final MainnetTransactionProcessor transactionProcessor = protocolSpec.getTransactionProcessor(); @@ -387,7 +402,7 @@ public abstract class AbstractBlockCreator implements AsyncBlockCreator { } } - private MutableWorldState duplicateWorldStateAtParent() { + private MutableWorldState duplicateWorldStateAtParent(final BlockHeader parentHeader) { final Hash parentStateRoot = parentHeader.getStateRoot(); return protocolContext .getWorldStateArchive() @@ -411,7 +426,8 @@ public abstract class AbstractBlockCreator implements AsyncBlockCreator { final long timestamp, final Optional maybePrevRandao, final Optional maybeParentBeaconBlockRoot, - final ProtocolSpec protocolSpec) { + final ProtocolSpec protocolSpec, + final BlockHeader parentHeader) { final long newBlockNumber = parentHeader.getNumber() + 1; long gasLimit = protocolSpec diff --git a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/BlockCreator.java b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/BlockCreator.java index 24bff4c47e..988cc7e763 100644 --- a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/BlockCreator.java +++ b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/BlockCreator.java @@ -50,15 +50,20 @@ public interface BlockCreator { } } - BlockCreationResult createBlock(final long timestamp); + BlockCreationResult createBlock(final long timestamp, final BlockHeader parentHeader); - BlockCreationResult createEmptyWithdrawalsBlock(final long timestamp); + BlockCreationResult createEmptyWithdrawalsBlock( + final long timestamp, final BlockHeader parentHeader); BlockCreationResult createBlock( - final List transactions, final List ommers, final long timestamp); + final List transactions, + final List ommers, + final long timestamp, + final BlockHeader parentHeader); BlockCreationResult createBlock( final Optional> maybeTransactions, final Optional> maybeOmmers, - final long timestamp); + final long timestamp, + final BlockHeader parentHeader); } diff --git a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/BlockMiner.java b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/BlockMiner.java index 646e6d5251..f51451f293 100644 --- a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/BlockMiner.java +++ b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/BlockMiner.java @@ -109,7 +109,7 @@ public class BlockMiner implements Runnable { final List ommers) { final BlockCreator blockCreator = this.blockCreatorFactory.apply(parentHeader); final long timestamp = scheduler.getNextTimestamp(parentHeader).timestampForHeader(); - return blockCreator.createBlock(transactions, ommers, timestamp); + return blockCreator.createBlock(transactions, ommers, timestamp, parentHeader); } /** @@ -121,7 +121,7 @@ public class BlockMiner implements Runnable { */ public BlockCreationResult createBlock(final BlockHeader parentHeader, final long timestamp) { final BlockCreator blockCreator = this.blockCreatorFactory.apply(parentHeader); - return blockCreator.createBlock(Optional.empty(), Optional.empty(), timestamp); + return blockCreator.createBlock(Optional.empty(), Optional.empty(), timestamp, parentHeader); } protected boolean shouldImportBlock(final Block block) throws InterruptedException { @@ -140,7 +140,7 @@ public class BlockMiner implements Runnable { LOG.trace("Mining a new block with timestamp {}", newBlockTimestamp); - final var blockCreationResult = minerBlockCreator.createBlock(newBlockTimestamp); + final var blockCreationResult = minerBlockCreator.createBlock(newBlockTimestamp, parentHeader); timing.registerAll(blockCreationResult.getBlockCreationTimings()); final Block block = blockCreationResult.getBlock(); diff --git a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/PoWBlockCreator.java b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/PoWBlockCreator.java index 39b055e817..d0042a5ad9 100644 --- a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/PoWBlockCreator.java +++ b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/PoWBlockCreator.java @@ -45,7 +45,6 @@ public class PoWBlockCreator extends AbstractBlockCreator { final ProtocolContext protocolContext, final ProtocolSchedule protocolSchedule, final PoWSolver nonceSolver, - final BlockHeader parentHeader, final EthScheduler ethScheduler) { super( miningParameters, @@ -54,7 +53,6 @@ public class PoWBlockCreator extends AbstractBlockCreator { transactionPool, protocolContext, protocolSchedule, - parentHeader, ethScheduler); this.nonceSolver = nonceSolver; diff --git a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/PoWMinerExecutor.java b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/PoWMinerExecutor.java index 78524e3035..b14eb19340 100644 --- a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/PoWMinerExecutor.java +++ b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/PoWMinerExecutor.java @@ -93,7 +93,6 @@ public class PoWMinerExecutor extends AbstractMinerExecutor { protocolContext, protocolSchedule, solver, - parentHeader, ethScheduler); return new PoWBlockMiner( 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 88a39925b9..ffab847bbd 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 @@ -161,18 +161,19 @@ abstract class AbstractBlockCreatorTest { @Test void withAllowedDepositRequestsAndContractAddress_DepositRequestsAreParsed() { - final AbstractBlockCreator blockCreator = + final CreateOn miningOn = blockCreatorWithAllowedDepositRequests(DEFAULT_DEPOSIT_CONTRACT_ADDRESS); final BlockCreationResult blockCreationResult = - blockCreator.createBlock( + miningOn.blockCreator.createBlock( Optional.empty(), Optional.empty(), Optional.of(emptyList()), Optional.empty(), Optional.empty(), 1L, - false); + false, + miningOn.parentHeader); List depositRequests = emptyList(); final Hash requestsRoot = BodyValidation.requestsRoot(depositRequests); @@ -182,17 +183,18 @@ abstract class AbstractBlockCreatorTest { @Test void withAllowedDepositRequestsAndNoContractAddress_DepositRequestsAreNotParsed() { - final AbstractBlockCreator blockCreator = blockCreatorWithAllowedDepositRequests(null); + final CreateOn miningOn = blockCreatorWithAllowedDepositRequests(null); final BlockCreationResult blockCreationResult = - blockCreator.createBlock( + miningOn.blockCreator.createBlock( Optional.empty(), Optional.empty(), Optional.of(emptyList()), Optional.empty(), Optional.empty(), 1L, - false); + false, + miningOn.parentHeader); assertThat(blockCreationResult.getBlock().getHeader().getRequestsRoot()).isEmpty(); assertThat(blockCreationResult.getBlock().getBody().getRequests()).isEmpty(); @@ -200,53 +202,28 @@ abstract class AbstractBlockCreatorTest { @Test void withProhibitedDepositRequests_DepositRequestsAreNotParsed() { - final AbstractBlockCreator blockCreator = blockCreatorWithProhibitedDepositRequests(); + + final CreateOn miningOn = blockCreatorWithProhibitedDepositRequests(); final BlockCreationResult blockCreationResult = - blockCreator.createBlock( + miningOn.blockCreator.createBlock( Optional.empty(), Optional.empty(), Optional.of(emptyList()), Optional.empty(), Optional.empty(), 1L, - false); + false, + miningOn.parentHeader); assertThat(blockCreationResult.getBlock().getHeader().getRequestsRoot()).isEmpty(); assertThat(blockCreationResult.getBlock().getBody().getRequests()).isEmpty(); } - private AbstractBlockCreator 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); - } - - private AbstractBlockCreator blockCreatorWithProhibitedDepositRequests() { - final ProtocolSpecAdapters protocolSpecAdapters = - ProtocolSpecAdapters.create(0, specBuilder -> specBuilder); - return createBlockCreator(protocolSpecAdapters); - } - @Test void withProcessorAndEmptyWithdrawals_NoWithdrawalsAreProcessed() { - final AbstractBlockCreator blockCreator = blockCreatorWithWithdrawalsProcessor(); + final CreateOn miningOn = blockCreatorWithWithdrawalsProcessor(); + final AbstractBlockCreator blockCreator = miningOn.blockCreator; final BlockCreationResult blockCreationResult = blockCreator.createBlock( Optional.empty(), @@ -255,7 +232,8 @@ abstract class AbstractBlockCreatorTest { Optional.empty(), Optional.empty(), 1L, - false); + false, + miningOn.parentHeader); verify(withdrawalsProcessor, never()).processWithdrawals(any(), any()); assertThat(blockCreationResult.getBlock().getHeader().getWithdrawalsRoot()).isEmpty(); assertThat(blockCreationResult.getBlock().getBody().getWithdrawals()).isEmpty(); @@ -263,7 +241,8 @@ abstract class AbstractBlockCreatorTest { @Test void withNoProcessorAndEmptyWithdrawals_NoWithdrawalsAreNotProcessed() { - final AbstractBlockCreator blockCreator = blockCreatorWithoutWithdrawalsProcessor(); + final CreateOn miningOn = blockCreatorWithoutWithdrawalsProcessor(); + final AbstractBlockCreator blockCreator = miningOn.blockCreator; final BlockCreationResult blockCreationResult = blockCreator.createBlock( Optional.empty(), @@ -272,7 +251,8 @@ abstract class AbstractBlockCreatorTest { Optional.empty(), Optional.empty(), 1L, - false); + false, + miningOn.parentHeader); verify(withdrawalsProcessor, never()).processWithdrawals(any(), any()); assertThat(blockCreationResult.getBlock().getHeader().getWithdrawalsRoot()).isEmpty(); assertThat(blockCreationResult.getBlock().getBody().getWithdrawals()).isEmpty(); @@ -280,7 +260,8 @@ abstract class AbstractBlockCreatorTest { @Test void withProcessorAndWithdrawals_WithdrawalsAreProcessed() { - final AbstractBlockCreator blockCreator = blockCreatorWithWithdrawalsProcessor(); + final CreateOn miningOn = blockCreatorWithWithdrawalsProcessor(); + final AbstractBlockCreator blockCreator = miningOn.blockCreator; final List withdrawals = List.of(new Withdrawal(UInt64.ONE, UInt64.ONE, Address.fromHexString("0x1"), GWei.ONE)); final BlockCreationResult blockCreationResult = @@ -291,7 +272,8 @@ abstract class AbstractBlockCreatorTest { Optional.empty(), Optional.empty(), 1L, - false); + false, + miningOn.parentHeader); final Hash withdrawalsRoot = BodyValidation.withdrawalsRoot(withdrawals); verify(withdrawalsProcessor).processWithdrawals(eq(withdrawals), any()); @@ -302,7 +284,8 @@ abstract class AbstractBlockCreatorTest { @Test void withNoProcessorAndWithdrawals_WithdrawalsAreNotProcessed() { - final AbstractBlockCreator blockCreator = blockCreatorWithoutWithdrawalsProcessor(); + final CreateOn miningOn = blockCreatorWithoutWithdrawalsProcessor(); + final AbstractBlockCreator blockCreator = miningOn.blockCreator; final List withdrawals = List.of(new Withdrawal(UInt64.ONE, UInt64.ONE, Address.fromHexString("0x1"), GWei.ONE)); final BlockCreationResult blockCreationResult = @@ -313,7 +296,8 @@ abstract class AbstractBlockCreatorTest { Optional.empty(), Optional.empty(), 1L, - false); + false, + miningOn.parentHeader); verify(withdrawalsProcessor, never()).processWithdrawals(any(), any()); assertThat(blockCreationResult.getBlock().getHeader().getWithdrawalsRoot()).isEmpty(); assertThat(blockCreationResult.getBlock().getBody().getWithdrawals()).isEmpty(); @@ -321,7 +305,8 @@ abstract class AbstractBlockCreatorTest { @Test public void computesGasUsageFromIncludedTransactions() { - final AbstractBlockCreator blockCreator = blockCreatorWithBlobGasSupport(); + final CreateOn miningOn = blockCreatorWithBlobGasSupport(); + final AbstractBlockCreator blockCreator = miningOn.blockCreator; BlobTestFixture blobTestFixture = new BlobTestFixture(); BlobsWithCommitments bwc = blobTestFixture.createBlobsWithCommitments(6); TransactionTestFixture ttf = new TransactionTestFixture(); @@ -345,14 +330,15 @@ abstract class AbstractBlockCreatorTest { Optional.empty(), Optional.empty(), 1L, - false); + false, + miningOn.parentHeader); long blobGasUsage = blockCreationResult.getBlock().getHeader().getGasUsed(); assertThat(blobGasUsage).isNotZero(); BlobGas excessBlobGas = blockCreationResult.getBlock().getHeader().getExcessBlobGas().get(); assertThat(excessBlobGas).isNotNull(); } - private AbstractBlockCreator blockCreatorWithBlobGasSupport() { + private CreateOn blockCreatorWithBlobGasSupport() { final var alwaysValidTransactionValidatorFactory = mock(TransactionValidatorFactory.class); when(alwaysValidTransactionValidatorFactory.get()) .thenReturn(new AlwaysValidTransactionValidator()); @@ -369,20 +355,49 @@ abstract class AbstractBlockCreatorTest { return createBlockCreator(protocolSpecAdapters); } - private AbstractBlockCreator blockCreatorWithWithdrawalsProcessor() { + private CreateOn blockCreatorWithProhibitedDepositRequests() { + final ProtocolSpecAdapters protocolSpecAdapters = + ProtocolSpecAdapters.create(0, specBuilder -> specBuilder); + return createBlockCreator(protocolSpecAdapters); + } + + private CreateOn blockCreatorWithWithdrawalsProcessor() { final ProtocolSpecAdapters protocolSpecAdapters = ProtocolSpecAdapters.create( 0, specBuilder -> specBuilder.withdrawalsProcessor(withdrawalsProcessor)); return createBlockCreator(protocolSpecAdapters); } - private AbstractBlockCreator blockCreatorWithoutWithdrawalsProcessor() { + private CreateOn blockCreatorWithoutWithdrawalsProcessor() { final ProtocolSpecAdapters protocolSpecAdapters = ProtocolSpecAdapters.create(0, specBuilder -> specBuilder.withdrawalsProcessor(null)); return createBlockCreator(protocolSpecAdapters); } - private AbstractBlockCreator createBlockCreator(final ProtocolSpecAdapters 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) { final var genesisConfigFile = GenesisConfigFile.fromResource("/block-creation-genesis.json"); final ExecutionContextTestFixture executionContextTestFixture = @@ -403,11 +418,15 @@ abstract class AbstractBlockCreatorTest { .build(); final MutableBlockchain blockchain = executionContextTestFixture.getBlockchain(); + BlockHeader parentHeader = blockchain.getChainHeadHeader(); final TransactionPoolConfiguration poolConf = ImmutableTransactionPoolConfiguration.builder().txPoolMaxSize(100).build(); final AbstractPendingTransactionsSorter sorter = new GasPricePendingTransactionsSorter( - poolConf, Clock.systemUTC(), new NoOpMetricsSystem(), blockchain::getChainHeadHeader); + poolConf, + Clock.systemUTC(), + new NoOpMetricsSystem(), + Suppliers.ofInstance(parentHeader)); final EthContext ethContext = mock(EthContext.class, RETURNS_DEEP_STUBS); when(ethContext.getEthPeers().subscribeConnect(any())).thenReturn(1L); @@ -435,15 +454,16 @@ abstract class AbstractBlockCreatorTest { .build()) .build(); - return new TestBlockCreator( - miningParameters, - __ -> Address.ZERO, - __ -> Bytes.fromHexString("deadbeef"), - transactionPool, - executionContextTestFixture.getProtocolContext(), - executionContextTestFixture.getProtocolSchedule(), - blockchain.getChainHeadHeader(), - ethScheduler); + return new CreateOn( + new TestBlockCreator( + miningParameters, + __ -> Address.ZERO, + __ -> Bytes.fromHexString("deadbeef"), + transactionPool, + executionContextTestFixture.getProtocolContext(), + executionContextTestFixture.getProtocolSchedule(), + ethScheduler), + parentHeader); } static class TestBlockCreator extends AbstractBlockCreator { @@ -455,7 +475,6 @@ abstract class AbstractBlockCreatorTest { final TransactionPool transactionPool, final ProtocolContext protocolContext, final ProtocolSchedule protocolSchedule, - final BlockHeader parentHeader, final EthScheduler ethScheduler) { super( miningParameters, @@ -464,7 +483,6 @@ abstract class AbstractBlockCreatorTest { transactionPool, protocolContext, protocolSchedule, - parentHeader, ethScheduler); } diff --git a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/BlockMinerTest.java b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/BlockMinerTest.java index 3910d899d9..e5b46925aa 100644 --- a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/BlockMinerTest.java +++ b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/BlockMinerTest.java @@ -63,7 +63,7 @@ public class BlockMinerTest { final PoWBlockCreator blockCreator = mock(PoWBlockCreator.class); final Function blockCreatorSupplier = (parentHeader) -> blockCreator; - when(blockCreator.createBlock(anyLong())) + when(blockCreator.createBlock(anyLong(), any())) .thenReturn( new BlockCreationResult( blockToCreate, new TransactionSelectionResults(), new BlockCreationTiming())); @@ -107,7 +107,7 @@ public class BlockMinerTest { final PoWBlockCreator blockCreator = mock(PoWBlockCreator.class); final Function blockCreatorSupplier = (parentHeader) -> blockCreator; - when(blockCreator.createBlock(anyLong())) + when(blockCreator.createBlock(anyLong(), any())) .thenReturn( new BlockCreationResult( blockToCreate, new TransactionSelectionResults(), new BlockCreationTiming())); @@ -155,7 +155,7 @@ public class BlockMinerTest { final PoWBlockCreator blockCreator = mock(PoWBlockCreator.class); final Function blockCreatorSupplier = (parentHeader) -> blockCreator; - when(blockCreator.createBlock(anyLong())) + when(blockCreator.createBlock(anyLong(), any())) .thenReturn( new BlockCreationResult( blockToCreate, new TransactionSelectionResults(), new BlockCreationTiming())); diff --git a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/PoWBlockCreatorTest.java b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/PoWBlockCreatorTest.java index e9e727d99c..509efd7b19 100644 --- a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/PoWBlockCreatorTest.java +++ b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/PoWBlockCreatorTest.java @@ -123,13 +123,14 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest { executionContextTestFixture.getProtocolContext(), executionContextTestFixture.getProtocolSchedule(), solver, - executionContextTestFixture.getBlockchain().getChainHeadHeader(), ethScheduler); // A Hashrate should not exist in the block creator prior to creating a block assertThat(blockCreator.getHashesPerSecond()).isNotPresent(); - final BlockCreationResult blockResult = blockCreator.createBlock(BLOCK_1_TIMESTAMP); + final BlockCreationResult blockResult = + blockCreator.createBlock( + BLOCK_1_TIMESTAMP, executionContextTestFixture.getBlockchain().getChainHeadHeader()); final Block actualBlock = blockResult.getBlock(); final Block expectedBlock = ValidationTestUtils.readBlock(1); @@ -186,10 +187,13 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest { executionContextTestFixture.getProtocolContext(), executionContextTestFixture.getProtocolSchedule(), solver, - executionContextTestFixture.getBlockchain().getChainHeadHeader(), ethScheduler); - assertThat(blockCreator.createBlock(BLOCK_1_TIMESTAMP)).isNotNull(); + assertThat( + blockCreator.createBlock( + BLOCK_1_TIMESTAMP, + executionContextTestFixture.getBlockchain().getChainHeadHeader())) + .isNotNull(); // If we weren't setting difficulty to 2^256-1 a difficulty of 1 would have caused a // IllegalArgumentException at the previous line, as 2^256 is 33 bytes. } @@ -242,7 +246,6 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest { executionContextTestFixture.getProtocolContext(), executionContextTestFixture.getProtocolSchedule(), solver, - executionContextTestFixture.getBlockchain().getChainHeadHeader(), ethScheduler); final MutableWorldState mutableWorldState = @@ -320,7 +323,6 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest { executionContextTestFixture.getProtocolContext(), executionContextTestFixture.getProtocolSchedule(), solver, - executionContextTestFixture.getBlockchain().getChainHeadHeader(), ethScheduler); final MutableWorldState mutableWorldState = diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/AbstractIsolationTests.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/AbstractIsolationTests.java index 939e3ec0cd..dd9257441e 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/AbstractIsolationTests.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/AbstractIsolationTests.java @@ -260,7 +260,6 @@ public abstract class AbstractIsolationTests { final TransactionPool transactionPool, final ProtocolContext protocolContext, final ProtocolSchedule protocolSchedule, - final BlockHeader parentHeader, final EthScheduler ethScheduler) { super( miningParameters, @@ -269,12 +268,10 @@ public abstract class AbstractIsolationTests { transactionPool, protocolContext, protocolSchedule, - parentHeader, ethScheduler); } static TestBlockCreator forHeader( - final BlockHeader parentHeader, final ProtocolContext protocolContext, final ProtocolSchedule protocolSchedule, final TransactionPool transactionPool, @@ -299,7 +296,6 @@ public abstract class AbstractIsolationTests { transactionPool, protocolContext, protocolSchedule, - parentHeader, ethScheduler); } @@ -332,8 +328,8 @@ public abstract class AbstractIsolationTests { protected Block forTransactions( final List transactions, final BlockHeader forHeader) { return TestBlockCreator.forHeader( - forHeader, protocolContext, protocolSchedule, transactionPool, ethScheduler) - .createBlock(transactions, Collections.emptyList(), System.currentTimeMillis()) + protocolContext, protocolSchedule, transactionPool, ethScheduler) + .createBlock(transactions, Collections.emptyList(), System.currentTimeMillis(), forHeader) .getBlock(); } diff --git a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestMineBlocks.java b/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestMineBlocks.java index 80a4872442..00a27bb7a8 100644 --- a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestMineBlocks.java +++ b/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestMineBlocks.java @@ -78,10 +78,11 @@ public class TestMineBlocks implements JsonRpcMethod { protocolContext, protocolSchedule, context.getEthHashSolver(), - blockchain.getChainHeadHeader(), context.getEthScheduler()); final Block block = - blockCreator.createBlock(retesethClock.instant().getEpochSecond()).getBlock(); + blockCreator + .createBlock(retesethClock.instant().getEpochSecond(), blockchain.getChainHeadHeader()) + .getBlock(); // advance clock so next mine won't hit the same timestamp retesethClock.advanceSeconds(1); From 36454b40d57cb699c7879746c6fb1e83e67717e1 Mon Sep 17 00:00:00 2001 From: ITStarMan100 Date: Tue, 10 Sep 2024 01:34:45 +0000 Subject: [PATCH 197/259] Added help for setting up Stratum mining (#7584) * Added help for setting up Stratum mining Signed-off-by: ITStarMan100 * removed duplication from help message; fixed spotless Signed-off-by: Sally MacFarlane --------- Signed-off-by: ITStarMan100 Signed-off-by: Sally MacFarlane Co-authored-by: Sally MacFarlane --- besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java | 2 +- .../java/org/hyperledger/besu/cli/options/MiningOptions.java | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java b/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java index 9eaf254bbf..39e4356a7f 100644 --- a/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java @@ -805,7 +805,7 @@ public class RunnerBuilder { if (miningParameters.isStratumMiningEnabled()) { if (!(miningCoordinator instanceof PoWMiningCoordinator powMiningCoordinator)) { throw new IllegalArgumentException( - "Stratum server requires an PoWMiningCoordinator not " + "Stratum mining requires the network option(--network) to be set to CLASSIC. Stratum server requires a PoWMiningCoordinator not " + ((miningCoordinator == null) ? "null" : miningCoordinator.getClass().getName())); } stratumServer = diff --git a/besu/src/main/java/org/hyperledger/besu/cli/options/MiningOptions.java b/besu/src/main/java/org/hyperledger/besu/cli/options/MiningOptions.java index ba4d99bc83..a884edfe33 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/options/MiningOptions.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/options/MiningOptions.java @@ -59,7 +59,10 @@ public class MiningOptions implements CLIOptions { @Option( names = {"--miner-stratum-enabled"}, - description = "Set if node will perform Stratum mining (default: ${DEFAULT-VALUE})") + description = + "Set if node will perform Stratum mining (default: ${DEFAULT-VALUE})." + + " Compatible with Proof of Work (PoW) only." + + " Requires the network option (--network) to be set to CLASSIC.") private Boolean iStratumMiningEnabled = false; @Option( From 01fcc7fcfb7b0a45ce73c02c537fa34d060ad44b Mon Sep 17 00:00:00 2001 From: daniellehrner Date: Tue, 10 Sep 2024 11:37:47 +0200 Subject: [PATCH 198/259] Fix tx validation if sender has delegated it's code via 7702 transaction (#7593) Signed-off-by: Daniel Lehrner --- ...deDelegationTransactionAcceptanceTest.java | 56 +++++++++++++++---- .../mainnet/MainnetTransactionValidator.java | 4 +- .../evm/worldstate/DelegatedCodeService.java | 16 ++++-- 3 files changed, 58 insertions(+), 18 deletions(-) diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/ethereum/CodeDelegationTransactionAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/ethereum/CodeDelegationTransactionAcceptanceTest.java index 6000915b44..ee896ccd27 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/ethereum/CodeDelegationTransactionAcceptanceTest.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/ethereum/CodeDelegationTransactionAcceptanceTest.java @@ -175,29 +175,61 @@ public class CodeDelegationTransactionAcceptanceTest extends AcceptanceTestBase besuNode.execute(ethTransactions.sendRawTransaction(tx.encoded().toHexString())); testHelper.buildNewBlock(); - Optional maybeTransactionReceipt = + final Optional maybeFirstTransactionReceipt = besuNode.execute(ethTransactions.getTransactionReceipt(txHash)); - assertThat(maybeTransactionReceipt).isPresent(); + assertThat(maybeFirstTransactionReceipt).isPresent(); final String gasPriceWithout0x = - maybeTransactionReceipt.get().getEffectiveGasPrice().substring(2); + maybeFirstTransactionReceipt.get().getEffectiveGasPrice().substring(2); final BigInteger gasPrice = new BigInteger(gasPriceWithout0x, 16); - final BigInteger txCost = maybeTransactionReceipt.get().getGasUsed().multiply(gasPrice); + final BigInteger txCost = maybeFirstTransactionReceipt.get().getGasUsed().multiply(gasPrice); - final BigInteger authorizerBalance = besuNode.execute(ethTransactions.getBalance(authorizer)); + final BigInteger authorizerBalanceAfterFirstTx = + besuNode.execute(ethTransactions.getBalance(authorizer)); // The remaining balance of the authorizer should the gas limit multiplied by the gas price // minus the transaction cost. // The following executes this calculation in reverse. - assertThat(GAS_LIMIT).isEqualTo(authorizerBalance.add(txCost).divide(gasPrice).longValue()); + assertThat(GAS_LIMIT) + .isEqualTo(authorizerBalanceAfterFirstTx.add(txCost).divide(gasPrice).longValue()); // The other accounts balance should be the initial 9000 ETH balance from the authorizer minus // the remaining balance of the authorizer and minus the transaction cost - cluster.verify( - otherAccount.balanceEquals( - Amount.wei( - new BigInteger("90000000000000000000000") - .subtract(authorizerBalance) - .subtract(txCost)))); + final BigInteger otherAccountBalanceAfterFirstTx = + new BigInteger("90000000000000000000000") + .subtract(authorizerBalanceAfterFirstTx) + .subtract(txCost); + + cluster.verify(otherAccount.balanceEquals(Amount.wei(otherAccountBalanceAfterFirstTx))); + + final Transaction txSendEthToOtherAccount = + Transaction.builder() + .type(TransactionType.EIP1559) + .chainId(BigInteger.valueOf(20211)) + .nonce(2) + .maxPriorityFeePerGas(Wei.of(10)) + .maxFeePerGas(Wei.of(100)) + .gasLimit(21000) + .to(Address.fromHexStringStrict(otherAccount.getAddress())) + .value(Wei.ONE) + .payload(Bytes.EMPTY) + .signAndBuild( + secp256k1.createKeyPair( + secp256k1.createPrivateKey(AUTHORIZER_PRIVATE_KEY.toUnsignedBigInteger()))); + + final String txSendEthToOtherAccountHash = + besuNode.execute( + ethTransactions.sendRawTransaction(txSendEthToOtherAccount.encoded().toHexString())); + testHelper.buildNewBlock(); + + final Optional maybeSecondTransactionReceipt = + besuNode.execute(ethTransactions.getTransactionReceipt(txSendEthToOtherAccountHash)); + assertThat(maybeSecondTransactionReceipt).isPresent(); + + // the balance of the other account should be the previous balance plus the value of the 1 Wei + final BigInteger otherAccountBalanceAfterSecondTx = + besuNode.execute(ethTransactions.getBalance(otherAccount)); + assertThat(otherAccountBalanceAfterFirstTx.add(BigInteger.ONE)) + .isEqualTo(otherAccountBalanceAfterSecondTx); } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionValidator.java index 4f4c554f3f..b5fbf7340b 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionValidator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionValidator.java @@ -32,6 +32,7 @@ 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.gascalculator.GasCalculator; +import org.hyperledger.besu.evm.worldstate.DelegatedCodeService; import java.math.BigInteger; import java.util.List; @@ -305,7 +306,8 @@ public class MainnetTransactionValidator implements TransactionValidator { } private static boolean canSendTransaction(final Account sender, final Hash codeHash) { - return codeHash.equals(Hash.EMPTY) || sender.hasDelegatedCode(); + return codeHash.equals(Hash.EMPTY) + || DelegatedCodeService.hasDelegatedCode(sender.getUnprocessedCode()); } private ValidationResult validateTransactionSignature( diff --git a/evm/src/main/java/org/hyperledger/besu/evm/worldstate/DelegatedCodeService.java b/evm/src/main/java/org/hyperledger/besu/evm/worldstate/DelegatedCodeService.java index 1c89fad8bc..885324b10b 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/worldstate/DelegatedCodeService.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/worldstate/DelegatedCodeService.java @@ -85,13 +85,19 @@ public class DelegatedCodeService { worldUpdater, account, resolveDelegatedAddress(account.getCode())); } - private Address resolveDelegatedAddress(final Bytes code) { - return Address.wrap(code.slice(DELEGATED_CODE_PREFIX.size())); - } - - private boolean hasDelegatedCode(final Bytes code) { + /** + * Returns if the provided code is delegated code. + * + * @param code the code to check. + * @return {@code true} if the code is delegated code, {@code false} otherwise. + */ + public static boolean hasDelegatedCode(final Bytes code) { return code != null && code.size() == DELEGATED_CODE_SIZE && code.slice(0, DELEGATED_CODE_PREFIX.size()).equals(DELEGATED_CODE_PREFIX); } + + private Address resolveDelegatedAddress(final Bytes code) { + return Address.wrap(code.slice(DELEGATED_CODE_PREFIX.size())); + } } From 500a98b6b605d25a9538f2d6d3b7eb955e8368da Mon Sep 17 00:00:00 2001 From: jonesho <81145364+jonesho@users.noreply.github.com> Date: Tue, 10 Sep 2024 19:57:04 +0800 Subject: [PATCH 199/259] feat: exported metrics for current finalized and safe block number (#7592) * feat: exported metrics for current finalized and safe block number Signed-off-by: Jones Ho * Update ethereum/core/src/main/java/org/hyperledger/besu/ethereum/chain/DefaultBlockchain.java Co-authored-by: Fabio Di Fabio Signed-off-by: jonesho <81145364+jonesho@users.noreply.github.com> * Update ethereum/core/src/main/java/org/hyperledger/besu/ethereum/chain/DefaultBlockchain.java Co-authored-by: Fabio Di Fabio Signed-off-by: jonesho <81145364+jonesho@users.noreply.github.com> * fix: spotless issue Signed-off-by: Jones Ho --------- Signed-off-by: Jones Ho Signed-off-by: jonesho <81145364+jonesho@users.noreply.github.com> Co-authored-by: Fabio Di Fabio --- .../ethereum/chain/DefaultBlockchain.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/chain/DefaultBlockchain.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/chain/DefaultBlockchain.java index 5849f3e676..1b21049074 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/chain/DefaultBlockchain.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/chain/DefaultBlockchain.java @@ -122,6 +122,18 @@ public class DefaultBlockchain implements MutableBlockchain { "The current height of the canonical chain", this::getChainHeadBlockNumber); + metricsSystem.createLongGauge( + BesuMetricCategory.ETHEREUM, + "blockchain_finalized_block", + "The current finalized block number", + this::getFinalizedBlockNumber); + + metricsSystem.createLongGauge( + BesuMetricCategory.ETHEREUM, + "blockchain_safe_block", + "The current safe block number", + this::getSafeBlockNumber); + metricsSystem.createGauge( BesuMetricCategory.BLOCKCHAIN, "difficulty_total", @@ -759,6 +771,14 @@ public class DefaultBlockchain implements MutableBlockchain { updater.commit(); } + private long getFinalizedBlockNumber() { + return this.getFinalized().flatMap(this::getBlockHeader).map(BlockHeader::getNumber).orElse(0L); + } + + private long getSafeBlockNumber() { + return this.getSafeBlock().flatMap(this::getBlockHeader).map(BlockHeader::getNumber).orElse(0L); + } + private void updateCacheForNewCanonicalHead(final Block block, final Difficulty uInt256) { chainHeader = block.getHeader(); totalDifficulty = uInt256; From 07adb415eec5341fe22442ac9938e7f7b8a9de11 Mon Sep 17 00:00:00 2001 From: Fabio Di Fabio Date: Wed, 11 Sep 2024 00:26:17 +0200 Subject: [PATCH 200/259] Re-enable TxPoolOptionsTest::txpoolForcePriceBumpToZeroWhenZeroBaseFeeMarket (#7565) Signed-off-by: Fabio Di Fabio --- .../test/java/org/hyperledger/besu/cli/TxPoolOptionsTest.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/besu/src/test/java/org/hyperledger/besu/cli/TxPoolOptionsTest.java b/besu/src/test/java/org/hyperledger/besu/cli/TxPoolOptionsTest.java index 8389ab5bae..a5ca07484a 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/TxPoolOptionsTest.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/TxPoolOptionsTest.java @@ -30,7 +30,6 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; public class TxPoolOptionsTest extends CommandTestAbstract { @@ -98,7 +97,6 @@ public class TxPoolOptionsTest extends CommandTestAbstract { } @Test - @Disabled // Failing in CI, but not locally public void txpoolForcePriceBumpToZeroWhenZeroBaseFeeMarket() throws IOException { final Path genesisFile = createFakeGenesisFile(GENESIS_WITH_ZERO_BASE_FEE_MARKET); parseCommand("--genesis-file", genesisFile.toString()); From 3d71254dfa781839f6cf7a54fc661bef13606a27 Mon Sep 17 00:00:00 2001 From: daniellehrner Date: Wed, 11 Sep 2024 00:50:23 +0200 Subject: [PATCH 201/259] Mandatoy to field for 7702 transactions (#7600) * fix 7702 tx validation in tx pool Signed-off-by: Daniel Lehrner * check that 7702 transactions always have a mandatory to field Signed-off-by: Daniel Lehrner --------- Signed-off-by: Daniel Lehrner Co-authored-by: Sally MacFarlane --- .../mainnet/MainnetTransactionValidator.java | 75 ++++++++++++------- 1 file changed, 46 insertions(+), 29 deletions(-) diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionValidator.java index b5fbf7340b..e67ccbb4c6 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionValidator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionValidator.java @@ -132,42 +132,59 @@ public class MainnetTransactionValidator implements TransactionValidator { } if (transactionType == TransactionType.DELEGATE_CODE) { - if (isDelegateCodeEmpty(transaction)) { - return ValidationResult.invalid( - TransactionInvalidReason.EMPTY_CODE_DELEGATION, - "transaction code delegation transactions must have a non-empty code delegation list"); + ValidationResult codeDelegationValidation = + validateCodeDelegation(transaction); + if (!codeDelegationValidation.isValid()) { + return codeDelegationValidation; } + } + + return validateCostAndFee(transaction, baseFee, blobFee, transactionValidationParams); + } - final BigInteger halfCurveOrder = SignatureAlgorithmFactory.getInstance().getHalfCurveOrder(); - final Optional> validationResult = - transaction - .getCodeDelegationList() - .map( - codeDelegations -> { - for (CodeDelegation codeDelegation : codeDelegations) { - if (codeDelegation.signature().getS().compareTo(halfCurveOrder) > 0) { - return ValidationResult.invalid( - TransactionInvalidReason.INVALID_SIGNATURE, - "Invalid signature for code delegation. S value must be less or equal than the half curve order."); - } - - if (codeDelegation.signature().getRecId() != 0 - && codeDelegation.signature().getRecId() != 1) { - return ValidationResult.invalid( - TransactionInvalidReason.INVALID_SIGNATURE, - "Invalid signature for code delegation. RecId value must be 0 or 1."); - } + private static ValidationResult validateCodeDelegation( + final Transaction transaction) { + if (isDelegateCodeEmpty(transaction)) { + return ValidationResult.invalid( + TransactionInvalidReason.EMPTY_CODE_DELEGATION, + "transaction code delegation transactions must have a non-empty code delegation list"); + } + + if (transaction.getTo().isEmpty()) { + return ValidationResult.invalid( + TransactionInvalidReason.INVALID_TRANSACTION_FORMAT, + "transaction code delegation transactions must have a to address"); + } + + final BigInteger halfCurveOrder = SignatureAlgorithmFactory.getInstance().getHalfCurveOrder(); + final Optional> validationResult = + transaction + .getCodeDelegationList() + .map( + codeDelegations -> { + for (CodeDelegation codeDelegation : codeDelegations) { + if (codeDelegation.signature().getS().compareTo(halfCurveOrder) > 0) { + return ValidationResult.invalid( + TransactionInvalidReason.INVALID_SIGNATURE, + "Invalid signature for code delegation. S value must be less or equal than the half curve order."); } - return ValidationResult.valid(); - }); + if (codeDelegation.signature().getRecId() != 0 + && codeDelegation.signature().getRecId() != 1) { + return ValidationResult.invalid( + TransactionInvalidReason.INVALID_SIGNATURE, + "Invalid signature for code delegation. RecId value must be 0 or 1."); + } + } - if (validationResult.isPresent() && !validationResult.get().isValid()) { - return validationResult.get(); - } + return ValidationResult.valid(); + }); + + if (validationResult.isPresent() && !validationResult.get().isValid()) { + return validationResult.get(); } - return validateCostAndFee(transaction, baseFee, blobFee, transactionValidationParams); + return ValidationResult.valid(); } private static boolean isDelegateCodeEmpty(final Transaction transaction) { From 46636c7af279c3530fe30e99bfa5f7956150dcb5 Mon Sep 17 00:00:00 2001 From: Luis Pinto Date: Wed, 11 Sep 2024 00:37:08 +0100 Subject: [PATCH 202/259] block header cache not initialized before used (#7601) Signed-off-by: Luis Pinto Co-authored-by: Sally MacFarlane --- .../ethereum/chain/DefaultBlockchain.java | 62 +++++++++---------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/chain/DefaultBlockchain.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/chain/DefaultBlockchain.java index 1b21049074..b2b4e6abfc 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/chain/DefaultBlockchain.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/chain/DefaultBlockchain.java @@ -116,6 +116,37 @@ public class DefaultBlockchain implements MutableBlockchain { chainHeadTransactionCount = chainHeadBody.getTransactions().size(); chainHeadOmmerCount = chainHeadBody.getOmmers().size(); + this.reorgLoggingThreshold = reorgLoggingThreshold; + this.blockChoiceRule = heaviestChainBlockChoiceRule; + this.numberOfBlocksToCache = numberOfBlocksToCache; + + if (numberOfBlocksToCache != 0) { + blockHeadersCache = + Optional.of( + CacheBuilder.newBuilder().recordStats().maximumSize(numberOfBlocksToCache).build()); + blockBodiesCache = + Optional.of( + CacheBuilder.newBuilder().recordStats().maximumSize(numberOfBlocksToCache).build()); + transactionReceiptsCache = + Optional.of( + CacheBuilder.newBuilder().recordStats().maximumSize(numberOfBlocksToCache).build()); + totalDifficultyCache = + Optional.of( + CacheBuilder.newBuilder().recordStats().maximumSize(numberOfBlocksToCache).build()); + CacheMetricsCollector cacheMetrics = new CacheMetricsCollector(); + cacheMetrics.addCache("blockHeaders", blockHeadersCache.get()); + cacheMetrics.addCache("blockBodies", blockBodiesCache.get()); + cacheMetrics.addCache("transactionReceipts", transactionReceiptsCache.get()); + cacheMetrics.addCache("totalDifficulty", totalDifficultyCache.get()); + if (metricsSystem instanceof PrometheusMetricsSystem prometheusMetricsSystem) + prometheusMetricsSystem.addCollector(BesuMetricCategory.BLOCKCHAIN, () -> cacheMetrics); + } else { + blockHeadersCache = Optional.empty(); + blockBodiesCache = Optional.empty(); + transactionReceiptsCache = Optional.empty(); + totalDifficultyCache = Optional.empty(); + } + metricsSystem.createLongGauge( BesuMetricCategory.ETHEREUM, "blockchain_height", @@ -179,37 +210,6 @@ public class DefaultBlockchain implements MutableBlockchain { "chain_head_ommer_count", "Number of ommers in the current chain head block", () -> chainHeadOmmerCount); - - this.reorgLoggingThreshold = reorgLoggingThreshold; - this.blockChoiceRule = heaviestChainBlockChoiceRule; - this.numberOfBlocksToCache = numberOfBlocksToCache; - - if (numberOfBlocksToCache != 0) { - blockHeadersCache = - Optional.of( - CacheBuilder.newBuilder().recordStats().maximumSize(numberOfBlocksToCache).build()); - blockBodiesCache = - Optional.of( - CacheBuilder.newBuilder().recordStats().maximumSize(numberOfBlocksToCache).build()); - transactionReceiptsCache = - Optional.of( - CacheBuilder.newBuilder().recordStats().maximumSize(numberOfBlocksToCache).build()); - totalDifficultyCache = - Optional.of( - CacheBuilder.newBuilder().recordStats().maximumSize(numberOfBlocksToCache).build()); - CacheMetricsCollector cacheMetrics = new CacheMetricsCollector(); - cacheMetrics.addCache("blockHeaders", blockHeadersCache.get()); - cacheMetrics.addCache("blockBodies", blockBodiesCache.get()); - cacheMetrics.addCache("transactionReceipts", transactionReceiptsCache.get()); - cacheMetrics.addCache("totalDifficulty", totalDifficultyCache.get()); - if (metricsSystem instanceof PrometheusMetricsSystem prometheusMetricsSystem) - prometheusMetricsSystem.addCollector(BesuMetricCategory.BLOCKCHAIN, () -> cacheMetrics); - } else { - blockHeadersCache = Optional.empty(); - blockBodiesCache = Optional.empty(); - transactionReceiptsCache = Optional.empty(); - totalDifficultyCache = Optional.empty(); - } } public static MutableBlockchain createMutable( From 6ea0ed4c7001895863964fc0e30858c0f6b735ce Mon Sep 17 00:00:00 2001 From: garyschulte Date: Tue, 10 Sep 2024 18:55:45 -0700 Subject: [PATCH 203/259] propagate release name preprocessing via job output (#7599) Signed-off-by: garyschulte --- .github/workflows/release.yml | 59 ++++++++++++++++++++++++----------- 1 file changed, 41 insertions(+), 18 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c743665357..2f0661e3cf 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,8 +9,28 @@ env: GRADLE_OPTS: "-Dorg.gradle.parallel=true -Dorg.gradle.caching=true" jobs: + preprocess_release: + runs-on: ubuntu-22.04 + steps: + - name: Pre-process Release Name + id: pre_process_release_name + run: | + RELEASE_NAME="${{ github.event.release.name }}" + # strip all whitespace + RELEASE_NAME="${RELEASE_NAME//[[:space:]]/}" + if [[ ! "$RELEASE_NAME" =~ ^[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 + outputs: + release_name: ${{ steps.pre_process_release_name.outputs.release_name }} + artifacts: runs-on: ubuntu-22.04 + needs: preprocess_release + env: + RELEASE_NAME: ${{ needs.preprocess_release.outputs.release_name }} # Use the output from the pre_process_release job permissions: contents: write outputs: @@ -19,17 +39,6 @@ jobs: steps: - name: checkout uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 - - name: Pre-process Release Name - id: pre_process_release_name - run: | - RELEASE_NAME="${{ github.event.release.name }}" - # strip all whitespace - RELEASE_NAME="${RELEASE_NAME//[[:space:]]/}" - if [[ ! "$RELEASE_NAME" =~ ^[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_ENV # Store in environment variable - name: Set up Java uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 with: @@ -90,7 +99,9 @@ jobs: publish: runs-on: ubuntu-22.04 - needs: [testWindows, artifacts] + needs: [preprocess_release, testWindows, artifacts] + env: + RELEASE_NAME: ${{ needs.preprocess_release.outputs.release_name }} # Use the output from the pre_process_release job permissions: contents: write steps: @@ -115,7 +126,9 @@ jobs: artifactoryPublish: runs-on: ubuntu-22.04 - needs: artifacts + needs: [preprocess_release, artifacts] + env: + RELEASE_NAME: ${{ needs.preprocess_release.outputs.release_name }} # Use the output from the pre_process_release job steps: - name: checkout uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 @@ -152,7 +165,9 @@ jobs: run: docker run --rm -i hadolint/hadolint < docker/Dockerfile buildDocker: - needs: hadolint + needs: [preprocess_release, hadolint] + env: + RELEASE_NAME: ${{ needs.preprocess_release.outputs.release_name }} # Use the output from the pre_process_release job permissions: contents: read packages: write @@ -213,7 +228,9 @@ jobs: run: ./gradlew --no-daemon dockerUpload -PdockerOrgName=${{ env.registry }}/${{ secrets.DOCKER_ORG }} -Pversion=${{env.RELEASE_NAME}} -Prelease.releaseVersion=${{ env.RELEASE_NAME }} multiArch: - needs: buildDocker + needs: [preprocess_release, buildDocker] + env: + RELEASE_NAME: ${{ needs.preprocess_release.outputs.release_name }} # Use the output from the pre_process_release job runs-on: ubuntu-22.04 permissions: contents: read @@ -240,7 +257,9 @@ jobs: run: ./gradlew manifestDocker -PdockerOrgName=${{ env.registry }}/${{ secrets.DOCKER_ORG }} -Pversion=${{env.RELEASE_NAME}} -Prelease.releaseVersion=${{ env.RELEASE_NAME }} amendNotes: - needs: multiArch + needs: [preprocess_release, multiArch] + env: + RELEASE_NAME: ${{ needs.preprocess_release.outputs.release_name }} # Use the output from the pre_process_release job runs-on: ubuntu-22.04 permissions: contents: write @@ -253,7 +272,9 @@ jobs: `docker pull ${{env.registry}}/${{secrets.DOCKER_ORG}}/besu:${{env.RELEASE_NAME}}` dockerPromoteX64: - needs: multiArch + needs: [preprocess_release, multiArch] + env: + RELEASE_NAME: ${{ needs.preprocess_release.outputs.release_name }} # Use the output from the pre_process_release job runs-on: ubuntu-22.04 steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 @@ -278,7 +299,9 @@ jobs: run: ./gradlew "-Prelease.releaseVersion=${{ env.RELEASE_NAME }}" "-PdockerOrgName=${{ env.registry }}/${{ secrets.DOCKER_ORG }}" manifestDockerRelease verifyContainer: - needs: dockerPromoteX64 + needs: [preprocess_release, dockerPromoteX64] + env: + RELEASE_NAME: ${{ needs.preprocess_release.outputs.release_name }} # Use the output from the pre_process_release job runs-on: ubuntu-22.04 permissions: contents: read From b18d15058f9b7bcd42a3ad4ed0b344f16a176c07 Mon Sep 17 00:00:00 2001 From: garyschulte Date: Wed, 11 Sep 2024 10:01:21 -0700 Subject: [PATCH 204/259] deprecate 24.9.0, create 24.9.1 release (#7606) Signed-off-by: garyschulte --- CHANGELOG.md | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aa6250508e..ec895443c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,16 +7,10 @@ ### Breaking Changes ### Additions and Improvements -- Update Java and Gradle dependecies [#7571](https://github.com/hyperledger/besu/pull/7571) -- Layered txpool: new options `--tx-pool-min-score` to remove a tx from pool when its score is lower than the specified value [#7576](https://github.com/hyperledger/besu/pull/7576) -- Add `engine_getBlobsV1` method to the Engine API [#7553](https://github.com/hyperledger/besu/pull/7553) ### Bug fixes -- Layered txpool: do not send notifications when moving tx between layers [#7539](https://github.com/hyperledger/besu/pull/7539) -- Layered txpool: fix for unsent drop notifications on remove [#7538](https://github.com/hyperledger/besu/pull/7538) -- Honor block number or tag parameter in eth_estimateGas and eth_createAccessList [#7502](https://github.com/hyperledger/besu/pull/7502) -## 24.9.0 +## 24.9.1 ### Upcoming Breaking Changes @@ -32,6 +26,9 @@ - Performance optimzation for ECMUL (2 of 2) [#7543](https://github.com/hyperledger/besu/pull/7543) - Include current chain head block when computing `eth_maxPriorityFeePerGas` [#7485](https://github.com/hyperledger/besu/pull/7485) - Remove (old) documentation updates from the changelog [#7562](https://github.com/hyperledger/besu/pull/7562) +- Update Java and Gradle dependecies [#7571](https://github.com/hyperledger/besu/pull/7571) +- Layered txpool: new options `--tx-pool-min-score` to remove a tx from pool when its score is lower than the specified value [#7576](https://github.com/hyperledger/besu/pull/7576) +- Add `engine_getBlobsV1` method to the Engine API [#7553](https://github.com/hyperledger/besu/pull/7553) ### Bug fixes - Fix tracing in precompiled contracts when halting for out of gas [#7318](https://github.com/hyperledger/besu/issues/7318) @@ -42,6 +39,14 @@ - `evmtool` was not respecting the `--genesis` setting, resulting in unexpected trace results. [#7433](https://github.com/hyperledger/besu/pull/7433) - The genesis config override `contractSizeLimit` was not wired into code size limits [#7557](https://github.com/hyperledger/besu/pull/7557) - Fix incorrect key filtering in LayeredKeyValueStorage stream [#7535](https://github.com/hyperledger/besu/pull/7557) +- Layered txpool: do not send notifications when moving tx between layers [#7539](https://github.com/hyperledger/besu/pull/7539) +- Layered txpool: fix for unsent drop notifications on remove [#7538](https://github.com/hyperledger/besu/pull/7538) +- Honor block number or tag parameter in eth_estimateGas and eth_createAccessList [#7502](https://github.com/hyperledger/besu/pull/7502) + +## 24.9.0 + +This release version has been deprecated release due to CI bug + ## 24.8.0 From 6ed1db32ae3c1b5bdc0576321fee35157feb6ae4 Mon Sep 17 00:00:00 2001 From: George Tebrean <99179176+gtebrean@users.noreply.github.com> Date: Thu, 12 Sep 2024 11:18:26 +0300 Subject: [PATCH 205/259] Issue - 7554 remove unused privacy test classes (#7569) * remove unused classes Signed-off-by: George Tebrean * removed duplication from changelog Signed-off-by: Sally MacFarlane --------- Signed-off-by: George Tebrean Signed-off-by: George Tebrean <99179176+gtebrean@users.noreply.github.com> Signed-off-by: Sally MacFarlane Co-authored-by: Sally MacFarlane --- CHANGELOG.md | 4 +- .../acceptance/dsl/AcceptanceTestBase.java | 7 - .../dsl/AcceptanceTestBaseJunit5.java | 7 - .../priv/EeaSendRawTransactionSuccess.java | 38 -- .../condition/priv/ExpectJsonRpcError.java | 53 -- .../dsl/condition/priv/PrivConditions.java | 120 ---- .../priv/PrivCreatePrivacyGroupSuccess.java | 39 -- .../priv/PrivDeletePrivacyGroupSuccess.java | 39 -- .../PrivDistributeRawTransactionSuccess.java | 42 -- .../priv/PrivFindPrivacyGroupSuccess.java | 40 -- .../PrivGetEeaTransactionCountSuccess.java | 42 -- ...ivGetExpectedFailedTransactionReceipt.java | 38 -- ...vGetExpectedInvalidTransactionReceipt.java | 38 -- ...tExpectedSuccessfulTransactionReceipt.java | 38 -- ...rivGetPrivacyPrecompileAddressSuccess.java | 42 -- .../PrivGetPrivateTransactionReturnsNull.java | 38 -- .../PrivGetPrivateTransactionSuccess.java | 43 -- .../priv/PrivGetTransactionCountSuccess.java | 42 -- .../priv/PrivateSyncingStatusCondition.java | 40 -- .../tests/acceptance/dsl/node/BesuNode.java | 2 - .../node/configuration/BesuNodeFactory.java | 54 -- .../privacy/PrivacyNodeConfiguration.java | 65 -- .../privacy/PrivacyNodeFactory.java | 294 -------- .../dsl/privacy/PrivacyCluster.java | 184 ----- .../acceptance/dsl/privacy/PrivacyNode.java | 315 --------- .../PrivateTransactionGroupResponse.java | 117 ---- .../dsl/privacy/account/PrivacyAccount.java | 85 --- .../account/PrivacyAccountResolver.java | 101 --- ...pectExistingPrivateTransactionReceipt.java | 41 -- ...nternalErrorPrivateTransactionReceipt.java | 40 -- .../ExpectNoPrivateTransactionReceipt.java | 41 -- .../condition/ExpectValidContractCode.java | 29 - ...xpectValidFlexiblePrivacyGroupCreated.java | 53 -- .../ExpectValidPrivacyGroupCreated.java | 51 -- ...ctValidPrivateContractDeployedReceipt.java | 57 -- .../ExpectValidPrivateTransactionReceipt.java | 91 --- .../PrivGetTransactionReceiptTransaction.java | 52 -- .../privacy/condition/PrivateCondition.java | 21 - .../condition/PrivateContractCondition.java | 23 - .../condition/PrivateContractVerifier.java | 29 - .../condition/PrivateTransactionVerifier.java | 88 --- ...issioningPrivateSmartContractFunction.java | 73 -- .../CallPrivateSmartContractFunction.java | 121 ---- ...DeployPrivateSmartContractTransaction.java | 87 --- ...ContractWithPrivacyGroupIdTransaction.java | 89 --- .../LoadPrivateSmartContractTransaction.java | 87 --- ...ContractTransactionWithPrivacyGroupId.java | 88 --- .../contract/PrivateContractTransactions.java | 154 ----- .../AddToFlexiblePrivacyGroupTransaction.java | 57 -- ...CreateFlexiblePrivacyGroupTransaction.java | 46 -- .../FindFlexiblePrivacyGroupTransaction.java | 52 -- .../FindPrivacyGroupTransaction.java | 45 -- .../GetAllPrivateMarkerTransactionHashes.java | 56 -- .../LockFlexiblePrivacyGroupTransaction.java | 47 -- ...CreateRandomPrivacyGroupIdTransaction.java | 31 - .../PrivDistributeTransactionTransaction.java | 40 -- .../transaction/PrivacyTransactions.java | 172 ----- ...veFromFlexiblePrivacyGroupTransaction.java | 50 -- ...strictedCreatePrivacyGroupTransaction.java | 60 -- ...UnlockFlexiblePrivacyGroupTransaction.java | 47 -- .../privacy/util/LogFilterJsonParameter.java | 59 -- .../dsl/transaction/NodeRequests.java | 8 - .../EeaSendRawTransactionTransaction.java | 47 -- .../privacy/PrivCallTransaction.java | 64 -- .../PrivCreatePrivacyGroupTransaction.java | 46 -- .../privacy/PrivDebugGetStateRoot.java | 45 -- .../PrivDeletePrivacyGroupTransaction.java | 46 -- ...ivDistributeRawTransactionTransaction.java | 46 -- .../PrivFindPrivacyGroupTransaction.java | 47 -- .../privacy/PrivGetCodeTransaction.java | 54 -- ...PrivGetEeaTransactionCountTransaction.java | 47 -- .../privacy/PrivGetLogsTransaction.java | 54 -- ...etPrivacyPrecompileAddressTransaction.java | 38 -- .../PrivGetPrivateTransactionTransaction.java | 46 -- .../privacy/PrivGetTransaction.java | 46 -- .../PrivGetTransactionCountTransaction.java | 47 -- .../PrivGetTransactionReceiptTransaction.java | 47 -- .../privacy/PrivSyncingTransactions.java | 40 -- .../privacy/PrivTraceTransaction.java | 49 -- .../privacy/PrivacyRequestFactory.java | 629 ------------------ .../privacy/PrivacyTransactions.java | 69 -- .../PrivGetFilterChangesTransaction.java | 53 -- .../filter/PrivGetFilterLogsTransaction.java | 53 -- .../filter/PrivNewFilterTransaction.java | 52 -- .../PrivUninstallFilterTransaction.java | 50 -- acceptance-tests/tests/build.gradle | 27 - .../privacy/contracts/PrivacyGroupTest.java | 195 ------ .../privacy/contracts/PrivacyProxyTest.java | 178 ----- .../MultiTenancyAcceptanceTest.java | 408 ------------ .../MultiTenancyPrivacyGroup.java | 58 -- .../multitenancy/MultiTenancyPrivacyNode.java | 50 -- ...tiTenancyPrivateNonceIncrementingTest.java | 241 ------- ...tiTenancyValidationFailAcceptanceTest.java | 232 ------- 93 files changed, 3 insertions(+), 7153 deletions(-) delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/EeaSendRawTransactionSuccess.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/ExpectJsonRpcError.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivConditions.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivCreatePrivacyGroupSuccess.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivDeletePrivacyGroupSuccess.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivDistributeRawTransactionSuccess.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivFindPrivacyGroupSuccess.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivGetEeaTransactionCountSuccess.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivGetExpectedFailedTransactionReceipt.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivGetExpectedInvalidTransactionReceipt.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivGetExpectedSuccessfulTransactionReceipt.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivGetPrivacyPrecompileAddressSuccess.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivGetPrivateTransactionReturnsNull.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivGetPrivateTransactionSuccess.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivGetTransactionCountSuccess.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivateSyncingStatusCondition.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/privacy/PrivacyNodeConfiguration.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/privacy/PrivacyNodeFactory.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/PrivacyCluster.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/PrivacyNode.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/PrivateTransactionGroupResponse.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/account/PrivacyAccount.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/account/PrivacyAccountResolver.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/ExpectExistingPrivateTransactionReceipt.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/ExpectInternalErrorPrivateTransactionReceipt.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/ExpectNoPrivateTransactionReceipt.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/ExpectValidContractCode.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/ExpectValidFlexiblePrivacyGroupCreated.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/ExpectValidPrivacyGroupCreated.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/ExpectValidPrivateContractDeployedReceipt.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/ExpectValidPrivateTransactionReceipt.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/PrivGetTransactionReceiptTransaction.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/PrivateCondition.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/PrivateContractCondition.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/PrivateContractVerifier.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/PrivateTransactionVerifier.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/contract/CallOnchainPermissioningPrivateSmartContractFunction.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/contract/CallPrivateSmartContractFunction.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/contract/DeployPrivateSmartContractTransaction.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/contract/DeployPrivateSmartContractWithPrivacyGroupIdTransaction.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/contract/LoadPrivateSmartContractTransaction.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/contract/LoadPrivateSmartContractTransactionWithPrivacyGroupId.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/contract/PrivateContractTransactions.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/AddToFlexiblePrivacyGroupTransaction.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/CreateFlexiblePrivacyGroupTransaction.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/FindFlexiblePrivacyGroupTransaction.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/FindPrivacyGroupTransaction.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/GetAllPrivateMarkerTransactionHashes.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/LockFlexiblePrivacyGroupTransaction.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/PluginCreateRandomPrivacyGroupIdTransaction.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/PrivDistributeTransactionTransaction.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/PrivacyTransactions.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/RemoveFromFlexiblePrivacyGroupTransaction.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/RestrictedCreatePrivacyGroupTransaction.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/UnlockFlexiblePrivacyGroupTransaction.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/util/LogFilterJsonParameter.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/EeaSendRawTransactionTransaction.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivCallTransaction.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivCreatePrivacyGroupTransaction.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivDebugGetStateRoot.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivDeletePrivacyGroupTransaction.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivDistributeRawTransactionTransaction.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivFindPrivacyGroupTransaction.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivGetCodeTransaction.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivGetEeaTransactionCountTransaction.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivGetLogsTransaction.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivGetPrivacyPrecompileAddressTransaction.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivGetPrivateTransactionTransaction.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivGetTransaction.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivGetTransactionCountTransaction.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivGetTransactionReceiptTransaction.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivSyncingTransactions.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivTraceTransaction.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivacyRequestFactory.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivacyTransactions.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/filter/PrivGetFilterChangesTransaction.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/filter/PrivGetFilterLogsTransaction.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/filter/PrivNewFilterTransaction.java delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/filter/PrivUninstallFilterTransaction.java delete mode 100644 acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/contracts/PrivacyGroupTest.java delete mode 100644 acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/contracts/PrivacyProxyTest.java delete mode 100644 acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/multitenancy/MultiTenancyAcceptanceTest.java delete mode 100644 acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/multitenancy/MultiTenancyPrivacyGroup.java delete mode 100644 acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/multitenancy/MultiTenancyPrivacyNode.java delete mode 100644 acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/multitenancy/MultiTenancyPrivateNonceIncrementingTest.java delete mode 100644 acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/multitenancy/MultiTenancyValidationFailAcceptanceTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index ec895443c3..9ea4ced222 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ ### Breaking Changes ### Additions and Improvements +- Remove privacy test classes support [#7569](https://github.com/hyperledger/besu/pull/7569) + ### Bug fixes @@ -26,7 +28,7 @@ - Performance optimzation for ECMUL (2 of 2) [#7543](https://github.com/hyperledger/besu/pull/7543) - Include current chain head block when computing `eth_maxPriorityFeePerGas` [#7485](https://github.com/hyperledger/besu/pull/7485) - Remove (old) documentation updates from the changelog [#7562](https://github.com/hyperledger/besu/pull/7562) -- Update Java and Gradle dependecies [#7571](https://github.com/hyperledger/besu/pull/7571) +- Update Java and Gradle dependencies [#7571](https://github.com/hyperledger/besu/pull/7571) - Layered txpool: new options `--tx-pool-min-score` to remove a tx from pool when its score is lower than the specified value [#7576](https://github.com/hyperledger/besu/pull/7576) - Add `engine_getBlobsV1` method to the Engine API [#7553](https://github.com/hyperledger/besu/pull/7553) 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 4072c6f1bc..5256e71ee3 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 @@ -26,7 +26,6 @@ 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.priv.PrivConditions; 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; @@ -44,7 +43,6 @@ 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.privacy.PrivacyTransactions; import org.hyperledger.besu.tests.acceptance.dsl.transaction.txpool.TxPoolTransactions; import org.hyperledger.besu.tests.acceptance.dsl.transaction.web3.Web3Transactions; @@ -93,8 +91,6 @@ public class AcceptanceTestBase { protected final PermissioningTransactions permissioningTransactions; protected final MinerTransactions minerTransactions; protected final Web3Conditions web3; - protected final PrivConditions priv; - protected final PrivacyTransactions privacyTransactions; protected final TxPoolConditions txPoolConditions; protected final TxPoolTransactions txPoolTransactions; protected final ExitedWithCode exitedSuccessfully; @@ -109,10 +105,8 @@ public class AcceptanceTestBase { bftTransactions = new BftTransactions(); accountTransactions = new AccountTransactions(accounts); permissioningTransactions = new PermissioningTransactions(); - privacyTransactions = new PrivacyTransactions(); contractTransactions = new ContractTransactions(); minerTransactions = new MinerTransactions(); - blockchain = new Blockchain(ethTransactions); clique = new CliqueConditions(ethTransactions, cliqueTransactions); eth = new EthConditions(ethTransactions); @@ -121,7 +115,6 @@ public class AcceptanceTestBase { net = new NetConditions(new NetTransactions()); cluster = new Cluster(net); perm = new PermissioningConditions(permissioningTransactions); - priv = new PrivConditions(privacyTransactions); admin = new AdminConditions(adminTransactions); web3 = new Web3Conditions(new Web3Transactions()); besu = new BesuNodeFactory(); 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 index 0cf24b5736..4f3046c1ab 100644 --- 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 @@ -26,7 +26,6 @@ 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.priv.PrivConditions; 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; @@ -44,7 +43,6 @@ 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.privacy.PrivacyTransactions; import org.hyperledger.besu.tests.acceptance.dsl.transaction.txpool.TxPoolTransactions; import org.hyperledger.besu.tests.acceptance.dsl.transaction.web3.Web3Transactions; @@ -96,8 +94,6 @@ public class AcceptanceTestBaseJunit5 { protected final PermissioningTransactions permissioningTransactions; protected final MinerTransactions minerTransactions; protected final Web3Conditions web3; - protected final PrivConditions priv; - protected final PrivacyTransactions privacyTransactions; protected final TxPoolConditions txPoolConditions; protected final TxPoolTransactions txPoolTransactions; protected final ExitedWithCode exitedSuccessfully; @@ -112,10 +108,8 @@ public class AcceptanceTestBaseJunit5 { bftTransactions = new BftTransactions(); accountTransactions = new AccountTransactions(accounts); permissioningTransactions = new PermissioningTransactions(); - privacyTransactions = new PrivacyTransactions(); contractTransactions = new ContractTransactions(); minerTransactions = new MinerTransactions(); - blockchain = new Blockchain(ethTransactions); clique = new CliqueConditions(ethTransactions, cliqueTransactions); eth = new EthConditions(ethTransactions); @@ -124,7 +118,6 @@ public class AcceptanceTestBaseJunit5 { net = new NetConditions(new NetTransactions()); cluster = new Cluster(net); perm = new PermissioningConditions(permissioningTransactions); - priv = new PrivConditions(privacyTransactions); admin = new AdminConditions(adminTransactions); web3 = new Web3Conditions(new Web3Transactions()); besu = new BesuNodeFactory(); diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/EeaSendRawTransactionSuccess.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/EeaSendRawTransactionSuccess.java deleted file mode 100644 index 9aef5825ea..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/EeaSendRawTransactionSuccess.java +++ /dev/null @@ -1,38 +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.tests.acceptance.dsl.condition.priv; - -import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; - -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.tests.acceptance.dsl.condition.Condition; -import org.hyperledger.besu.tests.acceptance.dsl.node.Node; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.privacy.EeaSendRawTransactionTransaction; - -public class EeaSendRawTransactionSuccess implements Condition { - - private final EeaSendRawTransactionTransaction sendRawTransactionTransaction; - - public EeaSendRawTransactionSuccess( - final EeaSendRawTransactionTransaction sendRawTransactionTransaction) { - this.sendRawTransactionTransaction = sendRawTransactionTransaction; - } - - @Override - public void verify(final Node node) { - final Hash transactionHash = node.execute(sendRawTransactionTransaction); - assertThat(transactionHash).isNotNull(); - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/ExpectJsonRpcError.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/ExpectJsonRpcError.java deleted file mode 100644 index a642a2731c..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/ExpectJsonRpcError.java +++ /dev/null @@ -1,53 +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.tests.acceptance.dsl.condition.priv; - -import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown; - -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; -import org.hyperledger.besu.tests.acceptance.dsl.condition.Condition; -import org.hyperledger.besu.tests.acceptance.dsl.node.Node; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -import org.assertj.core.api.Assertions; -import org.web3j.protocol.exceptions.ClientConnectionException; - -public class ExpectJsonRpcError implements Condition { - - private final Transaction transaction; - private final JsonRpcError error; - - public ExpectJsonRpcError(final Transaction transaction, final JsonRpcError error) { - this.transaction = transaction; - this.error = error; - } - - public ExpectJsonRpcError(final Transaction transaction, final RpcErrorType error) { - this(transaction, new JsonRpcError(error)); - } - - @Override - public void verify(final Node node) { - try { - node.execute(transaction); - failBecauseExceptionWasNotThrown(ClientConnectionException.class); - } catch (final Exception e) { - Assertions.assertThat(e) - .isInstanceOf(RuntimeException.class) - .hasMessageContaining(error.getMessage()); - } - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivConditions.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivConditions.java deleted file mode 100644 index 2bbf04534d..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivConditions.java +++ /dev/null @@ -1,120 +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.tests.acceptance.dsl.condition.priv; - -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; -import org.hyperledger.besu.ethereum.privacy.PrivateTransaction; -import org.hyperledger.besu.tests.acceptance.dsl.condition.Condition; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.condition.PrivateCondition; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.privacy.PrivacyTransactions; - -import java.util.List; - -public class PrivConditions { - - private final PrivacyTransactions transactions; - - public PrivConditions(final PrivacyTransactions transactions) { - this.transactions = transactions; - } - - public Condition getPrivacyPrecompileAddress(final Address precompileAddress) { - return new PrivGetPrivacyPrecompileAddressSuccess( - transactions.getPrivacyPrecompileAddress(), precompileAddress); - } - - public Condition getPrivateTransaction( - final Hash transactionHash, final PrivateTransaction privateTransaction) { - return new PrivGetPrivateTransactionSuccess( - transactions.getPrivateTransaction(transactionHash), privateTransaction); - } - - public Condition getPrivateTransactionReturnsNull(final Hash transactionHash) { - return new PrivGetPrivateTransactionReturnsNull( - transactions.getPrivateTransaction(transactionHash)); - } - - public Condition createPrivacyGroup( - final List addresses, - final String groupName, - final String groupDescription, - final String groupId) { - return new PrivCreatePrivacyGroupSuccess( - transactions.createPrivacyGroup(addresses, groupName, groupDescription), groupId); - } - - public Condition deletePrivacyGroup(final String groupId) { - return new PrivDeletePrivacyGroupSuccess(transactions.deletePrivacyGroup(groupId), groupId); - } - - public Condition findPrivacyGroup(final int numGroups, final String... groupMembers) { - return new PrivFindPrivacyGroupSuccess(transactions.findPrivacyGroup(groupMembers), numGroups); - } - - public Condition eeaSendRawTransaction(final String transaction) { - return new EeaSendRawTransactionSuccess(transactions.sendRawTransaction(transaction)); - } - - public Condition distributeRawTransaction( - final String transactionRLP, final String enclaveResponseKey) { - return new PrivDistributeRawTransactionSuccess( - transactions.distributeRawTransaction(transactionRLP), enclaveResponseKey); - } - - public Condition getTransactionCount( - final String accountAddress, - final String privacyGroupId, - final int expectedTransactionCount) { - return new PrivGetTransactionCountSuccess( - transactions.getTransactionCount(accountAddress, privacyGroupId), expectedTransactionCount); - } - - public Condition getEeaTransactionCount( - final String accountAddress, - final String privateFrom, - final String[] privateFor, - final int expectedTransactionCount) { - return new PrivGetEeaTransactionCountSuccess( - transactions.getEeaTransactionCount(accountAddress, privateFrom, privateFor), - expectedTransactionCount); - } - - public Condition getSuccessfulTransactionReceipt(final Hash transactionHash) { - return new PrivGetExpectedSuccessfulTransactionReceipt( - transactions.getTransactionReceipt(transactionHash)); - } - - public Condition getFailedTransactionReceipt(final Hash transactionHash) { - return new PrivGetExpectedFailedTransactionReceipt( - transactions.getTransactionReceipt(transactionHash)); - } - - public Condition getInvalidTransactionReceipt(final Hash transactionHash) { - return new PrivGetExpectedInvalidTransactionReceipt( - transactions.getTransactionReceipt(transactionHash)); - } - - public Condition multiTenancyValidationFail( - final Transaction transaction, final RpcErrorType error) { - return new ExpectJsonRpcError(transaction, error); - } - - public PrivateCondition syncingStatus(final boolean isSyncing) { - return new PrivateSyncingStatusCondition(transactions.syncing(), isSyncing); - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivCreatePrivacyGroupSuccess.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivCreatePrivacyGroupSuccess.java deleted file mode 100644 index c507ca4b50..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivCreatePrivacyGroupSuccess.java +++ /dev/null @@ -1,39 +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.tests.acceptance.dsl.condition.priv; - -import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; - -import org.hyperledger.besu.tests.acceptance.dsl.condition.Condition; -import org.hyperledger.besu.tests.acceptance.dsl.node.Node; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.privacy.PrivCreatePrivacyGroupTransaction; - -public class PrivCreatePrivacyGroupSuccess implements Condition { - - private final PrivCreatePrivacyGroupTransaction transaction; - private final String groupId; - - public PrivCreatePrivacyGroupSuccess( - final PrivCreatePrivacyGroupTransaction transaction, final String groupId) { - this.transaction = transaction; - this.groupId = groupId; - } - - @Override - public void verify(final Node node) { - final String result = node.execute(transaction); - assertThat(result).isEqualTo(groupId); - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivDeletePrivacyGroupSuccess.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivDeletePrivacyGroupSuccess.java deleted file mode 100644 index b2cd4a40ce..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivDeletePrivacyGroupSuccess.java +++ /dev/null @@ -1,39 +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.tests.acceptance.dsl.condition.priv; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.hyperledger.besu.tests.acceptance.dsl.condition.Condition; -import org.hyperledger.besu.tests.acceptance.dsl.node.Node; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.privacy.PrivDeletePrivacyGroupTransaction; - -public class PrivDeletePrivacyGroupSuccess implements Condition { - - private final PrivDeletePrivacyGroupTransaction transaction; - private final String groupId; - - public PrivDeletePrivacyGroupSuccess( - final PrivDeletePrivacyGroupTransaction transaction, final String groupId) { - this.transaction = transaction; - this.groupId = groupId; - } - - @Override - public void verify(final Node node) { - final String result = node.execute(transaction); - assertThat(result).isEqualTo(groupId); - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivDistributeRawTransactionSuccess.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivDistributeRawTransactionSuccess.java deleted file mode 100644 index 4184102cf5..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivDistributeRawTransactionSuccess.java +++ /dev/null @@ -1,42 +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.tests.acceptance.dsl.condition.priv; - -import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; - -import org.hyperledger.besu.tests.acceptance.dsl.condition.Condition; -import org.hyperledger.besu.tests.acceptance.dsl.node.Node; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.privacy.PrivDistributeRawTransactionTransaction; - -public class PrivDistributeRawTransactionSuccess implements Condition { - - private final PrivDistributeRawTransactionTransaction sendRawTransactionTransaction; - private final String enclaveResponseKey; - - public PrivDistributeRawTransactionSuccess( - final PrivDistributeRawTransactionTransaction sendRawTransactionTransaction, - final String enclaveResponseKey) { - this.sendRawTransactionTransaction = sendRawTransactionTransaction; - this.enclaveResponseKey = enclaveResponseKey; - } - - @Override - public void verify(final Node node) { - final String result = node.execute(sendRawTransactionTransaction); - assertThat(result).isNotNull(); - assertThat(result).isInstanceOf(String.class); - assertThat(result).isEqualTo(enclaveResponseKey); - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivFindPrivacyGroupSuccess.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivFindPrivacyGroupSuccess.java deleted file mode 100644 index f4a069a243..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivFindPrivacyGroupSuccess.java +++ /dev/null @@ -1,40 +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.tests.acceptance.dsl.condition.priv; - -import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; - -import org.hyperledger.besu.enclave.types.PrivacyGroup; -import org.hyperledger.besu.tests.acceptance.dsl.condition.Condition; -import org.hyperledger.besu.tests.acceptance.dsl.node.Node; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.privacy.PrivFindPrivacyGroupTransaction; - -public class PrivFindPrivacyGroupSuccess implements Condition { - - private final PrivFindPrivacyGroupTransaction transaction; - private final int numGroups; - - public PrivFindPrivacyGroupSuccess( - final PrivFindPrivacyGroupTransaction transaction, final int numGroups) { - this.transaction = transaction; - this.numGroups = numGroups; - } - - @Override - public void verify(final Node node) { - final PrivacyGroup[] privacyGroups = node.execute(transaction); - assertThat(privacyGroups).hasSize(numGroups); - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivGetEeaTransactionCountSuccess.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivGetEeaTransactionCountSuccess.java deleted file mode 100644 index def5502d98..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivGetEeaTransactionCountSuccess.java +++ /dev/null @@ -1,42 +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.tests.acceptance.dsl.condition.priv; - -import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; - -import org.hyperledger.besu.tests.acceptance.dsl.condition.Condition; -import org.hyperledger.besu.tests.acceptance.dsl.node.Node; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.privacy.PrivGetEeaTransactionCountTransaction; - -public class PrivGetEeaTransactionCountSuccess implements Condition { - - private final PrivGetEeaTransactionCountTransaction privGetEeaTransactionCountTransaction; - private final int expectedTransactionCount; - - public PrivGetEeaTransactionCountSuccess( - final PrivGetEeaTransactionCountTransaction privGetEeaTransactionCountTransaction, - final int expectedTransactionCount) { - this.privGetEeaTransactionCountTransaction = privGetEeaTransactionCountTransaction; - this.expectedTransactionCount = expectedTransactionCount; - } - - @Override - public void verify(final Node node) { - final int result = node.execute(privGetEeaTransactionCountTransaction); - assertThat(result).isNotNull(); - assertThat(result).isInstanceOf(Integer.class); - assertThat(result).isEqualTo(expectedTransactionCount); - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivGetExpectedFailedTransactionReceipt.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivGetExpectedFailedTransactionReceipt.java deleted file mode 100644 index fc3b081879..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivGetExpectedFailedTransactionReceipt.java +++ /dev/null @@ -1,38 +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.tests.acceptance.dsl.condition.priv; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.hyperledger.besu.tests.acceptance.dsl.WaitUtils; -import org.hyperledger.besu.tests.acceptance.dsl.condition.Condition; -import org.hyperledger.besu.tests.acceptance.dsl.node.Node; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.privacy.PrivGetTransactionReceiptTransaction; - -public class PrivGetExpectedFailedTransactionReceipt implements Condition { - - private final PrivGetTransactionReceiptTransaction getTransactionReceiptTransaction; - - public PrivGetExpectedFailedTransactionReceipt( - final PrivGetTransactionReceiptTransaction getTransactionReceiptTransaction) { - this.getTransactionReceiptTransaction = getTransactionReceiptTransaction; - } - - @Override - public void verify(final Node node) { - WaitUtils.waitFor(() -> assertThat(node.execute(getTransactionReceiptTransaction)).isNotNull()); - assertThat(node.execute(getTransactionReceiptTransaction).getStatus()).isEqualTo("0x0"); - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivGetExpectedInvalidTransactionReceipt.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivGetExpectedInvalidTransactionReceipt.java deleted file mode 100644 index 75a344ded7..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivGetExpectedInvalidTransactionReceipt.java +++ /dev/null @@ -1,38 +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.tests.acceptance.dsl.condition.priv; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.hyperledger.besu.tests.acceptance.dsl.WaitUtils; -import org.hyperledger.besu.tests.acceptance.dsl.condition.Condition; -import org.hyperledger.besu.tests.acceptance.dsl.node.Node; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.privacy.PrivGetTransactionReceiptTransaction; - -public class PrivGetExpectedInvalidTransactionReceipt implements Condition { - - private final PrivGetTransactionReceiptTransaction getTransactionReceiptTransaction; - - public PrivGetExpectedInvalidTransactionReceipt( - final PrivGetTransactionReceiptTransaction getTransactionReceiptTransaction) { - this.getTransactionReceiptTransaction = getTransactionReceiptTransaction; - } - - @Override - public void verify(final Node node) { - WaitUtils.waitFor(() -> assertThat(node.execute(getTransactionReceiptTransaction)).isNotNull()); - assertThat(node.execute(getTransactionReceiptTransaction).getStatus()).isEqualTo("0x2"); - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivGetExpectedSuccessfulTransactionReceipt.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivGetExpectedSuccessfulTransactionReceipt.java deleted file mode 100644 index cefc110e1b..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivGetExpectedSuccessfulTransactionReceipt.java +++ /dev/null @@ -1,38 +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.tests.acceptance.dsl.condition.priv; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.hyperledger.besu.tests.acceptance.dsl.WaitUtils; -import org.hyperledger.besu.tests.acceptance.dsl.condition.Condition; -import org.hyperledger.besu.tests.acceptance.dsl.node.Node; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.privacy.PrivGetTransactionReceiptTransaction; - -public class PrivGetExpectedSuccessfulTransactionReceipt implements Condition { - - private final PrivGetTransactionReceiptTransaction getTransactionReceiptTransaction; - - public PrivGetExpectedSuccessfulTransactionReceipt( - final PrivGetTransactionReceiptTransaction getTransactionReceiptTransaction) { - this.getTransactionReceiptTransaction = getTransactionReceiptTransaction; - } - - @Override - public void verify(final Node node) { - WaitUtils.waitFor(() -> assertThat(node.execute(getTransactionReceiptTransaction)).isNotNull()); - assertThat(node.execute(getTransactionReceiptTransaction).getStatus()).isEqualTo("0x1"); - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivGetPrivacyPrecompileAddressSuccess.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivGetPrivacyPrecompileAddressSuccess.java deleted file mode 100644 index a3992da432..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivGetPrivacyPrecompileAddressSuccess.java +++ /dev/null @@ -1,42 +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.tests.acceptance.dsl.condition.priv; - -import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; - -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.tests.acceptance.dsl.condition.Condition; -import org.hyperledger.besu.tests.acceptance.dsl.node.Node; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.privacy.PrivGetPrivacyPrecompileAddressTransaction; - -public class PrivGetPrivacyPrecompileAddressSuccess implements Condition { - - private final PrivGetPrivacyPrecompileAddressTransaction transaction; - private final Address precompileAddress; - - public PrivGetPrivacyPrecompileAddressSuccess( - final PrivGetPrivacyPrecompileAddressTransaction transaction, - final Address precompileAddress) { - this.transaction = transaction; - this.precompileAddress = precompileAddress; - } - - @Override - public void verify(final Node node) { - final Address result = node.execute(transaction); - assertThat(result).isInstanceOf(Address.class); - assertThat(result).isEqualTo(precompileAddress); - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivGetPrivateTransactionReturnsNull.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivGetPrivateTransactionReturnsNull.java deleted file mode 100644 index da6f7f519b..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivGetPrivateTransactionReturnsNull.java +++ /dev/null @@ -1,38 +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.tests.acceptance.dsl.condition.priv; - -import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; - -import org.hyperledger.besu.tests.acceptance.dsl.condition.Condition; -import org.hyperledger.besu.tests.acceptance.dsl.node.Node; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivateTransactionGroupResponse; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.privacy.PrivGetPrivateTransactionTransaction; - -public class PrivGetPrivateTransactionReturnsNull implements Condition { - - private final PrivGetPrivateTransactionTransaction transaction; - - public PrivGetPrivateTransactionReturnsNull( - final PrivGetPrivateTransactionTransaction transaction) { - this.transaction = transaction; - } - - @Override - public void verify(final Node node) { - final PrivateTransactionGroupResponse result = node.execute(transaction); - assertThat(result).isNull(); - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivGetPrivateTransactionSuccess.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivGetPrivateTransactionSuccess.java deleted file mode 100644 index b09b1b29bc..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivGetPrivateTransactionSuccess.java +++ /dev/null @@ -1,43 +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.tests.acceptance.dsl.condition.priv; - -import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; - -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.privacy.PrivateTransactionGroupResult; -import org.hyperledger.besu.ethereum.privacy.PrivateTransaction; -import org.hyperledger.besu.tests.acceptance.dsl.condition.Condition; -import org.hyperledger.besu.tests.acceptance.dsl.node.Node; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivateTransactionGroupResponse; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.privacy.PrivGetPrivateTransactionTransaction; - -public class PrivGetPrivateTransactionSuccess implements Condition { - - private final PrivGetPrivateTransactionTransaction transaction; - private final PrivateTransactionGroupResult privateTransaction; - - public PrivGetPrivateTransactionSuccess( - final PrivGetPrivateTransactionTransaction transaction, - final PrivateTransaction privateTransaction) { - this.transaction = transaction; - this.privateTransaction = new PrivateTransactionGroupResult(privateTransaction); - } - - @Override - public void verify(final Node node) { - final PrivateTransactionGroupResponse result = node.execute(transaction); - assertThat(result).usingRecursiveComparison().isEqualTo(privateTransaction); - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivGetTransactionCountSuccess.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivGetTransactionCountSuccess.java deleted file mode 100644 index 823548effa..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivGetTransactionCountSuccess.java +++ /dev/null @@ -1,42 +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.tests.acceptance.dsl.condition.priv; - -import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; - -import org.hyperledger.besu.tests.acceptance.dsl.condition.Condition; -import org.hyperledger.besu.tests.acceptance.dsl.node.Node; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.privacy.PrivGetTransactionCountTransaction; - -public class PrivGetTransactionCountSuccess implements Condition { - - private final PrivGetTransactionCountTransaction privGetTransactionCountTransaction; - private final int expectedTransactionCount; - - public PrivGetTransactionCountSuccess( - final PrivGetTransactionCountTransaction privGetTransactionCountTransaction, - final int expectedTransactionCount) { - this.privGetTransactionCountTransaction = privGetTransactionCountTransaction; - this.expectedTransactionCount = expectedTransactionCount; - } - - @Override - public void verify(final Node node) { - final Integer result = node.execute(privGetTransactionCountTransaction); - assertThat(result).isNotNull(); - assertThat(result).isInstanceOf(Integer.class); - assertThat(result).isEqualTo(expectedTransactionCount); - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivateSyncingStatusCondition.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivateSyncingStatusCondition.java deleted file mode 100644 index 067cba268d..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/priv/PrivateSyncingStatusCondition.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.tests.acceptance.dsl.condition.priv; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.hyperledger.besu.tests.acceptance.dsl.WaitUtils; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.condition.PrivateCondition; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.privacy.PrivSyncingTransactions; - -public class PrivateSyncingStatusCondition implements PrivateCondition { - - private final PrivSyncingTransactions transaction; - private final boolean syncingMiningStatus; - - public PrivateSyncingStatusCondition( - final PrivSyncingTransactions transaction, final boolean syncingStatus) { - this.transaction = transaction; - this.syncingMiningStatus = syncingStatus; - } - - @Override - public void verify(final PrivacyNode node) { - WaitUtils.waitFor( - 10, () -> assertThat(node.execute(transaction)).isEqualTo(syncingMiningStatus)); - } -} 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 1ae27d6261..157421531b 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 @@ -49,7 +49,6 @@ import org.hyperledger.besu.tests.acceptance.dsl.transaction.login.LoginRequestF import org.hyperledger.besu.tests.acceptance.dsl.transaction.miner.MinerRequestFactory; import org.hyperledger.besu.tests.acceptance.dsl.transaction.net.CustomRequestFactory; import org.hyperledger.besu.tests.acceptance.dsl.transaction.perm.PermissioningJsonRpcRequestFactory; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.privacy.PrivacyRequestFactory; import org.hyperledger.besu.tests.acceptance.dsl.transaction.txpool.TxPoolRequestFactory; import java.io.File; @@ -445,7 +444,6 @@ public class BesuNode implements NodeConfiguration, RunnableNode, AutoCloseable new BftRequestFactory(web3jService, bftType), new PermissioningJsonRpcRequestFactory(web3jService), new AdminRequestFactory(web3jService), - new PrivacyRequestFactory(web3jService), new CustomRequestFactory(web3jService), new MinerRequestFactory(web3jService), new TxPoolRequestFactory(web3jService), diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeFactory.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeFactory.java index 9660f6ee9d..0451d2a721 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeFactory.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeFactory.java @@ -20,16 +20,8 @@ import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis.ADMIN; import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis.IBFT; import org.hyperledger.besu.crypto.KeyPair; -import org.hyperledger.besu.datatypes.Wei; -import org.hyperledger.besu.enclave.EnclaveFactory; import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.websocket.WebSocketConfiguration; -import org.hyperledger.besu.ethereum.core.AddressHelpers; -import org.hyperledger.besu.ethereum.core.ImmutableMiningParameters; -import org.hyperledger.besu.ethereum.core.ImmutableMiningParameters.MutableInitValues; -import org.hyperledger.besu.ethereum.core.InMemoryPrivacyStorageProvider; -import org.hyperledger.besu.ethereum.core.MiningParameters; -import org.hyperledger.besu.ethereum.core.PrivacyParameters; import org.hyperledger.besu.ethereum.permissioning.LocalPermissioningConfiguration; import org.hyperledger.besu.ethereum.permissioning.PermissioningConfiguration; import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; @@ -45,7 +37,6 @@ import java.io.File; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; -import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -53,8 +44,6 @@ import java.util.Optional; import java.util.Set; import java.util.function.UnaryOperator; -import io.vertx.core.Vertx; - public class BesuNodeFactory { private final NodeConfigurationFactory node = new NodeConfigurationFactory(); @@ -288,49 +277,6 @@ public class BesuNodeFactory { .build()); } - public BesuNode createNodeWithMultiTenantedPrivacy( - final String name, - final String enclaveUrl, - final String authFile, - final String privTransactionSigningKey, - final boolean enableFlexiblePrivacy, - final boolean enablePrivateNonceAlwaysIncrements) - throws IOException, URISyntaxException { - final PrivacyParameters.Builder privacyParametersBuilder = new PrivacyParameters.Builder(); - final PrivacyParameters privacyParameters = - privacyParametersBuilder - .setMultiTenancyEnabled(true) - .setEnabled(true) - .setFlexiblePrivacyGroupsEnabled(enableFlexiblePrivacy) - .setStorageProvider(new InMemoryPrivacyStorageProvider()) - .setEnclaveFactory(new EnclaveFactory(Vertx.vertx())) - .setEnclaveUrl(URI.create(enclaveUrl)) - .setPrivateNonceAlwaysIncrementsEnabled(enablePrivateNonceAlwaysIncrements) - .setPrivateKeyPath( - Paths.get(ClassLoader.getSystemResource(privTransactionSigningKey).toURI())) - .build(); - - final MiningParameters miningParameters = - ImmutableMiningParameters.builder() - .mutableInitValues( - MutableInitValues.builder() - .isMiningEnabled(true) - .minTransactionGasPrice(Wei.ZERO) - .coinbase(AddressHelpers.ofValue(1)) - .build()) - .build(); - - return create( - new BesuNodeConfigurationBuilder() - .name(name) - .jsonRpcEnabled() - .jsonRpcAuthenticationConfiguration(authFile) - .enablePrivateTransactions() - .privacyParameters(privacyParameters) - .miningConfiguration(miningParameters) - .build()); - } - public BesuNode createArchiveNodeWithRpcDisabled(final String name) throws IOException { return create(new BesuNodeConfigurationBuilder().name(name).build()); } diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/privacy/PrivacyNodeConfiguration.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/privacy/PrivacyNodeConfiguration.java deleted file mode 100644 index 05c989e54a..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/privacy/PrivacyNodeConfiguration.java +++ /dev/null @@ -1,65 +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.tests.acceptance.dsl.node.configuration.privacy; - -import org.hyperledger.besu.tests.acceptance.dsl.node.configuration.BesuNodeConfiguration; -import org.hyperledger.enclave.testutil.EnclaveKeyConfiguration; - -public class PrivacyNodeConfiguration { - - private final boolean isFlexiblePrivacyGroupEnabled; - private final boolean isMultitenancyEnabled; - private final boolean isPrivacyPluginEnabled; - private final BesuNodeConfiguration besuConfig; - private final EnclaveKeyConfiguration keyConfig; - - PrivacyNodeConfiguration( - final BesuNodeConfiguration besuConfig, final EnclaveKeyConfiguration keyConfig) { - this(false, false, false, besuConfig, keyConfig); - } - - public PrivacyNodeConfiguration( - final boolean isFlexiblePrivacyGroupEnabled, - final boolean isMultitenancyEnabled, - final boolean isPrivacyPluginEnabled, - final BesuNodeConfiguration besuConfig, - final EnclaveKeyConfiguration keyConfig) { - this.isFlexiblePrivacyGroupEnabled = isFlexiblePrivacyGroupEnabled; - this.besuConfig = besuConfig; - this.keyConfig = keyConfig; - this.isMultitenancyEnabled = isMultitenancyEnabled; - this.isPrivacyPluginEnabled = isPrivacyPluginEnabled; - } - - public boolean isFlexiblePrivacyGroupEnabled() { - return isFlexiblePrivacyGroupEnabled; - } - - public boolean isMultitenancyEnabled() { - return isMultitenancyEnabled; - } - - public boolean isPrivacyPluginEnabled() { - return isPrivacyPluginEnabled; - } - - public BesuNodeConfiguration getBesuConfig() { - return besuConfig; - } - - public EnclaveKeyConfiguration getKeyConfig() { - return keyConfig; - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/privacy/PrivacyNodeFactory.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/privacy/PrivacyNodeFactory.java deleted file mode 100644 index 03188db8a2..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/privacy/PrivacyNodeFactory.java +++ /dev/null @@ -1,294 +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.tests.acceptance.dsl.node.configuration.privacy; - -import org.hyperledger.besu.tests.acceptance.dsl.node.configuration.BesuNodeConfigurationBuilder; -import org.hyperledger.besu.tests.acceptance.dsl.node.configuration.NodeConfigurationFactory; -import org.hyperledger.besu.tests.acceptance.dsl.node.configuration.genesis.GenesisConfigurationFactory; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.account.PrivacyAccount; -import org.hyperledger.enclave.testutil.EnclaveEncryptorType; -import org.hyperledger.enclave.testutil.EnclaveKeyConfiguration; -import org.hyperledger.enclave.testutil.EnclaveType; - -import java.io.IOException; -import java.net.URISyntaxException; -import java.util.Collections; -import java.util.List; -import java.util.Optional; - -import io.vertx.core.Vertx; -import org.testcontainers.containers.Network; - -public class PrivacyNodeFactory { - - private final NodeConfigurationFactory node = new NodeConfigurationFactory(); - private final Vertx vertx; - - public PrivacyNodeFactory(final Vertx vertx) { - this.vertx = vertx; - } - - public PrivacyNode create( - final PrivacyNodeConfiguration privacyNodeConfig, - final EnclaveType enclaveType, - final Optional containerNetwork) - throws IOException { - return new PrivacyNode(privacyNodeConfig, vertx, enclaveType, containerNetwork); - } - - public PrivacyNode createPrivateTransactionEnabledMinerNode( - final String name, - final PrivacyAccount privacyAccount, - final EnclaveType enclaveType, - final Optional containerNetwork, - final boolean isFlexiblePrivacyGroupEnabled, - final boolean isMultitenancyEnabled, - final boolean isPrivacyPluginEnabled) - throws IOException { - return create( - new PrivacyNodeConfiguration( - isFlexiblePrivacyGroupEnabled, - isMultitenancyEnabled, - isPrivacyPluginEnabled, - new BesuNodeConfigurationBuilder() - .name(name) - .miningEnabled() - .jsonRpcEnabled() - .webSocketEnabled() - .enablePrivateTransactions() - .keyFilePath(privacyAccount.getPrivateKeyPath()) - .plugins(Collections.singletonList("testPlugins")) - .extraCLIOptions(List.of("--plugin-privacy-service-encryption-prefix=0xAA")) - .build(), - new EnclaveKeyConfiguration( - privacyAccount.getEnclaveKeyPaths(), - privacyAccount.getEnclavePrivateKeyPaths(), - privacyAccount.getEnclaveEncryptorType())), - enclaveType, - containerNetwork); - } - - public PrivacyNode createPrivateTransactionEnabledNode( - final String name, - final PrivacyAccount privacyAccount, - final EnclaveType enclaveType, - final Optional containerNetwork, - final boolean isFlexiblePrivacyGroupEnabled, - final boolean isMultitenancyEnabled, - final boolean isPrivacyPluginEnabled) - throws IOException { - return create( - new PrivacyNodeConfiguration( - isFlexiblePrivacyGroupEnabled, - isMultitenancyEnabled, - isPrivacyPluginEnabled, - new BesuNodeConfigurationBuilder() - .name(name) - .jsonRpcEnabled() - .keyFilePath(privacyAccount.getPrivateKeyPath()) - .enablePrivateTransactions() - .webSocketEnabled() - .plugins(Collections.singletonList("testPlugins")) - .extraCLIOptions(List.of("--plugin-privacy-service-encryption-prefix=0xBB")) - .build(), - new EnclaveKeyConfiguration( - privacyAccount.getEnclaveKeyPaths(), - privacyAccount.getEnclavePrivateKeyPaths(), - privacyAccount.getEnclaveEncryptorType())), - enclaveType, - containerNetwork); - } - - public PrivacyNode createIbft2NodePrivacyEnabled( - final String name, - final PrivacyAccount privacyAccount, - final boolean minerEnabled, - final EnclaveType enclaveType, - final Optional containerNetwork, - final boolean isFlexiblePrivacyGroupEnabled, - final boolean isMultitenancyEnabled, - final boolean isPrivacyPluginEnabled, - final String unrestrictedPrefix) - throws IOException { - return create( - new PrivacyNodeConfiguration( - isFlexiblePrivacyGroupEnabled, - isMultitenancyEnabled, - isPrivacyPluginEnabled, - new BesuNodeConfigurationBuilder() - .name(name) - .miningEnabled() - .jsonRpcConfiguration(node.createJsonRpcWithIbft2EnabledConfig(minerEnabled)) - .webSocketConfiguration(node.createWebSocketEnabledConfig()) - .devMode(false) - .genesisConfigProvider(GenesisConfigurationFactory::createPrivacyIbft2GenesisConfig) - .keyFilePath(privacyAccount.getPrivateKeyPath()) - .enablePrivateTransactions() - .plugins(Collections.singletonList("testPlugins")) - .extraCLIOptions( - List.of("--plugin-privacy-service-encryption-prefix=" + unrestrictedPrefix)) - .build(), - new EnclaveKeyConfiguration( - privacyAccount.getEnclaveKeyPaths(), - privacyAccount.getEnclavePrivateKeyPaths(), - privacyAccount.getEnclaveEncryptorType())), - enclaveType, - containerNetwork); - } - - public PrivacyNode createIbft2NodePrivacyEnabledWithGenesis( - final String name, - final PrivacyAccount privacyAccount, - final boolean minerEnabled, - final EnclaveType enclaveType, - final Optional containerNetwork, - final boolean isFlexiblePrivacyGroupEnabled, - final boolean isMultitenancyEnabled, - final boolean isPrivacyPluginEnabled, - final String unrestrictedPrefix) - throws IOException { - return create( - new PrivacyNodeConfiguration( - isFlexiblePrivacyGroupEnabled, - isMultitenancyEnabled, - isPrivacyPluginEnabled, - new BesuNodeConfigurationBuilder() - .name(name) - .miningEnabled() - .jsonRpcConfiguration(node.createJsonRpcWithIbft2EnabledConfig(minerEnabled)) - .webSocketConfiguration(node.createWebSocketEnabledConfig()) - .devMode(false) - .genesisConfigProvider(GenesisConfigurationFactory::createPrivacyIbft2GenesisConfig) - .keyFilePath(privacyAccount.getPrivateKeyPath()) - .enablePrivateTransactions() - .plugins(Collections.singletonList("testPlugins")) - .extraCLIOptions( - List.of( - "--plugin-privacy-service-encryption-prefix=" + unrestrictedPrefix, - "--plugin-privacy-service-genesis-enabled=true")) - .build(), - new EnclaveKeyConfiguration( - privacyAccount.getEnclaveKeyPaths(), - privacyAccount.getEnclavePrivateKeyPaths(), - privacyAccount.getEnclaveEncryptorType())), - enclaveType, - containerNetwork); - } - - public PrivacyNode createQbftNodePrivacyEnabled( - final String name, - final PrivacyAccount privacyAccount, - final EnclaveType enclaveType, - final Optional containerNetwork, - final boolean isFlexiblePrivacyGroupEnabled, - final boolean isMultitenancyEnabled, - final boolean isPrivacyPluginEnabled, - final String unrestrictedPrefix) - throws IOException { - return create( - new PrivacyNodeConfiguration( - isFlexiblePrivacyGroupEnabled, - isMultitenancyEnabled, - isPrivacyPluginEnabled, - new BesuNodeConfigurationBuilder() - .name(name) - .miningEnabled() - .jsonRpcConfiguration(node.createJsonRpcWithQbftEnabledConfig(false)) - .webSocketConfiguration(node.createWebSocketEnabledConfig()) - .devMode(false) - .genesisConfigProvider(GenesisConfigurationFactory::createQbftGenesisConfig) - .keyFilePath(privacyAccount.getPrivateKeyPath()) - .enablePrivateTransactions() - .plugins(Collections.singletonList("testPlugins")) - .extraCLIOptions( - List.of("--plugin-privacy-service-encryption-prefix=" + unrestrictedPrefix)) - .build(), - new EnclaveKeyConfiguration( - privacyAccount.getEnclaveKeyPaths(), - privacyAccount.getEnclavePrivateKeyPaths(), - privacyAccount.getEnclaveEncryptorType())), - enclaveType, - containerNetwork); - } - - public PrivacyNode createFlexiblePrivacyGroupEnabledMinerNode( - final String name, - final PrivacyAccount privacyAccount, - final boolean multiTenancyEnabled, - final EnclaveType enclaveType, - final Optional containerNetwork) - throws IOException, URISyntaxException { - final BesuNodeConfigurationBuilder besuNodeConfigurationBuilder = - new BesuNodeConfigurationBuilder(); - if (multiTenancyEnabled) { - final String authPrivTomlPath = - EnclaveEncryptorType.EC.equals(privacyAccount.getEnclaveEncryptorType()) - ? "authentication/auth_priv_ec_pubkey.toml" - : "authentication/auth_priv.toml"; - besuNodeConfigurationBuilder.jsonRpcAuthenticationConfiguration(authPrivTomlPath); - } - return create( - new PrivacyNodeConfiguration( - true, - multiTenancyEnabled, - false, - besuNodeConfigurationBuilder - .name(name) - .miningEnabled() - .jsonRpcEnabled() - .webSocketEnabled() - .enablePrivateTransactions() - .plugins(Collections.singletonList("testPlugins")) - .extraCLIOptions(List.of("--plugin-privacy-service-genesis-enabled=true")) - .keyFilePath(privacyAccount.getPrivateKeyPath()) - .build(), - new EnclaveKeyConfiguration( - privacyAccount.getEnclaveKeyPaths(), - privacyAccount.getEnclavePrivateKeyPaths(), - privacyAccount.getEnclaveEncryptorType())), - enclaveType, - containerNetwork); - } - - public PrivacyNode createFlexiblePrivacyGroupEnabledNode( - final String name, - final PrivacyAccount privacyAccount, - final boolean multiTenancyEnabled, - final EnclaveType enclaveType, - final Optional containerNetwork) - throws IOException { - return create( - new PrivacyNodeConfiguration( - true, - multiTenancyEnabled, - false, - new BesuNodeConfigurationBuilder() - .name(name) - .jsonRpcEnabled() - .keyFilePath(privacyAccount.getPrivateKeyPath()) - .enablePrivateTransactions() - .plugins(Collections.singletonList("testPlugins")) - .extraCLIOptions(List.of("--plugin-privacy-service-genesis-enabled=true")) - .webSocketEnabled() - .build(), - new EnclaveKeyConfiguration( - privacyAccount.getEnclaveKeyPaths(), - privacyAccount.getEnclavePrivateKeyPaths(), - privacyAccount.getEnclaveEncryptorType())), - enclaveType, - containerNetwork); - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/PrivacyCluster.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/PrivacyCluster.java deleted file mode 100644 index 3d1fc14805..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/PrivacyCluster.java +++ /dev/null @@ -1,184 +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.tests.acceptance.dsl.privacy; - -import static java.util.Collections.emptyList; -import static java.util.function.Predicate.not; - -import org.hyperledger.besu.tests.acceptance.dsl.condition.net.NetConditions; -import org.hyperledger.besu.tests.acceptance.dsl.node.BesuNodeRunner; -import org.hyperledger.besu.tests.acceptance.dsl.node.RunnableNode; -import org.hyperledger.enclave.testutil.EnclaveType; -import org.hyperledger.enclave.testutil.TesseraTestHarness; - -import java.net.URI; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class PrivacyCluster { - private static final Logger LOG = LoggerFactory.getLogger(PrivacyCluster.class); - private final NetConditions net; - private final BesuNodeRunner besuNodeRunner; - - private List nodes = emptyList(); - private List runnableNodes = emptyList(); - private PrivacyNode bootNode; - - public PrivacyCluster(final NetConditions net) { - this.net = net; - this.besuNodeRunner = BesuNodeRunner.instance(); - } - - public void start(final PrivacyNode... nodes) { - start(Arrays.asList(nodes)); - } - - public void start(final List nodes) { - startNodes(nodes); - awaitPeerCount(nodes); - } - - public void startNodes(final PrivacyNode... nodes) { - startNodes(Arrays.asList(nodes)); - } - - public void startNodes(final List nodes) { - if (nodes.isEmpty()) { - throw new IllegalArgumentException("Can't start a cluster with no nodes"); - } - this.nodes = nodes; - this.runnableNodes = nodes.stream().map(PrivacyNode::getBesu).collect(Collectors.toList()); - - final Optional bootNode = selectAndStartBootnode(nodes); - - nodes.parallelStream() - .filter(node -> bootNode.map(boot -> boot != node).orElse(true)) - .forEach(this::startNode); - } - - public void awaitPeerCount(final PrivacyNode... nodes) { - awaitPeerCount(Arrays.asList(nodes)); - } - - public void awaitPeerCount(final List nodes) { - for (final PrivacyNode node : nodes) { - LOG.info("Awaiting peer discovery for node {}", node.getName()); - node.awaitPeerDiscovery(net.awaitPeerCount(nodes.size() - 1)); - } - - verifyAllEnclaveNetworkConnections(); - } - - public List getNodes() { - return nodes; - } - - /** Verify that each Enclave has connected to every other Enclave */ - public void verifyAllEnclaveNetworkConnections() { - nodes.forEach( - privacyNode -> { - final List otherNodes = - nodes.stream() - .filter(not(privacyNode::equals)) - .collect(Collectors.toUnmodifiableList()); - privacyNode.testEnclaveConnection(otherNodes); - }); - } - - public void stop() { - for (final PrivacyNode node : nodes) { - besuNodeRunner.stopNode(node.getBesu()); - } - } - - public void stopNode(final PrivacyNode node) { - node.getEnclave().stop(); - besuNodeRunner.stopNode(node.getBesu()); - } - - public void close() { - stop(); - for (final PrivacyNode node : nodes) { - node.close(); - } - besuNodeRunner.shutdown(); - } - - private Optional selectAndStartBootnode(final List nodes) { - final Optional bootNode = - nodes.stream() - .filter(node -> node.getConfiguration().isBootnodeEligible()) - .filter(node -> node.getConfiguration().isP2pEnabled()) - .filter(node -> node.getConfiguration().isDiscoveryEnabled()) - .findFirst(); - - bootNode.ifPresent( - b -> { - LOG.info("Selected node {} as bootnode", b.getName()); - startNode(b, true); - this.bootNode = b; - }); - - return bootNode; - } - - private void startNode(final PrivacyNode node) { - startNode(node, false); - } - - private void startNode(final PrivacyNode node, final boolean isBootNode) { - node.getConfiguration() - .setBootnodes(isBootNode ? emptyList() : Collections.singletonList(bootNode.enodeUrl())); - - node.getConfiguration() - .getGenesisConfigProvider() - .create(runnableNodes) - .ifPresent(node.getConfiguration()::setGenesisConfig); - - if (!isBootNode) { - if (bootNode.getEnclave().getEnclaveType() == EnclaveType.TESSERA) { - final URI otherNode = bootNode.getEnclave().nodeUrl(); - try { - // Substitute IP with hostname for test container network - final URI otherNodeHostname = - new URI( - otherNode.getScheme() - + "://" - + bootNode.getName() - + ":" - + TesseraTestHarness.p2pPort); - node.addOtherEnclaveNode(otherNodeHostname); - } catch (Exception ex) { - throw new RuntimeException("Invalid node URI"); - } - } else { - node.addOtherEnclaveNode(bootNode.getEnclave().nodeUrl()); - } - } - - LOG.info( - "Starting node {} (id = {}...{})", - node.getName(), - node.getNodeId().substring(0, 4), - node.getNodeId().substring(124)); - node.start(besuNodeRunner); - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/PrivacyNode.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/PrivacyNode.java deleted file mode 100644 index d54bf90872..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/PrivacyNode.java +++ /dev/null @@ -1,315 +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.tests.acceptance.dsl.privacy; - -import static org.hyperledger.besu.controller.BesuController.DATABASE_PATH; -import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_BACKGROUND_THREAD_COUNT; -import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_CACHE_CAPACITY; -import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_IS_HIGH_SPEC; -import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_MAX_OPEN_FILES; - -import org.hyperledger.besu.crypto.KeyPairUtil; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.enclave.Enclave; -import org.hyperledger.besu.enclave.EnclaveClientException; -import org.hyperledger.besu.enclave.EnclaveFactory; -import org.hyperledger.besu.enclave.EnclaveIOException; -import org.hyperledger.besu.enclave.EnclaveServerException; -import org.hyperledger.besu.ethereum.core.PrivacyParameters; -import org.hyperledger.besu.ethereum.privacy.storage.PrivacyStorageProvider; -import org.hyperledger.besu.ethereum.privacy.storage.keyvalue.PrivacyKeyValueStorageProviderBuilder; -import org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier; -import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; -import org.hyperledger.besu.plugin.services.storage.rocksdb.RocksDBKeyValuePrivacyStorageFactory; -import org.hyperledger.besu.plugin.services.storage.rocksdb.RocksDBKeyValueStorageFactory; -import org.hyperledger.besu.plugin.services.storage.rocksdb.RocksDBMetricsFactory; -import org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBFactoryConfiguration; -import org.hyperledger.besu.services.BesuConfigurationImpl; -import org.hyperledger.besu.tests.acceptance.dsl.condition.Condition; -import org.hyperledger.besu.tests.acceptance.dsl.node.BesuNode; -import org.hyperledger.besu.tests.acceptance.dsl.node.BesuNodeRunner; -import org.hyperledger.besu.tests.acceptance.dsl.node.configuration.BesuNodeConfiguration; -import org.hyperledger.besu.tests.acceptance.dsl.node.configuration.NodeConfiguration; -import org.hyperledger.besu.tests.acceptance.dsl.node.configuration.privacy.PrivacyNodeConfiguration; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.condition.PrivateCondition; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; -import org.hyperledger.enclave.testutil.EnclaveTestHarness; -import org.hyperledger.enclave.testutil.EnclaveType; -import org.hyperledger.enclave.testutil.NoopEnclaveTestHarness; -import org.hyperledger.enclave.testutil.TesseraTestHarnessFactory; - -import java.io.IOException; -import java.net.URI; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; - -import io.vertx.core.Vertx; -import org.awaitility.Awaitility; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.testcontainers.containers.Network; - -public class PrivacyNode implements AutoCloseable { - - private static final Logger LOG = LoggerFactory.getLogger(PrivacyNode.class); - - private final EnclaveTestHarness enclave; - private final BesuNode besu; - private final Vertx vertx; - private final boolean isFlexiblePrivacyEnabled; - private final boolean isMultitenancyEnabled; - private final boolean isPrivacyPluginEnabled; - private final BesuNodeConfiguration besuConfig; - - public PrivacyNode( - final PrivacyNodeConfiguration privacyConfiguration, - final Vertx vertx, - final EnclaveType enclaveType, - final Optional containerNetwork) - throws IOException { - final Path enclaveDir = Files.createTempDirectory("acctest-orion"); - final BesuNodeConfiguration config = privacyConfiguration.getBesuConfig(); - this.enclave = - selectEnclave(enclaveType, enclaveDir, config, privacyConfiguration, containerNetwork); - this.vertx = vertx; - - this.besuConfig = config; - - isFlexiblePrivacyEnabled = privacyConfiguration.isFlexiblePrivacyGroupEnabled(); - isMultitenancyEnabled = privacyConfiguration.isMultitenancyEnabled(); - isPrivacyPluginEnabled = privacyConfiguration.isPrivacyPluginEnabled(); - - this.besu = - new BesuNode( - besuConfig.getName(), - besuConfig.getDataPath(), - besuConfig.getMiningParameters(), - besuConfig.getTransactionPoolConfiguration(), - besuConfig.getJsonRpcConfiguration(), - besuConfig.getEngineRpcConfiguration(), - besuConfig.getWebSocketConfiguration(), - besuConfig.getJsonRpcIpcConfiguration(), - besuConfig.getInProcessRpcConfiguration(), - besuConfig.getMetricsConfiguration(), - besuConfig.getPermissioningConfiguration(), - besuConfig.getApiConfiguration(), - besuConfig.getDataStorageConfiguration(), - besuConfig.getKeyFilePath(), - besuConfig.isDevMode(), - besuConfig.getNetwork(), - besuConfig.getGenesisConfigProvider(), - besuConfig.isP2pEnabled(), - besuConfig.getP2pPort(), - besuConfig.getTLSConfiguration(), - besuConfig.getNetworkingConfiguration(), - besuConfig.isDiscoveryEnabled(), - besuConfig.isBootnodeEligible(), - besuConfig.isRevertReasonEnabled(), - besuConfig.isSecp256k1Native(), - besuConfig.isAltbn128Native(), - besuConfig.getPlugins(), - besuConfig.getExtraCLIOptions(), - Collections.emptyList(), - besuConfig.isDnsEnabled(), - besuConfig.getPrivacyParameters(), - List.of(), - Optional.empty(), - besuConfig.isStrictTxReplayProtectionEnabled(), - besuConfig.getEnvironment()); - } - - public void testEnclaveConnection(final List otherNodes) { - if (this.isPrivacyPluginEnabled) { - LOG.info("Skipping test as node has no enclave (isPrivacyPluginEnabled=true)"); - return; - } - - if (!otherNodes.isEmpty()) { - LOG.debug( - String.format( - "Testing Enclave connectivity between %s (%s) and %s (%s)", - besu.getName(), - enclave.nodeUrl(), - Arrays.toString(otherNodes.stream().map(node -> node.besu.getName()).toArray()), - Arrays.toString(otherNodes.stream().map(node -> node.enclave.nodeUrl()).toArray()))); - final EnclaveFactory factory = new EnclaveFactory(vertx); - final Enclave enclaveClient = factory.createVertxEnclave(enclave.clientUrl()); - final String payload = "SGVsbG8sIFdvcmxkIQ=="; - final List to = - otherNodes.stream() - .map(node -> node.enclave.getDefaultPublicKey()) - .collect(Collectors.toList()); - - Awaitility.await() - .until( - () -> { - try { - enclaveClient.send(payload, enclave.getDefaultPublicKey(), to); - return true; - } catch (final EnclaveClientException - | EnclaveIOException - | EnclaveServerException e) { - LOG.warn( - "Waiting for enclave connectivity between {} and {}: " + e.getMessage(), - enclave.getDefaultPublicKey(), - to.get(0)); - return false; - } - }); - } - } - - public EnclaveTestHarness getEnclave() { - return enclave; - } - - public BesuNode getBesu() { - return besu; - } - - public void stop() { - besu.stop(); - enclave.stop(); - } - - @Override - public void close() { - besu.close(); - enclave.close(); - } - - public void start(final BesuNodeRunner runner) { - enclave.start(); - - final PrivacyParameters privacyParameters; - - try { - final Path dataDir = Files.createTempDirectory("acctest-privacy"); - final Path dbDir = dataDir.resolve(DATABASE_PATH); - - var builder = - new PrivacyParameters.Builder() - .setEnabled(true) - .setEnclaveUrl(enclave.clientUrl()) - .setStorageProvider(createKeyValueStorageProvider(dataDir, dbDir)) - .setPrivateKeyPath(KeyPairUtil.getDefaultKeyFile(besu.homeDirectory()).toPath()) - .setEnclaveFactory(new EnclaveFactory(vertx)) - .setFlexiblePrivacyGroupsEnabled(isFlexiblePrivacyEnabled) - .setMultiTenancyEnabled(isMultitenancyEnabled) - .setPrivacyPluginEnabled(isPrivacyPluginEnabled); - - if (enclave.getPublicKeyPaths().size() > 0) { - builder.setPrivacyUserIdUsingFile(enclave.getPublicKeyPaths().get(0).toFile()); - } - - privacyParameters = builder.build(); - - } catch (final IOException e) { - throw new RuntimeException(e); - } - besu.setPrivacyParameters(privacyParameters); - besu.start(runner); - } - - public void awaitPeerDiscovery(final Condition condition) { - besu.awaitPeerDiscovery(condition); - } - - public String getName() { - return besu.getName(); - } - - public Address getAddress() { - return besu.getAddress(); - } - - public URI enodeUrl() { - return besu.enodeUrl(); - } - - public String getNodeId() { - return besu.getNodeId(); - } - - public T execute(final Transaction transaction) { - return besu.execute(transaction); - } - - public void verify(final PrivateCondition expected) { - expected.verify(this); - } - - public String getEnclaveKey() { - return enclave.getDefaultPublicKey(); - } - - public String getTransactionSigningKey() { - return besu.getPrivacyParameters().getSigningKeyPair().orElseThrow().getPrivateKey().toString(); - } - - public void addOtherEnclaveNode(final URI otherNode) { - enclave.addOtherNode(otherNode); - } - - public NodeConfiguration getConfiguration() { - return besu.getConfiguration(); - } - - private PrivacyStorageProvider createKeyValueStorageProvider( - final Path dataLocation, final Path dbLocation) { - final var besuConfiguration = new BesuConfigurationImpl(); - besuConfiguration - .init(dataLocation, dbLocation, besuConfig.getDataStorageConfiguration()) - .withMiningParameters(besuConfig.getMiningParameters()); - return new PrivacyKeyValueStorageProviderBuilder() - .withStorageFactory( - new RocksDBKeyValuePrivacyStorageFactory( - new RocksDBKeyValueStorageFactory( - () -> - new RocksDBFactoryConfiguration( - DEFAULT_MAX_OPEN_FILES, - DEFAULT_BACKGROUND_THREAD_COUNT, - DEFAULT_CACHE_CAPACITY, - DEFAULT_IS_HIGH_SPEC), - Arrays.asList(KeyValueSegmentIdentifier.values()), - RocksDBMetricsFactory.PRIVATE_ROCKS_DB_METRICS))) - .withCommonConfiguration(besuConfiguration) - .withMetricsSystem(new NoOpMetricsSystem()) - .build(); - } - - private EnclaveTestHarness selectEnclave( - final EnclaveType enclaveType, - final Path tempDir, - final BesuNodeConfiguration config, - final PrivacyNodeConfiguration privacyConfiguration, - final Optional containerNetwork) { - - switch (enclaveType) { - case ORION: - throw new UnsupportedOperationException("The Orion tests are getting deprecated"); - case TESSERA: - return TesseraTestHarnessFactory.create( - config.getName(), tempDir, privacyConfiguration.getKeyConfig(), containerNetwork); - default: - return new NoopEnclaveTestHarness(tempDir, privacyConfiguration.getKeyConfig()); - } - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/PrivateTransactionGroupResponse.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/PrivateTransactionGroupResponse.java deleted file mode 100644 index 3cd7ca49a4..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/PrivateTransactionGroupResponse.java +++ /dev/null @@ -1,117 +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.tests.acceptance.dsl.privacy; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; - -public class PrivateTransactionGroupResponse { - private final String from; - private final String gas; - private final String gasPrice; - private final String input; - private final String nonce; - private final String to; - private final String value; - private final String v; - private final String r; - private final String s; - private final String privateFrom; - private final String restriction; - private final String privacyGroupId; - - @JsonCreator - public PrivateTransactionGroupResponse( - @JsonProperty("from") final String from, - @JsonProperty("gas") final String gas, - @JsonProperty("gasPrice") final String gasPrice, - @JsonProperty("hash") final String hash, - @JsonProperty("input") final String input, - @JsonProperty("nonce") final String nonce, - @JsonProperty("to") final String to, - @JsonProperty("value") final String value, - @JsonProperty("v") final String v, - @JsonProperty("r") final String r, - @JsonProperty("s") final String s, - @JsonProperty("privateFrom") final String privateFrom, - @JsonProperty("restriction") final String restriction, - @JsonProperty("privacyGroupId") final String privacyGroupId) { - this.from = from; - this.gas = gas; - this.gasPrice = gasPrice; - this.input = input; - this.nonce = nonce; - this.to = to; - this.value = value; - this.v = v; - this.r = r; - this.s = s; - this.privateFrom = privateFrom; - this.restriction = restriction; - this.privacyGroupId = privacyGroupId; - } - - public String getFrom() { - return from; - } - - public String getGas() { - return gas; - } - - public String getGasPrice() { - return gasPrice; - } - - public String getInput() { - return input; - } - - public String getNonce() { - return nonce; - } - - public String getTo() { - return to; - } - - public String getValue() { - return value; - } - - public String getV() { - return v; - } - - public String getR() { - return r; - } - - public String getS() { - return s; - } - - public String getPrivateFrom() { - return privateFrom; - } - - public String getRestriction() { - return restriction; - } - - public String getPrivacyGroupId() { - return privacyGroupId; - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/account/PrivacyAccount.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/account/PrivacyAccount.java deleted file mode 100644 index c246dd585a..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/account/PrivacyAccount.java +++ /dev/null @@ -1,85 +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.tests.acceptance.dsl.privacy.account; - -import org.hyperledger.enclave.testutil.EnclaveEncryptorType; - -import java.io.File; -import java.net.URL; -import java.util.Arrays; - -public class PrivacyAccount { - - private final URL privateKeyPath; - private final URL[] enclaveKeyPaths; - private final URL[] enclavePrivateKeyPaths; - private final EnclaveEncryptorType enclaveEncryptorType; - - private PrivacyAccount( - final URL privateKeyPath, - final URL[] enclavePublicKeyPaths, - final URL[] enclavePrivateKeyPaths, - final EnclaveEncryptorType enclaveEncryptorType) { - this.privateKeyPath = privateKeyPath; - this.enclaveKeyPaths = enclavePublicKeyPaths; - this.enclavePrivateKeyPaths = enclavePrivateKeyPaths; - this.enclaveEncryptorType = enclaveEncryptorType; - } - - public static PrivacyAccount create( - final URL privateKeyPath, - final URL enclavePublicKeyPath, - final URL enclavePrivateKeyPath, - final EnclaveEncryptorType enclaveEncryptorType) { - return new PrivacyAccount( - privateKeyPath, - new URL[] {enclavePublicKeyPath}, - new URL[] {enclavePrivateKeyPath}, - enclaveEncryptorType); - } - - public static PrivacyAccount create( - final URL privateKeyPath, - final URL[] enclavePublicKeyPath, - final URL[] enclavePrivateKeyPath, - final EnclaveEncryptorType enclaveEncryptorType) { - return new PrivacyAccount( - privateKeyPath, enclavePublicKeyPath, enclavePrivateKeyPath, enclaveEncryptorType); - } - - public String getPrivateKeyPath() { - return toStringResource(privateKeyPath); - } - - public String[] getEnclaveKeyPaths() { - return Arrays.stream(enclaveKeyPaths) - .map(path -> toStringResource(path)) - .toArray(String[]::new); - } - - public String[] getEnclavePrivateKeyPaths() { - return Arrays.stream(enclavePrivateKeyPaths) - .map(path -> toStringResource(path)) - .toArray(String[]::new); - } - - public EnclaveEncryptorType getEnclaveEncryptorType() { - return enclaveEncryptorType; - } - - private String toStringResource(final URL path) { - return path.getPath().substring(path.getPath().lastIndexOf(File.separator) + 1); - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/account/PrivacyAccountResolver.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/account/PrivacyAccountResolver.java deleted file mode 100644 index 7a6e26f7bc..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/account/PrivacyAccountResolver.java +++ /dev/null @@ -1,101 +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.tests.acceptance.dsl.privacy.account; - -import org.hyperledger.enclave.testutil.EnclaveEncryptorType; - -import java.net.URL; - -/** Supplier of known funded accounts defined in dev.json */ -public enum PrivacyAccountResolver { - ALICE { - @Override - public PrivacyAccount resolve(final EnclaveEncryptorType enclaveEncryptorType) { - return PrivacyAccount.create( - resolveResource("key"), - enclaveEncryptorType.equals(EnclaveEncryptorType.EC) - ? resolveResource("enclave_ec_key_0.pub") - : resolveResource("enclave_key_0.pub"), - enclaveEncryptorType.equals(EnclaveEncryptorType.EC) - ? resolveResource("enclave_ec_key_0.key") - : resolveResource("enclave_key_0.key"), - enclaveEncryptorType); - } - }, - BOB { - @Override - public PrivacyAccount resolve(final EnclaveEncryptorType enclaveEncryptorType) { - return PrivacyAccount.create( - resolveResource("key1"), - enclaveEncryptorType.equals(EnclaveEncryptorType.EC) - ? resolveResource("enclave_ec_key_1.pub") - : resolveResource("enclave_key_1.pub"), - enclaveEncryptorType.equals(EnclaveEncryptorType.EC) - ? resolveResource("enclave_ec_key_1.key") - : resolveResource("enclave_key_1.key"), - enclaveEncryptorType); - } - }, - CHARLIE { - @Override - public PrivacyAccount resolve(final EnclaveEncryptorType enclaveEncryptorType) { - return PrivacyAccount.create( - resolveResource("key2"), - enclaveEncryptorType.equals(EnclaveEncryptorType.EC) - ? resolveResource("enclave_ec_key_2.pub") - : resolveResource("enclave_key_2.pub"), - enclaveEncryptorType.equals(EnclaveEncryptorType.EC) - ? resolveResource("enclave_ec_key_2.key") - : resolveResource("enclave_key_2.key"), - enclaveEncryptorType); - } - }, - MULTI_TENANCY { - @Override - public PrivacyAccount resolve(final EnclaveEncryptorType enclaveEncryptorType) { - return PrivacyAccount.create( - resolveResource("key"), - new URL[] { - enclaveEncryptorType.equals(EnclaveEncryptorType.EC) - ? resolveResource("enclave_ec_key_0.pub") - : resolveResource("enclave_key_0.pub"), - enclaveEncryptorType.equals(EnclaveEncryptorType.EC) - ? resolveResource("enclave_ec_key_1.pub") - : resolveResource("enclave_key_1.pub"), - enclaveEncryptorType.equals(EnclaveEncryptorType.EC) - ? resolveResource("enclave_ec_key_2.pub") - : resolveResource("enclave_key_2.pub") - }, - new URL[] { - enclaveEncryptorType.equals(EnclaveEncryptorType.EC) - ? resolveResource("enclave_ec_key_0.key") - : resolveResource("enclave_key_0.key"), - enclaveEncryptorType.equals(EnclaveEncryptorType.EC) - ? resolveResource("enclave_ec_key_1.key") - : resolveResource("enclave_key_1.key"), - enclaveEncryptorType.equals(EnclaveEncryptorType.EC) - ? resolveResource("enclave_ec_key_2.key") - : resolveResource("enclave_key_2.key") - }, - enclaveEncryptorType); - } - }; - - public abstract PrivacyAccount resolve(final EnclaveEncryptorType enclaveEncryptorType); - - URL resolveResource(final String resource) { - return PrivacyAccountResolver.class.getClassLoader().getResource(resource); - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/ExpectExistingPrivateTransactionReceipt.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/ExpectExistingPrivateTransactionReceipt.java deleted file mode 100644 index 7d1c97c13d..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/ExpectExistingPrivateTransactionReceipt.java +++ /dev/null @@ -1,41 +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.tests.acceptance.dsl.privacy.condition; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.transaction.PrivacyTransactions; - -import org.web3j.protocol.besu.response.privacy.PrivateTransactionReceipt; - -public class ExpectExistingPrivateTransactionReceipt implements PrivateCondition { - private final PrivacyTransactions transactions; - private final String transactionHash; - - public ExpectExistingPrivateTransactionReceipt( - final PrivacyTransactions transactions, final String transactionHash) { - - this.transactions = transactions; - this.transactionHash = transactionHash; - } - - @Override - public void verify(final PrivacyNode node) { - final PrivateTransactionReceipt privateTransactionReceipt = - node.execute(transactions.getPrivateTransactionReceipt(transactionHash)); - assertThat(privateTransactionReceipt).isNotNull(); - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/ExpectInternalErrorPrivateTransactionReceipt.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/ExpectInternalErrorPrivateTransactionReceipt.java deleted file mode 100644 index 450be72d42..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/ExpectInternalErrorPrivateTransactionReceipt.java +++ /dev/null @@ -1,40 +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.tests.acceptance.dsl.privacy.condition; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.transaction.PrivacyTransactions; - -public class ExpectInternalErrorPrivateTransactionReceipt implements PrivateCondition { - private final PrivacyTransactions transactions; - private final String transactionHash; - - public ExpectInternalErrorPrivateTransactionReceipt( - final PrivacyTransactions transactions, final String transactionHash) { - this.transactions = transactions; - this.transactionHash = transactionHash; - } - - @Override - public void verify(final PrivacyNode node) { - try { - node.execute(transactions.getPrivateTransactionReceipt(transactionHash)); - } catch (final RuntimeException e) { - assertThat(e.getMessage()).contains("Internal error"); - } - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/ExpectNoPrivateTransactionReceipt.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/ExpectNoPrivateTransactionReceipt.java deleted file mode 100644 index d14d0dde73..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/ExpectNoPrivateTransactionReceipt.java +++ /dev/null @@ -1,41 +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.tests.acceptance.dsl.privacy.condition; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.catchThrowable; - -import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.transaction.PrivacyTransactions; - -public class ExpectNoPrivateTransactionReceipt implements PrivateCondition { - private final PrivacyTransactions transactions; - private final String transactionHash; - - public ExpectNoPrivateTransactionReceipt( - final PrivacyTransactions transactions, final String transactionHash) { - this.transactions = transactions; - this.transactionHash = transactionHash; - } - - @Override - public void verify(final PrivacyNode node) { - final Throwable t = - catchThrowable( - () -> node.execute(transactions.getPrivateTransactionReceipt(transactionHash))); - - assertThat(t).hasMessageContaining("TransactionException"); - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/ExpectValidContractCode.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/ExpectValidContractCode.java deleted file mode 100644 index 574ace120d..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/ExpectValidContractCode.java +++ /dev/null @@ -1,29 +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.tests.acceptance.dsl.privacy.condition; - -import static org.assertj.core.api.Assertions.assertThat; - -import java.io.IOException; - -import org.web3j.tx.Contract; - -public class ExpectValidContractCode implements PrivateContractCondition { - @Override - public void verify(final Contract contract) throws IOException { - assertThat(contract).isNotNull(); - assertThat(contract.isValid()).isEqualTo(true); - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/ExpectValidFlexiblePrivacyGroupCreated.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/ExpectValidFlexiblePrivacyGroupCreated.java deleted file mode 100644 index ce9c93d23d..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/ExpectValidFlexiblePrivacyGroupCreated.java +++ /dev/null @@ -1,53 +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.tests.acceptance.dsl.privacy.condition; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.transaction.PrivacyTransactions; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.privacy.PrivacyRequestFactory; - -import java.util.List; -import java.util.concurrent.TimeUnit; - -import org.awaitility.Awaitility; -import org.web3j.utils.Base64String; - -public class ExpectValidFlexiblePrivacyGroupCreated implements PrivateCondition { - - private final PrivacyTransactions transactions; - private final PrivacyRequestFactory.FlexiblePrivacyGroup expected; - - public ExpectValidFlexiblePrivacyGroupCreated( - final PrivacyTransactions transactions, - final PrivacyRequestFactory.FlexiblePrivacyGroup expected) { - this.transactions = transactions; - this.expected = expected; - } - - @Override - public void verify(final PrivacyNode node) { - Awaitility.waitAtMost(20, TimeUnit.SECONDS) - .untilAsserted( - () -> { - final List groups = - node.execute( - transactions.findFlexiblePrivacyGroup( - Base64String.unwrapList(expected.getMembers()))); - assertThat(groups).contains(expected); - }); - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/ExpectValidPrivacyGroupCreated.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/ExpectValidPrivacyGroupCreated.java deleted file mode 100644 index 813050cc58..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/ExpectValidPrivacyGroupCreated.java +++ /dev/null @@ -1,51 +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.tests.acceptance.dsl.privacy.condition; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.transaction.PrivacyTransactions; - -import java.util.List; - -import org.awaitility.Awaitility; -import org.web3j.protocol.besu.response.privacy.PrivacyGroup; -import org.web3j.utils.Base64String; - -public class ExpectValidPrivacyGroupCreated implements PrivateCondition { - - private final PrivacyTransactions transactions; - private final PrivacyGroup expected; - - public ExpectValidPrivacyGroupCreated( - final PrivacyTransactions transactions, final PrivacyGroup expected) { - this.transactions = transactions; - this.expected = expected; - } - - @Override - public void verify(final PrivacyNode node) { - Awaitility.await() - .untilAsserted( - () -> { - final List groups = - node.execute( - transactions.findPrivacyGroup( - Base64String.unwrapList(expected.getMembers()))); - assertThat(groups).contains(expected); - }); - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/ExpectValidPrivateContractDeployedReceipt.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/ExpectValidPrivateContractDeployedReceipt.java deleted file mode 100644 index 687d6360c2..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/ExpectValidPrivateContractDeployedReceipt.java +++ /dev/null @@ -1,57 +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.tests.acceptance.dsl.privacy.condition; - -import static org.assertj.core.api.Assertions.assertThat; - -import java.util.Optional; - -import org.web3j.protocol.core.methods.response.TransactionReceipt; -import org.web3j.tx.Contract; - -public class ExpectValidPrivateContractDeployedReceipt implements PrivateContractCondition { - - private final String contractAddress; - private final String senderAddress; - - public ExpectValidPrivateContractDeployedReceipt( - final String contractAddress, final String senderAddress) { - this.contractAddress = contractAddress; - this.senderAddress = senderAddress; - } - - @Override - public void verify(final Contract contract) { - - assertThat(contract).isNotNull(); - final Optional receipt = contract.getTransactionReceipt(); - - // We're expecting a receipt - assertThat(receipt).isNotNull(); - assertThat(receipt.isPresent()).isTrue(); - final TransactionReceipt transactionReceipt = receipt.get(); - - assertThat(transactionReceipt.isStatusOK()).isTrue(); - - // Contract transaction has no 'to' address or contract address - assertThat(transactionReceipt.getTo()).isNull(); - - // Address generation is deterministic, based on the sender address and the transaction nonce - assertThat(transactionReceipt.getContractAddress()).isEqualTo(contractAddress); - - // Address for the account that signed (and paid) for the contract deployment transaction - assertThat(transactionReceipt.getFrom()).isEqualTo(senderAddress); - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/ExpectValidPrivateTransactionReceipt.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/ExpectValidPrivateTransactionReceipt.java deleted file mode 100644 index ff8e0c2c5f..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/ExpectValidPrivateTransactionReceipt.java +++ /dev/null @@ -1,91 +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.tests.acceptance.dsl.privacy.condition; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.transaction.PrivacyTransactions; - -import org.web3j.protocol.besu.response.privacy.PrivateTransactionReceipt; - -public class ExpectValidPrivateTransactionReceipt implements PrivateCondition { - private final PrivacyTransactions transactions; - private final String transactionHash; - private final PrivateTransactionReceipt expectedReceipt; - private final boolean ignoreOutput; - - public ExpectValidPrivateTransactionReceipt( - final PrivacyTransactions transactions, - final String transactionHash, - final PrivateTransactionReceipt expectedReceipt) { - this(transactions, transactionHash, expectedReceipt, false); - } - - public ExpectValidPrivateTransactionReceipt( - final PrivacyTransactions transactions, - final String transactionHash, - final PrivateTransactionReceipt expectedReceipt, - final boolean ignoreOutput) { - - this.transactions = transactions; - this.transactionHash = transactionHash; - this.expectedReceipt = expectedReceipt; - this.ignoreOutput = ignoreOutput; - } - - @Override - public void verify(final PrivacyNode node) { - final PrivateTransactionReceipt actualReceipt = - node.execute(transactions.getPrivateTransactionReceipt(transactionHash)); - if (ignoreOutput) { - // output can be ignored if it is checked separately - assertThat(actualReceipt) - .usingRecursiveComparison() - .ignoringFields( - "commitmentHash", - "logs", - "blockHash", - "blockNumber", - "logsBloom", - "transactionIndex", - "output") - // TODO: The fields blockHash, blockNumber, logsBloom, transactionIndex and output have to - // be ignored as - // the class org.web3j.protocol.besu.response.privacy.PrivateTransactionReceipt does not - // contain - // these fields. Once web3j has been updated these ignores can be removed. - .isEqualTo(expectedReceipt); - } else { - assertThat(actualReceipt) - .usingRecursiveComparison() - .ignoringFields( - "commitmentHash", "logs", "blockHash", "blockNumber", "logsBloom", "transactionIndex") - // TODO: The fields blockHash, blockNumber, logsBloom and transactionIndex have to be - // ignored as the class - // org.web3j.protocol.besu.response.privacy.PrivateTransactionReceipt does not contain - // these fields. Once web3j has been updated these ignores can be removed. - .isEqualTo(expectedReceipt); - } - assertThat(actualReceipt.getLogs().size()).isEqualTo(expectedReceipt.getLogs().size()); - - for (int i = 0; i < expectedReceipt.getLogs().size(); i++) { - assertThat(actualReceipt.getLogs().get(i)) - .usingRecursiveComparison() - .ignoringFields("blockHash", "blockNumber") - .isEqualTo(expectedReceipt.getLogs().get(i)); - } - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/PrivGetTransactionReceiptTransaction.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/PrivGetTransactionReceiptTransaction.java deleted file mode 100644 index b5922b25b0..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/PrivGetTransactionReceiptTransaction.java +++ /dev/null @@ -1,52 +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.tests.acceptance.dsl.privacy.condition; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -import java.io.IOException; - -import org.web3j.protocol.besu.Besu; -import org.web3j.protocol.besu.response.privacy.PrivateTransactionReceipt; -import org.web3j.protocol.exceptions.TransactionException; -import org.web3j.tx.response.PollingPrivateTransactionReceiptProcessor; - -public class PrivGetTransactionReceiptTransaction - implements Transaction { - - private final String transactionHash; - - public PrivGetTransactionReceiptTransaction(final String transactionHash) { - this.transactionHash = transactionHash; - } - - @Override - public PrivateTransactionReceipt execute(final NodeRequests node) { - final Besu besu = node.privacy().getBesuClient(); - final PollingPrivateTransactionReceiptProcessor receiptProcessor = - new PollingPrivateTransactionReceiptProcessor(besu, 1000, 15); - try { - final PrivateTransactionReceipt result = - receiptProcessor.waitForTransactionReceipt(transactionHash); - assertThat(result).isNotNull(); - return result; - } catch (final IOException | TransactionException e) { - throw new RuntimeException(e); - } - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/PrivateCondition.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/PrivateCondition.java deleted file mode 100644 index 873f015a49..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/PrivateCondition.java +++ /dev/null @@ -1,21 +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.tests.acceptance.dsl.privacy.condition; - -import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode; - -public interface PrivateCondition { - void verify(PrivacyNode node); -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/PrivateContractCondition.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/PrivateContractCondition.java deleted file mode 100644 index 7969e2d357..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/PrivateContractCondition.java +++ /dev/null @@ -1,23 +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.tests.acceptance.dsl.privacy.condition; - -import java.io.IOException; - -import org.web3j.tx.Contract; - -public interface PrivateContractCondition { - void verify(final Contract contract) throws IOException; -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/PrivateContractVerifier.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/PrivateContractVerifier.java deleted file mode 100644 index de9f36d08d..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/PrivateContractVerifier.java +++ /dev/null @@ -1,29 +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.tests.acceptance.dsl.privacy.condition; - -public class PrivateContractVerifier { - - public PrivateContractVerifier() {} - - public ExpectValidPrivateContractDeployedReceipt validPrivateContractDeployed( - final String contractAddress, final String senderAddress) { - return new ExpectValidPrivateContractDeployedReceipt(contractAddress, senderAddress); - } - - public ExpectValidContractCode validContractCodeProvided() { - return new ExpectValidContractCode(); - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/PrivateTransactionVerifier.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/PrivateTransactionVerifier.java deleted file mode 100644 index cfd83b6582..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/PrivateTransactionVerifier.java +++ /dev/null @@ -1,88 +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.tests.acceptance.dsl.privacy.condition; - -import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.transaction.PrivacyTransactions; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.privacy.PrivacyRequestFactory.FlexiblePrivacyGroup; - -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; - -import org.web3j.protocol.besu.response.privacy.PrivacyGroup; -import org.web3j.protocol.besu.response.privacy.PrivateTransactionReceipt; -import org.web3j.utils.Base64String; - -public class PrivateTransactionVerifier { - - private final PrivacyTransactions transactions; - - public PrivateTransactionVerifier(final PrivacyTransactions transactions) { - this.transactions = transactions; - } - - public ExpectValidPrivateTransactionReceipt validPrivateTransactionReceipt( - final String transactionHash, final PrivateTransactionReceipt receipt) { - return new ExpectValidPrivateTransactionReceipt(transactions, transactionHash, receipt); - } - - public ExpectValidPrivateTransactionReceipt validPrivateTransactionReceipt( - final String transactionHash, - final PrivateTransactionReceipt receipt, - final boolean ignoreOutput) { - return new ExpectValidPrivateTransactionReceipt( - transactions, transactionHash, receipt, ignoreOutput); - } - - public ExpectExistingPrivateTransactionReceipt existingPrivateTransactionReceipt( - final String transactionHash) { - return new ExpectExistingPrivateTransactionReceipt(transactions, transactionHash); - } - - public ExpectNoPrivateTransactionReceipt noPrivateTransactionReceipt( - final String transactionHash) { - return new ExpectNoPrivateTransactionReceipt(transactions, transactionHash); - } - - public ExpectValidPrivacyGroupCreated validPrivacyGroupCreated(final PrivacyGroup expected) { - return new ExpectValidPrivacyGroupCreated(transactions, expected); - } - - public ExpectValidFlexiblePrivacyGroupCreated flexiblePrivacyGroupExists( - final String privacyGroupId, final PrivacyNode... members) { - - final List membersEnclaveKeys = - Arrays.stream(members) - .map(PrivacyNode::getEnclaveKey) - .map(Base64String::wrap) - .collect(Collectors.toList()); - return flexiblePrivacyGroupExists(privacyGroupId, membersEnclaveKeys); - } - - public ExpectValidFlexiblePrivacyGroupCreated flexiblePrivacyGroupExists( - final String privacyGroupId, final List membersEnclaveKeys) { - - final FlexiblePrivacyGroup expectedGroup = - new FlexiblePrivacyGroup(privacyGroupId, membersEnclaveKeys); - - return new ExpectValidFlexiblePrivacyGroupCreated(transactions, expectedGroup); - } - - public ExpectInternalErrorPrivateTransactionReceipt internalErrorPrivateTransactionReceipt( - final String transactionHash) { - return new ExpectInternalErrorPrivateTransactionReceipt(transactions, transactionHash); - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/contract/CallOnchainPermissioningPrivateSmartContractFunction.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/contract/CallOnchainPermissioningPrivateSmartContractFunction.java deleted file mode 100644 index 0820d65d1d..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/contract/CallOnchainPermissioningPrivateSmartContractFunction.java +++ /dev/null @@ -1,73 +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.tests.acceptance.dsl.privacy.contract; - -import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -import java.io.IOException; -import java.math.BigInteger; - -import org.web3j.crypto.Credentials; -import org.web3j.tx.PrivateTransactionManager; -import org.web3j.tx.gas.BesuPrivacyGasProvider; -import org.web3j.utils.Base64String; -import org.web3j.utils.Restriction; - -public class CallOnchainPermissioningPrivateSmartContractFunction implements Transaction { - - private static final BesuPrivacyGasProvider GAS_PROVIDER = - new BesuPrivacyGasProvider(BigInteger.valueOf(1000)); - private final String contractAddress; - private final String encodedFunction; - private final Credentials senderCredentials; - private final Base64String privateFrom; - private final Base64String privacyGroupId; - - public CallOnchainPermissioningPrivateSmartContractFunction( - final String contractAddress, - final String encodedFunction, - final String transactionSigningKey, - final String privateFrom, - final String privacyGroupId) { - - this.contractAddress = contractAddress; - this.encodedFunction = encodedFunction; - this.senderCredentials = Credentials.create(transactionSigningKey); - this.privateFrom = Base64String.wrap(privateFrom); - this.privacyGroupId = Base64String.wrap(privacyGroupId); - } - - @Override - public String execute(final NodeRequests node) { - final PrivateTransactionManager privateTransactionManager = - node.privacy() - .getTransactionManager( - senderCredentials, privateFrom, privacyGroupId, Restriction.RESTRICTED); - - try { - return privateTransactionManager - .sendTransaction( - GAS_PROVIDER.getGasPrice(), - GAS_PROVIDER.getGasLimit(), - contractAddress, - encodedFunction, - null) - .getTransactionHash(); - } catch (final IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/contract/CallPrivateSmartContractFunction.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/contract/CallPrivateSmartContractFunction.java deleted file mode 100644 index d3ec7989e5..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/contract/CallPrivateSmartContractFunction.java +++ /dev/null @@ -1,121 +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.tests.acceptance.dsl.privacy.contract; - -import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -import java.io.IOException; -import java.math.BigInteger; -import java.util.List; - -import org.web3j.crypto.Credentials; -import org.web3j.tx.PrivateTransactionManager; -import org.web3j.tx.gas.BesuPrivacyGasProvider; -import org.web3j.utils.Base64String; -import org.web3j.utils.Restriction; - -public class CallPrivateSmartContractFunction implements Transaction { - - private static final BesuPrivacyGasProvider GAS_PROVIDER = - new BesuPrivacyGasProvider(BigInteger.valueOf(1000)); - private final String contractAddress; - private final String encodedFunction; - private final Credentials senderCredentials; - private final Restriction restriction; - private final Base64String privateFrom; - private final List privateFor; - private final Base64String privacyGroupId; - - public CallPrivateSmartContractFunction( - final String contractAddress, - final String encodedFunction, - final String transactionSigningKey, - final Restriction restriction, - final String privateFrom, - final List privateFor) { - this( - contractAddress, - encodedFunction, - transactionSigningKey, - restriction, - privateFrom, - privateFor, - null); - } - - public CallPrivateSmartContractFunction( - final String contractAddress, - final String encodedFunction, - final String transactionSigningKey, - final Restriction restriction, - final String privateFrom, - final String privacyGroupId) { - this( - contractAddress, - encodedFunction, - transactionSigningKey, - restriction, - privateFrom, - null, - privacyGroupId); - } - - private CallPrivateSmartContractFunction( - final String contractAddress, - final String encodedFunction, - final String transactionSigningKey, - final Restriction restriction, - final String privateFrom, - final List privateFor, - final String privacyGroupId) { - - this.contractAddress = contractAddress; - this.encodedFunction = encodedFunction; - this.senderCredentials = Credentials.create(transactionSigningKey); - this.restriction = restriction; - this.privateFrom = Base64String.wrap(privateFrom); - this.privateFor = privateFor != null ? Base64String.wrapList(privateFor) : null; - this.privacyGroupId = privacyGroupId != null ? Base64String.wrap(privacyGroupId) : null; - } - - @Override - public String execute(final NodeRequests node) { - final PrivateTransactionManager privateTransactionManager; - - if (privateFor != null) { - privateTransactionManager = - node.privacy() - .getTransactionManager(senderCredentials, privateFrom, privateFor, restriction); - } else { - privateTransactionManager = - node.privacy() - .getTransactionManager(senderCredentials, privateFrom, privacyGroupId, restriction); - } - - try { - return privateTransactionManager - .sendTransaction( - GAS_PROVIDER.getGasPrice(), - GAS_PROVIDER.getGasLimit(), - contractAddress, - encodedFunction, - null) - .getTransactionHash(); - } catch (final IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/contract/DeployPrivateSmartContractTransaction.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/contract/DeployPrivateSmartContractTransaction.java deleted file mode 100644 index ed7ca9cd9a..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/contract/DeployPrivateSmartContractTransaction.java +++ /dev/null @@ -1,87 +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.tests.acceptance.dsl.privacy.contract; - -import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -import java.lang.reflect.Method; -import java.math.BigInteger; -import java.util.List; - -import org.web3j.crypto.Credentials; -import org.web3j.protocol.Web3j; -import org.web3j.protocol.core.RemoteCall; -import org.web3j.tx.Contract; -import org.web3j.tx.PrivateTransactionManager; -import org.web3j.tx.TransactionManager; -import org.web3j.tx.gas.BesuPrivacyGasProvider; -import org.web3j.tx.gas.ContractGasProvider; -import org.web3j.utils.Base64String; -import org.web3j.utils.Restriction; - -public class DeployPrivateSmartContractTransaction implements Transaction { - - private static final BesuPrivacyGasProvider GAS_PROVIDER = - new BesuPrivacyGasProvider(BigInteger.valueOf(1000)); - private static final Object METHOD_IS_STATIC = null; - - private final Class clazz; - private final Credentials senderCredentials; - private final Base64String privateFrom; - private final List privateFor; - - public DeployPrivateSmartContractTransaction( - final Class clazz, - final String transactionSigningKey, - final String privateFrom, - final List privateFor) { - this.clazz = clazz; - this.senderCredentials = Credentials.create(transactionSigningKey); - this.privateFrom = Base64String.wrap(privateFrom); - this.privateFor = Base64String.wrapList(privateFor); - } - - @Override - public T execute(final NodeRequests node) { - - final PrivateTransactionManager privateTransactionManager = - node.privacy() - .getTransactionManager( - senderCredentials, privateFrom, privateFor, Restriction.RESTRICTED); - - try { - final Method method = - clazz.getMethod( - "deploy", Web3j.class, TransactionManager.class, ContractGasProvider.class); - - final Object invoked = - method.invoke( - METHOD_IS_STATIC, - node.privacy().getBesuClient(), - privateTransactionManager, - GAS_PROVIDER); - - return cast(invoked).send(); - } catch (final Exception e) { - throw new RuntimeException(e); - } - } - - @SuppressWarnings("unchecked") - private RemoteCall cast(final Object invokedMethod) { - return (RemoteCall) invokedMethod; - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/contract/DeployPrivateSmartContractWithPrivacyGroupIdTransaction.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/contract/DeployPrivateSmartContractWithPrivacyGroupIdTransaction.java deleted file mode 100644 index c5d0116431..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/contract/DeployPrivateSmartContractWithPrivacyGroupIdTransaction.java +++ /dev/null @@ -1,89 +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.tests.acceptance.dsl.privacy.contract; - -import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -import java.lang.reflect.Method; -import java.math.BigInteger; - -import org.web3j.crypto.Credentials; -import org.web3j.protocol.Web3j; -import org.web3j.protocol.core.RemoteCall; -import org.web3j.tx.Contract; -import org.web3j.tx.PrivateTransactionManager; -import org.web3j.tx.TransactionManager; -import org.web3j.tx.gas.BesuPrivacyGasProvider; -import org.web3j.tx.gas.ContractGasProvider; -import org.web3j.utils.Base64String; -import org.web3j.utils.Restriction; - -public class DeployPrivateSmartContractWithPrivacyGroupIdTransaction - implements Transaction { - - private static final BesuPrivacyGasProvider GAS_PROVIDER = - new BesuPrivacyGasProvider(BigInteger.valueOf(1000)); - private static final Object METHOD_IS_STATIC = null; - - private final Class clazz; - private final Credentials senderCredentials; - private final Restriction restriction; - private final Base64String privateFrom; - private final Base64String privacyGroupId; - - public DeployPrivateSmartContractWithPrivacyGroupIdTransaction( - final Class clazz, - final String transactionSigningKey, - final Restriction restriction, - final String privateFrom, - final String privacyGroupId) { - this.clazz = clazz; - this.senderCredentials = Credentials.create(transactionSigningKey); - this.restriction = restriction; - this.privateFrom = Base64String.wrap(privateFrom); - this.privacyGroupId = Base64String.wrap(privacyGroupId); - } - - @Override - public T execute(final NodeRequests node) { - - final PrivateTransactionManager privateTransactionManager = - node.privacy() - .getTransactionManager(senderCredentials, privateFrom, privacyGroupId, restriction); - - try { - final Method method = - clazz.getMethod( - "deploy", Web3j.class, TransactionManager.class, ContractGasProvider.class); - - final Object invoked = - method.invoke( - METHOD_IS_STATIC, - node.privacy().getBesuClient(), - privateTransactionManager, - GAS_PROVIDER); - - return cast(invoked).send(); - } catch (final Exception e) { - throw new RuntimeException(e); - } - } - - @SuppressWarnings("unchecked") - private RemoteCall cast(final Object invokedMethod) { - return (RemoteCall) invokedMethod; - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/contract/LoadPrivateSmartContractTransaction.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/contract/LoadPrivateSmartContractTransaction.java deleted file mode 100644 index aac5f293f9..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/contract/LoadPrivateSmartContractTransaction.java +++ /dev/null @@ -1,87 +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.tests.acceptance.dsl.privacy.contract; - -import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -import java.lang.reflect.Method; -import java.math.BigInteger; -import java.util.List; - -import org.web3j.crypto.Credentials; -import org.web3j.protocol.Web3j; -import org.web3j.tx.Contract; -import org.web3j.tx.PrivateTransactionManager; -import org.web3j.tx.TransactionManager; -import org.web3j.tx.gas.BesuPrivacyGasProvider; -import org.web3j.tx.gas.ContractGasProvider; -import org.web3j.utils.Base64String; -import org.web3j.utils.Restriction; - -public class LoadPrivateSmartContractTransaction implements Transaction { - private static final BesuPrivacyGasProvider GAS_PROVIDER = - new BesuPrivacyGasProvider(BigInteger.valueOf(1000)); - private static final Object METHOD_IS_STATIC = null; - - private final Class clazz; - private final Credentials senderCredentials; - private final Base64String privateFrom; - private final List privateFor; - private final String contractAddress; - - public LoadPrivateSmartContractTransaction( - final String contractAddress, - final Class clazz, - final String transactionSigningKey, - final String privateFrom, - final List privateFor) { - - this.contractAddress = contractAddress; - this.clazz = clazz; - this.senderCredentials = Credentials.create(transactionSigningKey); - this.privateFrom = Base64String.wrap(privateFrom); - this.privateFor = Base64String.wrapList(privateFor); - } - - @SuppressWarnings("unchecked") - @Override - public T execute(final NodeRequests node) { - final PrivateTransactionManager privateTransactionManager = - node.privacy() - .getTransactionManager( - senderCredentials, privateFrom, privateFor, Restriction.RESTRICTED); - - try { - final Method method = - clazz.getMethod( - "load", - String.class, - Web3j.class, - TransactionManager.class, - ContractGasProvider.class); - - return (T) - method.invoke( - METHOD_IS_STATIC, - contractAddress, - node.privacy().getBesuClient(), - privateTransactionManager, - GAS_PROVIDER); - } catch (final Exception e) { - throw new RuntimeException(e); - } - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/contract/LoadPrivateSmartContractTransactionWithPrivacyGroupId.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/contract/LoadPrivateSmartContractTransactionWithPrivacyGroupId.java deleted file mode 100644 index 11a5045752..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/contract/LoadPrivateSmartContractTransactionWithPrivacyGroupId.java +++ /dev/null @@ -1,88 +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.tests.acceptance.dsl.privacy.contract; - -import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -import java.lang.reflect.Method; -import java.math.BigInteger; - -import org.web3j.crypto.Credentials; -import org.web3j.protocol.Web3j; -import org.web3j.tx.Contract; -import org.web3j.tx.PrivateTransactionManager; -import org.web3j.tx.TransactionManager; -import org.web3j.tx.gas.BesuPrivacyGasProvider; -import org.web3j.tx.gas.ContractGasProvider; -import org.web3j.utils.Base64String; -import org.web3j.utils.Restriction; - -public class LoadPrivateSmartContractTransactionWithPrivacyGroupId - implements Transaction { - - private static final BesuPrivacyGasProvider GAS_PROVIDER = - new BesuPrivacyGasProvider(BigInteger.valueOf(1000)); - private static final Object METHOD_IS_STATIC = null; - - private final Class clazz; - private final Credentials senderCredentials; - private final Base64String privateFrom; - private final Base64String privacyGroupId; - private final String contractAddress; - - public LoadPrivateSmartContractTransactionWithPrivacyGroupId( - final String contractAddress, - final Class clazz, - final String transactionSigningKey, - final String privateFrom, - final String privacyGroupId) { - - this.contractAddress = contractAddress; - this.clazz = clazz; - this.senderCredentials = Credentials.create(transactionSigningKey); - this.privateFrom = Base64String.wrap(privateFrom); - this.privacyGroupId = Base64String.wrap(privacyGroupId); - } - - @SuppressWarnings("unchecked") - @Override - public T execute(final NodeRequests node) { - final PrivateTransactionManager privateTransactionManager = - node.privacy() - .getTransactionManager( - senderCredentials, privateFrom, privacyGroupId, Restriction.RESTRICTED); - - try { - final Method method = - clazz.getMethod( - "load", - String.class, - Web3j.class, - TransactionManager.class, - ContractGasProvider.class); - - return (T) - method.invoke( - METHOD_IS_STATIC, - contractAddress, - node.privacy().getBesuClient(), - privateTransactionManager, - GAS_PROVIDER); - } catch (final Exception e) { - throw new RuntimeException(e); - } - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/contract/PrivateContractTransactions.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/contract/PrivateContractTransactions.java deleted file mode 100644 index 97e7e65401..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/contract/PrivateContractTransactions.java +++ /dev/null @@ -1,154 +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.tests.acceptance.dsl.privacy.contract; - -import java.util.Arrays; -import java.util.List; - -import org.web3j.tx.Contract; -import org.web3j.utils.Restriction; - -public class PrivateContractTransactions { - - public - DeployPrivateSmartContractWithPrivacyGroupIdTransaction - createSmartContractWithPrivacyGroupId( - final Class clazz, - final String transactionSigningKey, - final Restriction restriction, - final String privateFrom, - final String privacyGroupId) { - return new DeployPrivateSmartContractWithPrivacyGroupIdTransaction<>( - clazz, transactionSigningKey, restriction, privateFrom, privacyGroupId); - } - - public - DeployPrivateSmartContractWithPrivacyGroupIdTransaction - createSmartContractWithPrivacyGroupId( - final Class clazz, - final String transactionSigningKey, - final String privateFrom, - final String privacyGroupId) { - return new DeployPrivateSmartContractWithPrivacyGroupIdTransaction<>( - clazz, transactionSigningKey, Restriction.RESTRICTED, privateFrom, privacyGroupId); - } - - public DeployPrivateSmartContractTransaction createSmartContract( - final Class clazz, - final String transactionSigningKey, - final String privateFrom, - final String... privateFor) { - return createSmartContract( - clazz, transactionSigningKey, privateFrom, Arrays.asList(privateFor)); - } - - public DeployPrivateSmartContractTransaction createSmartContract( - final Class clazz, - final String transactionSigningKey, - final String privateFrom, - final List privateFor) { - return new DeployPrivateSmartContractTransaction<>( - clazz, transactionSigningKey, privateFrom, privateFor); - } - - public CallPrivateSmartContractFunction callSmartContract( - final String contractAddress, - final String encodedFunction, - final String transactionSigningKey, - final Restriction restriction, - final String privateFrom, - final String... privateFor) { - return callSmartContract( - contractAddress, - encodedFunction, - transactionSigningKey, - restriction, - privateFrom, - Arrays.asList(privateFor)); - } - - public CallPrivateSmartContractFunction callSmartContract( - final String contractAddress, - final String encodedFunction, - final String transactionSigningKey, - final Restriction restriction, - final String privateFrom, - final List privateFor) { - return new CallPrivateSmartContractFunction( - contractAddress, - encodedFunction, - transactionSigningKey, - restriction, - privateFrom, - privateFor); - } - - public CallPrivateSmartContractFunction callSmartContractWithPrivacyGroupId( - final String contractAddress, - final String encodedFunction, - final String transactionSigningKey, - final Restriction restriction, - final String privateFrom, - final String privacyGroupId) { - return new CallPrivateSmartContractFunction( - contractAddress, - encodedFunction, - transactionSigningKey, - restriction, - privateFrom, - privacyGroupId); - } - - public LoadPrivateSmartContractTransaction loadSmartContract( - final String contractAddress, - final Class clazz, - final String transactionSigningKey, - final String privateFrom, - final String... privateFor) { - return loadSmartContract( - contractAddress, clazz, transactionSigningKey, privateFrom, Arrays.asList(privateFor)); - } - - public LoadPrivateSmartContractTransaction loadSmartContract( - final String contractAddress, - final Class clazz, - final String transactionSigningKey, - final String privateFrom, - final List privateFor) { - return new LoadPrivateSmartContractTransaction<>( - contractAddress, clazz, transactionSigningKey, privateFrom, privateFor); - } - - public - LoadPrivateSmartContractTransactionWithPrivacyGroupId loadSmartContractWithPrivacyGroupId( - final String contractAddress, - final Class clazz, - final String transactionSigningKey, - final String privateFrom, - final String privacyGroupId) { - return new LoadPrivateSmartContractTransactionWithPrivacyGroupId<>( - contractAddress, clazz, transactionSigningKey, privateFrom, privacyGroupId); - } - - public CallOnchainPermissioningPrivateSmartContractFunction callOnchainPermissioningSmartContract( - final String contractAddress, - final String encodedFunction, - final String transactionSigningKey, - final String privateFrom, - final String privacyGroupId) { - return new CallOnchainPermissioningPrivateSmartContractFunction( - contractAddress, encodedFunction, transactionSigningKey, privateFrom, privacyGroupId); - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/AddToFlexiblePrivacyGroupTransaction.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/AddToFlexiblePrivacyGroupTransaction.java deleted file mode 100644 index 9c879bc421..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/AddToFlexiblePrivacyGroupTransaction.java +++ /dev/null @@ -1,57 +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.tests.acceptance.dsl.privacy.transaction; - -import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -import java.io.IOException; -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; - -import org.web3j.crypto.Credentials; -import org.web3j.utils.Base64String; - -public class AddToFlexiblePrivacyGroupTransaction implements Transaction { - private final Base64String privacyGroupId; - private final PrivacyNode adder; - private final List addresses; - private final Credentials signer; - - public AddToFlexiblePrivacyGroupTransaction( - final String privacyGroupId, - final PrivacyNode adder, - final Credentials signer, - final PrivacyNode... nodes) { - this.privacyGroupId = Base64String.wrap(privacyGroupId); - this.adder = adder; - this.signer = signer; - this.addresses = - Arrays.stream(nodes) - .map(n -> n.getEnclave().getDefaultPublicKey()) - .collect(Collectors.toList()); - } - - @Override - public String execute(final NodeRequests node) { - try { - return node.privacy().privxAddToPrivacyGroup(privacyGroupId, adder, signer, addresses); - } catch (final IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/CreateFlexiblePrivacyGroupTransaction.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/CreateFlexiblePrivacyGroupTransaction.java deleted file mode 100644 index bf2814a4b1..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/CreateFlexiblePrivacyGroupTransaction.java +++ /dev/null @@ -1,46 +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.tests.acceptance.dsl.privacy.transaction; - -import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.privacy.PrivacyRequestFactory.PrivxCreatePrivacyGroupResponse; - -import java.io.IOException; -import java.util.List; - -public class CreateFlexiblePrivacyGroupTransaction - implements Transaction { - private final PrivacyNode creator; - private final List addresses; - private final String privateFrom; - - CreateFlexiblePrivacyGroupTransaction( - final PrivacyNode creator, final String privateFrom, final List addresses) { - this.creator = creator; - this.addresses = addresses; - this.privateFrom = privateFrom; - } - - @Override - public PrivxCreatePrivacyGroupResponse execute(final NodeRequests node) { - try { - return node.privacy().privxCreatePrivacyGroup(creator, privateFrom, addresses); - } catch (final IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/FindFlexiblePrivacyGroupTransaction.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/FindFlexiblePrivacyGroupTransaction.java deleted file mode 100644 index 0e8ac95b4f..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/FindFlexiblePrivacyGroupTransaction.java +++ /dev/null @@ -1,52 +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.tests.acceptance.dsl.privacy.transaction; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.privacy.PrivacyRequestFactory; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.privacy.PrivacyRequestFactory.PrivxFindPrivacyGroupResponse; - -import java.io.IOException; -import java.util.List; -import java.util.stream.Collectors; - -import org.web3j.utils.Base64String; - -public class FindFlexiblePrivacyGroupTransaction - implements Transaction> { - private final List nodes; - - public FindFlexiblePrivacyGroupTransaction(final List nodeEnclaveKeys) { - this.nodes = nodeEnclaveKeys.stream().map(Base64String::wrap).collect(Collectors.toList()); - } - - @Override - public List execute(final NodeRequests node) { - try { - PrivxFindPrivacyGroupResponse result = - node.privacy().privxFindFlexiblePrivacyGroup(nodes).send(); - assertThat(result).isNotNull(); - if (result.hasError()) { - throw new RuntimeException(result.getError().getMessage()); - } - return result.getGroups(); - } catch (final IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/FindPrivacyGroupTransaction.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/FindPrivacyGroupTransaction.java deleted file mode 100644 index 0b15b4c0c8..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/FindPrivacyGroupTransaction.java +++ /dev/null @@ -1,45 +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.tests.acceptance.dsl.privacy.transaction; - -import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -import java.io.IOException; -import java.util.List; -import java.util.stream.Collectors; - -import org.web3j.protocol.besu.Besu; -import org.web3j.protocol.besu.response.privacy.PrivacyGroup; -import org.web3j.utils.Base64String; - -public class FindPrivacyGroupTransaction implements Transaction> { - private final List nodes; - - public FindPrivacyGroupTransaction(final List nodeEnclaveKeys) { - - this.nodes = nodeEnclaveKeys.stream().map(Base64String::wrap).collect(Collectors.toList()); - } - - @Override - public List execute(final NodeRequests node) { - final Besu besu = node.privacy().getBesuClient(); - try { - return besu.privFindPrivacyGroup(nodes).send().getGroups(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/GetAllPrivateMarkerTransactionHashes.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/GetAllPrivateMarkerTransactionHashes.java deleted file mode 100644 index d0056f50b4..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/GetAllPrivateMarkerTransactionHashes.java +++ /dev/null @@ -1,56 +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.tests.acceptance.dsl.privacy.transaction; - -import static org.hyperledger.besu.ethereum.core.PrivacyParameters.DEFAULT_PRIVACY; - -import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -import java.io.IOException; -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.List; - -import org.web3j.protocol.besu.Besu; -import org.web3j.protocol.core.DefaultBlockParameter; -import org.web3j.protocol.core.methods.response.EthBlock; - -public class GetAllPrivateMarkerTransactionHashes implements Transaction> { - @Override - public List execute(final NodeRequests node) { - final Besu besu = node.privacy().getBesuClient(); - final List toReturn = new ArrayList<>(); - try { - final long blockchainHeight = besu.ethBlockNumber().send().getBlockNumber().longValueExact(); - for (long i = 0; i <= blockchainHeight; i++) { - besu.ethGetBlockByNumber(DefaultBlockParameter.valueOf(BigInteger.valueOf(i)), true) - .send() - .getBlock() - .getTransactions() - .forEach( - t -> { - if (((EthBlock.TransactionObject) t).getTo().equals(DEFAULT_PRIVACY.toString())) { - toReturn.add(((EthBlock.TransactionObject) t).getHash()); - } - }); - } - } catch (IOException e) { - throw new RuntimeException(e); - } - - return toReturn; - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/LockFlexiblePrivacyGroupTransaction.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/LockFlexiblePrivacyGroupTransaction.java deleted file mode 100644 index 92ed003ad4..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/LockFlexiblePrivacyGroupTransaction.java +++ /dev/null @@ -1,47 +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.tests.acceptance.dsl.privacy.transaction; - -import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -import java.io.IOException; - -import org.web3j.crypto.Credentials; -import org.web3j.protocol.exceptions.TransactionException; -import org.web3j.utils.Base64String; - -public class LockFlexiblePrivacyGroupTransaction implements Transaction { - private final Base64String privacyGroupId; - private final PrivacyNode locker; - private final Credentials signer; - - public LockFlexiblePrivacyGroupTransaction( - final String privacyGroupId, final PrivacyNode locker, final Credentials signer) { - this.privacyGroupId = Base64String.wrap(privacyGroupId); - this.locker = locker; - this.signer = signer; - } - - @Override - public String execute(final NodeRequests node) { - try { - return node.privacy().privxLockPrivacyGroup(locker, privacyGroupId, signer); - } catch (final IOException | TransactionException e) { - throw new RuntimeException(e); - } - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/PluginCreateRandomPrivacyGroupIdTransaction.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/PluginCreateRandomPrivacyGroupIdTransaction.java deleted file mode 100644 index 180764449f..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/PluginCreateRandomPrivacyGroupIdTransaction.java +++ /dev/null @@ -1,31 +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.tests.acceptance.dsl.privacy.transaction; - -import org.hyperledger.besu.crypto.SecureRandomProvider; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -import org.apache.tuweni.bytes.Bytes; - -public class PluginCreateRandomPrivacyGroupIdTransaction implements Transaction { - - @Override - public String execute(final NodeRequests node) { - final byte[] bytes = new byte[32]; - SecureRandomProvider.createSecureRandom().nextBytes(bytes); - return Bytes.wrap(bytes).toBase64String(); - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/PrivDistributeTransactionTransaction.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/PrivDistributeTransactionTransaction.java deleted file mode 100644 index 60f0a746a9..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/PrivDistributeTransactionTransaction.java +++ /dev/null @@ -1,40 +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.tests.acceptance.dsl.privacy.transaction; - -import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -import java.io.IOException; - -public class PrivDistributeTransactionTransaction implements Transaction { - private final String signedPrivateTransaction; - - public PrivDistributeTransactionTransaction(final String signedPrivateTransaction) { - this.signedPrivateTransaction = signedPrivateTransaction; - } - - @Override - public String execute(final NodeRequests node) { - try { - return node.privacy() - .privDistributeTransaction(signedPrivateTransaction) - .send() - .getTransactionKey(); - } catch (final IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/PrivacyTransactions.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/PrivacyTransactions.java deleted file mode 100644 index d168108c97..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/PrivacyTransactions.java +++ /dev/null @@ -1,172 +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.tests.acceptance.dsl.privacy.transaction; - -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.ethereum.privacy.PrivacyGroupUtil; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.condition.PrivGetTransactionReceiptTransaction; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.util.LogFilterJsonParameter; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.privacy.EeaSendRawTransactionTransaction; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.privacy.PrivCallTransaction; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.privacy.PrivDebugGetStateRoot; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.privacy.PrivGetCodeTransaction; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.privacy.PrivGetLogsTransaction; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.privacy.PrivGetTransaction; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.privacy.PrivTraceTransaction; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.privacy.filter.PrivGetFilterChangesTransaction; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.privacy.filter.PrivGetFilterLogsTransaction; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.privacy.filter.PrivNewFilterTransaction; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.privacy.filter.PrivUninstallFilterTransaction; - -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; - -import org.apache.tuweni.bytes.Bytes; -import org.apache.tuweni.bytes.Bytes32; -import org.web3j.crypto.Credentials; -import org.web3j.tx.Contract; - -public class PrivacyTransactions { - - public PrivGetTransactionReceiptTransaction getPrivateTransactionReceipt( - final String transactionHash) { - return new PrivGetTransactionReceiptTransaction(transactionHash); - } - - public RestrictedCreatePrivacyGroupTransaction createPrivacyGroup( - final String name, final String description, final PrivacyNode... nodes) { - return new RestrictedCreatePrivacyGroupTransaction(name, description, nodes); - } - - public CreateFlexiblePrivacyGroupTransaction createFlexiblePrivacyGroup( - final PrivacyNode creator, - final String privateFrom, - final List addresses, - final String token) { - creator.getBesu().useAuthenticationTokenInHeaderForJsonRpc(token); - return new CreateFlexiblePrivacyGroupTransaction(creator, privateFrom, addresses); - } - - public CreateFlexiblePrivacyGroupTransaction createFlexiblePrivacyGroup( - final PrivacyNode creator, final String privateFrom, final List addresses) { - return new CreateFlexiblePrivacyGroupTransaction(creator, privateFrom, addresses); - } - - public AddToFlexiblePrivacyGroupTransaction addToPrivacyGroup( - final String privacyGroupId, - final PrivacyNode adder, - final Credentials signer, - final PrivacyNode... nodes) { - return new AddToFlexiblePrivacyGroupTransaction(privacyGroupId, adder, signer, nodes); - } - - public LockFlexiblePrivacyGroupTransaction privxLockPrivacyGroupAndCheck( - final String privacyGroupId, final PrivacyNode locker, final Credentials signer) { - return new LockFlexiblePrivacyGroupTransaction(privacyGroupId, locker, signer); - } - - public UnlockFlexiblePrivacyGroupTransaction privxUnlockPrivacyGroupAndCheck( - final String privacyGroupId, final PrivacyNode locker, final Credentials signer) { - return new UnlockFlexiblePrivacyGroupTransaction(privacyGroupId, locker, signer); - } - - public FindPrivacyGroupTransaction findPrivacyGroup(final List nodes) { - return new FindPrivacyGroupTransaction(nodes); - } - - public FindFlexiblePrivacyGroupTransaction findFlexiblePrivacyGroup(final List nodes) { - return new FindFlexiblePrivacyGroupTransaction(nodes); - } - - public PrivDistributeTransactionTransaction privDistributeTransaction( - final String signedPrivateTransaction) { - return new PrivDistributeTransactionTransaction(signedPrivateTransaction); - } - - public PrivCallTransaction privCall( - final String privacyGroupId, final Contract contract, final String encoded) { - return new PrivCallTransaction(privacyGroupId, contract, encoded); - } - - public PrivGetTransaction privGetTransaction(final String transactionHash) { - return new PrivGetTransaction(transactionHash); - } - - public PrivGetCodeTransaction privGetCode( - final String privacyGroupId, final Address contractAddress, final String blockParameter) { - return new PrivGetCodeTransaction(privacyGroupId, contractAddress, blockParameter); - } - - public PrivGetLogsTransaction privGetLogs( - final String privacyGroupId, final LogFilterJsonParameter filterParameter) { - return new PrivGetLogsTransaction(privacyGroupId, filterParameter); - } - - public PrivTraceTransaction privTraceTransaction( - final String privacyGroupId, final Hash transactionHash) { - return new PrivTraceTransaction(privacyGroupId, transactionHash); - } - - public RemoveFromFlexiblePrivacyGroupTransaction removeFromPrivacyGroup( - final String privacyGroupId, - final String remover, - final Credentials signer, - final String memberToRemove) { - return new RemoveFromFlexiblePrivacyGroupTransaction( - privacyGroupId, remover, signer, memberToRemove); - } - - public EeaSendRawTransactionTransaction sendRawTransaction(final String transaction) { - return new EeaSendRawTransactionTransaction(transaction); - } - - public PrivNewFilterTransaction newFilter( - final String privacyGroupId, final LogFilterJsonParameter filterParameter) { - return new PrivNewFilterTransaction(privacyGroupId, filterParameter); - } - - public PrivUninstallFilterTransaction uninstallFilter( - final String privacyGroupId, final String filterId) { - return new PrivUninstallFilterTransaction(privacyGroupId, filterId); - } - - public PrivGetFilterLogsTransaction getFilterLogs( - final String privacyGroupId, final String filterId) { - return new PrivGetFilterLogsTransaction(privacyGroupId, filterId); - } - - public PrivGetFilterChangesTransaction getFilterChanges( - final String privacyGroupId, final String filterId) { - return new PrivGetFilterChangesTransaction(privacyGroupId, filterId); - } - - public PrivDebugGetStateRoot debugGetStateRoot( - final String privacyGroupId, final String blockParam) { - return new PrivDebugGetStateRoot(privacyGroupId, blockParam); - } - - public String getLegacyPrivacyGroupId(final String privateFrom, final String... privateFor) { - - final Bytes32 privacyGroupId = - PrivacyGroupUtil.calculateEeaPrivacyGroupId( - Bytes.fromBase64String(privateFrom), - Arrays.stream(privateFor).map(Bytes::fromBase64String).collect(Collectors.toList())); - - return privacyGroupId.toBase64String(); - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/RemoveFromFlexiblePrivacyGroupTransaction.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/RemoveFromFlexiblePrivacyGroupTransaction.java deleted file mode 100644 index 7f2712c81d..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/RemoveFromFlexiblePrivacyGroupTransaction.java +++ /dev/null @@ -1,50 +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.tests.acceptance.dsl.privacy.transaction; - -import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -import java.io.IOException; - -import org.web3j.crypto.Credentials; -import org.web3j.utils.Base64String; - -public class RemoveFromFlexiblePrivacyGroupTransaction implements Transaction { - private final Base64String privacyGroupId; - private final String remover; - private final String toRemove; - private final Credentials signer; - - public RemoveFromFlexiblePrivacyGroupTransaction( - final String privacyGroupId, - final String remover, - final Credentials signer, - final String toRemove) { - this.privacyGroupId = Base64String.wrap(privacyGroupId); - this.remover = remover; - this.signer = signer; - this.toRemove = toRemove; - } - - @Override - public String execute(final NodeRequests node) { - try { - return node.privacy().privxRemoveFromPrivacyGroup(privacyGroupId, remover, signer, toRemove); - } catch (final IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/RestrictedCreatePrivacyGroupTransaction.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/RestrictedCreatePrivacyGroupTransaction.java deleted file mode 100644 index a455076f9f..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/RestrictedCreatePrivacyGroupTransaction.java +++ /dev/null @@ -1,60 +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.tests.acceptance.dsl.privacy.transaction; - -import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -import java.io.IOException; -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; - -import org.web3j.protocol.besu.Besu; -import org.web3j.protocol.besu.response.privacy.PrivCreatePrivacyGroup; -import org.web3j.utils.Base64String; - -public class RestrictedCreatePrivacyGroupTransaction implements Transaction { - private final String name; - private final String description; - private final List addresses; - - public RestrictedCreatePrivacyGroupTransaction( - final String name, final String description, final PrivacyNode... nodes) { - this.name = name; - this.description = description; - this.addresses = - Arrays.stream(nodes) - .map(n -> Base64String.wrap(n.getEnclave().getDefaultPublicKey())) - .collect(Collectors.toList()); - } - - @Override - public String execute(final NodeRequests node) { - final Besu besu = node.privacy().getBesuClient(); - try { - final PrivCreatePrivacyGroup result = - besu.privCreatePrivacyGroup(addresses, name, description).send(); - if (result.hasError()) { - throw new RuntimeException(result.getError().getMessage()); - } else { - return result.getPrivacyGroupId().toString(); - } - } catch (final IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/UnlockFlexiblePrivacyGroupTransaction.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/UnlockFlexiblePrivacyGroupTransaction.java deleted file mode 100644 index 98b0236c32..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/UnlockFlexiblePrivacyGroupTransaction.java +++ /dev/null @@ -1,47 +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.tests.acceptance.dsl.privacy.transaction; - -import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -import java.io.IOException; - -import org.web3j.crypto.Credentials; -import org.web3j.protocol.exceptions.TransactionException; -import org.web3j.utils.Base64String; - -public class UnlockFlexiblePrivacyGroupTransaction implements Transaction { - private final Base64String privacyGroupId; - private final PrivacyNode locker; - private final Credentials signer; - - public UnlockFlexiblePrivacyGroupTransaction( - final String privacyGroupId, final PrivacyNode locker, final Credentials signer) { - this.privacyGroupId = Base64String.wrap(privacyGroupId); - this.locker = locker; - this.signer = signer; - } - - @Override - public String execute(final NodeRequests node) { - try { - return node.privacy().privxUnlockPrivacyGroup(locker, privacyGroupId, signer); - } catch (final IOException | TransactionException e) { - throw new RuntimeException(e); - } - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/util/LogFilterJsonParameter.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/util/LogFilterJsonParameter.java deleted file mode 100644 index 0ef7c51dc0..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/util/LogFilterJsonParameter.java +++ /dev/null @@ -1,59 +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.tests.acceptance.dsl.privacy.util; - -import java.util.List; - -public class LogFilterJsonParameter { - - private final String fromBlock; - private final String toBlock; - private final List addresses; - private final List> topics; - private final String blockhash; - - public LogFilterJsonParameter( - final String fromBlock, - final String toBlock, - final List addresses, - final List> topics, - final String blockhash) { - this.fromBlock = fromBlock; - this.toBlock = toBlock; - this.addresses = addresses; - this.topics = topics; - this.blockhash = blockhash; - } - - public String getFromBlock() { - return fromBlock; - } - - public String getToBlock() { - return toBlock; - } - - public List getAddresses() { - return addresses; - } - - public List> getTopics() { - return topics; - } - - public String getBlockhash() { - return blockhash; - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/NodeRequests.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/NodeRequests.java index 1151100065..fea5dba3ff 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/NodeRequests.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/NodeRequests.java @@ -21,7 +21,6 @@ import org.hyperledger.besu.tests.acceptance.dsl.transaction.login.LoginRequestF import org.hyperledger.besu.tests.acceptance.dsl.transaction.miner.MinerRequestFactory; import org.hyperledger.besu.tests.acceptance.dsl.transaction.net.CustomRequestFactory; import org.hyperledger.besu.tests.acceptance.dsl.transaction.perm.PermissioningJsonRpcRequestFactory; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.privacy.PrivacyRequestFactory; import org.hyperledger.besu.tests.acceptance.dsl.transaction.txpool.TxPoolRequestFactory; import java.util.Optional; @@ -37,7 +36,6 @@ public class NodeRequests { private final BftRequestFactory bft; private final PermissioningJsonRpcRequestFactory perm; private final AdminRequestFactory admin; - private final PrivacyRequestFactory privacy; private final CustomRequestFactory custom; private final Optional websocketService; private final LoginRequestFactory login; @@ -51,7 +49,6 @@ public class NodeRequests { final BftRequestFactory bft, final PermissioningJsonRpcRequestFactory perm, final AdminRequestFactory admin, - final PrivacyRequestFactory privacy, final CustomRequestFactory custom, final MinerRequestFactory miner, final TxPoolRequestFactory txPool, @@ -63,7 +60,6 @@ public class NodeRequests { this.bft = bft; this.perm = perm; this.admin = admin; - this.privacy = privacy; this.custom = custom; this.miner = miner; this.txPool = txPool; @@ -99,10 +95,6 @@ public class NodeRequests { return custom; } - public PrivacyRequestFactory privacy() { - return privacy; - } - public LoginRequestFactory login() { return login; } diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/EeaSendRawTransactionTransaction.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/EeaSendRawTransactionTransaction.java deleted file mode 100644 index 5d2786ae8a..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/EeaSendRawTransactionTransaction.java +++ /dev/null @@ -1,47 +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.tests.acceptance.dsl.transaction.privacy; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -import java.io.IOException; - -public class EeaSendRawTransactionTransaction implements Transaction { - - final String transaction; - - public EeaSendRawTransactionTransaction(final String transaction) { - this.transaction = transaction; - } - - @Override - public Hash execute(final NodeRequests node) { - try { - final PrivacyRequestFactory.SendRawTransactionResponse result = - node.privacy().eeaSendRawTransaction(transaction).send(); - assertThat(result).isNotNull(); - if (result.hasError()) { - throw new RuntimeException(result.getError().getMessage()); - } - return result.getResult(); - } catch (final IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivCallTransaction.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivCallTransaction.java deleted file mode 100644 index 7520ada483..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivCallTransaction.java +++ /dev/null @@ -1,64 +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.tests.acceptance.dsl.transaction.privacy; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -import java.io.IOException; - -import org.web3j.protocol.core.methods.response.EthCall; -import org.web3j.tx.Contract; - -public class PrivCallTransaction implements Transaction { - - private final String privacyGroupId; - private final Contract contract; - private final String encoded; - private final String blockNumberLatestPending; - - public PrivCallTransaction( - final String privacyGroupId, final Contract contract, final String encoded) { - this(privacyGroupId, contract, encoded, "latest"); - } - - public PrivCallTransaction( - final String privacyGroupId, - final Contract contract, - final String encoded, - final String blockNumberLatestPending) { - this.privacyGroupId = privacyGroupId; - this.contract = contract; - this.encoded = encoded; - this.blockNumberLatestPending = blockNumberLatestPending; - } - - @Override - public EthCall execute(final NodeRequests node) { - try { - final EthCall response = - node.privacy() - .privCall(privacyGroupId, contract, encoded, blockNumberLatestPending) - .send(); - assertThat(response).as("check response is not null").isNotNull(); - assertThat(response.getResult()).as("check result in response isn't null").isNotNull(); - return response; - } catch (final IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivCreatePrivacyGroupTransaction.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivCreatePrivacyGroupTransaction.java deleted file mode 100644 index eaddb84fc5..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivCreatePrivacyGroupTransaction.java +++ /dev/null @@ -1,46 +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.tests.acceptance.dsl.transaction.privacy; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.parameters.CreatePrivacyGroupParameter; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -import java.io.IOException; -import java.util.List; - -public class PrivCreatePrivacyGroupTransaction implements Transaction { - - final CreatePrivacyGroupParameter params; - - public PrivCreatePrivacyGroupTransaction( - final List addresses, final String groupName, final String groupDescription) { - this.params = new CreatePrivacyGroupParameter(addresses, groupName, groupDescription); - } - - @Override - public String execute(final NodeRequests node) { - try { - final PrivacyRequestFactory.CreatePrivacyGroupResponse result = - node.privacy().privCreatePrivacyGroup(params).send(); - assertThat(result).isNotNull(); - return result.getResult(); - } catch (final IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivDebugGetStateRoot.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivDebugGetStateRoot.java deleted file mode 100644 index 59e9dd36a6..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivDebugGetStateRoot.java +++ /dev/null @@ -1,45 +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.tests.acceptance.dsl.transaction.privacy; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -import java.io.IOException; - -public class PrivDebugGetStateRoot implements Transaction { - - private final String privacyGroupId; - private final String blockParam; - - public PrivDebugGetStateRoot(final String privacyGroupId, final String blockParam) { - this.privacyGroupId = privacyGroupId; - this.blockParam = blockParam; - } - - @Override - public PrivacyRequestFactory.DebugGetStateRoot execute(final NodeRequests node) { - try { - final PrivacyRequestFactory.DebugGetStateRoot response = - node.privacy().privDebugGetStateRoot(privacyGroupId, blockParam).send(); - assertThat(response).as("check response is not null").isNotNull(); - return response; - } catch (final IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivDeletePrivacyGroupTransaction.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivDeletePrivacyGroupTransaction.java deleted file mode 100644 index caf755839d..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivDeletePrivacyGroupTransaction.java +++ /dev/null @@ -1,46 +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.tests.acceptance.dsl.transaction.privacy; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -import java.io.IOException; - -public class PrivDeletePrivacyGroupTransaction implements Transaction { - - final String transactionHash; - - public PrivDeletePrivacyGroupTransaction(final String transactionHash) { - this.transactionHash = transactionHash; - } - - @Override - public String execute(final NodeRequests node) { - try { - final PrivacyRequestFactory.DeletePrivacyGroupResponse result = - node.privacy().privDeletePrivacyGroup(transactionHash).send(); - assertThat(result).isNotNull(); - if (result.hasError()) { - throw new RuntimeException(result.getError().getMessage()); - } - return result.getResult(); - } catch (final IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivDistributeRawTransactionTransaction.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivDistributeRawTransactionTransaction.java deleted file mode 100644 index 8a9c70f873..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivDistributeRawTransactionTransaction.java +++ /dev/null @@ -1,46 +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.tests.acceptance.dsl.transaction.privacy; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -import java.io.IOException; - -public class PrivDistributeRawTransactionTransaction implements Transaction { - - final String transaction; - - public PrivDistributeRawTransactionTransaction(final String transaction) { - this.transaction = transaction; - } - - @Override - public String execute(final NodeRequests node) { - try { - final PrivacyRequestFactory.PrivDistributeTransactionResponse result = - node.privacy().privDistributeTransaction(transaction).send(); - assertThat(result).isNotNull(); - if (result.hasError()) { - throw new RuntimeException(result.getError().getMessage()); - } - return result.getTransactionKey(); - } catch (final IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivFindPrivacyGroupTransaction.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivFindPrivacyGroupTransaction.java deleted file mode 100644 index 47fad9455c..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivFindPrivacyGroupTransaction.java +++ /dev/null @@ -1,47 +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.tests.acceptance.dsl.transaction.privacy; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.hyperledger.besu.enclave.types.PrivacyGroup; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -import java.io.IOException; - -public class PrivFindPrivacyGroupTransaction implements Transaction { - - final String[] groupMembers; - - public PrivFindPrivacyGroupTransaction(final String[] groupMembers) { - this.groupMembers = groupMembers; - } - - @Override - public PrivacyGroup[] execute(final NodeRequests node) { - try { - final PrivacyRequestFactory.FindPrivacyGroupResponse result = - node.privacy().privFindPrivacyGroup(groupMembers).send(); - assertThat(result).isNotNull(); - if (result.hasError()) { - throw new RuntimeException(result.getError().getMessage()); - } - return result.getResult(); - } catch (final IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivGetCodeTransaction.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivGetCodeTransaction.java deleted file mode 100644 index dbe708f53b..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivGetCodeTransaction.java +++ /dev/null @@ -1,54 +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.tests.acceptance.dsl.transaction.privacy; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -import java.io.IOException; - -import org.apache.tuweni.bytes.Bytes; - -public class PrivGetCodeTransaction implements Transaction { - - private final String privacyGroupId; - private final Address contractAddress; - private final String blockParameter; - - public PrivGetCodeTransaction( - final String privacyGroupId, final Address contractAddress, final String blockParameter) { - this.privacyGroupId = privacyGroupId; - this.contractAddress = contractAddress; - this.blockParameter = blockParameter; - } - - @Override - public Bytes execute(final NodeRequests node) { - try { - final PrivacyRequestFactory.GetCodeResponse response = - node.privacy() - .privGetCode(privacyGroupId, contractAddress.toHexString(), blockParameter) - .send(); - assertThat(response).as("check response is not null").isNotNull(); - assertThat(response.getResult()).as("check code in response isn't null").isNotNull(); - return Bytes.fromHexString(response.getResult()); - } catch (final IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivGetEeaTransactionCountTransaction.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivGetEeaTransactionCountTransaction.java deleted file mode 100644 index b27240d1bc..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivGetEeaTransactionCountTransaction.java +++ /dev/null @@ -1,47 +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.tests.acceptance.dsl.transaction.privacy; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -import java.io.IOException; - -public class PrivGetEeaTransactionCountTransaction implements Transaction { - - private final Object[] params; - - public PrivGetEeaTransactionCountTransaction( - final String accountAddress, final String privateFrom, final String[] privateFor) { - this.params = new Object[] {accountAddress, privateFrom, privateFor}; - } - - @Override - public Integer execute(final NodeRequests node) { - try { - final PrivacyRequestFactory.GetTransactionCountResponse result = - node.privacy().privGetEeaTransactionCount(params).send(); - assertThat(result).isNotNull(); - if (result.hasError()) { - throw new RuntimeException(result.getError().getMessage()); - } - return result.getCount(); - } catch (final IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivGetLogsTransaction.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivGetLogsTransaction.java deleted file mode 100644 index 562a247b5f..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivGetLogsTransaction.java +++ /dev/null @@ -1,54 +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.tests.acceptance.dsl.transaction.privacy; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.hyperledger.besu.tests.acceptance.dsl.privacy.util.LogFilterJsonParameter; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -import java.io.IOException; -import java.util.List; - -import org.web3j.protocol.core.methods.response.EthLog; -import org.web3j.protocol.core.methods.response.EthLog.LogResult; - -@SuppressWarnings("rawtypes") -public class PrivGetLogsTransaction implements Transaction> { - - private final String privacyGroupId; - private final LogFilterJsonParameter filterParameter; - - public PrivGetLogsTransaction( - final String privacyGroupId, final LogFilterJsonParameter filterParameter) { - this.privacyGroupId = privacyGroupId; - this.filterParameter = filterParameter; - } - - @Override - public List execute(final NodeRequests node) { - try { - final EthLog response = node.privacy().privGetLogs(privacyGroupId, filterParameter).send(); - - assertThat(response).as("check response is not null").isNotNull(); - assertThat(response.getResult()).as("check result in response isn't null").isNotNull(); - - return response.getLogs(); - } catch (final IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivGetPrivacyPrecompileAddressTransaction.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivGetPrivacyPrecompileAddressTransaction.java deleted file mode 100644 index cf8cd3f065..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivGetPrivacyPrecompileAddressTransaction.java +++ /dev/null @@ -1,38 +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.tests.acceptance.dsl.transaction.privacy; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -import java.io.IOException; - -public class PrivGetPrivacyPrecompileAddressTransaction implements Transaction

{ - - @Override - public Address execute(final NodeRequests node) { - try { - final PrivacyRequestFactory.GetPrivacyPrecompileAddressResponse result = - node.privacy().privGetPrivacyPrecompileAddress().send(); - assertThat(result).isNotNull(); - return result.getResult(); - } catch (final IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivGetPrivateTransactionTransaction.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivGetPrivateTransactionTransaction.java deleted file mode 100644 index e91a83f314..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivGetPrivateTransactionTransaction.java +++ /dev/null @@ -1,46 +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.tests.acceptance.dsl.transaction.privacy; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivateTransactionGroupResponse; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -import java.io.IOException; - -public class PrivGetPrivateTransactionTransaction - implements Transaction { - - private final Hash transactionHash; - - public PrivGetPrivateTransactionTransaction(final Hash transactionHash) { - this.transactionHash = transactionHash; - } - - @Override - public PrivateTransactionGroupResponse execute(final NodeRequests node) { - try { - final PrivacyRequestFactory.GetPrivateTransactionResponse result = - node.privacy().privGetPrivateTransaction(transactionHash).send(); - assertThat(result).isNotNull(); - return result.getResult(); - } catch (final IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivGetTransaction.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivGetTransaction.java deleted file mode 100644 index 0d6e599a1e..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivGetTransaction.java +++ /dev/null @@ -1,46 +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.tests.acceptance.dsl.transaction.privacy; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -import java.io.IOException; - -public class PrivGetTransaction - implements Transaction { - - private final String transactionHash; - - public PrivGetTransaction(final String transactionHash) { - this.transactionHash = transactionHash; - } - - @Override - public PrivacyRequestFactory.GetPrivateTransactionResponse execute(final NodeRequests node) { - try { - final PrivacyRequestFactory.GetPrivateTransactionResponse response = - node.privacy().privGetPrivateTransaction(Hash.fromHexString(transactionHash)).send(); - assertThat(response).as("check response is not null").isNotNull(); - assertThat(response.getResult()).as("check result in response isn't null").isNotNull(); - return response; - } catch (final IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivGetTransactionCountTransaction.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivGetTransactionCountTransaction.java deleted file mode 100644 index e222516bee..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivGetTransactionCountTransaction.java +++ /dev/null @@ -1,47 +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.tests.acceptance.dsl.transaction.privacy; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -import java.io.IOException; - -public class PrivGetTransactionCountTransaction implements Transaction { - - private final Object[] params; - - public PrivGetTransactionCountTransaction( - final String accountAddress, final String privacyGroupId) { - this.params = new String[] {accountAddress, privacyGroupId}; - } - - @Override - public Integer execute(final NodeRequests node) { - try { - final PrivacyRequestFactory.GetTransactionCountResponse result = - node.privacy().privGetTransactionCount(params).send(); - assertThat(result).isNotNull(); - if (result.hasError()) { - throw new RuntimeException(result.getError().getMessage()); - } - return result.getCount(); - } catch (final IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivGetTransactionReceiptTransaction.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivGetTransactionReceiptTransaction.java deleted file mode 100644 index da2f6b310c..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivGetTransactionReceiptTransaction.java +++ /dev/null @@ -1,47 +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.tests.acceptance.dsl.transaction.privacy; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -import java.io.IOException; - -import org.web3j.protocol.besu.response.privacy.PrivateTransactionReceipt; - -public class PrivGetTransactionReceiptTransaction - implements Transaction { - - private final Hash transaction; - - public PrivGetTransactionReceiptTransaction(final Hash transaction) { - this.transaction = transaction; - } - - @Override - public PrivateTransactionReceipt execute(final NodeRequests node) { - try { - final PrivacyRequestFactory.GetTransactionReceiptResponse result = - node.privacy().privGetTransactionReceipt(transaction).send(); - assertThat(result).isNotNull(); - return result.getResult(); - } catch (final IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivSyncingTransactions.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivSyncingTransactions.java deleted file mode 100644 index 361d2c556a..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivSyncingTransactions.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.tests.acceptance.dsl.transaction.privacy; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -import java.io.IOException; - -import org.web3j.protocol.core.methods.response.EthSyncing; - -public class PrivSyncingTransactions implements Transaction { - - PrivSyncingTransactions() {} - - @Override - public Boolean execute(final NodeRequests node) { - try { - EthSyncing response = node.eth().ethSyncing().send(); - assertThat(response).isNotNull(); - return response.isSyncing(); - } catch (final IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivTraceTransaction.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivTraceTransaction.java deleted file mode 100644 index b971c4afde..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivTraceTransaction.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.tests.acceptance.dsl.transaction.privacy; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -import java.io.IOException; - -public class PrivTraceTransaction implements Transaction { - - private final String privacyGroupId; - private final Hash transactionHash; - - public PrivTraceTransaction(final String privacyGroupId, final Hash transactionHash) { - this.privacyGroupId = privacyGroupId; - this.transactionHash = transactionHash; - } - - @Override - public String execute(final NodeRequests node) { - try { - final PrivacyRequestFactory.PrivTraceTransaction response = - node.privacy().privTraceTransaction(privacyGroupId, transactionHash).send(); - - assertThat(response).as("check response is not null").isNotNull(); - assertThat(response.getResult()).as("check result in response is not null").isNotNull(); - - return response.getResult(); - } catch (final IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivacyRequestFactory.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivacyRequestFactory.java deleted file mode 100644 index 7c01c02c48..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivacyRequestFactory.java +++ /dev/null @@ -1,629 +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.tests.acceptance.dsl.transaction.privacy; - -import static java.util.Collections.singletonList; -import static org.assertj.core.api.Assertions.assertThat; -import static org.hyperledger.besu.ethereum.core.PrivacyParameters.FLEXIBLE_PRIVACY_PROXY; - -import org.hyperledger.besu.crypto.SecureRandomProvider; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.enclave.types.PrivacyGroup; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.parameters.CreatePrivacyGroupParameter; -import org.hyperledger.besu.ethereum.privacy.group.FlexibleGroupManagement; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivateTransactionGroupResponse; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.util.LogFilterJsonParameter; - -import java.io.IOException; -import java.math.BigInteger; -import java.security.SecureRandom; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import org.apache.tuweni.bytes.Bytes; -import org.web3j.abi.FunctionEncoder; -import org.web3j.abi.TypeReference; -import org.web3j.abi.Utils; -import org.web3j.abi.datatypes.Bool; -import org.web3j.abi.datatypes.DynamicArray; -import org.web3j.abi.datatypes.DynamicBytes; -import org.web3j.abi.datatypes.Function; -import org.web3j.abi.datatypes.Type; -import org.web3j.crypto.Credentials; -import org.web3j.protocol.Web3jService; -import org.web3j.protocol.besu.Besu; -import org.web3j.protocol.besu.response.privacy.PrivateTransactionReceipt; -import org.web3j.protocol.core.Request; -import org.web3j.protocol.core.Response; -import org.web3j.protocol.core.methods.response.EthCall; -import org.web3j.protocol.core.methods.response.EthFilter; -import org.web3j.protocol.core.methods.response.EthLog; -import org.web3j.protocol.core.methods.response.EthSendTransaction; -import org.web3j.protocol.core.methods.response.EthUninstallFilter; -import org.web3j.protocol.eea.crypto.PrivateTransactionEncoder; -import org.web3j.protocol.eea.crypto.RawPrivateTransaction; -import org.web3j.protocol.exceptions.TransactionException; -import org.web3j.tx.ChainIdLong; -import org.web3j.tx.Contract; -import org.web3j.tx.PrivateTransactionManager; -import org.web3j.tx.response.PollingPrivateTransactionReceiptProcessor; -import org.web3j.utils.Base64String; -import org.web3j.utils.Numeric; -import org.web3j.utils.Restriction; - -public class PrivacyRequestFactory { - - private final SecureRandom secureRandom; - - public PrivateTransactionManager getTransactionManager( - final Credentials credentials, - final Base64String privateFrom, - final List privateFor, - final Restriction restriction) { - return new PrivateTransactionManager( - getBesuClient(), - credentials, - new PollingPrivateTransactionReceiptProcessor(getBesuClient(), 1000, 60), - ChainIdLong.NONE, - privateFrom, - privateFor, - restriction); - } - - public PrivateTransactionManager getTransactionManager( - final Credentials credentials, - final Base64String privateFrom, - final Base64String privacyGroupId, - final Restriction restriction) { - return new PrivateTransactionManager( - getBesuClient(), - credentials, - new PollingPrivateTransactionReceiptProcessor(getBesuClient(), 1000, 60), - ChainIdLong.NONE, - privateFrom, - privacyGroupId, - restriction); - } - - public static class GetPrivacyPrecompileAddressResponse extends Response
{} - - public static class GetPrivateTransactionResponse - extends Response {} - - public static class PrivTraceTransaction extends Response {} - - public static class CreatePrivacyGroupResponse extends Response {} - - public static class DeletePrivacyGroupResponse extends Response {} - - public static class FindPrivacyGroupResponse extends Response {} - - public static class SendRawTransactionResponse extends Response {} - - public static class GetTransactionReceiptResponse extends Response {} - - public static class GetTransactionCountResponse extends Response { - - final Integer count; - - @JsonCreator - public GetTransactionCountResponse(@JsonProperty("result") final String result) { - this.count = result == null ? null : Integer.decode(result); - } - - public Integer getCount() { - return count; - } - } - - public static class GetCodeResponse extends Response {} - - public static class DebugGetStateRoot extends Response {} - - public Request privDistributeTransaction( - final String signedPrivateTransaction) { - return new Request<>( - "priv_distributeRawTransaction", - singletonList(signedPrivateTransaction), - web3jService, - PrivDistributeTransactionResponse.class); - } - - private final Besu besuClient; - private final Web3jService web3jService; - - public PrivacyRequestFactory(final Web3jService web3jService) { - this.web3jService = web3jService; - this.besuClient = Besu.build(web3jService); - this.secureRandom = SecureRandomProvider.createSecureRandom(); - } - - public Besu getBesuClient() { - return besuClient; - } - - public static class PrivDistributeTransactionResponse extends Response { - - public PrivDistributeTransactionResponse() {} - - public String getTransactionKey() { - return getResult(); - } - } - - public String privxAddToPrivacyGroup( - final Base64String privacyGroupId, - final PrivacyNode adder, - final Credentials signer, - final List addresses) - throws IOException { - - final BigInteger nonce = - besuClient - .privGetTransactionCount(signer.getAddress(), privacyGroupId) - .send() - .getTransactionCount(); - - final Bytes payload = - encodeAddToGroupFunctionCall( - addresses.stream().map(Bytes::fromBase64String).collect(Collectors.toList())); - - final RawPrivateTransaction privateTransaction = - RawPrivateTransaction.createTransaction( - nonce, - BigInteger.valueOf(1000), - BigInteger.valueOf(3000000), - FLEXIBLE_PRIVACY_PROXY.toHexString(), - payload.toHexString(), - Base64String.wrap(adder.getEnclaveKey()), - privacyGroupId, - org.web3j.utils.Restriction.RESTRICTED); - - return besuClient - .eeaSendRawTransaction( - Numeric.toHexString(PrivateTransactionEncoder.signMessage(privateTransaction, signer))) - .send() - .getTransactionHash(); - } - - public String privxRemoveFromPrivacyGroup( - final Base64String privacyGroupId, - final String removerTenant, - final Credentials signer, - final String toRemove) - throws IOException { - - final BigInteger nonce = - besuClient - .privGetTransactionCount(signer.getAddress(), privacyGroupId) - .send() - .getTransactionCount(); - - final Bytes payload = encodeRemoveFromGroupFunctionCall(Bytes.fromBase64String(toRemove)); - - final RawPrivateTransaction privateTransaction = - RawPrivateTransaction.createTransaction( - nonce, - BigInteger.valueOf(1000), - BigInteger.valueOf(3000000), - FLEXIBLE_PRIVACY_PROXY.toHexString(), - payload.toHexString(), - Base64String.wrap(removerTenant), - privacyGroupId, - org.web3j.utils.Restriction.RESTRICTED); - - return besuClient - .eeaSendRawTransaction( - Numeric.toHexString(PrivateTransactionEncoder.signMessage(privateTransaction, signer))) - .send() - .getTransactionHash(); - } - - private Bytes encodeRemoveFromGroupFunctionCall(final Bytes toRemove) { - final Function function = - new Function( - "removeParticipant", - Arrays.asList(new DynamicBytes(toRemove.toArrayUnsafe())), - Arrays.asList(new TypeReference() {})); - - return Bytes.fromHexString(FunctionEncoder.encode(function)); - } - - public String privxLockPrivacyGroup( - final PrivacyNode locker, final Base64String privacyGroupId, final Credentials signer) - throws IOException, TransactionException { - return privxLockOrUnlockPrivacyGroup( - locker, - privacyGroupId, - signer, - FlexibleGroupManagement.LOCK_GROUP_METHOD_SIGNATURE.toHexString()); - } - - public String privxUnlockPrivacyGroup( - final PrivacyNode locker, final Base64String privacyGroupId, final Credentials signer) - throws IOException, TransactionException { - return privxLockOrUnlockPrivacyGroup( - locker, - privacyGroupId, - signer, - FlexibleGroupManagement.UNLOCK_GROUP_METHOD_SIGNATURE.toHexString()); - } - - private String privxLockOrUnlockPrivacyGroup( - final PrivacyNode locker, - final Base64String privacyGroupId, - final Credentials signer, - final String callData) - throws IOException, TransactionException { - final BigInteger nonce = - besuClient - .privGetTransactionCount(signer.getAddress(), privacyGroupId) - .send() - .getTransactionCount(); - - final RawPrivateTransaction privateTransaction = - RawPrivateTransaction.createTransaction( - nonce, - BigInteger.valueOf(1000), - BigInteger.valueOf(3000000), - FLEXIBLE_PRIVACY_PROXY.toHexString(), - callData, - Base64String.wrap(locker.getEnclaveKey()), - privacyGroupId, - org.web3j.utils.Restriction.RESTRICTED); - - final String transactionHash = - besuClient - .eeaSendRawTransaction( - Numeric.toHexString( - PrivateTransactionEncoder.signMessage(privateTransaction, signer))) - .send() - .getTransactionHash(); - - final PrivateTransactionReceipt privateTransactionReceipt = - new PollingPrivateTransactionReceiptProcessor(besuClient, 3000, 10) - .waitForTransactionReceipt(transactionHash); - - assertThat(privateTransactionReceipt.getStatus()).isEqualTo("0x1"); - - return privateTransactionReceipt.getcommitmentHash(); - } - - public PrivxCreatePrivacyGroupResponse privxCreatePrivacyGroup( - final PrivacyNode creator, final String privateFrom, final List addresses) - throws IOException { - - final byte[] bytes = new byte[32]; - secureRandom.nextBytes(bytes); - final Bytes privacyGroupId = Bytes.wrap(bytes); - - final Bytes payload = - encodeAddToGroupFunctionCall( - addresses.stream().map(Bytes::fromBase64String).collect(Collectors.toList())); - - final RawPrivateTransaction privateTransaction = - RawPrivateTransaction.createTransaction( - BigInteger.ZERO, - BigInteger.valueOf(1000), - BigInteger.valueOf(3000000), - FLEXIBLE_PRIVACY_PROXY.toHexString(), - payload.toHexString(), - Base64String.wrap(privateFrom), - Base64String.wrap(privacyGroupId.toArrayUnsafe()), - org.web3j.utils.Restriction.RESTRICTED); - - final Request ethSendTransactionRequest = - besuClient.eeaSendRawTransaction( - Numeric.toHexString( - PrivateTransactionEncoder.signMessage( - privateTransaction, Credentials.create(creator.getTransactionSigningKey())))); - final String transactionHash = ethSendTransactionRequest.send().getTransactionHash(); - return new PrivxCreatePrivacyGroupResponse(privacyGroupId.toBase64String(), transactionHash); - } - - public Request privxFindFlexiblePrivacyGroup( - final List nodes) { - return new Request<>( - "privx_findFlexiblePrivacyGroup", - singletonList(nodes), - web3jService, - PrivxFindPrivacyGroupResponse.class); - } - - public Request privGetPrivacyPrecompileAddress() { - return new Request<>( - "priv_getPrivacyPrecompileAddress", - Collections.emptyList(), - web3jService, - GetPrivacyPrecompileAddressResponse.class); - } - - public Request privGetPrivateTransaction( - final Hash transactionHash) { - return new Request<>( - "priv_getPrivateTransaction", - singletonList(transactionHash.toHexString()), - web3jService, - GetPrivateTransactionResponse.class); - } - - public Request privCreatePrivacyGroup( - final CreatePrivacyGroupParameter params) { - return new Request<>( - "priv_createPrivacyGroup", - singletonList(params), - web3jService, - CreatePrivacyGroupResponse.class); - } - - public Request privDeletePrivacyGroup(final String groupId) { - return new Request<>( - "priv_deletePrivacyGroup", - singletonList(groupId), - web3jService, - DeletePrivacyGroupResponse.class); - } - - public Request privFindPrivacyGroup(final String[] groupMembers) { - return new Request<>( - "priv_findPrivacyGroup", - singletonList(groupMembers), - web3jService, - FindPrivacyGroupResponse.class); - } - - public Request eeaSendRawTransaction(final String transaction) { - return new Request<>( - "eea_sendRawTransaction", - singletonList(transaction), - web3jService, - SendRawTransactionResponse.class); - } - - public Request privGetTransactionReceipt( - final Hash transactionHash) { - return new Request<>( - "priv_getTransactionReceipt", - singletonList(transactionHash.toHexString()), - web3jService, - GetTransactionReceiptResponse.class); - } - - public Request privGetTransactionCount(final Object[] params) { - return new Request<>( - "priv_getTransactionCount", - List.of(params), - web3jService, - GetTransactionCountResponse.class); - } - - public Request privGetEeaTransactionCount(final Object[] params) { - return new Request<>( - "priv_getEeaTransactionCount", - List.of(params), - web3jService, - GetTransactionCountResponse.class); - } - - public Request privGetCode( - final String privacyGroupId, final String contractAddress, final String blockParameter) { - return new Request<>( - "priv_getCode", - List.of(privacyGroupId, contractAddress, blockParameter), - web3jService, - GetCodeResponse.class); - } - - public Request privCall( - final String privacyGroupId, - final Contract contract, - final String encoded, - final String blockNumberLatestPending) { - - final org.web3j.protocol.core.methods.request.Transaction transaction = - org.web3j.protocol.core.methods.request.Transaction.createEthCallTransaction( - null, contract.getContractAddress(), encoded); - - return new Request<>( - "priv_call", - Arrays.asList(privacyGroupId, transaction, blockNumberLatestPending), - web3jService, - EthCall.class); - } - - public Request privGetLogs( - final String privacyGroupId, final LogFilterJsonParameter filterParameter) { - - return new Request<>( - "priv_getLogs", Arrays.asList(privacyGroupId, filterParameter), web3jService, EthLog.class); - } - - public Request privTraceTransaction( - final String privacyGroupId, final Hash transactionHash) { - - return new Request<>( - "priv_traceTransaction", - Arrays.asList(privacyGroupId, transactionHash), - web3jService, - PrivTraceTransaction.class); - } - - public Request privNewFilter( - final String privacyGroupId, final LogFilterJsonParameter filterParameter) { - return new Request<>( - "priv_newFilter", - Arrays.asList(privacyGroupId, filterParameter), - web3jService, - EthFilter.class); - } - - public Request privUninstallFilter( - final String privacyGroupId, final String filterId) { - return new Request<>( - "priv_uninstallFilter", - Arrays.asList(privacyGroupId, filterId), - web3jService, - EthUninstallFilter.class); - } - - public Request privGetFilterLogs(final String privacyGroupId, final String filterId) { - - return new Request<>( - "priv_getFilterLogs", Arrays.asList(privacyGroupId, filterId), web3jService, EthLog.class); - } - - public Request privGetFilterChanges( - final String privacyGroupId, final String filterId) { - - return new Request<>( - "priv_getFilterChanges", - Arrays.asList(privacyGroupId, filterId), - web3jService, - EthLog.class); - } - - public Request privDebugGetStateRoot( - final String privacyGroupId, final String blockParam) { - return new Request<>( - "priv_debugGetStateRoot", - Arrays.asList(privacyGroupId, blockParam), - web3jService, - DebugGetStateRoot.class); - } - - public static class PrivxFindPrivacyGroupResponse extends Response> { - - public List getGroups() { - return getResult(); - } - } - - public static class FlexiblePrivacyGroup { - - private final Base64String privacyGroupId; - private final List members; - private final String name; - private final String description; - - public enum Type { - FLEXIBLE - } - - @JsonCreator - public FlexiblePrivacyGroup( - @JsonProperty(value = "privacyGroupId") final String privacyGroupId, - @JsonProperty(value = "type") final Type type, - @JsonProperty(value = "name") final String name, - @JsonProperty(value = "description") final String description, - @JsonProperty(value = "members") final List members) { - this(privacyGroupId, members); - } - - public FlexiblePrivacyGroup(final String privacyGroupId, final List members) { - this.privacyGroupId = Base64String.wrap(privacyGroupId); - this.name = ""; - this.description = ""; - this.members = members; - } - - public Base64String getPrivacyGroupId() { - return privacyGroupId; - } - - public String getName() { - return name; - } - - public String getDescription() { - return description; - } - - public Type getType() { - return Type.FLEXIBLE; - } - - public List getMembers() { - return members; - } - - @Override - public boolean equals(final Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - final FlexiblePrivacyGroup that = (FlexiblePrivacyGroup) o; - return getPrivacyGroupId().equals(that.getPrivacyGroupId()) - && getName().equals(that.getName()) - && getDescription().equals(that.getDescription()) - && getType() == that.getType() - && getMembers().equals(that.getMembers()); - } - - @Override - public int hashCode() { - return Objects.hash( - getPrivacyGroupId(), getName(), getDescription(), getType(), getMembers()); - } - } - - public static class PrivxCreatePrivacyGroupResponse { - - final String privacyGroupId; - final String transactionHash; - - @JsonCreator - public PrivxCreatePrivacyGroupResponse( - @JsonProperty("privacyGroupId") final String privacyGroupId, - @JsonProperty("transactionHash") final String transactionHash) { - this.privacyGroupId = privacyGroupId; - this.transactionHash = transactionHash; - } - - public String getPrivacyGroupId() { - return privacyGroupId; - } - - public String getTransactionHash() { - return transactionHash; - } - } - - private Bytes encodeAddToGroupFunctionCall(final List participants) { - final Function function = - new Function( - "addParticipants", - Arrays.asList( - new DynamicArray<>( - DynamicBytes.class, - Utils.typeMap( - participants.stream() - .map(Bytes::toArrayUnsafe) - .collect(Collectors.toList()), - DynamicBytes.class))), - Collections.emptyList()); - - return Bytes.fromHexString(FunctionEncoder.encode(function)); - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivacyTransactions.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivacyTransactions.java deleted file mode 100644 index db51fc2742..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/PrivacyTransactions.java +++ /dev/null @@ -1,69 +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.tests.acceptance.dsl.transaction.privacy; - -import org.hyperledger.besu.datatypes.Hash; - -import java.util.List; - -public class PrivacyTransactions { - public PrivGetPrivacyPrecompileAddressTransaction getPrivacyPrecompileAddress() { - return new PrivGetPrivacyPrecompileAddressTransaction(); - } - - public PrivGetPrivateTransactionTransaction getPrivateTransaction(final Hash transactionHash) { - return new PrivGetPrivateTransactionTransaction(transactionHash); - } - - public PrivCreatePrivacyGroupTransaction createPrivacyGroup( - final List addresses, final String groupName, final String groupDescription) { - return new PrivCreatePrivacyGroupTransaction(addresses, groupName, groupDescription); - } - - public PrivDeletePrivacyGroupTransaction deletePrivacyGroup(final String transactionHash) { - return new PrivDeletePrivacyGroupTransaction(transactionHash); - } - - public PrivFindPrivacyGroupTransaction findPrivacyGroup(final String[] groupMembers) { - return new PrivFindPrivacyGroupTransaction(groupMembers); - } - - public EeaSendRawTransactionTransaction sendRawTransaction(final String transaction) { - return new EeaSendRawTransactionTransaction(transaction); - } - - public PrivDistributeRawTransactionTransaction distributeRawTransaction( - final String transaction) { - return new PrivDistributeRawTransactionTransaction(transaction); - } - - public PrivGetTransactionCountTransaction getTransactionCount( - final String accountAddress, final String privacyGroupId) { - return new PrivGetTransactionCountTransaction(accountAddress, privacyGroupId); - } - - public PrivGetEeaTransactionCountTransaction getEeaTransactionCount( - final String accountAddress, final String privateFrom, final String[] privateFor) { - return new PrivGetEeaTransactionCountTransaction(accountAddress, privateFrom, privateFor); - } - - public PrivGetTransactionReceiptTransaction getTransactionReceipt(final Hash transactionHash) { - return new PrivGetTransactionReceiptTransaction(transactionHash); - } - - public PrivSyncingTransactions syncing() { - return new PrivSyncingTransactions(); - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/filter/PrivGetFilterChangesTransaction.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/filter/PrivGetFilterChangesTransaction.java deleted file mode 100644 index de8f2390c8..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/filter/PrivGetFilterChangesTransaction.java +++ /dev/null @@ -1,53 +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.tests.acceptance.dsl.transaction.privacy.filter; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -import java.io.IOException; -import java.util.List; - -import org.web3j.protocol.core.methods.response.EthLog; -import org.web3j.protocol.core.methods.response.EthLog.LogResult; - -@SuppressWarnings("rawtypes") -public class PrivGetFilterChangesTransaction implements Transaction> { - - private final String privacyGroupId; - private final String filterId; - - public PrivGetFilterChangesTransaction(final String privacyGroupId, final String filterId) { - this.privacyGroupId = privacyGroupId; - this.filterId = filterId; - } - - @Override - public List execute(final NodeRequests node) { - try { - final EthLog response = node.privacy().privGetFilterChanges(privacyGroupId, filterId).send(); - - assertThat(response).as("check response is not null").isNotNull(); - assertThat(response.getResult()).as("check result in response isn't null").isNotNull(); - assertThat(response.getLogs()).isNotNull(); - - return response.getLogs(); - } catch (final IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/filter/PrivGetFilterLogsTransaction.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/filter/PrivGetFilterLogsTransaction.java deleted file mode 100644 index 4362062d8f..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/filter/PrivGetFilterLogsTransaction.java +++ /dev/null @@ -1,53 +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.tests.acceptance.dsl.transaction.privacy.filter; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -import java.io.IOException; -import java.util.List; - -import org.web3j.protocol.core.methods.response.EthLog; -import org.web3j.protocol.core.methods.response.EthLog.LogResult; - -@SuppressWarnings("rawtypes") -public class PrivGetFilterLogsTransaction implements Transaction> { - - private final String privacyGroupId; - private final String filterId; - - public PrivGetFilterLogsTransaction(final String privacyGroupId, final String filterId) { - this.privacyGroupId = privacyGroupId; - this.filterId = filterId; - } - - @Override - public List execute(final NodeRequests node) { - try { - final EthLog response = node.privacy().privGetFilterLogs(privacyGroupId, filterId).send(); - - assertThat(response).as("check response is not null").isNotNull(); - assertThat(response.getResult()).as("check result in response isn't null").isNotNull(); - assertThat(response.getLogs()).isNotNull(); - - return response.getLogs(); - } catch (final IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/filter/PrivNewFilterTransaction.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/filter/PrivNewFilterTransaction.java deleted file mode 100644 index fd2d76f432..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/filter/PrivNewFilterTransaction.java +++ /dev/null @@ -1,52 +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.tests.acceptance.dsl.transaction.privacy.filter; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.hyperledger.besu.tests.acceptance.dsl.privacy.util.LogFilterJsonParameter; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -import java.io.IOException; - -import org.web3j.protocol.core.methods.response.EthFilter; - -public class PrivNewFilterTransaction implements Transaction { - - private final String privacyGroupId; - private final LogFilterJsonParameter filterParameter; - - public PrivNewFilterTransaction( - final String privacyGroupId, final LogFilterJsonParameter filterParameter) { - this.privacyGroupId = privacyGroupId; - this.filterParameter = filterParameter; - } - - @Override - public String execute(final NodeRequests node) { - try { - final EthFilter response = - node.privacy().privNewFilter(privacyGroupId, filterParameter).send(); - - assertThat(response).as("check response is not null").isNotNull(); - assertThat(response.getResult()).as("check result in response isn't null").isNotNull(); - - return response.getResult(); - } catch (final IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/filter/PrivUninstallFilterTransaction.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/filter/PrivUninstallFilterTransaction.java deleted file mode 100644 index b628d99cd4..0000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/privacy/filter/PrivUninstallFilterTransaction.java +++ /dev/null @@ -1,50 +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.tests.acceptance.dsl.transaction.privacy.filter; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -import java.io.IOException; - -import org.web3j.protocol.core.methods.response.EthUninstallFilter; - -public class PrivUninstallFilterTransaction implements Transaction { - - private final String privacyGroupId; - private final String filterId; - - public PrivUninstallFilterTransaction(final String privacyGroupId, final String filterId) { - this.privacyGroupId = privacyGroupId; - this.filterId = filterId; - } - - @Override - public Boolean execute(final NodeRequests node) { - try { - final EthUninstallFilter response = - node.privacy().privUninstallFilter(privacyGroupId, filterId).send(); - - assertThat(response).as("check response is not null").isNotNull(); - assertThat(response.getResult()).as("check result in response isn't null").isNotNull(); - - return response.isUninstalled(); - } catch (final IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/acceptance-tests/tests/build.gradle b/acceptance-tests/tests/build.gradle index 953d1859e8..8bb8fb2f2f 100644 --- a/acceptance-tests/tests/build.gradle +++ b/acceptance-tests/tests/build.gradle @@ -209,33 +209,6 @@ task acceptanceTestBftSoak(type: Test) { doFirst { mkdir "${buildDir}/jvmErrorLogs" } } -task acceptanceTestPrivacy(type: Test) { - inputs.property "integration.date", LocalTime.now() // so it runs at every invocation - include '**/privacy/**' - - useJUnitPlatform {} - - dependsOn(rootProject.installDist) - setSystemProperties(test.getSystemProperties()) - systemProperty 'acctests.runBesuAsProcess', 'true' - systemProperty 'java.security.properties', "${buildDir}/resources/test/acceptanceTesting.security" - mustRunAfter rootProject.subprojects*.test - description = 'Runs Privacy Besu acceptance tests.' - group = 'verification' - - jvmArgs "-XX:ErrorFile=${buildDir}/jvmErrorLogs/java_err_pid%p.log" - - testLogging { - exceptionFormat = 'full' - showStackTraces = true - showStandardStreams = Boolean.getBoolean('acctests.showStandardStreams') - showExceptions = true - showCauses = true - } - - doFirst { mkdir "${buildDir}/jvmErrorLogs" } -} - task acceptanceTestPermissioning(type: Test) { inputs.property "integration.date", LocalTime.now() // so it runs at every invocation include '**/permissioning/**' diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/contracts/PrivacyGroupTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/contracts/PrivacyGroupTest.java deleted file mode 100644 index b805fa43c4..0000000000 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/contracts/PrivacyGroupTest.java +++ /dev/null @@ -1,195 +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.tests.acceptance.privacy.contracts; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -import org.hyperledger.besu.privacy.contracts.generated.DefaultFlexiblePrivacyGroupManagementContract; -import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBase; -import org.hyperledger.besu.tests.acceptance.dsl.node.BesuNode; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.web3j.protocol.core.RemoteFunctionCall; -import org.web3j.protocol.core.methods.response.TransactionReceipt; -import org.web3j.protocol.exceptions.TransactionException; -import org.web3j.utils.Base64String; - -@SuppressWarnings("unchecked") -public class PrivacyGroupTest extends AcceptanceTestBase { - - private final Base64String firstParticipant = - Base64String.wrap("A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo="); - private final Base64String secondParticipant = - Base64String.wrap("Ko2bVqD+nNlNYL5EE7y3IdOnviftjiizpjRt+HTuFBs="); - private final Base64String thirdParticipant = - Base64String.wrap("Jo2bVqD+nNlNYL5EE7y3IdOnviftjiizpjRt+HTuFBs="); - private DefaultFlexiblePrivacyGroupManagementContract defaultPrivacyGroupManagementContract; - - private static final String RAW_FIRST_PARTICIPANT = "0x5aa68ac0"; - private static final String RAW_ADD_PARTICIPANT = - "0x965a25ef00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000202a8d9b56a0fe9cd94d60be4413bcb721d3a7be27ed8e28b3a6346df874ee141b"; - private static final String RAW_REMOVE_PARTICIPANT = - "0x1f52a8ee000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000202a8d9b56a0fe9cd94d60be4413bcb721d3a7be27ed8e28b3a6346df874ee141b"; - private static final String RAW_LOCK = "0xf83d08ba"; - private static final String RAW_UNLOCK = "0xa69df4b5"; - private static final String RAW_CAN_EXECUTE = "0x78b90337"; - private static final String RAW_GET_VERSION = "0x0d8e6e2c"; - - private BesuNode minerNode; - - @BeforeEach - public void setUp() throws Exception { - minerNode = besu.createMinerNode("node"); - cluster.start(minerNode); - defaultPrivacyGroupManagementContract = - minerNode.execute( - contractTransactions.createSmartContract( - DefaultFlexiblePrivacyGroupManagementContract.class)); - } - - @Test - public void rlp() throws Exception { - final String contractAddress = "0x42699a7612a82f1d9c36148af9c77354759b210b"; - assertThat(defaultPrivacyGroupManagementContract.isValid()).isEqualTo(true); - contractVerifier - .validTransactionReceipt(contractAddress) - .verify(defaultPrivacyGroupManagementContract); - // 0x0b0235be - assertThat(defaultPrivacyGroupManagementContract.getParticipants().encodeFunctionCall()) - .isEqualTo(RAW_FIRST_PARTICIPANT); - // 0xf744b089 - assertThat( - defaultPrivacyGroupManagementContract - .addParticipants(Collections.singletonList(secondParticipant.raw())) - .encodeFunctionCall()) - .isEqualTo(RAW_ADD_PARTICIPANT); - // 0xf744b089 - assertThat( - defaultPrivacyGroupManagementContract - .removeParticipant(secondParticipant.raw()) - .encodeFunctionCall()) - .isEqualTo(RAW_REMOVE_PARTICIPANT); - assertThat(defaultPrivacyGroupManagementContract.lock().encodeFunctionCall()) - .isEqualTo(RAW_LOCK); - assertThat(defaultPrivacyGroupManagementContract.unlock().encodeFunctionCall()) - .isEqualTo(RAW_UNLOCK); - assertThat(defaultPrivacyGroupManagementContract.canExecute().encodeFunctionCall()) - .isEqualTo(RAW_CAN_EXECUTE); - assertThat(defaultPrivacyGroupManagementContract.getVersion().encodeFunctionCall()) - .isEqualTo(RAW_GET_VERSION); - } - - @Test - public void canInitiallyAddParticipants() throws Exception { - final RemoteFunctionCall transactionReceiptRemoteFunctionCall = - defaultPrivacyGroupManagementContract.addParticipants( - Arrays.asList(firstParticipant.raw(), secondParticipant.raw())); - transactionReceiptRemoteFunctionCall.send(); - final List participants = - defaultPrivacyGroupManagementContract.getParticipants().send(); - assertThat(participants.size()).isEqualTo(2); - assertThat(firstParticipant.raw()).isEqualTo(participants.get(0)); - assertThat(secondParticipant.raw()).isEqualTo(participants.get(1)); - } - - @Test - public void canRemoveParticipant() throws Exception { - defaultPrivacyGroupManagementContract - .addParticipants(Arrays.asList(firstParticipant.raw(), secondParticipant.raw())) - .send(); - final List participants = - defaultPrivacyGroupManagementContract.getParticipants().send(); - assertThat(participants.size()).isEqualTo(2); - assertThat(firstParticipant.raw()).isEqualTo(participants.get(0)); - assertThat(secondParticipant.raw()).isEqualTo(participants.get(1)); - defaultPrivacyGroupManagementContract.removeParticipant(secondParticipant.raw()).send(); - final List participantsAfterRemove = - defaultPrivacyGroupManagementContract.getParticipants().send(); - assertThat(participantsAfterRemove.size()).isEqualTo(1); - assertThat(firstParticipant.raw()).isEqualTo(participantsAfterRemove.get(0)); - } - - @Test - public void cannotAddToContractWhenNotLocked() throws Exception { - defaultPrivacyGroupManagementContract - .addParticipants(Collections.singletonList(thirdParticipant.raw())) - .send(); - - assertThatThrownBy( - () -> - defaultPrivacyGroupManagementContract - .addParticipants(Collections.singletonList(secondParticipant.raw())) - .send()) - .isInstanceOf(TransactionException.class); - } - - @Test - public void ensureContractIsLockedAfterDeploy() throws Exception { - assertThat(defaultPrivacyGroupManagementContract.canExecute().send()).isFalse(); - } - - @Test - public void ensurePrivacyGroupVersionIsAlwaysDifferent() throws Exception { - defaultPrivacyGroupManagementContract - .addParticipants(Collections.singletonList(secondParticipant.raw())) - .send(); - final byte[] version1 = defaultPrivacyGroupManagementContract.getVersion().send(); - defaultPrivacyGroupManagementContract.lock().send(); - defaultPrivacyGroupManagementContract - .addParticipants(Collections.singletonList(thirdParticipant.raw())) - .send(); - final byte[] version2 = defaultPrivacyGroupManagementContract.getVersion().send(); - defaultPrivacyGroupManagementContract.removeParticipant(secondParticipant.raw()).send(); - final byte[] version3 = defaultPrivacyGroupManagementContract.getVersion().send(); - - assertThat(version1).isNotEqualTo(version2); - assertThat(version1).isNotEqualTo(version3); - assertThat(version2).isNotEqualTo(version3); - } - - @Test - public void canAddTwiceToContractWhenCallLock() throws Exception { - defaultPrivacyGroupManagementContract - .addParticipants(Arrays.asList(firstParticipant.raw(), thirdParticipant.raw())) - .send(); - defaultPrivacyGroupManagementContract.lock().send(); - defaultPrivacyGroupManagementContract - .addParticipants(Collections.singletonList(secondParticipant.raw())) - .send(); - - final List participants = - defaultPrivacyGroupManagementContract.getParticipants().send(); - assertThat(participants.size()).isEqualTo(3); - assertThat(firstParticipant.raw()).isEqualTo(participants.get(0)); - assertThat(thirdParticipant.raw()).isEqualTo(participants.get(1)); - assertThat(secondParticipant.raw()).isEqualTo(participants.get(2)); - } - - @Test - public void cannotLockTwice() throws Exception { - defaultPrivacyGroupManagementContract - .addParticipants(Collections.singletonList(thirdParticipant.raw())) - .send(); - defaultPrivacyGroupManagementContract.lock().send(); - assertThatThrownBy(() -> defaultPrivacyGroupManagementContract.lock().send()) - .isInstanceOf(TransactionException.class); - } -} diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/contracts/PrivacyProxyTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/contracts/PrivacyProxyTest.java deleted file mode 100644 index 931770ee32..0000000000 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/contracts/PrivacyProxyTest.java +++ /dev/null @@ -1,178 +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.tests.acceptance.privacy.contracts; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -import org.hyperledger.besu.privacy.contracts.generated.DefaultFlexiblePrivacyGroupManagementContract; -import org.hyperledger.besu.privacy.contracts.generated.FlexiblePrivacyGroupManagementProxy; -import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBase; -import org.hyperledger.besu.tests.acceptance.dsl.account.Accounts; -import org.hyperledger.besu.tests.acceptance.dsl.node.BesuNode; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.web3j.crypto.Credentials; -import org.web3j.protocol.Web3j; -import org.web3j.protocol.exceptions.TransactionException; -import org.web3j.protocol.http.HttpService; -import org.web3j.tx.gas.DefaultGasProvider; -import org.web3j.utils.Base64String; - -@SuppressWarnings("unchecked") -public class PrivacyProxyTest extends AcceptanceTestBase { - - private final Base64String firstParticipant = - Base64String.wrap("93Ky7lXwFkMc7+ckoFgUMku5bpr9tz4zhmWmk9RlNng="); - private final Base64String secondParticipant = - Base64String.wrap("9iaJ6OObl6TUWYjXAOyZsL0VaDPwF+tRFkMwwYSeqqw="); - private final Base64String thirdParticipant = - Base64String.wrap("Jo2bVqD+nNlNYL5EE7y3IdOnviftjiizpjRt+HTuFBs="); - private FlexiblePrivacyGroupManagementProxy flexiblePrivacyGroupManagementProxy; - - private static final String RAW_GET_PARTICIPANTS = "0x5aa68ac0"; - private static final String RAW_ADD_PARTICIPANT = - "0x965a25ef0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020f772b2ee55f016431cefe724a05814324bb96e9afdb73e338665a693d4653678"; - - private BesuNode minerNode; - private DefaultFlexiblePrivacyGroupManagementContract - defaultFlexiblePrivacyGroupManagementContract; - - @BeforeEach - public void setUp() throws Exception { - minerNode = besu.createMinerNode("node"); - cluster.start(minerNode); - defaultFlexiblePrivacyGroupManagementContract = - minerNode.execute( - contractTransactions.createSmartContract( - DefaultFlexiblePrivacyGroupManagementContract.class)); - flexiblePrivacyGroupManagementProxy = - minerNode.execute( - contractTransactions.createSmartContract( - FlexiblePrivacyGroupManagementProxy.class, - defaultFlexiblePrivacyGroupManagementContract.getContractAddress())); - } - - @Test - public void rlp() throws Exception { - assertThat(flexiblePrivacyGroupManagementProxy.isValid()).isEqualTo(true); - contractVerifier - .validTransactionReceipt(flexiblePrivacyGroupManagementProxy.getContractAddress()) - .verify(flexiblePrivacyGroupManagementProxy); - assertThat(flexiblePrivacyGroupManagementProxy.getParticipants().encodeFunctionCall()) - .isEqualTo(RAW_GET_PARTICIPANTS); - - assertThat( - flexiblePrivacyGroupManagementProxy - .addParticipants(List.of(firstParticipant.raw())) - .encodeFunctionCall()) - .isEqualTo(RAW_ADD_PARTICIPANT); - } - - @Test - public void deploysWithNoParticipant() throws Exception { - final List participants = flexiblePrivacyGroupManagementProxy.getParticipants().send(); - assertThat(participants.size()).isEqualTo(0); - } - - @Test - public void canAddParticipants() throws Exception { - flexiblePrivacyGroupManagementProxy - .addParticipants(Arrays.asList(firstParticipant.raw(), secondParticipant.raw())) - .send(); - final List participants = flexiblePrivacyGroupManagementProxy.getParticipants().send(); - assertThat(participants.size()).isEqualTo(2); - assertThat(firstParticipant.raw()).isEqualTo(participants.get(0)); - assertThat(secondParticipant.raw()).isEqualTo(participants.get(1)); - } - - @Test - public void nonOwnerCannotUpgrade() throws Exception { - flexiblePrivacyGroupManagementProxy - .addParticipants(Arrays.asList(firstParticipant.raw(), secondParticipant.raw())) - .send(); - final List participants = flexiblePrivacyGroupManagementProxy.getParticipants().send(); - assertThat(participants.size()).isEqualTo(2); - assertThat(firstParticipant.raw()).isEqualTo(participants.get(0)); - assertThat(secondParticipant.raw()).isEqualTo(participants.get(1)); - - final DefaultFlexiblePrivacyGroupManagementContract upgradedContract = - minerNode.execute( - contractTransactions.createSmartContract( - DefaultFlexiblePrivacyGroupManagementContract.class)); - - final HttpService httpService = - new HttpService( - "http://" + minerNode.getHostName() + ":" + minerNode.getJsonRpcPort().get()); - final Web3j web3j = Web3j.build(httpService); - - // load the proxy contract, use it with another signer - final FlexiblePrivacyGroupManagementProxy proxyContractAccount2 = - FlexiblePrivacyGroupManagementProxy.load( - flexiblePrivacyGroupManagementProxy.getContractAddress(), - web3j, - Credentials.create(Accounts.GENESIS_ACCOUNT_TWO_PRIVATE_KEY), - new DefaultGasProvider()); - // contract is the proxy contract and uses genesis account 2. It should not be able to upgrade - // the contract, because it is not the owner of "upgradedContract" - assertThatThrownBy( - () -> proxyContractAccount2.upgradeTo(upgradedContract.getContractAddress()).send()) - .isInstanceOf(TransactionException.class); - } - - @Test - public void ownerCanUpgrade() throws Exception { - flexiblePrivacyGroupManagementProxy - .addParticipants(Arrays.asList(firstParticipant.raw(), secondParticipant.raw())) - .send(); - final List participants = flexiblePrivacyGroupManagementProxy.getParticipants().send(); - assertThat(participants.size()).isEqualTo(2); - assertThat(firstParticipant.raw()).isEqualTo(participants.get(0)); - assertThat(secondParticipant.raw()).isEqualTo(participants.get(1)); - - final DefaultFlexiblePrivacyGroupManagementContract upgradedContract = - minerNode.execute( - contractTransactions.createSmartContract( - DefaultFlexiblePrivacyGroupManagementContract.class)); - - flexiblePrivacyGroupManagementProxy.upgradeTo(upgradedContract.getContractAddress()).send(); - final List participantsAfterUpgrade = - flexiblePrivacyGroupManagementProxy.getParticipants().send(); - assertThat(participantsAfterUpgrade.size()).isEqualTo(2); - assertThat(firstParticipant.raw()).isEqualTo(participantsAfterUpgrade.get(0)); - assertThat(secondParticipant.raw()).isEqualTo(participantsAfterUpgrade.get(1)); - } - - @Test - public void canAddTwiceToContractWhenCallLock() throws Exception { - flexiblePrivacyGroupManagementProxy - .addParticipants(Arrays.asList(firstParticipant.raw(), thirdParticipant.raw())) - .send(); - flexiblePrivacyGroupManagementProxy.lock().send(); - flexiblePrivacyGroupManagementProxy - .addParticipants(Collections.singletonList(secondParticipant.raw())) - .send(); - final List participants = flexiblePrivacyGroupManagementProxy.getParticipants().send(); - assertThat(participants.size()).isEqualTo(3); - assertThat(firstParticipant.raw()).isEqualTo(participants.get(0)); - assertThat(thirdParticipant.raw()).isEqualTo(participants.get(1)); - assertThat(secondParticipant.raw()).isEqualTo(participants.get(2)); - } -} diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/multitenancy/MultiTenancyAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/multitenancy/MultiTenancyAcceptanceTest.java deleted file mode 100644 index b1c175f646..0000000000 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/multitenancy/MultiTenancyAcceptanceTest.java +++ /dev/null @@ -1,408 +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.tests.acceptance.privacy.multitenancy; - -import static com.github.tomakehurst.wiremock.client.WireMock.ok; -import static com.github.tomakehurst.wiremock.client.WireMock.post; -import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; -import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options; -import static java.nio.charset.StandardCharsets.UTF_8; -import static java.util.Collections.emptyList; -import static java.util.Collections.singletonList; -import static org.hyperledger.besu.ethereum.core.PrivacyParameters.DEFAULT_PRIVACY; - -import org.hyperledger.besu.crypto.KeyPair; -import org.hyperledger.besu.crypto.SignatureAlgorithm; -import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.datatypes.Wei; -import org.hyperledger.besu.enclave.types.PrivacyGroup; -import org.hyperledger.besu.enclave.types.ReceiveResponse; -import org.hyperledger.besu.enclave.types.SendResponse; -import org.hyperledger.besu.ethereum.privacy.PrivacyGroupUtil; -import org.hyperledger.besu.ethereum.privacy.PrivateTransaction; -import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; -import org.hyperledger.besu.plugin.data.Restriction; -import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBase; -import org.hyperledger.besu.tests.acceptance.dsl.node.BesuNode; -import org.hyperledger.besu.tests.acceptance.dsl.node.cluster.Cluster; -import org.hyperledger.besu.tests.acceptance.dsl.node.cluster.ClusterConfiguration; -import org.hyperledger.besu.tests.acceptance.dsl.node.cluster.ClusterConfigurationBuilder; - -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Collectors; -import javax.annotation.Nonnull; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.github.tomakehurst.wiremock.junit.WireMockRule; -import com.google.common.base.Supplier; -import com.google.common.base.Suppliers; -import org.apache.tuweni.bytes.Bytes; -import org.apache.tuweni.bytes.Bytes32; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; - -public class MultiTenancyAcceptanceTest extends AcceptanceTestBase { - private BesuNode node; - private final ObjectMapper mapper = new ObjectMapper(); - private Cluster multiTenancyCluster; - - private static final Supplier SIGNATURE_ALGORITHM = - Suppliers.memoize(SignatureAlgorithmFactory::getInstance); - private static final KeyPair TEST_KEY = - SIGNATURE_ALGORITHM - .get() - .createKeyPair( - SIGNATURE_ALGORITHM - .get() - .createPrivateKey( - new BigInteger( - "853d7f0010fd86d0d7811c1f9d968ea89a24484a8127b4a483ddf5d2cfec766d", 16))); - private static final String PRIVACY_GROUP_ID = "B1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo="; - private static final String PARTICIPANT_ENCLAVE_KEY0 = - "A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo="; - private static final Bytes LEAGCY_PRIVATE_FROM = Bytes.fromBase64String(PARTICIPANT_ENCLAVE_KEY0); - private static final String PARTICIPANT_ENCLAVE_KEY1 = - "sgFkVOyFndZe/5SAZJO5UYbrl7pezHetveriBBWWnE8="; - private static final List LEGACY_PRIVATE_FOR = - List.of(Bytes.fromBase64String(PARTICIPANT_ENCLAVE_KEY1)); - private static final String PARTICIPANT_ENCLAVE_KEY2 = - "R1kW75NQC9XX3kwNpyPjCBFflM29+XvnKKS9VLrUkzo="; - private static final String PARTICIPANT_ENCLAVE_KEY3 = - "A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo="; - private final Address senderAddress = - Address.wrap(Bytes.fromHexString(accounts.getPrimaryBenefactor().getAddress())); - - @Rule public WireMockRule wireMockRule = new WireMockRule(options().dynamicPort()); - - @Before - public void setUp() throws Exception { - final ClusterConfiguration clusterConfiguration = - new ClusterConfigurationBuilder().awaitPeerDiscovery(false).build(); - multiTenancyCluster = new Cluster(clusterConfiguration, net); - node = - besu.createNodeWithMultiTenantedPrivacy( - "node1", - "http://127.0.0.1:" + wireMockRule.port(), - "authentication/auth_priv.toml", - "authentication/auth_priv_key", - false, - false); - multiTenancyCluster.start(node); - final String token = - node.execute(permissioningTransactions.createSuccessfulLogin("user", "pegasys")); - node.useAuthenticationTokenInHeaderForJsonRpc(token); - } - - @After - public void tearDown() { - multiTenancyCluster.close(); - } - - @Test - public void privGetPrivacyPrecompileAddressShouldReturnExpectedAddress() { - node.verify(priv.getPrivacyPrecompileAddress(DEFAULT_PRIVACY)); - } - - @Test - public void privGetPrivateTransactionSuccessShouldReturnExpectedPrivateTransaction() - throws JsonProcessingException { - final PrivateTransaction validSignedPrivateTransaction = - getValidSignedPrivateTransaction(senderAddress); - - receiveEnclaveStub(validSignedPrivateTransaction); - retrievePrivacyGroupEnclaveStub(); - sendEnclaveStub(PARTICIPANT_ENCLAVE_KEY1); - - final Hash transactionHash = - node.execute( - privacyTransactions.sendRawTransaction( - getRLPOutput(validSignedPrivateTransaction).encoded().toHexString())); - node.verify(priv.getSuccessfulTransactionReceipt(transactionHash)); - node.verify(priv.getPrivateTransaction(transactionHash, validSignedPrivateTransaction)); - } - - @Test - public void privCreatePrivacyGroupSuccessShouldReturnNewId() throws JsonProcessingException { - createPrivacyGroupEnclaveStub(); - - node.verify( - priv.createPrivacyGroup( - List.of(PARTICIPANT_ENCLAVE_KEY1, PARTICIPANT_ENCLAVE_KEY2, PARTICIPANT_ENCLAVE_KEY3), - "GroupName", - "Group description.", - PRIVACY_GROUP_ID)); - } - - @Test - public void privDeletePrivacyGroupSuccessShouldReturnId() throws JsonProcessingException { - retrievePrivacyGroupEnclaveStub(); - deletePrivacyGroupEnclaveStub(); - - node.verify(priv.deletePrivacyGroup(PRIVACY_GROUP_ID)); - } - - @Test - public void privFindPrivacyGroupSuccessShouldReturnExpectedGroupMembership() - throws JsonProcessingException { - final List groupMembership = - List.of( - testPrivacyGroup(singletonList(PARTICIPANT_ENCLAVE_KEY0), PrivacyGroup.Type.PANTHEON), - testPrivacyGroup(singletonList(PARTICIPANT_ENCLAVE_KEY0), PrivacyGroup.Type.PANTHEON), - testPrivacyGroup(singletonList(PARTICIPANT_ENCLAVE_KEY0), PrivacyGroup.Type.PANTHEON)); - - findPrivacyGroupEnclaveStub(groupMembership); - - node.verify(priv.findPrivacyGroup(groupMembership.size(), PARTICIPANT_ENCLAVE_KEY0)); - } - - @Test - public void eeaSendRawTransactionSuccessShouldReturnPrivateTransactionHash() - throws JsonProcessingException { - final PrivateTransaction validSignedPrivateTransaction = - getValidSignedPrivateTransaction(senderAddress); - - retrievePrivacyGroupEnclaveStub(); - sendEnclaveStub(PARTICIPANT_ENCLAVE_KEY1); - receiveEnclaveStub(validSignedPrivateTransaction); - - node.verify( - priv.eeaSendRawTransaction( - getRLPOutput(validSignedPrivateTransaction).encoded().toHexString())); - } - - @Test - public void privGetTransactionCountSuccessShouldReturnExpectedTransactionCount() - throws JsonProcessingException { - final PrivateTransaction validSignedPrivateTransaction = - getValidSignedPrivateTransaction(senderAddress); - final String accountAddress = validSignedPrivateTransaction.getSender().toHexString(); - final BytesValueRLPOutput rlpOutput = getRLPOutput(validSignedPrivateTransaction); - - retrievePrivacyGroupEnclaveStub(); - sendEnclaveStub(PARTICIPANT_ENCLAVE_KEY1); - receiveEnclaveStub(validSignedPrivateTransaction); - - node.verify(priv.getTransactionCount(accountAddress, PRIVACY_GROUP_ID, 0)); - final Hash transactionReceipt = - node.execute(privacyTransactions.sendRawTransaction(rlpOutput.encoded().toHexString())); - - node.verify(priv.getSuccessfulTransactionReceipt(transactionReceipt)); - node.verify(priv.getTransactionCount(accountAddress, PRIVACY_GROUP_ID, 1)); - } - - @Test - public void privDistributeRawTransactionSuccessShouldReturnEnclaveKey() - throws JsonProcessingException { - final String enclaveResponseKeyBytes = - Bytes.wrap(Bytes.fromBase64String(PARTICIPANT_ENCLAVE_KEY1)).toString(); - - retrievePrivacyGroupEnclaveStub(); - sendEnclaveStub(PARTICIPANT_ENCLAVE_KEY1); - - node.verify( - priv.distributeRawTransaction( - getRLPOutput(getValidSignedPrivateTransaction(senderAddress)).encoded().toHexString(), - enclaveResponseKeyBytes)); - } - - @Test - public void privGetTransactionReceiptSuccessShouldReturnTransactionReceiptAfterMined() - throws JsonProcessingException { - final PrivateTransaction validSignedPrivateTransaction = - getValidSignedPrivateTransaction(senderAddress); - final BytesValueRLPOutput rlpOutput = getRLPOutput(validSignedPrivateTransaction); - - retrievePrivacyGroupEnclaveStub(); - sendEnclaveStub(PARTICIPANT_ENCLAVE_KEY1); - receiveEnclaveStub(validSignedPrivateTransaction); - - final Hash transactionReceipt = - node.execute(privacyTransactions.sendRawTransaction(rlpOutput.encoded().toHexString())); - - node.verify(priv.getSuccessfulTransactionReceipt(transactionReceipt)); - } - - @Test - public void privGetEeaTransactionCountSuccessShouldReturnExpectedTransactionCount() - throws JsonProcessingException { - final PrivateTransaction validSignedPrivateTransaction = - getValidLegacySignedPrivateTransaction(senderAddress); - final String accountAddress = validSignedPrivateTransaction.getSender().toHexString(); - final String privateTxRlp = getRLPOutput(validSignedPrivateTransaction).encoded().toHexString(); - - retrieveEeaPrivacyGroupEnclaveStub(validSignedPrivateTransaction); - sendEnclaveStub( - Bytes32.ZERO.toBase64String()); // can be any value, as we are stubbing the enclave - receiveEnclaveStubEea(validSignedPrivateTransaction); - - final String privateFrom = validSignedPrivateTransaction.getPrivateFrom().toBase64String(); - final String[] privateFor = - validSignedPrivateTransaction.getPrivateFor().orElseThrow().stream() - .map(Bytes::toBase64String) - .toArray(String[]::new); - node.verify(priv.getEeaTransactionCount(accountAddress, privateFrom, privateFor, 0)); - - final Hash transactionHash = node.execute(privacyTransactions.sendRawTransaction(privateTxRlp)); - - node.verify(priv.getSuccessfulTransactionReceipt(transactionHash)); - - node.verify(priv.getEeaTransactionCount(accountAddress, privateFrom, privateFor, 1)); - } - - @Nonnull - private Bytes32 getPrivacyGroupIdFromEeaTransaction( - final PrivateTransaction validSignedPrivateTransaction) { - return PrivacyGroupUtil.calculateEeaPrivacyGroupId( - validSignedPrivateTransaction.getPrivateFrom(), - validSignedPrivateTransaction.getPrivateFor().get()); - } - - private void findPrivacyGroupEnclaveStub(final List groupMembership) - throws JsonProcessingException { - final String findGroupResponse = mapper.writeValueAsString(groupMembership); - stubFor(post("/findPrivacyGroup").willReturn(ok(findGroupResponse))); - } - - private void createPrivacyGroupEnclaveStub() throws JsonProcessingException { - final String createGroupResponse = - mapper.writeValueAsString(testPrivacyGroup(emptyList(), PrivacyGroup.Type.PANTHEON)); - stubFor(post("/createPrivacyGroup").willReturn(ok(createGroupResponse))); - } - - private void deletePrivacyGroupEnclaveStub() throws JsonProcessingException { - final String deleteGroupResponse = mapper.writeValueAsString(PRIVACY_GROUP_ID); - stubFor(post("/deletePrivacyGroup").willReturn(ok(deleteGroupResponse))); - } - - private void retrievePrivacyGroupEnclaveStub() throws JsonProcessingException { - final String retrieveGroupResponse = - mapper.writeValueAsString( - testPrivacyGroup( - List.of(PARTICIPANT_ENCLAVE_KEY0, PARTICIPANT_ENCLAVE_KEY1), - PrivacyGroup.Type.PANTHEON)); - stubFor(post("/retrievePrivacyGroup").willReturn(ok(retrieveGroupResponse))); - } - - private void retrieveEeaPrivacyGroupEnclaveStub(final PrivateTransaction tx) - throws JsonProcessingException { - final ArrayList members = new ArrayList<>(); - members.add(tx.getPrivateFrom().toBase64String()); - members.addAll( - tx.getPrivateFor().orElseThrow().stream() - .map(Bytes::toBase64String) - .collect(Collectors.toList())); - final String retrieveGroupResponse = - mapper.writeValueAsString(testPrivacyGroupEea(members, PrivacyGroup.Type.LEGACY)); - stubFor(post("/retrievePrivacyGroup").willReturn(ok(retrieveGroupResponse))); - } - - private void sendEnclaveStub(final String testKey) throws JsonProcessingException { - final String sendResponse = mapper.writeValueAsString(new SendResponse(testKey)); - stubFor(post("/send").willReturn(ok(sendResponse))); - } - - private void receiveEnclaveStub(final PrivateTransaction privTx) throws JsonProcessingException { - final BytesValueRLPOutput rlpOutput = getRLPOutputForReceiveResponse(privTx); - final String senderKey = privTx.getPrivateFrom().toBase64String(); - final String receiveResponse = - mapper.writeValueAsString( - new ReceiveResponse( - rlpOutput.encoded().toBase64String().getBytes(UTF_8), PRIVACY_GROUP_ID, senderKey)); - stubFor(post("/receive").willReturn(ok(receiveResponse))); - } - - private void receiveEnclaveStubEea(final PrivateTransaction privTx) - throws JsonProcessingException { - final BytesValueRLPOutput rlpOutput = getRLPOutputForReceiveResponse(privTx); - final String senderKey = privTx.getPrivateFrom().toBase64String(); - final String receiveResponse = - mapper.writeValueAsString( - new ReceiveResponse( - rlpOutput.encoded().toBase64String().getBytes(UTF_8), - getPrivacyGroupIdFromEeaTransaction(privTx).toBase64String(), - senderKey)); - stubFor(post("/receive").willReturn(ok(receiveResponse))); - } - - private BytesValueRLPOutput getRLPOutputForReceiveResponse( - final PrivateTransaction privateTransaction) { - final BytesValueRLPOutput bvrlpo = new BytesValueRLPOutput(); - privateTransaction.writeTo(bvrlpo); - return bvrlpo; - } - - private BytesValueRLPOutput getRLPOutput(final PrivateTransaction privateTransaction) { - final BytesValueRLPOutput bvrlpo = new BytesValueRLPOutput(); - privateTransaction.writeTo(bvrlpo); - return bvrlpo; - } - - private PrivacyGroup testPrivacyGroup( - final List groupMembers, final PrivacyGroup.Type groupType) { - return new PrivacyGroup(PRIVACY_GROUP_ID, groupType, "test", "testGroup", groupMembers); - } - - private PrivacyGroup testPrivacyGroupEea( - final List groupMembers, final PrivacyGroup.Type groupType) { - final Bytes32 privacyGroupId = - PrivacyGroupUtil.calculateEeaPrivacyGroupId( - Bytes.fromBase64String(groupMembers.get(0)), - groupMembers.stream() - .map(gm -> Bytes.fromBase64String(gm)) - .collect(Collectors.toList())); - return new PrivacyGroup( - privacyGroupId.toBase64String(), groupType, "test", "testGroup", groupMembers); - } - - private static PrivateTransaction getValidSignedPrivateTransaction(final Address senderAddress) { - return PrivateTransaction.builder() - .nonce(0) - .gasPrice(Wei.ZERO) - .gasLimit(3000000) - .to(null) - .value(Wei.ZERO) - .payload(Bytes.wrap(new byte[] {})) - .sender(senderAddress) - .chainId(BigInteger.valueOf(1337)) - .privateFrom(Bytes.fromBase64String(PARTICIPANT_ENCLAVE_KEY0)) - .restriction(Restriction.RESTRICTED) - .privacyGroupId(Bytes.fromBase64String(PRIVACY_GROUP_ID)) - .signAndBuild(TEST_KEY); - } - - private static PrivateTransaction getValidLegacySignedPrivateTransaction( - final Address senderAddress) { - return PrivateTransaction.builder() - .nonce(0) - .gasPrice(Wei.ZERO) - .gasLimit(3000000) - .to(null) - .value(Wei.ZERO) - .payload(Bytes.wrap(new byte[] {})) - .sender(senderAddress) - .chainId(BigInteger.valueOf(1337)) - .privateFrom(LEAGCY_PRIVATE_FROM) - .privateFor(LEGACY_PRIVATE_FOR) - .restriction(Restriction.RESTRICTED) - .signAndBuild(TEST_KEY); - } -} diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/multitenancy/MultiTenancyPrivacyGroup.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/multitenancy/MultiTenancyPrivacyGroup.java deleted file mode 100644 index a53a173a0d..0000000000 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/multitenancy/MultiTenancyPrivacyGroup.java +++ /dev/null @@ -1,58 +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.tests.acceptance.privacy.multitenancy; - -import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode; - -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -public class MultiTenancyPrivacyGroup { - - private final Map> map; - - public MultiTenancyPrivacyGroup() { - this.map = new HashMap<>(); - } - - public MultiTenancyPrivacyGroup addNodeWithTenants( - final MultiTenancyPrivacyNode privacyNode, final List tenants) { - map.put(privacyNode, tenants); - return this; - } - - public List getPrivacyNodes() { - return map.keySet().stream().collect(Collectors.toList()); - } - - public List getTenantsForNode(final MultiTenancyPrivacyNode privacyNode) { - return map.get(privacyNode); - } - - public List getTenants() { - return map.values().stream().flatMap(Collection::stream).collect(Collectors.toList()); - } - - public PrivacyNode getGroupCreatingPrivacyNode() { - return getPrivacyNodes().get(0).getPrivacyNode(); - } - - public String getGroupCreatingTenant() { - return getPrivacyNodes().get(0).getTenants().get(0); - } -} diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/multitenancy/MultiTenancyPrivacyNode.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/multitenancy/MultiTenancyPrivacyNode.java deleted file mode 100644 index 1126d44067..0000000000 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/multitenancy/MultiTenancyPrivacyNode.java +++ /dev/null @@ -1,50 +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.tests.acceptance.privacy.multitenancy; - -import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -public class MultiTenancyPrivacyNode { - - private final PrivacyNode privacyNode; - private final Map tenantToTokenMap; - - public MultiTenancyPrivacyNode(final PrivacyNode privacyNode) { - this.privacyNode = privacyNode; - this.tenantToTokenMap = new HashMap<>(); - } - - public MultiTenancyPrivacyNode addTenantWithToken(final String tenant, final String token) { - tenantToTokenMap.put(tenant, token); - return this; - } - - public List getTenants() { - return tenantToTokenMap.keySet().stream().collect(Collectors.toList()); - } - - public String getTokenForTenant(final String tenant) { - return tenantToTokenMap.get(tenant); - } - - public PrivacyNode getPrivacyNode() { - return privacyNode; - } -} diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/multitenancy/MultiTenancyPrivateNonceIncrementingTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/multitenancy/MultiTenancyPrivateNonceIncrementingTest.java deleted file mode 100644 index 11c405c37a..0000000000 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/multitenancy/MultiTenancyPrivateNonceIncrementingTest.java +++ /dev/null @@ -1,241 +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.privacy.multitenancy; - -import static com.github.tomakehurst.wiremock.client.WireMock.ok; -import static com.github.tomakehurst.wiremock.client.WireMock.post; -import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; -import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options; -import static java.nio.charset.StandardCharsets.UTF_8; - -import org.hyperledger.besu.crypto.KeyPair; -import org.hyperledger.besu.crypto.SignatureAlgorithm; -import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.datatypes.Wei; -import org.hyperledger.besu.enclave.types.PrivacyGroup; -import org.hyperledger.besu.enclave.types.ReceiveResponse; -import org.hyperledger.besu.enclave.types.SendResponse; -import org.hyperledger.besu.ethereum.privacy.PrivateTransaction; -import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; -import org.hyperledger.besu.plugin.data.Restriction; -import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBase; -import org.hyperledger.besu.tests.acceptance.dsl.node.BesuNode; -import org.hyperledger.besu.tests.acceptance.dsl.node.cluster.Cluster; -import org.hyperledger.besu.tests.acceptance.dsl.node.cluster.ClusterConfiguration; -import org.hyperledger.besu.tests.acceptance.dsl.node.cluster.ClusterConfigurationBuilder; - -import java.math.BigInteger; -import java.util.List; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.github.tomakehurst.wiremock.junit.WireMockRule; -import com.google.common.base.Supplier; -import com.google.common.base.Suppliers; -import org.apache.tuweni.bytes.Bytes; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; - -public class MultiTenancyPrivateNonceIncrementingTest extends AcceptanceTestBase { - private BesuNode node; - private final ObjectMapper mapper = new ObjectMapper(); - private Cluster multiTenancyCluster; - - private static final Supplier SIGNATURE_ALGORITHM = - Suppliers.memoize(SignatureAlgorithmFactory::getInstance); - private static final KeyPair TEST_KEY = - SIGNATURE_ALGORITHM - .get() - .createKeyPair( - SIGNATURE_ALGORITHM - .get() - .createPrivateKey( - new BigInteger( - "853d7f0010fd86d0d7811c1f9d968ea89a24484a8127b4a483ddf5d2cfec766d", 16))); - private static final String PRIVACY_GROUP_ID = "B1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo="; - private static final String PARTICIPANT_ENCLAVE_KEY0 = - "A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo="; - private static final String PARTICIPANT_ENCLAVE_KEY1 = - "sgFkVOyFndZe/5SAZJO5UYbrl7pezHetveriBBWWnE8="; - private final Address senderAddress = - Address.wrap(Bytes.fromHexString(accounts.getPrimaryBenefactor().getAddress())); - - @Rule public WireMockRule wireMockRule = new WireMockRule(options().dynamicPort()); - - @Before - public void setUp() throws Exception { - final ClusterConfiguration clusterConfiguration = - new ClusterConfigurationBuilder().awaitPeerDiscovery(false).build(); - multiTenancyCluster = new Cluster(clusterConfiguration, net); - node = - besu.createNodeWithMultiTenantedPrivacy( - "node1", - "http://127.0.0.1:" + wireMockRule.port(), - "authentication/auth_priv.toml", - "authentication/auth_priv_key", - false, - true); - multiTenancyCluster.start(node); - final String token = - node.execute(permissioningTransactions.createSuccessfulLogin("user", "pegasys")); - node.useAuthenticationTokenInHeaderForJsonRpc(token); - } - - @After - public void tearDown() { - multiTenancyCluster.close(); - } - - @Test - public void validateUnsuccessfulPrivateTransactionsNonceIncrementation() - throws JsonProcessingException { - executePrivateFailingTransaction(0, 0, 1); - executePrivateValidTransaction(1, 1, 2); - executePrivateFailingTransaction(2, 2, 3); - executePrivateFailingTransaction(3, 3, 4); - executePrivateValidTransaction(4, 4, 5); - } - - private void executePrivateValidTransaction( - final int nonce, - final int expectedTransactionCountBeforeExecution, - final int expectedTransactionCountAfterExecution) - throws JsonProcessingException { - final PrivateTransaction validSignedPrivateTransaction = - getValidSignedPrivateTransaction(senderAddress, nonce); - - final String accountAddress = validSignedPrivateTransaction.getSender().toHexString(); - final BytesValueRLPOutput rlpOutput = getRLPOutput(validSignedPrivateTransaction); - - processEnclaveStub(validSignedPrivateTransaction); - - node.verify( - priv.getTransactionCount( - accountAddress, PRIVACY_GROUP_ID, expectedTransactionCountBeforeExecution)); - - final Hash transactionReceipt = - node.execute(privacyTransactions.sendRawTransaction(rlpOutput.encoded().toHexString())); - - node.verify(priv.getSuccessfulTransactionReceipt(transactionReceipt)); - node.verify( - priv.getTransactionCount( - accountAddress, PRIVACY_GROUP_ID, expectedTransactionCountAfterExecution)); - } - - private void executePrivateFailingTransaction( - final int nonce, - final int expectedTransactionCountBeforeExecution, - final int expectedTransactionCountAfterExecution) - throws JsonProcessingException { - final PrivateTransaction invalidSignedPrivateTransaction = - getInvalidSignedPrivateTransaction(senderAddress, nonce); - final String accountAddress = invalidSignedPrivateTransaction.getSender().toHexString(); - final BytesValueRLPOutput invalidTxRlp = getRLPOutput(invalidSignedPrivateTransaction); - - processEnclaveStub(invalidSignedPrivateTransaction); - - node.verify( - priv.getTransactionCount( - accountAddress, PRIVACY_GROUP_ID, expectedTransactionCountBeforeExecution)); - final Hash invalidTransactionReceipt = - node.execute(privacyTransactions.sendRawTransaction(invalidTxRlp.encoded().toHexString())); - - node.verify(priv.getFailedTransactionReceipt(invalidTransactionReceipt)); - node.verify( - priv.getTransactionCount( - accountAddress, PRIVACY_GROUP_ID, expectedTransactionCountAfterExecution)); - } - - private void processEnclaveStub(final PrivateTransaction validSignedPrivateTransaction) - throws JsonProcessingException { - retrievePrivacyGroupEnclaveStub(); - sendEnclaveStub(); - receiveEnclaveStub(validSignedPrivateTransaction); - } - - private void retrievePrivacyGroupEnclaveStub() throws JsonProcessingException { - final String retrieveGroupResponse = - mapper.writeValueAsString( - createPrivacyGroup( - List.of(PARTICIPANT_ENCLAVE_KEY0, PARTICIPANT_ENCLAVE_KEY1), - PrivacyGroup.Type.PANTHEON)); - stubFor(post("/retrievePrivacyGroup").willReturn(ok(retrieveGroupResponse))); - } - - private void sendEnclaveStub() throws JsonProcessingException { - final String sendResponse = - mapper.writeValueAsString(new SendResponse(PARTICIPANT_ENCLAVE_KEY1)); - stubFor(post("/send").willReturn(ok(sendResponse))); - } - - private void receiveEnclaveStub(final PrivateTransaction privTx) throws JsonProcessingException { - final BytesValueRLPOutput rlpOutput = getRLPOutput(privTx); - final String senderKey = privTx.getPrivateFrom().toBase64String(); - final String receiveResponse = - mapper.writeValueAsString( - new ReceiveResponse( - rlpOutput.encoded().toBase64String().getBytes(UTF_8), PRIVACY_GROUP_ID, senderKey)); - stubFor(post("/receive").willReturn(ok(receiveResponse))); - } - - private BytesValueRLPOutput getRLPOutput(final PrivateTransaction privateTransaction) { - final BytesValueRLPOutput bvrlpo = new BytesValueRLPOutput(); - privateTransaction.writeTo(bvrlpo); - return bvrlpo; - } - - private PrivacyGroup createPrivacyGroup( - final List groupMembers, final PrivacyGroup.Type groupType) { - return new PrivacyGroup(PRIVACY_GROUP_ID, groupType, "test", "testGroup", groupMembers); - } - - private static PrivateTransaction getInvalidSignedPrivateTransaction( - final Address senderAddress, final int nonce) { - return PrivateTransaction.builder() - .nonce(nonce) - .gasPrice(Wei.ZERO) - .gasLimit(3000000) - .to(null) - .value(Wei.ZERO) - .payload(Bytes.fromHexString("0x1234")) - .sender(senderAddress) - .chainId(BigInteger.valueOf(1337)) - .privateFrom(Bytes.fromBase64String(PARTICIPANT_ENCLAVE_KEY0)) - .restriction(Restriction.RESTRICTED) - .privacyGroupId(Bytes.fromBase64String(PRIVACY_GROUP_ID)) - .signAndBuild(TEST_KEY); - } - - private static PrivateTransaction getValidSignedPrivateTransaction( - final Address senderAddress, final int nonce) { - return PrivateTransaction.builder() - .nonce(nonce) - .gasPrice(Wei.ZERO) - .gasLimit(3000000) - .to(null) - .value(Wei.ZERO) - .payload(Bytes.wrap(new byte[] {})) - .sender(senderAddress) - .chainId(BigInteger.valueOf(1337)) - .privateFrom(Bytes.fromBase64String(PARTICIPANT_ENCLAVE_KEY0)) - .restriction(Restriction.RESTRICTED) - .privacyGroupId(Bytes.fromBase64String(PRIVACY_GROUP_ID)) - .signAndBuild(TEST_KEY); - } -} diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/multitenancy/MultiTenancyValidationFailAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/multitenancy/MultiTenancyValidationFailAcceptanceTest.java deleted file mode 100644 index 28bf140bb3..0000000000 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/multitenancy/MultiTenancyValidationFailAcceptanceTest.java +++ /dev/null @@ -1,232 +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.tests.acceptance.privacy.multitenancy; - -import static com.github.tomakehurst.wiremock.client.WireMock.ok; -import static com.github.tomakehurst.wiremock.client.WireMock.post; -import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; -import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options; -import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType.DELETE_PRIVACY_GROUP_ERROR; -import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType.ENCLAVE_ERROR; -import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType.FIND_PRIVACY_GROUP_ERROR; -import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType.GET_PRIVATE_TRANSACTION_NONCE_ERROR; -import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType.PRIVATE_FROM_DOES_NOT_MATCH_ENCLAVE_PUBLIC_KEY; - -import org.hyperledger.besu.crypto.SignatureAlgorithm; -import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.datatypes.Wei; -import org.hyperledger.besu.enclave.types.PrivacyGroup; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; -import org.hyperledger.besu.ethereum.privacy.PrivateTransaction; -import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; -import org.hyperledger.besu.plugin.data.Restriction; -import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBase; -import org.hyperledger.besu.tests.acceptance.dsl.node.BesuNode; -import org.hyperledger.besu.tests.acceptance.dsl.node.cluster.Cluster; -import org.hyperledger.besu.tests.acceptance.dsl.node.cluster.ClusterConfiguration; -import org.hyperledger.besu.tests.acceptance.dsl.node.cluster.ClusterConfigurationBuilder; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -import java.math.BigInteger; -import java.util.List; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.github.tomakehurst.wiremock.junit.WireMockRule; -import org.apache.tuweni.bytes.Bytes; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; - -public class MultiTenancyValidationFailAcceptanceTest extends AcceptanceTestBase { - private BesuNode node; - private final ObjectMapper mapper = new ObjectMapper(); - private Cluster multiTenancyCluster; - - private static final String PRIVACY_GROUP_ID = "B1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo="; - private static final String ENCLAVE_PUBLIC_KEY = "B1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo="; - private static final String OTHER_ENCLAVE_PUBLIC_KEY = - "A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo="; - private final Address senderAddress = - Address.wrap(Bytes.fromHexString(accounts.getPrimaryBenefactor().getAddress())); - - @Rule public WireMockRule wireMockRule = new WireMockRule(options().dynamicPort()); - - @Before - public void setUp() throws Exception { - final ClusterConfiguration clusterConfiguration = - new ClusterConfigurationBuilder().awaitPeerDiscovery(false).build(); - multiTenancyCluster = new Cluster(clusterConfiguration, net); - node = - besu.createNodeWithMultiTenantedPrivacy( - "node1", - "http://127.0.0.1:" + wireMockRule.port(), - "authentication/auth_priv.toml", - "authentication/auth_priv_key", - false, - false); - multiTenancyCluster.start(node); - - final String token = - node.execute(permissioningTransactions.createSuccessfulLogin("failUser", "pegasys")); - node.useAuthenticationTokenInHeaderForJsonRpc(token); - } - - @After - public void tearDown() { - multiTenancyCluster.close(); - } - - @Test - public void sendRawTransactionShouldFailWhenPrivateFromNotMatchEnclaveKey() - throws JsonProcessingException { - final PrivateTransaction validSignedPrivateTransaction = - getValidSignedPrivateTransaction(senderAddress, OTHER_ENCLAVE_PUBLIC_KEY); - retrievePrivacyGroupEnclaveStub(); - final Transaction transaction = - privacyTransactions.sendRawTransaction( - getRLPOutput(validSignedPrivateTransaction).encoded().toHexString()); - node.verify( - priv.multiTenancyValidationFail( - transaction, RpcErrorType.PRIVATE_FROM_DOES_NOT_MATCH_ENCLAVE_PUBLIC_KEY)); - } - - @Test - public void sendRawTransactionShouldFailWhenPrivacyGroupDoesNotContainEnclaveKey() - throws JsonProcessingException { - final PrivateTransaction validSignedPrivateTransaction = - getValidSignedPrivateTransaction(senderAddress, ENCLAVE_PUBLIC_KEY); - retrievePrivacyGroupEnclaveStub(); - final Transaction transaction = - privacyTransactions.sendRawTransaction( - getRLPOutput(validSignedPrivateTransaction).encoded().toHexString()); - node.verify(priv.multiTenancyValidationFail(transaction, ENCLAVE_ERROR)); - } - - @Test - public void distributeRawTransactionShouldFailWhenPrivateFromNotMatchEnclaveKey() { - final Address senderAddress = - Address.wrap(Bytes.fromHexString(accounts.getPrimaryBenefactor().getAddress())); - - final Transaction transaction = - privacyTransactions.distributeRawTransaction( - getRLPOutput(getValidSignedPrivateTransaction(senderAddress, OTHER_ENCLAVE_PUBLIC_KEY)) - .encoded() - .toHexString()); - node.verify( - priv.multiTenancyValidationFail( - transaction, PRIVATE_FROM_DOES_NOT_MATCH_ENCLAVE_PUBLIC_KEY)); - } - - @Test - public void distributeRawTransactionShouldFailWhenPrivacyGroupDoesNotContainEnclaveKey() - throws JsonProcessingException { - final Address senderAddress = - Address.wrap(Bytes.fromHexString(accounts.getPrimaryBenefactor().getAddress())); - - retrievePrivacyGroupEnclaveStub(); - - final Transaction transaction = - privacyTransactions.distributeRawTransaction( - getRLPOutput(getValidSignedPrivateTransaction(senderAddress, ENCLAVE_PUBLIC_KEY)) - .encoded() - .toHexString()); - node.verify(priv.multiTenancyValidationFail(transaction, ENCLAVE_ERROR)); - } - - @Test - public void deletePrivacyGroupShouldFailWhenEnclaveKeyNotInPrivacyGroup() - throws JsonProcessingException { - retrievePrivacyGroupEnclaveStub(); - final Transaction transaction = - privacyTransactions.deletePrivacyGroup(PRIVACY_GROUP_ID); - node.verify(priv.multiTenancyValidationFail(transaction, DELETE_PRIVACY_GROUP_ERROR)); - } - - @Test - public void findPrivacyGroupShouldFailWhenEnclaveKeyNotInPrivacyGroup() { - final Transaction transaction = - privacyTransactions.findPrivacyGroup(new String[] {OTHER_ENCLAVE_PUBLIC_KEY}); - node.verify(priv.multiTenancyValidationFail(transaction, FIND_PRIVACY_GROUP_ERROR)); - } - - @Test - public void determineEeaNonceShouldFailWhenPrivateFromNotMatchEnclaveKey() { - final String accountAddress = Address.ZERO.toHexString(); - final String senderAddressBase64 = Bytes.fromHexString(accountAddress).toBase64String(); - final String[] privateFor = {senderAddressBase64}; - final Transaction transaction = - privacyTransactions.getEeaTransactionCount( - accountAddress, OTHER_ENCLAVE_PUBLIC_KEY, privateFor); - node.verify( - priv.multiTenancyValidationFail( - transaction, PRIVATE_FROM_DOES_NOT_MATCH_ENCLAVE_PUBLIC_KEY)); - } - - @Test - public void determineBesuNonceShouldFailWhenEnclaveKeyNotInPrivacyGroup() - throws JsonProcessingException { - retrievePrivacyGroupEnclaveStub(); - final String accountAddress = Address.ZERO.toHexString(); - final Transaction transaction = - privacyTransactions.getTransactionCount(accountAddress, PRIVACY_GROUP_ID); - node.verify(priv.multiTenancyValidationFail(transaction, GET_PRIVATE_TRANSACTION_NONCE_ERROR)); - } - - private void retrievePrivacyGroupEnclaveStub() throws JsonProcessingException { - final String retrieveGroupResponse = - mapper.writeValueAsString( - testPrivacyGroup(List.of(OTHER_ENCLAVE_PUBLIC_KEY), PrivacyGroup.Type.PANTHEON)); - stubFor(post("/retrievePrivacyGroup").willReturn(ok(retrieveGroupResponse))); - } - - private PrivacyGroup testPrivacyGroup( - final List groupMembers, final PrivacyGroup.Type groupType) { - return new PrivacyGroup(PRIVACY_GROUP_ID, groupType, "test", "testGroup", groupMembers); - } - - private BytesValueRLPOutput getRLPOutput(final PrivateTransaction validSignedPrivateTransaction) { - final BytesValueRLPOutput bvrlpo = new BytesValueRLPOutput(); - validSignedPrivateTransaction.writeTo(bvrlpo); - return bvrlpo; - } - - private static PrivateTransaction getValidSignedPrivateTransaction( - final Address senderAddress, final String privateFrom) { - - final SignatureAlgorithm signatureAlgorithm = SignatureAlgorithmFactory.getInstance(); - - return PrivateTransaction.builder() - .nonce(0) - .gasPrice(Wei.ZERO) - .gasLimit(3000000) - .to(null) - .value(Wei.ZERO) - .payload(Bytes.wrap(new byte[] {})) - .sender(senderAddress) - .chainId(BigInteger.valueOf(2018)) - .privateFrom(Bytes.fromBase64String(privateFrom)) - .restriction(Restriction.RESTRICTED) - .privacyGroupId(Bytes.fromBase64String(PRIVACY_GROUP_ID)) - .signAndBuild( - signatureAlgorithm.createKeyPair( - signatureAlgorithm.createPrivateKey( - new BigInteger( - "853d7f0010fd86d0d7811c1f9d968ea89a24484a8127b4a483ddf5d2cfec766d", 16)))); - } -} From e0cd5084c7787a21c53e27f8591511887c84bf6b Mon Sep 17 00:00:00 2001 From: Luis Pinto Date: Thu, 12 Sep 2024 12:56:54 +0100 Subject: [PATCH 206/259] Change test to tease NPEs during DefaultBlockchain.() caused by initilization order (#7607) * Change test to tease NPEs during DefaultBlockchain.() caused by initilization order * fixup! Change test to tease NPEs during DefaultBlockchain.() caused by initilization order * move counters into their own method Signed-off-by: Luis Pinto --- CHANGELOG.md | 1 + .../ethereum/chain/DefaultBlockchain.java | 32 +++++++++------ .../ethereum/chain/DefaultBlockchainTest.java | 41 ++++++++++++------- 3 files changed, 47 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ea4ced222..c38c30a421 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,7 @@ - Layered txpool: do not send notifications when moving tx between layers [#7539](https://github.com/hyperledger/besu/pull/7539) - Layered txpool: fix for unsent drop notifications on remove [#7538](https://github.com/hyperledger/besu/pull/7538) - Honor block number or tag parameter in eth_estimateGas and eth_createAccessList [#7502](https://github.com/hyperledger/besu/pull/7502) +- Fixed NPE during DefaultBlockchain object initialization [#7601](https://github.com/hyperledger/besu/pull/7601) ## 24.9.0 diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/chain/DefaultBlockchain.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/chain/DefaultBlockchain.java index b2b4e6abfc..bce94a1915 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/chain/DefaultBlockchain.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/chain/DefaultBlockchain.java @@ -31,6 +31,7 @@ import org.hyperledger.besu.ethereum.core.LogWithMetadata; import org.hyperledger.besu.ethereum.core.Transaction; import org.hyperledger.besu.ethereum.core.TransactionReceipt; import org.hyperledger.besu.metrics.BesuMetricCategory; +import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import org.hyperledger.besu.metrics.prometheus.PrometheusMetricsSystem; import org.hyperledger.besu.plugin.services.MetricsSystem; import org.hyperledger.besu.plugin.services.metrics.Counter; @@ -84,8 +85,8 @@ public class DefaultBlockchain implements MutableBlockchain { private final Optional>> transactionReceiptsCache; private final Optional> totalDifficultyCache; - private final Counter gasUsedCounter; - private final Counter numberOfTransactionsCounter; + private Counter gasUsedCounter = NoOpMetricsSystem.NO_OP_COUNTER; + private Counter numberOfTransactionsCounter = NoOpMetricsSystem.NO_OP_COUNTER; private DefaultBlockchain( final Optional genesisBlock, @@ -147,6 +148,23 @@ public class DefaultBlockchain implements MutableBlockchain { totalDifficultyCache = Optional.empty(); } + createCounters(metricsSystem); + createGauges(metricsSystem); + } + + private void createCounters(final MetricsSystem metricsSystem) { + gasUsedCounter = + metricsSystem.createCounter( + BesuMetricCategory.BLOCKCHAIN, "chain_head_gas_used_counter", "Counter for Gas used"); + + numberOfTransactionsCounter = + metricsSystem.createCounter( + BesuMetricCategory.BLOCKCHAIN, + "chain_head_transaction_count_counter", + "Counter for the number of transactions"); + } + + private void createGauges(final MetricsSystem metricsSystem) { metricsSystem.createLongGauge( BesuMetricCategory.ETHEREUM, "blockchain_height", @@ -183,10 +201,6 @@ public class DefaultBlockchain implements MutableBlockchain { "Gas used by the current chain head block", () -> getChainHeadHeader().getGasUsed()); - gasUsedCounter = - metricsSystem.createCounter( - BesuMetricCategory.BLOCKCHAIN, "chain_head_gas_used_counter", "Counter for Gas used"); - metricsSystem.createLongGauge( BesuMetricCategory.BLOCKCHAIN, "chain_head_gas_limit", @@ -199,12 +213,6 @@ public class DefaultBlockchain implements MutableBlockchain { "Number of transactions in the current chain head block", () -> chainHeadTransactionCount); - numberOfTransactionsCounter = - metricsSystem.createCounter( - BesuMetricCategory.BLOCKCHAIN, - "chain_head_transaction_count_counter", - "Counter for the number of transactions"); - metricsSystem.createIntegerGauge( BesuMetricCategory.BLOCKCHAIN, "chain_head_ommer_count", diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/chain/DefaultBlockchainTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/chain/DefaultBlockchainTest.java index 69fbfcdbd6..7ad1d82bfd 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/chain/DefaultBlockchainTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/chain/DefaultBlockchainTest.java @@ -35,8 +35,10 @@ import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration; import org.hyperledger.besu.plugin.services.storage.KeyValueStorage; import org.hyperledger.besu.services.kvstore.InMemoryKeyValueStorage; +import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Collections; +import java.util.Iterator; import java.util.List; import java.util.Optional; import java.util.Set; @@ -161,33 +163,42 @@ public class DefaultBlockchainTest { () -> BlockOptions.create().setDifficulty(Difficulty.of(Long.MAX_VALUE))); final KeyValueStorage kvStore = new InMemoryKeyValueStorage(); final KeyValueStorage kvStoreVariables = new InMemoryKeyValueStorage(); - final List blocks = gen.blockSequence(10); + final ArrayDeque blocks = new ArrayDeque<>(gen.blockSequence(10)); final List> blockReceipts = new ArrayList<>(blocks.size()); blockReceipts.add(Collections.emptyList()); // Write small chain to storage final MutableBlockchain mutableBlockchain = - createMutableBlockchain(kvStore, kvStoreVariables, blocks.get(0)); - for (int i = 1; i < blocks.size(); i++) { - final Block block = blocks.get(i); - final List receipts = gen.receipts(block); - blockReceipts.add(receipts); - mutableBlockchain.appendBlock(block, receipts); - } + createMutableBlockchain(kvStore, kvStoreVariables, blocks.getFirst()); + blocks.stream() + .filter(block -> !block.equals(blocks.getFirst())) + .forEach( + block -> { + final List receipts = gen.receipts(block); + blockReceipts.add(receipts); + mutableBlockchain.appendBlock(block, receipts); + }); + + // To make sure there are no surprising NPEs during DefaultBlockchain. + BlockchainStorage blockchainStorage = createStorage(kvStore, kvStoreVariables); + BlockchainStorage.Updater updater = blockchainStorage.updater(); + updater.setFinalized(blocks.getLast().getHash()); + updater.setSafeBlock(blocks.getLast().getHash()); + updater.setChainHead(blocks.getLast().getHash()); + updater.commit(); // Create read only chain final Blockchain blockchain = DefaultBlockchain.create( - createStorage(kvStore, kvStoreVariables), + blockchainStorage, MetricsSystemFactory.create(MetricsConfiguration.builder().enabled(true).build()), 0); - for (int i = 0; i < blocks.size(); i++) { - assertBlockDataIsStored(blockchain, blocks.get(i), blockReceipts.get(i)); - } - final Block lastBlock = blocks.get(blocks.size() - 1); - assertBlockIsHead(blockchain, lastBlock); - assertTotalDifficultiesAreConsistent(blockchain, lastBlock); + assertThat(blockReceipts.size()).isEqualTo(blocks.size()); + Iterator> it = blockReceipts.iterator(); + blocks.forEach(block -> assertBlockDataIsStored(blockchain, block, it.next())); + assertBlockIsHead(blockchain, blocks.getLast()); + assertTotalDifficultiesAreConsistent(blockchain, blocks.getLast()); } @Test From 31c174b0c6fddca44033b4d6c7f1a53395bfe7a3 Mon Sep 17 00:00:00 2001 From: Fabio Di Fabio Date: Fri, 13 Sep 2024 12:43:08 +0200 Subject: [PATCH 207/259] Revert "Re-enable TxPoolOptionsTest::txpoolForcePriceBumpToZeroWhenZeroBaseFeeMarket (#7565)" (#7613) This reverts commit 07adb415eec5341fe22442ac9938e7f7b8a9de11. Signed-off-by: Fabio Di Fabio --- .../test/java/org/hyperledger/besu/cli/TxPoolOptionsTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/besu/src/test/java/org/hyperledger/besu/cli/TxPoolOptionsTest.java b/besu/src/test/java/org/hyperledger/besu/cli/TxPoolOptionsTest.java index a5ca07484a..8389ab5bae 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/TxPoolOptionsTest.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/TxPoolOptionsTest.java @@ -30,6 +30,7 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; public class TxPoolOptionsTest extends CommandTestAbstract { @@ -97,6 +98,7 @@ public class TxPoolOptionsTest extends CommandTestAbstract { } @Test + @Disabled // Failing in CI, but not locally public void txpoolForcePriceBumpToZeroWhenZeroBaseFeeMarket() throws IOException { final Path genesisFile = createFakeGenesisFile(GENESIS_WITH_ZERO_BASE_FEE_MARKET); parseCommand("--genesis-file", genesisFile.toString()); From 5df2a71a4db886444ed458938e58ea6705e3d49c Mon Sep 17 00:00:00 2001 From: Suyash Nayan <89125422+7suyash7@users.noreply.github.com> Date: Fri, 13 Sep 2024 19:05:34 +0530 Subject: [PATCH 208/259] Fix debug_traceCall to handle underpriced transactions (#7510) * Fix debug_traceCall to handle underpriced transactions Signed-off-by: 7suyash7 * remove unused methods Signed-off-by: 7suyash7 * Add test case and changelog entry for debug_traceCall fix Signed-off-by: 7suyash7 --------- Signed-off-by: 7suyash7 Signed-off-by: Fabio Di Fabio Co-authored-by: Fabio Di Fabio --- CHANGELOG.md | 3 +- .../internal/methods/DebugTraceCall.java | 16 ++++--- .../debug_traceCall_noGasPrice.json | 42 +++++++++++++++++++ 3 files changed, 54 insertions(+), 7 deletions(-) create mode 100644 ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/debug/trace-call/debug_traceCall_noGasPrice.json diff --git a/CHANGELOG.md b/CHANGELOG.md index c38c30a421..1da225c56c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,8 +9,8 @@ ### Additions and Improvements - Remove privacy test classes support [#7569](https://github.com/hyperledger/besu/pull/7569) - ### Bug fixes +- Fix for `debug_traceCall` to handle transactions without specified gas price. [#7510](https://github.com/hyperledger/besu/pull/7510) ## 24.9.1 @@ -50,7 +50,6 @@ This release version has been deprecated release due to CI bug - ## 24.8.0 ### Upcoming Breaking Changes diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceCall.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceCall.java index e808e79ddc..45b06ce691 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceCall.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceCall.java @@ -29,18 +29,16 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.DebugTraceTransactionResult; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; import org.hyperledger.besu.ethereum.debug.TraceOptions; +import org.hyperledger.besu.ethereum.mainnet.ImmutableTransactionValidationParams; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; +import org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams; import org.hyperledger.besu.ethereum.transaction.PreCloseStateHandler; import org.hyperledger.besu.ethereum.transaction.TransactionSimulator; import org.hyperledger.besu.ethereum.vm.DebugOperationTracer; import java.util.Optional; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - public class DebugTraceCall extends AbstractTraceCall { - private static final Logger LOG = LoggerFactory.getLogger(DebugTraceCall.class); public DebugTraceCall( final BlockchainQueries blockchainQueries, @@ -89,7 +87,6 @@ public class DebugTraceCall extends AbstractTraceCall { maybeSimulatorResult.map( result -> { if (result.isInvalid()) { - LOG.error("Invalid simulator result {}", result); final JsonRpcError error = new JsonRpcError( INTERNAL_ERROR, result.getValidationResult().getErrorMessage()); @@ -103,4 +100,13 @@ public class DebugTraceCall extends AbstractTraceCall { return new DebugTraceTransactionResult(transactionTrace); }); } + + @Override + protected TransactionValidationParams buildTransactionValidationParams() { + return ImmutableTransactionValidationParams.builder() + .from(TransactionValidationParams.transactionSimulator()) + .isAllowExceedingBalance(true) + .allowUnderpriced(true) + .build(); + } } diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/debug/trace-call/debug_traceCall_noGasPrice.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/debug/trace-call/debug_traceCall_noGasPrice.json new file mode 100644 index 0000000000..18fe53baa1 --- /dev/null +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/debug/trace-call/debug_traceCall_noGasPrice.json @@ -0,0 +1,42 @@ +{ + "request": { + "jsonrpc": "2.0", + "method": "debug_traceCall", + "params": [ + { + "to": "0x0aae40965e6800cd9b1f4b05ff21581047e3f91e", + "data": "0x000000000000000000000000000000000000000000000000000000000001A00E" + }, + "latest", + { + "disableMemory": true, + "disableStack": true, + "disableStorage": true + } + ], + "id": 1 + }, + "response": { + "jsonrpc": "2.0", + "id": 1, + "result": { + "gas": 21164, + "failed": false, + "returnValue": "", + "structLogs": [ + { + "pc": 0, + "op": "STOP", + "gas": 17592186023252, + "gasCost": 0, + "depth": 1, + "stack": null, + "memory": null, + "storage": null, + "reason": null + } + ] + } + }, + "statusCode": 200 +} \ No newline at end of file From 87bad72b52da257c430039562aed2bcc2e1302f0 Mon Sep 17 00:00:00 2001 From: Sally MacFarlane Date: Mon, 16 Sep 2024 11:17:09 +1000 Subject: [PATCH 209/259] removed hyperledger from discord refs (#7618) Signed-off-by: Sally MacFarlane --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d54b6bb329..cd4930fc76 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ Besu is an Apache 2.0 licensed, MainNet compatible, Ethereum client written in J 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. -If you have any questions, queries or comments, [Besu channel on Hyperledger Discord] is the place to find us. +If you have any questions, queries or comments, [Besu channel on Discord] is the place to find us. ## Besu Users @@ -68,5 +68,5 @@ and YourKit YouMonitor. [Besu Issues]: https://github.com/hyperledger/besu/issues [Besu User Documentation]: https://besu.hyperledger.org -[Besu channel on Hyperledger Discord]: https://discord.gg/hyperledger +[Besu channel on Discord]: https://discord.gg/hyperledger [Contributing Guidelines]: CONTRIBUTING.md From 12caf7d83c6a6fec90ccbb444a1d76b4c7e38d80 Mon Sep 17 00:00:00 2001 From: ITStarMan100 Date: Mon, 16 Sep 2024 02:31:05 +0000 Subject: [PATCH 210/259] Added GraphQL Service Information in responese result NetServices (#7580) Signed-off-by: ITStarMan100 Co-authored-by: Justin Florentine Co-authored-by: Sally MacFarlane --- .../java/org/hyperledger/besu/RunnerBuilder.java | 7 +++++++ .../api/jsonrpc/JsonRpcTestMethodsFactory.java | 4 ++++ .../api/jsonrpc/internal/methods/NetServices.java | 11 ++++++++++- .../api/jsonrpc/methods/JsonRpcMethodsFactory.java | 5 ++++- .../api/jsonrpc/methods/NetJsonRpcMethods.java | 12 ++++++++++-- .../api/jsonrpc/AbstractJsonRpcHttpServiceTest.java | 2 ++ .../jsonrpc/JsonRpcHttpServiceHostAllowlistTest.java | 2 ++ .../api/jsonrpc/JsonRpcHttpServiceLoginTest.java | 2 ++ .../api/jsonrpc/JsonRpcHttpServiceRpcApisTest.java | 3 +++ .../api/jsonrpc/JsonRpcHttpServiceTestBase.java | 2 ++ .../jsonrpc/JsonRpcHttpServiceTlsClientAuthTest.java | 2 ++ .../JsonRpcHttpServiceTlsMisconfigurationTest.java | 2 ++ .../api/jsonrpc/JsonRpcHttpServiceTlsTest.java | 2 ++ .../jsonrpc/websocket/WebSocketServiceLoginTest.java | 2 ++ 14 files changed, 54 insertions(+), 4 deletions(-) diff --git a/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java b/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java index 39e4356a7f..96eef547fe 100644 --- a/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java @@ -863,6 +863,7 @@ public class RunnerBuilder { jsonRpcConfiguration, webSocketConfiguration, metricsConfiguration, + graphQLConfiguration, natService, besuPluginContext.getNamedPlugins(), dataDir, @@ -907,6 +908,7 @@ public class RunnerBuilder { engineJsonRpcConfiguration.get(), webSocketConfiguration, metricsConfiguration, + graphQLConfiguration, natService, besuPluginContext.getNamedPlugins(), dataDir, @@ -1001,6 +1003,7 @@ public class RunnerBuilder { jsonRpcConfiguration, webSocketConfiguration, metricsConfiguration, + graphQLConfiguration, natService, besuPluginContext.getNamedPlugins(), dataDir, @@ -1081,6 +1084,7 @@ public class RunnerBuilder { jsonRpcConfiguration, webSocketConfiguration, metricsConfiguration, + graphQLConfiguration, natService, besuPluginContext.getNamedPlugins(), dataDir, @@ -1119,6 +1123,7 @@ public class RunnerBuilder { jsonRpcConfiguration, webSocketConfiguration, metricsConfiguration, + graphQLConfiguration, natService, besuPluginContext.getNamedPlugins(), dataDir, @@ -1280,6 +1285,7 @@ public class RunnerBuilder { final JsonRpcConfiguration jsonRpcConfiguration, final WebSocketConfiguration webSocketConfiguration, final MetricsConfiguration metricsConfiguration, + final GraphQLConfiguration graphQLConfiguration, final NatService natService, final Map namedPlugins, final Path dataDir, @@ -1313,6 +1319,7 @@ public class RunnerBuilder { jsonRpcConfiguration, webSocketConfiguration, metricsConfiguration, + graphQLConfiguration, natService, namedPlugins, dataDir, 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 b5f65e6d4b..538060a905 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 @@ -21,6 +21,7 @@ import static org.mockito.Mockito.mock; import org.hyperledger.besu.config.StubGenesisConfigOptions; import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.api.ImmutableApiConfiguration; +import org.hyperledger.besu.ethereum.api.graphql.GraphQLConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.filter.FilterManager; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.filter.FilterManagerBuilder; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; @@ -164,6 +165,8 @@ public class JsonRpcTestMethodsFactory { final JsonRpcConfiguration jsonRpcConfiguration = mock(JsonRpcConfiguration.class); final WebSocketConfiguration webSocketConfiguration = mock(WebSocketConfiguration.class); final MetricsConfiguration metricsConfiguration = mock(MetricsConfiguration.class); + final GraphQLConfiguration graphQLConfiguration = mock(GraphQLConfiguration.class); + final NatService natService = new NatService(Optional.empty()); final List apis = new ArrayList<>(); @@ -200,6 +203,7 @@ public class JsonRpcTestMethodsFactory { jsonRpcConfiguration, webSocketConfiguration, metricsConfiguration, + graphQLConfiguration, natService, new HashMap<>(), dataDir, diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/NetServices.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/NetServices.java index 335a74846f..fbc3a88574 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/NetServices.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/NetServices.java @@ -14,6 +14,7 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; +import org.hyperledger.besu.ethereum.api.graphql.GraphQLConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; @@ -32,16 +33,19 @@ public class NetServices implements JsonRpcMethod { private final WebSocketConfiguration webSocketConfiguration; private final P2PNetwork p2pNetwork; private final MetricsConfiguration metricsConfiguration; + private final GraphQLConfiguration graphQLConfiguration; public NetServices( final JsonRpcConfiguration jsonRpcConfiguration, final WebSocketConfiguration webSocketConfiguration, final P2PNetwork p2pNetwork, - final MetricsConfiguration metricsConfiguration) { + final MetricsConfiguration metricsConfiguration, + final GraphQLConfiguration graphQLConfiguration) { this.jsonRpcConfiguration = jsonRpcConfiguration; this.webSocketConfiguration = webSocketConfiguration; this.p2pNetwork = p2pNetwork; this.metricsConfiguration = metricsConfiguration; + this.graphQLConfiguration = graphQLConfiguration; } @Override @@ -82,6 +86,11 @@ public class NetServices implements JsonRpcMethod { createServiceDetailsMap( metricsConfiguration.getHost(), metricsConfiguration.getActualPort())); } + if (graphQLConfiguration.isEnabled()) { + servicesMapBuilder.put( + "graphQL", + createServiceDetailsMap(graphQLConfiguration.getHost(), graphQLConfiguration.getPort())); + } return new JsonRpcSuccessResponse( requestContext.getRequest().getId(), servicesMapBuilder.build()); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/JsonRpcMethodsFactory.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/JsonRpcMethodsFactory.java index 55d9ef6029..cdf4440bde 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/JsonRpcMethodsFactory.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/JsonRpcMethodsFactory.java @@ -17,6 +17,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.methods; import org.hyperledger.besu.config.GenesisConfigOptions; import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.api.ApiConfiguration; +import org.hyperledger.besu.ethereum.api.graphql.GraphQLConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.filter.FilterManager; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; @@ -77,6 +78,7 @@ public class JsonRpcMethodsFactory { final JsonRpcConfiguration jsonRpcConfiguration, final WebSocketConfiguration webSocketConfiguration, final MetricsConfiguration metricsConfiguration, + final GraphQLConfiguration graphQLConfiguration, final NatService natService, final Map namedPlugins, final Path dataDir, @@ -135,7 +137,8 @@ public class JsonRpcMethodsFactory { networkId, jsonRpcConfiguration, webSocketConfiguration, - metricsConfiguration), + metricsConfiguration, + graphQLConfiguration), new MinerJsonRpcMethods(miningParameters, miningCoordinator), new PermJsonRpcMethods(accountsAllowlistController, nodeAllowlistController), new PrivJsonRpcMethods( diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/NetJsonRpcMethods.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/NetJsonRpcMethods.java index a3fcc318cf..9ccfc81fed 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/NetJsonRpcMethods.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/NetJsonRpcMethods.java @@ -14,6 +14,7 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.methods; +import org.hyperledger.besu.ethereum.api.graphql.GraphQLConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; @@ -37,18 +38,21 @@ public class NetJsonRpcMethods extends ApiGroupJsonRpcMethods { private final JsonRpcConfiguration jsonRpcConfiguration; private final WebSocketConfiguration webSocketConfiguration; private final MetricsConfiguration metricsConfiguration; + private final GraphQLConfiguration graphQLConfiguration; public NetJsonRpcMethods( final P2PNetwork p2pNetwork, final BigInteger networkId, final JsonRpcConfiguration jsonRpcConfiguration, final WebSocketConfiguration webSocketConfiguration, - final MetricsConfiguration metricsConfiguration) { + final MetricsConfiguration metricsConfiguration, + final GraphQLConfiguration graphQLConfiguration) { this.p2pNetwork = p2pNetwork; this.networkId = networkId; this.jsonRpcConfiguration = jsonRpcConfiguration; this.webSocketConfiguration = webSocketConfiguration; this.metricsConfiguration = metricsConfiguration; + this.graphQLConfiguration = graphQLConfiguration; } @Override @@ -64,6 +68,10 @@ public class NetJsonRpcMethods extends ApiGroupJsonRpcMethods { new NetPeerCount(p2pNetwork), new NetEnode(p2pNetwork), new NetServices( - jsonRpcConfiguration, webSocketConfiguration, p2pNetwork, metricsConfiguration)); + jsonRpcConfiguration, + webSocketConfiguration, + p2pNetwork, + metricsConfiguration, + graphQLConfiguration)); } } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/AbstractJsonRpcHttpServiceTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/AbstractJsonRpcHttpServiceTest.java index 862e17b890..d504e3bb0d 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/AbstractJsonRpcHttpServiceTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/AbstractJsonRpcHttpServiceTest.java @@ -23,6 +23,7 @@ import static org.mockito.Mockito.when; import org.hyperledger.besu.config.StubGenesisConfigOptions; import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.api.ApiConfiguration; +import org.hyperledger.besu.ethereum.api.graphql.GraphQLConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.health.HealthService; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.filter.FilterIdGenerator; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.filter.FilterManager; @@ -193,6 +194,7 @@ public abstract class AbstractJsonRpcHttpServiceTest { config, mock(WebSocketConfiguration.class), mock(MetricsConfiguration.class), + mock(GraphQLConfiguration.class), natService, new HashMap<>(), folder, diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceHostAllowlistTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceHostAllowlistTest.java index 25077bbf82..022aa24422 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceHostAllowlistTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceHostAllowlistTest.java @@ -21,6 +21,7 @@ import static org.mockito.Mockito.mock; import org.hyperledger.besu.config.StubGenesisConfigOptions; import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.api.ApiConfiguration; +import org.hyperledger.besu.ethereum.api.graphql.GraphQLConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.health.HealthService; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.filter.FilterManager; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; @@ -130,6 +131,7 @@ public class JsonRpcHttpServiceHostAllowlistTest { mock(JsonRpcConfiguration.class), mock(WebSocketConfiguration.class), mock(MetricsConfiguration.class), + mock(GraphQLConfiguration.class), natService, new HashMap<>(), folder, diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceLoginTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceLoginTest.java index eb23b054d0..f9dba0bc26 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceLoginTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceLoginTest.java @@ -23,6 +23,7 @@ import static org.mockito.Mockito.mock; import org.hyperledger.besu.config.StubGenesisConfigOptions; import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.api.ApiConfiguration; +import org.hyperledger.besu.ethereum.api.graphql.GraphQLConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.health.HealthService; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.filter.FilterManager; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.EthAccounts; @@ -161,6 +162,7 @@ public class JsonRpcHttpServiceLoginTest { mock(JsonRpcConfiguration.class), mock(WebSocketConfiguration.class), mock(MetricsConfiguration.class), + mock(GraphQLConfiguration.class), natService, new HashMap<>(), folder, diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceRpcApisTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceRpcApisTest.java index f35893490a..63ae1b8bfb 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceRpcApisTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceRpcApisTest.java @@ -24,6 +24,7 @@ import org.hyperledger.besu.cryptoservices.NodeKeyUtils; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.api.ApiConfiguration; +import org.hyperledger.besu.ethereum.api.graphql.GraphQLConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.health.HealthService; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.filter.FilterManager; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; @@ -227,6 +228,7 @@ public class JsonRpcHttpServiceRpcApisTest { mock(JsonRpcConfiguration.class), mock(WebSocketConfiguration.class), mock(MetricsConfiguration.class), + mock(GraphQLConfiguration.class), natService, new HashMap<>(), folder, @@ -337,6 +339,7 @@ public class JsonRpcHttpServiceRpcApisTest { jsonRpcConfiguration, webSocketConfiguration, metricsConfiguration, + mock(GraphQLConfiguration.class), natService, new HashMap<>(), folder, diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTestBase.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTestBase.java index 5e5dc36bb0..5a439fa194 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTestBase.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTestBase.java @@ -19,6 +19,7 @@ import static org.mockito.Mockito.mock; import org.hyperledger.besu.config.StubGenesisConfigOptions; import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.api.ApiConfiguration; +import org.hyperledger.besu.ethereum.api.graphql.GraphQLConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.health.HealthService; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.filter.FilterManager; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; @@ -139,6 +140,7 @@ public class JsonRpcHttpServiceTestBase { mock(JsonRpcConfiguration.class), mock(WebSocketConfiguration.class), mock(MetricsConfiguration.class), + mock(GraphQLConfiguration.class), natService, new HashMap<>(), folder, diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsClientAuthTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsClientAuthTest.java index 5cf13a4576..28474d3c53 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsClientAuthTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsClientAuthTest.java @@ -25,6 +25,7 @@ import static org.mockito.Mockito.mock; import org.hyperledger.besu.config.StubGenesisConfigOptions; import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.api.ApiConfiguration; +import org.hyperledger.besu.ethereum.api.graphql.GraphQLConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.health.HealthService; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.filter.FilterManager; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; @@ -144,6 +145,7 @@ public class JsonRpcHttpServiceTlsClientAuthTest { mock(JsonRpcConfiguration.class), mock(WebSocketConfiguration.class), mock(MetricsConfiguration.class), + mock(GraphQLConfiguration.class), natService, Collections.emptyMap(), folder, diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsMisconfigurationTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsMisconfigurationTest.java index c2661141a4..15df60230b 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsMisconfigurationTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsMisconfigurationTest.java @@ -24,6 +24,7 @@ import static org.mockito.Mockito.mock; import org.hyperledger.besu.config.StubGenesisConfigOptions; import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.api.ApiConfiguration; +import org.hyperledger.besu.ethereum.api.graphql.GraphQLConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.health.HealthService; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.filter.FilterManager; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; @@ -132,6 +133,7 @@ class JsonRpcHttpServiceTlsMisconfigurationTest { mock(JsonRpcConfiguration.class), mock(WebSocketConfiguration.class), mock(MetricsConfiguration.class), + mock(GraphQLConfiguration.class), natService, Collections.emptyMap(), tempDir.getRoot(), diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsTest.java index c0846ed9f2..6f7ce4e1d6 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsTest.java @@ -24,6 +24,7 @@ import static org.mockito.Mockito.mock; import org.hyperledger.besu.config.StubGenesisConfigOptions; import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.api.ApiConfiguration; +import org.hyperledger.besu.ethereum.api.graphql.GraphQLConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.health.HealthService; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.filter.FilterManager; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; @@ -133,6 +134,7 @@ public class JsonRpcHttpServiceTlsTest { mock(JsonRpcConfiguration.class), mock(WebSocketConfiguration.class), mock(MetricsConfiguration.class), + mock(GraphQLConfiguration.class), natService, Collections.emptyMap(), folder, diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/WebSocketServiceLoginTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/WebSocketServiceLoginTest.java index 342941d0e9..47a16135ff 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/WebSocketServiceLoginTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/websocket/WebSocketServiceLoginTest.java @@ -26,6 +26,7 @@ import static org.mockito.Mockito.spy; import org.hyperledger.besu.config.StubGenesisConfigOptions; import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.api.ApiConfiguration; +import org.hyperledger.besu.ethereum.api.graphql.GraphQLConfiguration; import org.hyperledger.besu.ethereum.api.handlers.TimeoutOptions; import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcHttpService; @@ -197,6 +198,7 @@ public class WebSocketServiceLoginTest { mock(JsonRpcConfiguration.class), mock(WebSocketConfiguration.class), mock(MetricsConfiguration.class), + mock(GraphQLConfiguration.class), natService, new HashMap<>(), folder, From 89dfa958607e362ee550cc8b948f93bdf13904ff Mon Sep 17 00:00:00 2001 From: Sally MacFarlane Date: Mon, 16 Sep 2024 13:26:14 +1000 Subject: [PATCH 211/259] [CHANGELOG] upcoming breaking change for k8s nat (#7534) * upcoming breaking change for k8s nat * log warning if deprecated NAT method used Signed-off-by: Sally MacFarlane --------- Signed-off-by: Sally MacFarlane --- CHANGELOG.md | 1 + .../main/java/org/hyperledger/besu/cli/BesuCommand.java | 7 +++++++ nat/src/main/java/org/hyperledger/besu/nat/NatMethod.java | 2 +- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1da225c56c..c241838637 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## [Unreleased] ### Upcoming Breaking Changes +- k8s (KUBERNETES) Nat method is now deprecated and will be removed in a future release ### Breaking Changes 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 f79ef45b99..ecfc0eaadb 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java @@ -1568,6 +1568,13 @@ public class BesuCommand implements DefaultCommandValues, Runnable { @SuppressWarnings("ConstantConditions") private void validateNatParams() { + if (natMethod.equals(NatMethod.KUBERNETES)) { + logger.warn("Kubernetes NAT method is deprecated. Please use Docker or UPNP"); + } + if (!unstableNatOptions.getNatManagerServiceName().equals(DEFAULT_BESU_SERVICE_NAME_FILTER)) { + logger.warn( + "`--Xnat-kube-service-name` and Kubernetes NAT method are deprecated. Please use Docker or UPNP"); + } if (!(natMethod.equals(NatMethod.AUTO) || natMethod.equals(NatMethod.KUBERNETES)) && !unstableNatOptions .getNatManagerServiceName() diff --git a/nat/src/main/java/org/hyperledger/besu/nat/NatMethod.java b/nat/src/main/java/org/hyperledger/besu/nat/NatMethod.java index bbd1c02c40..ed7d46a712 100644 --- a/nat/src/main/java/org/hyperledger/besu/nat/NatMethod.java +++ b/nat/src/main/java/org/hyperledger/besu/nat/NatMethod.java @@ -18,7 +18,7 @@ package org.hyperledger.besu.nat; public enum NatMethod { /** Upnp nat method. */ UPNP, - /** Upnpp 2 ponly nat method. */ + /** Upnp p2p only nat method. */ UPNPP2PONLY, /** Docker nat method. */ DOCKER, From 33085dd2331d137bb846d2d16833341b3dec53eb Mon Sep 17 00:00:00 2001 From: Fabio Di Fabio Date: Wed, 18 Sep 2024 05:35:06 +0200 Subject: [PATCH 212/259] Fix flakiness ofTxPoolOptionsTest::txpoolForcePriceBumpToZeroWhenZeroBaseFeeMarket (#7610) Signed-off-by: Fabio Di Fabio --- .../hyperledger/besu/cli/CommandTestAbstract.java | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) 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 3dd9641b48..7d11a4a8e9 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/CommandTestAbstract.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/CommandTestAbstract.java @@ -24,7 +24,6 @@ import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.atLeast; -import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -43,7 +42,6 @@ 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; import org.hyperledger.besu.config.GenesisConfigOptions; import org.hyperledger.besu.controller.BesuController; import org.hyperledger.besu.controller.BesuControllerBuilder; @@ -256,10 +254,8 @@ public abstract class CommandTestAbstract { @BeforeEach public void initMocks() throws Exception { - // doReturn used because of generic BesuController - doReturn(mockControllerBuilder) - .when(mockControllerBuilderFactory) - .fromEthNetworkConfig(any(), any()); + when(mockControllerBuilderFactory.fromEthNetworkConfig(any(), any())) + .thenReturn(mockControllerBuilder); when(mockControllerBuilder.synchronizerConfiguration(any())).thenReturn(mockControllerBuilder); when(mockControllerBuilder.ethProtocolConfiguration(any())).thenReturn(mockControllerBuilder); when(mockControllerBuilder.transactionPoolConfiguration(any())) @@ -288,14 +284,12 @@ public abstract class CommandTestAbstract { when(mockControllerBuilder.maxPeers(anyInt())).thenReturn(mockControllerBuilder); when(mockControllerBuilder.maxRemotelyInitiatedPeers(anyInt())) .thenReturn(mockControllerBuilder); - when(mockControllerBuilder.besuComponent(any(BesuComponent.class))) - .thenReturn(mockControllerBuilder); + when(mockControllerBuilder.besuComponent(any())).thenReturn(mockControllerBuilder); when(mockControllerBuilder.cacheLastBlocks(any())).thenReturn(mockControllerBuilder); when(mockControllerBuilder.genesisStateHashCacheEnabled(any())) .thenReturn(mockControllerBuilder); - // doReturn used because of generic BesuController - doReturn(mockController).when(mockControllerBuilder).build(); + when(mockControllerBuilder.build()).thenReturn(mockController); lenient().when(mockController.getProtocolManager()).thenReturn(mockEthProtocolManager); lenient().when(mockController.getProtocolSchedule()).thenReturn(mockProtocolSchedule); lenient().when(mockController.getProtocolContext()).thenReturn(mockProtocolContext); From 578104e222619eedcf90740b8b1176b10c7ce165 Mon Sep 17 00:00:00 2001 From: Gabriel-Trintinalia Date: Wed, 18 Sep 2024 15:20:14 +1000 Subject: [PATCH 213/259] Fix Snap Server Account Range tests (#7552) Signed-off-by: Gabriel-Trintinalia --- .../ethereum/core/BlockchainSetupUtil.java | 21 +- .../ethereum/eth/manager/snap/SnapServer.java | 18 +- .../messages/snap/AccountRangeMessage.java | 25 +- .../messages/snap/GetAccountRangeMessage.java | 12 +- .../snap/SnapServerGetAccountRangeTest.java | 495 ++++++++++++++++++ .../eth/manager/snap/SnapServerTest.java | 2 +- .../snap/AccountRangeMessageTest.java | 83 ++- .../besu/testutil/BlockTestUtil.java | 20 + .../src/main/resources/snap/snapGenesis.json | 111 ++++ .../main/resources/snap/testBlockchain.blocks | Bin 0 -> 342468 bytes 10 files changed, 772 insertions(+), 15 deletions(-) create mode 100644 ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/snap/SnapServerGetAccountRangeTest.java create mode 100644 testutil/src/main/resources/snap/snapGenesis.json create mode 100644 testutil/src/main/resources/snap/testBlockchain.blocks 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 551f593e82..62d670c07a 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 @@ -85,6 +85,13 @@ public class BlockchainSetupUtil { return blockchain; } + public Blockchain importAllBlocks( + final HeaderValidationMode headerValidationMode, + final HeaderValidationMode ommerValidationMode) { + importBlocks(blocks, headerValidationMode, ommerValidationMode); + return blockchain; + } + public void importFirstBlocks(final int count) { importBlocks(blocks.subList(0, count)); } @@ -126,6 +133,10 @@ public class BlockchainSetupUtil { return createForEthashChain(BlockTestUtil.getUpgradedForkResources(), DataStorageFormat.FOREST); } + public static BlockchainSetupUtil forSnapTesting(final DataStorageFormat storageFormat) { + return createForEthashChain(BlockTestUtil.getSnapTestChainResources(), storageFormat); + } + public static BlockchainSetupUtil createForEthashChain( final ChainResources chainResources, final DataStorageFormat storageFormat) { return create( @@ -241,6 +252,13 @@ public class BlockchainSetupUtil { } private void importBlocks(final List blocks) { + importBlocks(blocks, HeaderValidationMode.FULL, HeaderValidationMode.FULL); + } + + private void importBlocks( + final List blocks, + final HeaderValidationMode headerValidationMode, + final HeaderValidationMode ommerValidationMode) { for (final Block block : blocks) { if (block.getHeader().getNumber() == BlockHeader.GENESIS_BLOCK_NUMBER) { continue; @@ -248,7 +266,8 @@ public class BlockchainSetupUtil { final ProtocolSpec protocolSpec = protocolSchedule.getByBlockHeader(block.getHeader()); final BlockImporter blockImporter = protocolSpec.getBlockImporter(); final BlockImportResult result = - blockImporter.importBlock(protocolContext, block, HeaderValidationMode.FULL); + blockImporter.importBlock( + protocolContext, block, headerValidationMode, ommerValidationMode); if (!result.isImported()) { throw new IllegalStateException("Unable to import block " + block.getHeader().getNumber()); } 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 c1b855f2d6..7de933e137 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 @@ -31,6 +31,7 @@ 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; import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; +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.BonsaiWorldStateProvider; @@ -240,12 +241,9 @@ class SnapServer implements BesuEvents.InitialSyncCompletionListener { stopWatch, maxResponseBytes, (pair) -> { - var rlpOutput = new BytesValueRLPOutput(); - rlpOutput.startList(); - rlpOutput.writeBytes(pair.getFirst()); - rlpOutput.writeRLPBytes(pair.getSecond()); - rlpOutput.endList(); - return rlpOutput.encodedSize(); + Bytes bytes = + AccountRangeMessage.toSlimAccount(RLP.input(pair.getSecond())); + return Hash.SIZE + bytes.size(); }); final Bytes32 endKeyBytes = range.endKeyHash(); @@ -257,11 +255,15 @@ class SnapServer implements BesuEvents.InitialSyncCompletionListener { storage.streamFlatAccounts(range.startKeyHash(), shouldContinuePredicate); if (accounts.isEmpty() && shouldContinuePredicate.shouldContinue.get()) { + var fromNextHash = + range.endKeyHash().compareTo(range.startKeyHash()) >= 0 + ? range.endKeyHash() + : range.startKeyHash(); // fetch next account after range, if it exists LOGGER.debug( "found no accounts in range, taking first value starting from {}", - asLogHash(range.endKeyHash())); - accounts = storage.streamFlatAccounts(range.endKeyHash(), UInt256.MAX_VALUE, 1L); + asLogHash(fromNextHash)); + accounts = storage.streamFlatAccounts(fromNextHash, UInt256.MAX_VALUE, 1L); } final var worldStateProof = diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/messages/snap/AccountRangeMessage.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/messages/snap/AccountRangeMessage.java index 8e1b1a31a5..71d0429592 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/messages/snap/AccountRangeMessage.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/messages/snap/AccountRangeMessage.java @@ -14,6 +14,7 @@ */ package org.hyperledger.besu.ethereum.eth.messages.snap; +import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.AbstractSnapMessageData; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.MessageData; import org.hyperledger.besu.ethereum.rlp.BytesValueRLPInput; @@ -28,6 +29,7 @@ import java.util.NavigableMap; import java.util.Optional; import java.util.TreeMap; +import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.Maps; import kotlin.collections.ArrayDeque; import org.apache.tuweni.bytes.Bytes; @@ -117,7 +119,8 @@ public final class AccountRangeMessage extends AbstractSnapMessageData { return ImmutableAccountRangeData.builder().accounts(accounts).proofs(proofs).build(); } - private Bytes toFullAccount(final RLPInput rlpInput) { + @VisibleForTesting + public static Bytes toFullAccount(final RLPInput rlpInput) { final StateTrieAccountValue accountValue = StateTrieAccountValue.readFrom(rlpInput); final BytesValueRLPOutput rlpOutput = new BytesValueRLPOutput(); @@ -131,6 +134,26 @@ public final class AccountRangeMessage extends AbstractSnapMessageData { return rlpOutput.encoded(); } + public static Bytes toSlimAccount(final RLPInput rlpInput) { + StateTrieAccountValue accountValue = StateTrieAccountValue.readFrom(rlpInput); + var rlpOutput = new BytesValueRLPOutput(); + rlpOutput.startList(); + rlpOutput.writeLongScalar(accountValue.getNonce()); + rlpOutput.writeUInt256Scalar(accountValue.getBalance()); + if (accountValue.getStorageRoot().equals(Hash.EMPTY_TRIE_HASH)) { + rlpOutput.writeNull(); + } else { + rlpOutput.writeBytes(accountValue.getStorageRoot()); + } + if (accountValue.getCodeHash().equals(Hash.EMPTY)) { + rlpOutput.writeNull(); + } else { + rlpOutput.writeBytes(accountValue.getCodeHash()); + } + rlpOutput.endList(); + return rlpOutput.encoded(); + } + @Value.Immutable public interface AccountRangeData { diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/messages/snap/GetAccountRangeMessage.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/messages/snap/GetAccountRangeMessage.java index 8f5fcaf9a7..6d8c8c128c 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/messages/snap/GetAccountRangeMessage.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/messages/snap/GetAccountRangeMessage.java @@ -24,6 +24,7 @@ import org.hyperledger.besu.ethereum.rlp.RLPInput; import java.math.BigInteger; import java.util.Optional; +import com.google.common.annotations.VisibleForTesting; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; import org.immutables.value.Value; @@ -48,12 +49,21 @@ public final class GetAccountRangeMessage extends AbstractSnapMessageData { public static GetAccountRangeMessage create( final Hash worldStateRootHash, final Bytes32 startKeyHash, final Bytes32 endKeyHash) { + return create(worldStateRootHash, startKeyHash, endKeyHash, SIZE_REQUEST); + } + + @VisibleForTesting + public static GetAccountRangeMessage create( + final Hash worldStateRootHash, + final Bytes32 startKeyHash, + final Bytes32 endKeyHash, + final BigInteger sizeRequest) { final BytesValueRLPOutput tmp = new BytesValueRLPOutput(); tmp.startList(); tmp.writeBytes(worldStateRootHash); tmp.writeBytes(startKeyHash); tmp.writeBytes(endKeyHash); - tmp.writeBigIntegerScalar(SIZE_REQUEST); + tmp.writeBigIntegerScalar(sizeRequest); tmp.endList(); return new GetAccountRangeMessage(tmp.encoded()); } diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/snap/SnapServerGetAccountRangeTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/snap/SnapServerGetAccountRangeTest.java new file mode 100644 index 0000000000..6d8180c8c0 --- /dev/null +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/snap/SnapServerGetAccountRangeTest.java @@ -0,0 +1,495 @@ +/* + * 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.snap; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + +import org.hyperledger.besu.datatypes.Hash; +import org.hyperledger.besu.ethereum.ProtocolContext; +import org.hyperledger.besu.ethereum.core.BlockchainSetupUtil; +import org.hyperledger.besu.ethereum.eth.manager.EthMessages; +import org.hyperledger.besu.ethereum.eth.messages.snap.AccountRangeMessage; +import org.hyperledger.besu.ethereum.eth.messages.snap.GetAccountRangeMessage; +import org.hyperledger.besu.ethereum.eth.sync.snapsync.ImmutableSnapSyncConfiguration; +import org.hyperledger.besu.ethereum.eth.sync.snapsync.SnapSyncConfiguration; +import org.hyperledger.besu.ethereum.mainnet.HeaderValidationMode; +import org.hyperledger.besu.ethereum.trie.diffbased.common.DiffBasedWorldStateProvider; +import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator; +import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; + +import java.math.BigInteger; +import java.util.NavigableMap; + +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class SnapServerGetAccountRangeTest { + private Hash rootHash; + public Bytes32 firstAccount; + public Bytes32 secondAccount; + private SnapServer snapServer; + private static ProtocolContext protocolContext; + + @BeforeAll + public static void setup() { + // Setup local blockchain for testing + BlockchainSetupUtil localBlockchainSetup = + BlockchainSetupUtil.forSnapTesting(DataStorageFormat.BONSAI); + localBlockchainSetup.importAllBlocks( + HeaderValidationMode.LIGHT_DETACHED_ONLY, HeaderValidationMode.LIGHT); + + protocolContext = localBlockchainSetup.getProtocolContext(); + } + + @BeforeEach + public void setupTest() { + WorldStateStorageCoordinator worldStateStorageCoordinator = + new WorldStateStorageCoordinator( + ((DiffBasedWorldStateProvider) protocolContext.getWorldStateArchive()) + .getWorldStateKeyValueStorage()); + + SnapSyncConfiguration snapSyncConfiguration = + ImmutableSnapSyncConfiguration.builder().isSnapServerEnabled(true).build(); + snapServer = + new SnapServer( + snapSyncConfiguration, + new EthMessages(), + worldStateStorageCoordinator, + protocolContext) + .start(); + initAccounts(); + } + + /** + * In this test, we request the entire state range, but limit the response to 4000 bytes. + * Expected: 86 accounts. + */ + @Test + public void test0_RequestEntireStateRangeWith4000BytesLimit() { + testAccountRangeRequest( + new AccountRangeRequestParams.Builder() + .rootHash(rootHash) + .responseBytes(4000) + .expectedAccounts(86) + .expectedFirstAccount(firstAccount) + .expectedLastAccount( + Bytes32.fromHexString( + "0x445cb5c1278fdce2f9cbdb681bdd76c52f8e50e41dbd9e220242a69ba99ac099")) + .build()); + } + + /** + * In this test, we request the entire state range, but limit the response to 3000 bytes. + * Expected: 65 accounts. + */ + @Test + public void test1_RequestEntireStateRangeWith3000BytesLimit() { + testAccountRangeRequest( + new AccountRangeRequestParams.Builder() + .rootHash(rootHash) + .responseBytes(3000) + .expectedAccounts(65) + .expectedFirstAccount(firstAccount) + .expectedLastAccount( + Bytes32.fromHexString( + "0x2e6fe1362b3e388184fd7bf08e99e74170b26361624ffd1c5f646da7067b58b6")) + .build()); + } + + /** + * In this test, we request the entire state range, but limit the response to 2000 bytes. + * Expected: 44 accounts. + */ + @Test + public void test2_RequestEntireStateRangeWith2000BytesLimit() { + testAccountRangeRequest( + new AccountRangeRequestParams.Builder() + .rootHash(rootHash) + .responseBytes(2000) + .expectedAccounts(44) + .expectedFirstAccount(firstAccount) + .expectedLastAccount( + Bytes32.fromHexString( + "0x1c3f74249a4892081ba0634a819aec9ed25f34c7653f5719b9098487e65ab595")) + .build()); + } + + /** + * In this test, we request the entire state range, but limit the response to 1 byte. The server + * should return the first account of the state. Expected: 1 account. + */ + @Test + public void test3_RequestEntireStateRangeWith1ByteLimit() { + testAccountRangeRequest( + new AccountRangeRequestParams.Builder() + .rootHash(rootHash) + .responseBytes(1) + .expectedAccounts(1) + .expectedFirstAccount(firstAccount) + .expectedLastAccount(firstAccount) + .build()); + } + + /** + * Here we request with a responseBytes limit of zero. The server should return one account. + * Expected: 1 account. + */ + @Test + public void test4_RequestEntireStateRangeWithZeroBytesLimit() { + testAccountRangeRequest( + new AccountRangeRequestParams.Builder() + .rootHash(rootHash) + .responseBytes(0) + .expectedAccounts(1) + .expectedFirstAccount(firstAccount) + .expectedLastAccount(firstAccount) + .build()); + } + + /** + * In this test, we request a range where startingHash is before the first available account key, + * and limitHash is after. The server should return the first and second account of the state + * (because the second account is the 'next available'). Expected: 2 accounts. + */ + @Test + public void test5_RequestRangeBeforeFirstAccountKey() { + testAccountRangeRequest( + new AccountRangeRequestParams.Builder() + .rootHash(rootHash) + .startHash(hashAdd(firstAccount, -500)) + .limitHash(hashAdd(firstAccount, 1)) + .expectedAccounts(2) + .expectedFirstAccount(firstAccount) + .expectedLastAccount(secondAccount) + .build()); + } + + /** + * Here we request range where both bounds are before the first available account key. This should + * return the first account (even though it's out of bounds). Expected: 1 account. + */ + @Test + public void test6_RequestRangeBothBoundsBeforeFirstAccountKey() { + testAccountRangeRequest( + new AccountRangeRequestParams.Builder() + .rootHash(rootHash) + .startHash(hashAdd(firstAccount, -500)) + .limitHash(hashAdd(firstAccount, -400)) + .expectedAccounts(1) + .expectedFirstAccount(firstAccount) + .expectedLastAccount(firstAccount) + .build()); + } + + /** + * In this test, both startingHash and limitHash are zero. The server should return the first + * available account. Expected: 1 account. + */ + @Test + public void test7_RequestBothBoundsZero() { + testAccountRangeRequest( + new AccountRangeRequestParams.Builder() + .rootHash(rootHash) + .startHash(Hash.ZERO) + .limitHash(Hash.ZERO) + .expectedAccounts(1) + .expectedFirstAccount(firstAccount) + .expectedLastAccount(firstAccount) + .build()); + } + + /** + * In this test, startingHash is exactly the first available account key. The server should return + * the first available account of the state as the first item. Expected: 86 accounts. + */ + @Test + public void test8_RequestStartingHashFirstAvailableAccountKey() { + testAccountRangeRequest( + new AccountRangeRequestParams.Builder() + .rootHash(rootHash) + .startHash(firstAccount) + .responseBytes(4000) + .expectedAccounts(86) + .expectedFirstAccount(firstAccount) + .expectedLastAccount( + Bytes32.fromHexString( + "0x445cb5c1278fdce2f9cbdb681bdd76c52f8e50e41dbd9e220242a69ba99ac099")) + .build()); + } + + /** + * In this test, startingHash is after the first available key. The server should return the + * second account of the state as the first item. Expected: 86 accounts. + */ + @Test + public void test9_RequestStartingHashAfterFirstAvailableKey() { + testAccountRangeRequest( + new AccountRangeRequestParams.Builder() + .rootHash(rootHash) + .startHash(secondAccount) + .responseBytes(4000) + .expectedAccounts(86) + .expectedFirstAccount(secondAccount) + .expectedLastAccount( + Bytes32.fromHexString( + "0x4615e5f5df5b25349a00ad313c6cd0436b6c08ee5826e33a018661997f85ebaa")) + .build()); + } + + /** This test requests a non-existent state root. Expected: 0 accounts. */ + @Test + public void test10_RequestNonExistentStateRoot() { + Hash rootHash = + Hash.fromHexString("1337000000000000000000000000000000000000000000000000000000000000"); + testAccountRangeRequest( + new AccountRangeRequestParams.Builder().rootHash(rootHash).expectedAccounts(0).build()); + } + + /** + * This test requests data at a state root that is 127 blocks old. We expect the server to have + * this state available. Expected: 84 accounts. + */ + @Test + public void test12_RequestStateRoot127BlocksOld() { + + Hash rootHash = + protocolContext + .getBlockchain() + .getBlockHeader((protocolContext.getBlockchain().getChainHeadBlockNumber() - 127)) + .orElseThrow() + .getStateRoot(); + testAccountRangeRequest( + new AccountRangeRequestParams.Builder() + .rootHash(rootHash) + .expectedAccounts(84) + .responseBytes(4000) + .expectedFirstAccount(firstAccount) + .expectedLastAccount( + Bytes32.fromHexString( + "0x580aa878e2f92d113a12c0a3ce3c21972b03dbe80786858d49a72097e2c491a3")) + .build()); + } + + /** + * This test requests data at a state root that is actually the storage root of an existing + * account. The server is supposed to ignore this request. Expected: 0 accounts. + */ + @Test + public void test13_RequestStateRootIsStorageRoot() { + Hash rootHash = + Hash.fromHexString("df97f94bc47471870606f626fb7a0b42eed2d45fcc84dc1200ce62f7831da990"); + testAccountRangeRequest( + new AccountRangeRequestParams.Builder().rootHash(rootHash).expectedAccounts(0).build()); + } + + /** + * In this test, the startingHash is after limitHash (wrong order). The server should ignore this + * invalid request. Expected: 0 accounts. + */ + @Test + public void test14_RequestStartingHashAfterLimitHash() { + testAccountRangeRequest( + new AccountRangeRequestParams.Builder() + .rootHash(rootHash) + .startHash(Hash.LAST) + .limitHash(Hash.ZERO) + .expectedAccounts(0) + .build()); + } + + /** + * In this test, the startingHash is the first available key, and limitHash is a key before + * startingHash (wrong order). The server should return the first available key. Expected: 1 + * account. + */ + @Test + public void test15_RequestStartingHashFirstAvailableKeyAndLimitHashBefore() { + testAccountRangeRequest( + new AccountRangeRequestParams.Builder() + .rootHash(rootHash) + .startHash(firstAccount) + .limitHash(hashAdd(firstAccount, -1)) + .expectedAccounts(1) + .expectedFirstAccount(firstAccount) + .expectedLastAccount(firstAccount) + .build()); + } + + /** + * In this test, the startingHash is the first available key and limitHash is zero. (wrong order). + * The server should return the first available key. Expected: 1 account. + */ + @Test + public void test16_RequestStartingHashFirstAvailableKeyAndLimitHashZero() { + testAccountRangeRequest( + new AccountRangeRequestParams.Builder() + .rootHash(rootHash) + .startHash(firstAccount) + .limitHash(Hash.ZERO) + .expectedAccounts(1) + .expectedFirstAccount(firstAccount) + .expectedLastAccount(firstAccount) + .build()); + } + + private void testAccountRangeRequest(final AccountRangeRequestParams params) { + NavigableMap accounts = getAccountRange(params); + assertThat(accounts.size()).isEqualTo(params.getExpectedAccounts()); + + if (params.getExpectedAccounts() > 0) { + assertThat(accounts.firstKey()).isEqualTo(params.getExpectedFirstAccount()); + assertThat(accounts.lastKey()).isEqualTo(params.getExpectedLastAccount()); + } + } + + private NavigableMap getAccountRange(final AccountRangeRequestParams params) { + Hash rootHash = params.getRootHash(); + Bytes32 startHash = params.getStartHash(); + Bytes32 limitHash = params.getLimitHash(); + BigInteger sizeRequest = BigInteger.valueOf(params.getResponseBytes()); + + GetAccountRangeMessage requestMessage = + GetAccountRangeMessage.create(rootHash, startHash, limitHash, sizeRequest); + + AccountRangeMessage resultMessage = + AccountRangeMessage.readFrom( + snapServer.constructGetAccountRangeResponse( + requestMessage.wrapMessageData(BigInteger.ONE))); + NavigableMap accounts = resultMessage.accountData(false).accounts(); + return accounts; + } + + @SuppressWarnings("UnusedVariable") + private void initAccounts() { + rootHash = protocolContext.getWorldStateArchive().getMutable().rootHash(); + GetAccountRangeMessage requestMessage = + GetAccountRangeMessage.create(rootHash, Hash.ZERO, Hash.LAST, BigInteger.valueOf(4000)); + AccountRangeMessage resultMessage = + AccountRangeMessage.readFrom( + snapServer.constructGetAccountRangeResponse( + requestMessage.wrapMessageData(BigInteger.ONE))); + NavigableMap accounts = resultMessage.accountData(false).accounts(); + firstAccount = accounts.firstEntry().getKey(); + secondAccount = + accounts.entrySet().stream().skip(1).findFirst().orElse(accounts.firstEntry()).getKey(); + } + + private Bytes32 hashAdd(final Bytes32 hash, final int value) { + var result = Hash.wrap(hash).toBigInteger().add(BigInteger.valueOf(value)); + Bytes resultBytes = Bytes.wrap(result.toByteArray()); + return Bytes32.leftPad(resultBytes); + } + + public static class AccountRangeRequestParams { + private final Hash rootHash; + private final Bytes32 startHash; + private final Bytes32 limitHash; + private final int responseBytes; + private final int expectedAccounts; + private final Bytes32 expectedFirstAccount; + private final Bytes32 expectedLastAccount; + + private AccountRangeRequestParams(final Builder builder) { + this.rootHash = builder.rootHash; + this.startHash = builder.startHash; + this.limitHash = builder.limitHash; + this.responseBytes = builder.responseBytes; + this.expectedAccounts = builder.expectedAccounts; + this.expectedFirstAccount = builder.expectedFirstAccount; + this.expectedLastAccount = builder.expectedLastAccount; + } + + public static class Builder { + private Hash rootHash = null; + private Bytes32 startHash = Bytes32.ZERO; + private Bytes32 limitHash = Hash.LAST; + private int responseBytes = Integer.MAX_VALUE; + private int expectedAccounts = 0; + private Bytes32 expectedFirstAccount = null; + private Bytes32 expectedLastAccount = null; + + public Builder rootHash(final Hash rootHashHex) { + this.rootHash = rootHashHex; + return this; + } + + public Builder startHash(final Bytes32 startHashHex) { + this.startHash = startHashHex; + return this; + } + + public Builder limitHash(final Bytes32 limitHashHex) { + this.limitHash = limitHashHex; + return this; + } + + public Builder responseBytes(final int responseBytes) { + this.responseBytes = responseBytes; + return this; + } + + public Builder expectedAccounts(final int expectedAccounts) { + this.expectedAccounts = expectedAccounts; + return this; + } + + public Builder expectedFirstAccount(final Bytes32 expectedFirstAccount) { + this.expectedFirstAccount = expectedFirstAccount; + return this; + } + + public Builder expectedLastAccount(final Bytes32 expectedLastAccount) { + this.expectedLastAccount = expectedLastAccount; + return this; + } + + public AccountRangeRequestParams build() { + return new AccountRangeRequestParams(this); + } + } + + // Getters for each field + public Hash getRootHash() { + return rootHash; + } + + public Bytes32 getStartHash() { + return startHash; + } + + public Bytes32 getLimitHash() { + return limitHash; + } + + public int getResponseBytes() { + return responseBytes; + } + + public int getExpectedAccounts() { + return expectedAccounts; + } + + public Bytes32 getExpectedFirstAccount() { + return expectedFirstAccount; + } + + public Bytes32 getExpectedLastAccount() { + return expectedLastAccount; + } + } +} 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 a41da1ef6b..e168b7e2fe 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 @@ -188,7 +188,7 @@ public class SnapServerTest { public void assertAccountLimitRangeResponse() { // assert we limit the range response according to size final int acctCount = 2000; - final long acctRLPSize = 105; + final long acctRLPSize = 37; List randomLoad = IntStream.range(1, 4096).boxed().collect(Collectors.toList()); Collections.shuffle(randomLoad); diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/messages/snap/AccountRangeMessageTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/messages/snap/AccountRangeMessageTest.java index bd715b6459..c7e5bf74c4 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/messages/snap/AccountRangeMessageTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/messages/snap/AccountRangeMessageTest.java @@ -14,11 +14,15 @@ */ package org.hyperledger.besu.ethereum.eth.messages.snap; +import static org.assertj.core.api.Assertions.assertThat; + import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.MessageData; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.RawMessage; +import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; import org.hyperledger.besu.ethereum.rlp.RLP; +import org.hyperledger.besu.ethereum.rlp.RLPInput; import org.hyperledger.besu.ethereum.worldstate.StateTrieAccountValue; import java.util.ArrayList; @@ -28,7 +32,6 @@ import java.util.Map; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; -import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; public final class AccountRangeMessageTest { @@ -51,7 +54,81 @@ public final class AccountRangeMessageTest { // check match originals. final AccountRangeMessage.AccountRangeData range = message.accountData(false); - Assertions.assertThat(range.accounts()).isEqualTo(keys); - Assertions.assertThat(range.proofs()).isEqualTo(proofs); + assertThat(range.accounts()).isEqualTo(keys); + assertThat(range.proofs()).isEqualTo(proofs); + } + + @Test + public void toSlimAccountTest() { + // Initialize nonce and balance + long nonce = 1L; + Wei balance = Wei.of(2L); + + // Create a StateTrieAccountValue with the given nonce and balance + final StateTrieAccountValue accountValue = + new StateTrieAccountValue(nonce, balance, Hash.EMPTY_TRIE_HASH, Hash.EMPTY); + + // Encode the account value to RLP + final BytesValueRLPOutput rlpOut = new BytesValueRLPOutput(); + accountValue.writeTo(rlpOut); + + // Convert the encoded account value to a slim account representation + Bytes slimAccount = AccountRangeMessage.toSlimAccount(RLP.input(rlpOut.encoded())); + + // Read the slim account RLP input + RLPInput in = RLP.input(slimAccount); + in.enterList(); + + // Verify the nonce and balance + final long expectedNonce = in.readLongScalar(); + final Wei expectedWei = Wei.of(in.readUInt256Scalar()); + assertThat(expectedNonce).isEqualTo(nonce); + assertThat(expectedWei).isEqualTo(balance); + + // Check that the storageRoot is empty + assertThat(in.nextIsNull()).isTrue(); + in.skipNext(); + + // Check that the codeHash is empty + assertThat(in.nextIsNull()).isTrue(); + in.skipNext(); + + // Exit the list + in.leaveList(); + } + + @Test + public void toFullAccountTest() { + // Initialize nonce and balance + long nonce = 1L; + Wei balance = Wei.of(2L); + + // Create a StateTrieAccountValue with the given nonce and balance + final StateTrieAccountValue accountValue = + new StateTrieAccountValue(nonce, balance, Hash.EMPTY_TRIE_HASH, Hash.EMPTY); + + // Encode the account value to RLP + final BytesValueRLPOutput rlpOut = new BytesValueRLPOutput(); + accountValue.writeTo(rlpOut); + + // Convert the encoded account value to a full account representation + Bytes fullAccount = AccountRangeMessage.toFullAccount(RLP.input(rlpOut.encoded())); + + // Read the full account RLP input + RLPInput in = RLP.input(fullAccount); + in.enterList(); + + // Verify the nonce and balance + final long expectedNonce = in.readLongScalar(); + final Wei expectedWei = Wei.of(in.readUInt256Scalar()); + assertThat(expectedNonce).isEqualTo(nonce); + assertThat(expectedWei).isEqualTo(balance); + + // Verify the storageRoot and codeHash + assertThat(in.readBytes32()).isEqualTo(Hash.EMPTY_TRIE_HASH); + assertThat(in.readBytes32()).isEqualTo(Hash.EMPTY); + + // Exit the list + in.leaveList(); } } diff --git a/testutil/src/main/java/org/hyperledger/besu/testutil/BlockTestUtil.java b/testutil/src/main/java/org/hyperledger/besu/testutil/BlockTestUtil.java index 9f31283bfc..4c45d3cf74 100644 --- a/testutil/src/main/java/org/hyperledger/besu/testutil/BlockTestUtil.java +++ b/testutil/src/main/java/org/hyperledger/besu/testutil/BlockTestUtil.java @@ -52,6 +52,8 @@ public final class BlockTestUtil { Suppliers.memoize(BlockTestUtil::supplyUpgradedForkResources); private static final Supplier testRpcCompactChainSupplier = Suppliers.memoize(BlockTestUtil::supplyTestRpcCompactResources); + private static final Supplier snapTestChainSupplier = + Suppliers.memoize(BlockTestUtil::supplySnapTestChainResources); /** * Gets test blockchain url. @@ -156,6 +158,15 @@ public final class BlockTestUtil { return testRpcCompactChainSupplier.get(); } + /** + * Gets test chain resources for Snap tests. + * + * @return the test chain resources + */ + public static ChainResources getSnapTestChainResources() { + return snapTestChainSupplier.get(); + } + private static ChainResources supplyTestChainResources() { final URL genesisURL = ensureFileUrl(BlockTestUtil.class.getClassLoader().getResource("testGenesis.json")); @@ -164,6 +175,15 @@ public final class BlockTestUtil { return new ChainResources(genesisURL, blocksURL); } + private static ChainResources supplySnapTestChainResources() { + final URL genesisURL = + ensureFileUrl(BlockTestUtil.class.getClassLoader().getResource("snap/snapGenesis.json")); + final URL blocksURL = + ensureFileUrl( + BlockTestUtil.class.getClassLoader().getResource("snap/testBlockchain.blocks")); + return new ChainResources(genesisURL, blocksURL); + } + private static ChainResources supplyHiveTestChainResources() { final URL genesisURL = ensureFileUrl(BlockTestUtil.class.getClassLoader().getResource("hive/testGenesis.json")); diff --git a/testutil/src/main/resources/snap/snapGenesis.json b/testutil/src/main/resources/snap/snapGenesis.json new file mode 100644 index 0000000000..20979e7f74 --- /dev/null +++ b/testutil/src/main/resources/snap/snapGenesis.json @@ -0,0 +1,111 @@ +{ + "config": { + "ethash": {}, + "chainID": 3503995874084926, + "homesteadBlock": 0, + "eip150Block": 6, + "eip155Block": 12, + "eip158Block": 12, + "byzantiumBlock": 18, + "constantinopleBlock": 24, + "constantinopleFixBlock": 30, + "istanbulBlock": 36, + "muirGlacierBlock": 42, + "berlinBlock": 48, + "londonBlock": 54, + "arrowGlacierBlock": 60, + "grayGlacierBlock": 66, + "mergeNetsplitBlock": 72, + "terminalTotalDifficulty": 9454784, + "shanghaiTime": 780, + "cancunTime": 840 + }, + "nonce": "0x0", + "timestamp": "0x0", + "extraData": "0x68697665636861696e", + "gasLimit": "0x23f3e20", + "difficulty": "0x20000", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "coinbase": "0x0000000000000000000000000000000000000000", + "alloc": { + "000f3df6d732807ef1319fb7b8bb8522d0beac02": { + "code": "0x3373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500", + "balance": "0x2a" + }, + "0c2c51a0990aee1d73c1228de158688341557508": { + "balance": "0xc097ce7bc90715b34b9f1000000000" + }, + "14e46043e63d0e3cdcf2530519f4cfaf35058cb2": { + "balance": "0xc097ce7bc90715b34b9f1000000000" + }, + "16c57edf7fa9d9525378b0b81bf8a3ced0620c1c": { + "balance": "0xc097ce7bc90715b34b9f1000000000" + }, + "1f4924b14f34e24159387c0a4cdbaa32f3ddb0cf": { + "balance": "0xc097ce7bc90715b34b9f1000000000" + }, + "1f5bde34b4afc686f136c7a3cb6ec376f7357759": { + "balance": "0xc097ce7bc90715b34b9f1000000000" + }, + "2d389075be5be9f2246ad654ce152cf05990b209": { + "balance": "0xc097ce7bc90715b34b9f1000000000" + }, + "3ae75c08b4c907eb63a8960c45b86e1e9ab6123c": { + "balance": "0xc097ce7bc90715b34b9f1000000000" + }, + "4340ee1b812acb40a1eb561c019c327b243b92df": { + "balance": "0xc097ce7bc90715b34b9f1000000000" + }, + "4a0f1452281bcec5bd90c3dce6162a5995bfe9df": { + "balance": "0xc097ce7bc90715b34b9f1000000000" + }, + "4dde844b71bcdf95512fb4dc94e84fb67b512ed8": { + "balance": "0xc097ce7bc90715b34b9f1000000000" + }, + "5f552da00dfb4d3749d9e62dcee3c918855a86a0": { + "balance": "0xc097ce7bc90715b34b9f1000000000" + }, + "654aa64f5fbefb84c270ec74211b81ca8c44a72e": { + "balance": "0xc097ce7bc90715b34b9f1000000000" + }, + "717f8aa2b982bee0e29f573d31df288663e1ce16": { + "balance": "0xc097ce7bc90715b34b9f1000000000" + }, + "7435ed30a8b4aeb0877cef0c6e8cffe834eb865f": { + "balance": "0xc097ce7bc90715b34b9f1000000000" + }, + "83c7e323d189f18725ac510004fdc2941f8c4a78": { + "balance": "0xc097ce7bc90715b34b9f1000000000" + }, + "84e75c28348fb86acea1a93a39426d7d60f4cc46": { + "balance": "0xc097ce7bc90715b34b9f1000000000" + }, + "8bebc8ba651aee624937e7d897853ac30c95a067": { + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000000000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000000000000000000000000000003": "0x0000000000000000000000000000000000000000000000000000000000000003" + }, + "balance": "0x1", + "nonce": "0x1" + }, + "c7b99a164efd027a93f147376cc7da7c67c6bbe0": { + "balance": "0xc097ce7bc90715b34b9f1000000000" + }, + "d803681e487e6ac18053afc5a6cd813c86ec3e4d": { + "balance": "0xc097ce7bc90715b34b9f1000000000" + }, + "e7d13f7aa2a838d24c59b40186a0aca1e21cffcc": { + "balance": "0xc097ce7bc90715b34b9f1000000000" + }, + "eda8645ba6948855e3b3cd596bbb07596d59c603": { + "balance": "0xc097ce7bc90715b34b9f1000000000" + } + }, + "number": "0x0", + "gasUsed": "0x0", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "baseFeePerGas": null, + "excessBlobGas": null, + "blobGasUsed": null +} \ No newline at end of file diff --git a/testutil/src/main/resources/snap/testBlockchain.blocks b/testutil/src/main/resources/snap/testBlockchain.blocks new file mode 100644 index 0000000000000000000000000000000000000000..0df8d2f63ad54f13682181181b114e78f0e4229f GIT binary patch literal 342468 zcmeF4c|278`~S@#B5TMNW68c{7cr>p+4m*;maK`aV~s+#qEwEulx#^t_R79wNo2_u zBH1FO{LTzh-QCN4xF7dFzpwXw&v|dxIWx`ma-HjW-e+dkpwKnQHvkJm0S>pQO%2tX z`aBGKVprVKP1{9&k}mP``GfOma^K+H2?~jSbpYVddi>?Y{)nt=H`p!Dr4%&qa<~y2 zX2(@er*R97VSm#C^rjdO(Y5GiZibwkh_7CCHdY*_yWx~u4YA~ZGGfs% ze`+iQiiL#;g~~|75Qs>7hYL1V_7)D#0H*gK0&P%Ty#|d~gM0ywiwqY>wszvd40&&= z5y7H|E%?fdoF&L)H5mMLUmMHqQUs$j*6z);gD>LB7uA}K8>KHZ&S)VnN=_I^2YB!N(3PgXcqzEe|P`tmDNZDBm{zsk3f`2nG=a) zBg~1+u_Vl~mdvr_gS5qoNf9MQ=(ZGzsVR0M#r)M= z2q;BjYEX*ie~_Z6Ih4YjS>Mge-No6C*UG}l$=c$)g@=QWjX9Qgka^GSX?|q}K`8eA1hRJ~|hP}MWE771_FCyg{@}y70 zhODtwhi%qRt-NoI;##6`)3d4wegP(8tFboSUCK3m?A<&0cbgJ?!!$KRRi|wQv$Wr} z9Qy*fDkpqG@-qPqkY61UMnH>)M@>_a?p5~vCPl*3m(EOJE}RlV0wFUMadO=TdwM^3_Fpl->MH3l&iWc0+A<= zloggaOv@Z@Yz{Zaf|VptZF4VVYw9va4ARKSb09;JFmk2A+_&yyKKIKz5oJ%--{-E>oOMVs{∨M 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�H&F!^bdyob?nq3cZroaYEZ$T@>N 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

4STe(;*%O0HVBDiN@v}+fy;}fnSs&TAt2I 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

F zI=f(W4TL2%1rW7T$Mic?Cn{C6rc&OYGhozz#sY9p%GaKri5}GzoP^Q}%StJlH$}%A z%yZ%{3L~GCJQ>}Psje298Klx;kv6X6X)tlbcpDi|zJq25x~|{3Q=HNKx^6cpUeDT} zaU!GGHuqCO(GXx&q}8<;v6?4utD1*>&)bH1@KS2pn~qKa%YIKW^- z*01n*3-u_KKMku)>vRxlw;|h(3W62!;4Sb|N87nHgY*yQz_+YKLp8*I$x8Xdvr?u4 z^7KKpn<91fXF+Jf7VF-svq7+|RQQRwcc``cIHBRH9K^&X%1Htt_^#_7r4}!^6`gOo z2mp8RM7yg5A7@8_v~bT~A18XFALDTneg5=@4v^(UR}6bfD$J%-CH(A`Ep=29JSM}H zTsLViSuL2WqR9!V%w^JR7-VN3ky`fE?qVwQk;su)bpiheY`5-ybr#IQW1g8b9Uw`{ zr#pS9EFC&v|5L(G*YW>W1w!pSj9Q3IY5o?onKjcH?ytwpMYEanDX$vRXJLyzC(+b9 zZ%N!h$1%5z4za1bB%HO1-HNT^y^^`DHkdbqLu-~RHxR_aio4k?=N&bmHl>IfY+RoD z+=gNCZjE2yn@;4K=_~nLUHdjQM%mLuFlrq6C~#4`&5!uX>L#y}exje#R3Ao#yb40w z5!sT(L&_rIVLA1>I4tT!JgAx$tKmtb6Mv?N2Tinfo##*?8W@(?Q^HL;=B zAu=RiD=G>SY02Lm;l7-__Z`0{|IwyCc^JxC#D6XRU|~zVQirE(iy?n`B0JiYW*cp= zi#RVAP-!cdU+o=yK^{EJ8D0n`Sd+!OoWibv_GH}U>G`1%>I0kN)XhjY_6y^Sp~>%! zYttDQ&m|AkOe7vH$>~$iEatzt>^MI5@fQ?RzCK z8h8G>v?|lute{4M_EvhzYpP(R6vdMh@+d^s@F*ojFVZc_n=+7w<$1i5$v+5Nbk1vTH|4}{h?862{F*GZ7ylOaE1 zeJ%!=kYf^D`dBv8kSU`hilh3DUo)X$C(W~$TZCeJ9-|TVSAJMlDkO;&U6c=8GZ=Pf zD_g-K<+@4Q6j7j0JELBCnH$v%-w|n@l0GLBovbfSbyHf6CD_Nl`c0BzQ!$Cwmo2q3 zvE;XdftemYB#r7?%qBa3o4J-0#a#8Fkyajl&cg1SepP4HB#yIEzrguR1BBLPc)W$$ zl-HkzbyczFM&q|@91B8@cRAbxCLWf|OAZL(Uc|Hn>r92*F@|TQ0%2Jx!i@U}1dg7p zIZc8Txg0_qtFlEu-YfMutI}qIwGvrUTz@3N$wN4K>`UIemV4F)!>Hvv*)?5&!f=YO kW+?&l+=YeEH-oPpt`9ttw!?7i1`SlV774ugTwebF01?>9A^-pY literal 0 HcmV?d00001 From 0d9fa16a1f5ec11d22e4a03942a563940f7c35f4 Mon Sep 17 00:00:00 2001 From: Bhanu Pulluri <59369753+pullurib@users.noreply.github.com> Date: Wed, 18 Sep 2024 05:35:00 -0400 Subject: [PATCH 214/259] [#4292] Fix mounted data path directory permissions for besu user (#7575) * Fix mounted data path directory permissions for besu user Signed-off-by: Bhanu Pulluri * Add besu CLI option to output dirs needing permission update Signed-off-by: Bhanu Pulluri * run spotless apply to handle PR test failure Signed-off-by: Bhanu Pulluri * Remove newly added --print-paths-and-exit option from config file test This option doesn't have a corresponding config file entry as it's a standalone option to be used with docker containers Signed-off-by: Bhanu Pulluri * Add optional user argument to --print-paths-and-exit and fix directory permissions Signed-off-by: Bhanu Pulluri * Correct build.gradle changes, remove a duplicate line and extra whitespaces Signed-off-by: Bhanu Pulluri * Fix checking for user in path's group membership Signed-off-by: Bhanu Pulluri * Add platform check to restrict --print-paths-and-exit option usage to Linux and Mac Signed-off-by: Bhanu Pulluri * Apply suggestions from code review Co-authored-by: Fabio Di Fabio Signed-off-by: Bhanu Pulluri <59369753+pullurib@users.noreply.github.com> --------- Signed-off-by: Bhanu Pulluri Signed-off-by: Bhanu Pulluri <59369753+pullurib@users.noreply.github.com> Co-authored-by: Bhanu Pulluri Co-authored-by: Fabio Di Fabio --- CHANGELOG.md | 2 + .../org/hyperledger/besu/cli/BesuCommand.java | 137 ++++++++++++++++++ besu/src/main/scripts/besu-entry.sh | 49 +++++++ .../hyperledger/besu/cli/BesuCommandTest.java | 1 + build.gradle | 1 + docker/Dockerfile | 10 +- docker/test.sh | 8 + docker/tests/02/goss.yaml | 10 ++ docker/tests/dgoss | 2 +- 9 files changed, 217 insertions(+), 3 deletions(-) create mode 100755 besu/src/main/scripts/besu-entry.sh create mode 100644 docker/tests/02/goss.yaml diff --git a/CHANGELOG.md b/CHANGELOG.md index c241838637..d30ad08c98 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,8 +11,10 @@ - Remove privacy test classes support [#7569](https://github.com/hyperledger/besu/pull/7569) ### Bug fixes +- Fix mounted data path directory permissions for besu user [#7575](https://github.com/hyperledger/besu/pull/7575) - Fix for `debug_traceCall` to handle transactions without specified gas price. [#7510](https://github.com/hyperledger/besu/pull/7510) + ## 24.9.1 ### Upcoming Breaking Changes 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 ecfc0eaadb..01ee6172f6 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java @@ -16,6 +16,7 @@ package org.hyperledger.besu.cli; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; +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; @@ -203,16 +204,23 @@ import org.hyperledger.besu.util.number.Fraction; import org.hyperledger.besu.util.number.Percentage; import org.hyperledger.besu.util.number.PositiveNumber; +import java.io.BufferedReader; import java.io.File; 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; import java.net.UnknownHostException; +import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.attribute.GroupPrincipal; +import java.nio.file.attribute.PosixFileAttributes; +import java.nio.file.attribute.PosixFilePermission; +import java.nio.file.attribute.UserPrincipal; import java.time.Clock; import java.util.ArrayList; import java.util.Arrays; @@ -232,6 +240,7 @@ import java.util.function.Supplier; import java.util.stream.Collectors; import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Splitter; import com.google.common.base.Strings; import com.google.common.base.Suppliers; import com.google.common.collect.ImmutableMap; @@ -243,6 +252,8 @@ 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; +import oshi.PlatformEnum; +import oshi.SystemInfo; import picocli.AutoComplete; import picocli.CommandLine; import picocli.CommandLine.Command; @@ -382,6 +393,28 @@ public class BesuCommand implements DefaultCommandValues, Runnable { arity = "1") private final Optional identityString = Optional.empty(); + private Boolean printPathsAndExit = Boolean.FALSE; + private String besuUserName = "besu"; + + @Option( + names = "--print-paths-and-exit", + paramLabel = "", + description = "Print the configured paths and exit without starting the node.", + arity = "0..1") + void setUserName(final String userName) { + PlatformEnum currentPlatform = SystemInfo.getCurrentPlatform(); + // Only allow on Linux and macOS + if (currentPlatform == PlatformEnum.LINUX || currentPlatform == PlatformEnum.MACOS) { + if (userName != null) { + besuUserName = userName; + } + printPathsAndExit = Boolean.TRUE; + } else { + throw new UnsupportedOperationException( + "--print-paths-and-exit is only supported on Linux and macOS."); + } + } + // P2P Discovery Option Group @CommandLine.ArgGroup(validate = false, heading = "@|bold P2P Discovery Options|@%n") P2PDiscoveryOptionGroup p2PDiscoveryOptionGroup = new P2PDiscoveryOptionGroup(); @@ -1093,6 +1126,12 @@ public class BesuCommand implements DefaultCommandValues, Runnable { try { configureLogging(true); + if (printPathsAndExit) { + // Print configured paths requiring read/write permissions to be adjusted + checkPermissionsAndPrintPaths(besuUserName); + System.exit(0); // Exit before any services are started + } + // set merge config on the basis of genesis config setMergeConfigOptions(); @@ -1138,6 +1177,104 @@ public class BesuCommand implements DefaultCommandValues, Runnable { } } + private void checkPermissionsAndPrintPaths(final String userName) { + // Check permissions for the data path + checkPermissions(dataDir(), userName, false); + + // Check permissions for genesis file + try { + if (genesisFile != null) { + checkPermissions(genesisFile.toPath(), userName, true); + } + } catch (Exception e) { + commandLine + .getOut() + .println("Error: Failed checking genesis file: Reason: " + e.getMessage()); + } + } + + // Helper method to check permissions on a given path + private void checkPermissions(final Path path, final String besuUser, final boolean readOnly) { + try { + // Get the permissions of the file + // check if besu user is the owner - get owner permissions if yes + // else, check if besu user and owner are in the same group - if yes, check the group + // permission + // otherwise check permissions for others + + // Get the owner of the file or directory + UserPrincipal owner = Files.getOwner(path); + boolean hasReadPermission, hasWritePermission; + + // Get file permissions + Set permissions = Files.getPosixFilePermissions(path); + + // Check if besu is the owner + if (owner.getName().equals(besuUser)) { + // Owner permissions + hasReadPermission = permissions.contains(PosixFilePermission.OWNER_READ); + hasWritePermission = permissions.contains(PosixFilePermission.OWNER_WRITE); + } else { + // Get the group of the file + // Get POSIX file attributes and then group + PosixFileAttributes attrs = Files.readAttributes(path, PosixFileAttributes.class); + GroupPrincipal group = attrs.group(); + + // Check if besu user belongs to this group + boolean isMember = isGroupMember(besuUserName, group); + + if (isMember) { + // Group's permissions + hasReadPermission = permissions.contains(PosixFilePermission.GROUP_READ); + hasWritePermission = permissions.contains(PosixFilePermission.GROUP_WRITE); + } else { + // Others' permissions + hasReadPermission = permissions.contains(PosixFilePermission.OTHERS_READ); + hasWritePermission = permissions.contains(PosixFilePermission.OTHERS_WRITE); + } + } + + if (!hasReadPermission || (!readOnly && !hasWritePermission)) { + String accessType = readOnly ? "READ" : "READ_WRITE"; + commandLine.getOut().println("PERMISSION_CHECK_PATH:" + path + ":" + accessType); + } + } catch (Exception e) { + // Do nothing upon catching an error + commandLine + .getOut() + .println( + "Error: Failed to check permissions for path: '" + + path + + "'. Reason: " + + e.getMessage()); + } + } + + private static boolean isGroupMember(final String userName, final GroupPrincipal group) + throws IOException { + // Get the groups of the user by executing 'id -Gn username' + Process process = Runtime.getRuntime().exec(new String[] {"id", "-Gn", userName}); + BufferedReader reader = + new BufferedReader(new InputStreamReader(process.getInputStream(), UTF_8)); + + // Read the output of the command + String line = reader.readLine(); + boolean isMember = false; + if (line != null) { + // Split the groups + Iterable userGroups = Splitter.on(" ").split(line); + // Check if any of the user's groups match the file's group + + for (String grp : userGroups) { + if (grp.equals(group.getName())) { + isMember = true; + break; + } + } + } + return isMember; + } + @VisibleForTesting void setBesuConfiguration(final BesuConfigurationImpl pluginCommonConfiguration) { this.pluginCommonConfiguration = pluginCommonConfiguration; diff --git a/besu/src/main/scripts/besu-entry.sh b/besu/src/main/scripts/besu-entry.sh new file mode 100755 index 0000000000..ed3687b229 --- /dev/null +++ b/besu/src/main/scripts/besu-entry.sh @@ -0,0 +1,49 @@ +#!/bin/bash +## +## 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 +## + +# Run Besu first to get paths needing permission adjustment +output=$(/opt/besu/bin/besu --print-paths-and-exit $BESU_USER_NAME "$@") + +# Parse the output to find the paths and their required access types +echo "$output" | while IFS=: read -r prefix path accessType; do + if [[ "$prefix" == "PERMISSION_CHECK_PATH" ]]; then + # Change ownership to besu user and group + chown -R $BESU_USER_NAME:$BESU_USER_NAME $path + + # Ensure read/write permissions for besu user + + echo "Setting permissions for: $path with access: $accessType" + + if [[ "$accessType" == "READ" ]]; then + # Set read-only permissions for besu user + # Add execute for directories to allow access + find $path -type d -exec chmod u+rx {} \; + find $path -type f -exec chmod u+r {} \; + elif [[ "$accessType" == "READ_WRITE" ]]; then + # Set read/write permissions for besu user + # Add execute for directories to allow access + find $path -type d -exec chmod u+rwx {} \; + find $path -type f -exec chmod u+rw {} \; + fi + fi +done + +# Finally, run Besu with the actual arguments passed to the container +# Construct the command as a single string +COMMAND="/opt/besu/bin/besu $@" + +# Switch to the besu user and execute the command +exec su -s /bin/bash $BESU_USER_NAME -c "$COMMAND" 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 e6e0e85951..99b45ada1b 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java @@ -390,6 +390,7 @@ public class BesuCommandTest extends CommandTestAbstract { options.remove(spec.optionsMap().get("--config-file")); options.remove(spec.optionsMap().get("--help")); options.remove(spec.optionsMap().get("--version")); + options.remove(spec.optionsMap().get("--print-paths-and-exit")); for (final String tomlKey : tomlResult.keySet()) { final CommandLine.Model.OptionSpec optionSpec = spec.optionsMap().get("--" + tomlKey); diff --git a/build.gradle b/build.gradle index 792355417f..ee4392c9fc 100644 --- a/build.gradle +++ b/build.gradle @@ -1097,6 +1097,7 @@ distributions { from("build/reports/license/license-dependency.html") { into "." } from("./docs/GettingStartedBinaries.md") { into "." } from("./docs/DocsArchive0.8.0.html") { into "." } + from("./besu/src/main/scripts/besu-entry.sh") { into "./bin/" } from(autocomplete) { into "." } } } diff --git a/docker/Dockerfile b/docker/Dockerfile index c16345a82b..a45a3ac73d 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -18,7 +18,8 @@ RUN apt-get update $NO_PROXY_CACHE && \ chown besu:besu /opt/besu && \ chmod 0755 /opt/besu -USER besu +ARG BESU_USER=besu +USER ${BESU_USER} WORKDIR /opt/besu COPY --chown=besu:besu besu /opt/besu/ @@ -43,7 +44,12 @@ ENV OTEL_RESOURCE_ATTRIBUTES="service.name=besu,service.version=$VERSION" ENV OLDPATH="${PATH}" ENV PATH="/opt/besu/bin:${OLDPATH}" -ENTRYPOINT ["besu"] +USER root +RUN chmod +x /opt/besu/bin/besu-entry.sh + +ENV BESU_USER_NAME=${BESU_USER} + +ENTRYPOINT ["besu-entry.sh"] HEALTHCHECK --start-period=5s --interval=5s --timeout=1s --retries=10 CMD bash -c "[ -f /tmp/pid ]" # Build-time metadata as defined at http://label-schema.org diff --git a/docker/test.sh b/docker/test.sh index 6e08db13b5..e230f79ad1 100755 --- a/docker/test.sh +++ b/docker/test.sh @@ -41,4 +41,12 @@ bash $TEST_PATH/dgoss run --sysctl net.ipv6.conf.all.disable_ipv6=1 $DOCKER_IMAG --graphql-http-enabled \ > ./reports/01.xml || i=`expr $i + 1` +if [[ $i != 0 ]]; then exit $i; fi + +# Test for directory permissions +GOSS_FILES_PATH=$TEST_PATH/02 \ +bash $TEST_PATH/dgoss run --sysctl net.ipv6.conf.all.disable_ipv6=1 -v besu-data:/var/lib/besu $DOCKER_IMAGE --data-path=/var/lib/besu \ +--network=dev \ +> ./reports/02.xml || i=`expr $i + 1` + exit $i diff --git a/docker/tests/02/goss.yaml b/docker/tests/02/goss.yaml new file mode 100644 index 0000000000..d266cafa39 --- /dev/null +++ b/docker/tests/02/goss.yaml @@ -0,0 +1,10 @@ +--- +# runtime docker tests +file: + /var/lib/besu: + exists: true + owner: besu + mode: "0755" +process: + java: + running: true diff --git a/docker/tests/dgoss b/docker/tests/dgoss index 59bbc4683e..170270eff3 100755 --- a/docker/tests/dgoss +++ b/docker/tests/dgoss @@ -76,7 +76,7 @@ GOSS_PATH="${GOSS_PATH:-$(which goss 2> /dev/null || true)}" [[ $GOSS_PATH ]] || { error "Couldn't find goss installation, please set GOSS_PATH to it"; } [[ ${GOSS_OPTS+x} ]] || GOSS_OPTS="--color --format documentation" [[ ${GOSS_WAIT_OPTS+x} ]] || GOSS_WAIT_OPTS="-r 30s -s 1s > /dev/null" -GOSS_SLEEP=${GOSS_SLEEP:-0.2} +GOSS_SLEEP=${GOSS_SLEEP:-1.0} case "$1" in run) From 6df4149f2a04555fb36702911b8f6142b843c5b3 Mon Sep 17 00:00:00 2001 From: Fabio Di Fabio Date: Wed, 18 Sep 2024 15:55:10 +0200 Subject: [PATCH 215/259] Fix logging the evaluation time when a tx is selected for block creation (#7636) Signed-off-by: Fabio Di Fabio --- .../blockcreation/txselection/BlockTransactionSelector.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/BlockTransactionSelector.java b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/BlockTransactionSelector.java index 3d56c1fc07..e07b43b990 100644 --- a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/BlockTransactionSelector.java +++ b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/BlockTransactionSelector.java @@ -401,7 +401,7 @@ public class BlockTransactionSelector { LOG.atTrace() .setMessage("Selected {} for block creation, evaluated in {}") .addArgument(transaction::toTraceLog) - .addArgument(evaluationContext.getPendingTransaction()) + .addArgument(evaluationContext.getEvaluationTimer()) .log(); return SELECTED; } From 7d3e376771f99598e3730a0569793c7c1bd58834 Mon Sep 17 00:00:00 2001 From: Justin Florentine Date: Wed, 18 Sep 2024 10:31:03 -0400 Subject: [PATCH 216/259] shift creation of plugin context to BesuCommand for now (#7625) * shift creation of plugin context to BesuCommand for now * mock component will provide a no-op metrics sys --------- Signed-off-by: Justin Florentine --- CHANGELOG.md | 1 + .../dsl/node/ProcessBesuNodeRunner.java | 125 +++++++++--------- .../dsl/node/ThreadBesuNodeRunner.java | 23 ++-- .../main/java/org/hyperledger/besu/Besu.java | 5 +- .../org/hyperledger/besu/cli/BesuCommand.java | 38 ++++-- .../besu/components/BesuCommandModule.java | 12 +- .../besu/components/BesuComponent.java | 4 +- .../components/BesuPluginContextModule.java | 16 --- .../controller/BesuControllerBuilder.java | 2 +- .../besu/cli/CommandTestAbstract.java | 7 + .../components/MockBesuCommandModule.java | 16 +++ .../BonsaiCachedMerkleTrieLoaderModule.java | 5 +- .../besu/metrics/MetricsSystemModule.java | 6 - .../opentelemetry/OpenTelemetrySystem.java | 2 + 14 files changed, 148 insertions(+), 114 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d30ad08c98..ff4d7cfbf9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ ### Bug fixes - Fix mounted data path directory permissions for besu user [#7575](https://github.com/hyperledger/besu/pull/7575) - Fix for `debug_traceCall` to handle transactions without specified gas price. [#7510](https://github.com/hyperledger/besu/pull/7510) +- Corrects a regression where custom plugin services are not initialized correctly. [#7625](https://github.com/hyperledger/besu/pull/7625) ## 24.9.1 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 c6696b15a2..6e00701ef2 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 @@ -75,6 +75,70 @@ public class ProcessBesuNodeRunner implements BesuNodeRunner { final Path dataDir = node.homeDirectory(); + final List params = commandlineArgs(node, dataDir); + + LOG.info("Creating besu process with params {}", params); + final ProcessBuilder processBuilder = + new ProcessBuilder(params) + .directory(new File(System.getProperty("user.dir")).getParentFile().getParentFile()) + .redirectErrorStream(true) + .redirectInput(Redirect.INHERIT); + if (!node.getPlugins().isEmpty()) { + processBuilder + .environment() + .put( + "BESU_OPTS", + "-Dbesu.plugins.dir=" + dataDir.resolve("plugins").toAbsolutePath().toString()); + } + // Use non-blocking randomness for acceptance tests + processBuilder + .environment() + .put( + "JAVA_OPTS", + "-Djava.security.properties=" + + "acceptance-tests/tests/build/resources/test/acceptanceTesting.security"); + // add additional environment variables + processBuilder.environment().putAll(node.getEnvironment()); + + try { + int debugPort = Integer.parseInt(System.getenv("BESU_DEBUG_CHILD_PROCESS_PORT")); + LOG.warn("Waiting for debugger to attach to SUSPENDED child process"); + String debugOpts = + " -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:" + debugPort; + String prevJavaOpts = processBuilder.environment().get("JAVA_OPTS"); + if (prevJavaOpts == null) { + processBuilder.environment().put("JAVA_OPTS", debugOpts); + } else { + processBuilder.environment().put("JAVA_OPTS", prevJavaOpts + debugOpts); + } + + } catch (NumberFormatException e) { + LOG.debug( + "Child process may be attached to by exporting BESU_DEBUG_CHILD_PROCESS_PORT= to env"); + } + + try { + checkState( + isNotAliveOrphan(node.getName()), + "A live process with name: %s, already exists. Cannot create another with the same name as it would orphan the first", + node.getName()); + + final Process process = processBuilder.start(); + process.onExit().thenRun(() -> node.setExitCode(process.exitValue())); + outputProcessorExecutor.execute(() -> printOutput(node, process)); + besuProcesses.put(node.getName(), process); + } catch (final IOException e) { + LOG.error("Error starting BesuNode process", e); + } + + if (node.getRunCommand().isEmpty()) { + waitForFile(dataDir, "besu.ports"); + waitForFile(dataDir, "besu.networks"); + } + MDC.remove("node"); + } + + private List commandlineArgs(final BesuNode node, final Path dataDir) { final List params = new ArrayList<>(); params.add("build/install/besu/bin/besu"); @@ -388,66 +452,7 @@ public class ProcessBesuNodeRunner implements BesuNodeRunner { } params.addAll(node.getRunCommand()); - - LOG.info("Creating besu process with params {}", params); - final ProcessBuilder processBuilder = - new ProcessBuilder(params) - .directory(new File(System.getProperty("user.dir")).getParentFile().getParentFile()) - .redirectErrorStream(true) - .redirectInput(Redirect.INHERIT); - if (!node.getPlugins().isEmpty()) { - processBuilder - .environment() - .put( - "BESU_OPTS", - "-Dbesu.plugins.dir=" + dataDir.resolve("plugins").toAbsolutePath().toString()); - } - // Use non-blocking randomness for acceptance tests - processBuilder - .environment() - .put( - "JAVA_OPTS", - "-Djava.security.properties=" - + "acceptance-tests/tests/build/resources/test/acceptanceTesting.security"); - // add additional environment variables - processBuilder.environment().putAll(node.getEnvironment()); - - try { - int debugPort = Integer.parseInt(System.getenv("BESU_DEBUG_CHILD_PROCESS_PORT")); - LOG.warn("Waiting for debugger to attach to SUSPENDED child process"); - String debugOpts = - " -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:" + debugPort; - String prevJavaOpts = processBuilder.environment().get("JAVA_OPTS"); - if (prevJavaOpts == null) { - processBuilder.environment().put("JAVA_OPTS", debugOpts); - } else { - processBuilder.environment().put("JAVA_OPTS", prevJavaOpts + debugOpts); - } - - } catch (NumberFormatException e) { - LOG.debug( - "Child process may be attached to by exporting BESU_DEBUG_CHILD_PROCESS_PORT= to env"); - } - - try { - checkState( - isNotAliveOrphan(node.getName()), - "A live process with name: %s, already exists. Cannot create another with the same name as it would orphan the first", - node.getName()); - - final Process process = processBuilder.start(); - process.onExit().thenRun(() -> node.setExitCode(process.exitValue())); - outputProcessorExecutor.execute(() -> printOutput(node, process)); - besuProcesses.put(node.getName(), process); - } catch (final IOException e) { - LOG.error("Error starting BesuNode process", e); - } - - if (node.getRunCommand().isEmpty()) { - waitForFile(dataDir, "besu.ports"); - waitForFile(dataDir, "besu.networks"); - } - MDC.remove("node"); + return params; } private boolean isNotAliveOrphan(final String name) { 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 d4ec54045d..5d78f1460c 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 @@ -138,7 +138,8 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner { final PermissioningServiceImpl permissioningService = new PermissioningServiceImpl(); GlobalOpenTelemetry.resetForTest(); - final ObservableMetricsSystem metricsSystem = component.getObservableMetricsSystem(); + final ObservableMetricsSystem metricsSystem = + (ObservableMetricsSystem) component.getMetricsSystem(); final List bootnodes = node.getConfiguration().getBootnodes().stream().map(EnodeURLImpl::fromURI).toList(); @@ -280,6 +281,16 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner { this.toProvide = toProvide; } + @Provides + @Singleton + MetricsConfiguration provideMetricsConfiguration() { + if (toProvide.getMetricsConfiguration() != null) { + return toProvide.getMetricsConfiguration(); + } else { + return MetricsConfiguration.builder().build(); + } + } + @Provides public BesuNode provideBesuNodeRunner() { return toProvide; @@ -410,13 +421,13 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner { public BesuController provideBesuController( final SynchronizerConfiguration synchronizerConfiguration, final BesuControllerBuilder builder, - final ObservableMetricsSystem metricsSystem, + final MetricsSystem metricsSystem, final KeyValueStorageProvider storageProvider, final MiningParameters miningParameters) { builder .synchronizerConfiguration(synchronizerConfiguration) - .metricsSystem(metricsSystem) + .metricsSystem((ObservableMetricsSystem) metricsSystem) .dataStorageConfiguration(DataStorageConfiguration.DEFAULT_FOREST_CONFIG) .ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig()) .clock(Clock.systemUTC()) @@ -562,12 +573,6 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner { return besuCommand; } - @Provides - @Singleton - MetricsConfiguration provideMetricsConfiguration() { - return MetricsConfiguration.builder().build(); - } - @Provides @Named("besuCommandLogger") @Singleton diff --git a/besu/src/main/java/org/hyperledger/besu/Besu.java b/besu/src/main/java/org/hyperledger/besu/Besu.java index 8d40a10eb4..3ba0af0a9b 100644 --- a/besu/src/main/java/org/hyperledger/besu/Besu.java +++ b/besu/src/main/java/org/hyperledger/besu/Besu.java @@ -16,6 +16,7 @@ package org.hyperledger.besu; import org.hyperledger.besu.cli.BesuCommand; import org.hyperledger.besu.cli.logging.BesuLoggingConfigurationFactory; +import org.hyperledger.besu.components.BesuComponent; import org.hyperledger.besu.components.DaggerBesuComponent; import io.netty.util.internal.logging.InternalLoggerFactory; @@ -36,13 +37,15 @@ public final class Besu { */ public static void main(final String... args) { setupLogging(); - final BesuCommand besuCommand = DaggerBesuComponent.create().getBesuCommand(); + final BesuComponent besuComponent = DaggerBesuComponent.create(); + final BesuCommand besuCommand = besuComponent.getBesuCommand(); int exitCode = besuCommand.parse( new RunLast(), besuCommand.parameterExceptionHandler(), besuCommand.executionExceptionHandler(), System.in, + besuComponent, args); System.exit(exitCode); 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 01ee6172f6..79879538bd 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java @@ -85,6 +85,7 @@ import org.hyperledger.besu.cli.util.BesuCommandCustomFactory; import org.hyperledger.besu.cli.util.CommandLineUtils; import org.hyperledger.besu.cli.util.ConfigDefaultValueProviderStrategy; import org.hyperledger.besu.cli.util.VersionProvider; +import org.hyperledger.besu.components.BesuComponent; import org.hyperledger.besu.config.CheckpointConfigOptions; import org.hyperledger.besu.config.GenesisConfigFile; import org.hyperledger.besu.config.GenesisConfigOptions; @@ -145,7 +146,6 @@ import org.hyperledger.besu.evm.precompile.KZGPointEvalPrecompiledContract; import org.hyperledger.besu.metrics.BesuMetricCategory; import org.hyperledger.besu.metrics.MetricCategoryRegistryImpl; import org.hyperledger.besu.metrics.MetricsProtocol; -import org.hyperledger.besu.metrics.MetricsSystemFactory; import org.hyperledger.besu.metrics.ObservableMetricsSystem; import org.hyperledger.besu.metrics.StandardMetricCategory; import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration; @@ -423,6 +423,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { private final TransactionPoolValidatorServiceImpl transactionValidatorServiceImpl; private final TransactionSimulationServiceImpl transactionSimulationServiceImpl; private final BlockchainServiceImpl blockchainServiceImpl; + private BesuComponent besuComponent; static class P2PDiscoveryOptionGroup { @@ -897,9 +898,6 @@ public class BesuCommand implements DefaultCommandValues, Runnable { private BesuController besuController; private BesuConfigurationImpl pluginCommonConfiguration; - private final Supplier metricsSystem = - Suppliers.memoize(() -> MetricsSystemFactory.create(metricsConfiguration())); - private Vertx vertx; private EnodeDnsConfiguration enodeDnsConfiguration; private KeyValueStorageProvider keyValueStorageProvider; @@ -1029,6 +1027,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { * @param parameterExceptionHandler Handler for exceptions related to command line parameters. * @param executionExceptionHandler Handler for exceptions during command execution. * @param in The input stream for commands. + * @param besuComponent The Besu component. * @param args The command line arguments. * @return The execution result status code. */ @@ -1037,8 +1036,12 @@ public class BesuCommand implements DefaultCommandValues, Runnable { final BesuParameterExceptionHandler parameterExceptionHandler, final BesuExecutionExceptionHandler executionExceptionHandler, final InputStream in, + final BesuComponent besuComponent, final String... args) { - + if (besuComponent == null) { + throw new IllegalArgumentException("BesuComponent must be provided"); + } + this.besuComponent = besuComponent; initializeCommandLineSettings(in); // Create the execution strategy chain. @@ -1142,7 +1145,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { logger.info("Starting Besu"); // Need to create vertx after cmdline has been parsed, such that metricsSystem is configurable - vertx = createVertx(createVertxOptions(metricsSystem.get())); + vertx = createVertx(createVertxOptions(besuComponent.getMetricsSystem())); validateOptions(); @@ -1527,8 +1530,8 @@ public class BesuCommand implements DefaultCommandValues, Runnable { } private void setReleaseMetrics() { - metricsSystem - .get() + besuComponent + .getMetricsSystem() .createLabelledGauge( StandardMetricCategory.PROCESS, "release", "Release information", "version") .labels(() -> 1, BesuInfo.version()); @@ -1992,7 +1995,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { .miningParameters(miningParametersSupplier.get()) .transactionPoolConfiguration(buildTransactionPoolConfiguration()) .nodeKey(new NodeKey(securityModule())) - .metricsSystem(metricsSystem.get()) + .metricsSystem((ObservableMetricsSystem) besuComponent.getMetricsSystem()) .messagePermissioningProviders(permissioningService.getMessagePermissioningProviders()) .privacyParameters(privacyParameters()) .clock(Clock.systemUTC()) @@ -2012,7 +2015,8 @@ public class BesuCommand implements DefaultCommandValues, Runnable { .randomPeerPriority(p2PDiscoveryOptionGroup.randomPeerPriority) .chainPruningConfiguration(unstableChainPruningOptions.toDomainObject()) .cacheLastBlocks(numberOfblocksToCache) - .genesisStateHashCacheEnabled(genesisStateHashCacheEnabled); + .genesisStateHashCacheEnabled(genesisStateHashCacheEnabled) + .besuComponent(besuComponent); } private JsonRpcConfiguration createEngineJsonRpcConfiguration( @@ -2414,7 +2418,6 @@ public class BesuCommand implements DefaultCommandValues, Runnable { p2pTLSConfiguration.ifPresent(runnerBuilder::p2pTLSConfiguration); - final ObservableMetricsSystem metricsSystem = this.metricsSystem.get(); final Runner runner = runnerBuilder .vertx(vertx) @@ -2441,7 +2444,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { .pidPath(pidPath) .dataDir(dataDir()) .bannedNodeIds(p2PDiscoveryOptionGroup.bannedNodeIds) - .metricsSystem(metricsSystem) + .metricsSystem((ObservableMetricsSystem) besuComponent.getMetricsSystem()) .permissioningService(permissioningService) .metricsConfiguration(metricsConfiguration) .staticNodes(staticNodes) @@ -2608,7 +2611,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { * @return Instance of MetricsSystem */ public MetricsSystem getMetricsSystem() { - return metricsSystem.get(); + return besuComponent.getMetricsSystem(); } private Set loadStaticNodes() throws IOException { @@ -2946,4 +2949,13 @@ public class BesuCommand implements DefaultCommandValues, Runnable { return builder.build(); } + + /** + * Returns the plugin context. + * + * @return the plugin context. + */ + public BesuPluginContextImpl getBesuPluginContext() { + return besuPluginContext; + } } 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 86aa8c7594..59e2d60bf3 100644 --- a/besu/src/main/java/org/hyperledger/besu/components/BesuCommandModule.java +++ b/besu/src/main/java/org/hyperledger/besu/components/BesuCommandModule.java @@ -42,9 +42,7 @@ public class BesuCommandModule { @Provides @Singleton - BesuCommand provideBesuCommand( - final BesuPluginContextImpl pluginContext, - final @Named("besuCommandLogger") Logger commandLogger) { + BesuCommand provideBesuCommand(final @Named("besuCommandLogger") Logger commandLogger) { final BesuCommand besuCommand = new BesuCommand( RlpBlockImporter::new, @@ -52,7 +50,7 @@ public class BesuCommandModule { RlpBlockExporter::new, new RunnerBuilder(), new BesuController.Builder(), - pluginContext, + new BesuPluginContextImpl(), System.getenv(), commandLogger); besuCommand.toCommandLine(); @@ -71,4 +69,10 @@ public class BesuCommandModule { Logger provideBesuCommandLogger() { return Besu.getFirstLogger(); } + + @Provides + @Singleton + BesuPluginContextImpl provideBesuPluginContextImpl(final BesuCommand provideFrom) { + return provideFrom.getBesuPluginContext(); + } } diff --git a/besu/src/main/java/org/hyperledger/besu/components/BesuComponent.java b/besu/src/main/java/org/hyperledger/besu/components/BesuComponent.java index 9f810a6dc6..b0d5c3da0f 100644 --- a/besu/src/main/java/org/hyperledger/besu/components/BesuComponent.java +++ b/besu/src/main/java/org/hyperledger/besu/components/BesuComponent.java @@ -20,7 +20,7 @@ import org.hyperledger.besu.ethereum.eth.transactions.BlobCacheModule; import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.cache.BonsaiCachedMerkleTrieLoader; import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.cache.BonsaiCachedMerkleTrieLoaderModule; import org.hyperledger.besu.metrics.MetricsSystemModule; -import org.hyperledger.besu.metrics.ObservableMetricsSystem; +import org.hyperledger.besu.plugin.services.MetricsSystem; import org.hyperledger.besu.services.BesuPluginContextImpl; import javax.inject.Named; @@ -60,7 +60,7 @@ public interface BesuComponent { * * @return ObservableMetricsSystem */ - ObservableMetricsSystem getObservableMetricsSystem(); + MetricsSystem getMetricsSystem(); /** * a Logger specifically configured to provide configuration feedback to users. diff --git a/besu/src/main/java/org/hyperledger/besu/components/BesuPluginContextModule.java b/besu/src/main/java/org/hyperledger/besu/components/BesuPluginContextModule.java index d62ab70224..702b63af19 100644 --- a/besu/src/main/java/org/hyperledger/besu/components/BesuPluginContextModule.java +++ b/besu/src/main/java/org/hyperledger/besu/components/BesuPluginContextModule.java @@ -14,9 +14,7 @@ */ package org.hyperledger.besu.components; -import org.hyperledger.besu.plugin.services.BesuConfiguration; import org.hyperledger.besu.services.BesuConfigurationImpl; -import org.hyperledger.besu.services.BesuPluginContextImpl; import javax.inject.Singleton; @@ -35,18 +33,4 @@ public class BesuPluginContextModule { BesuConfigurationImpl provideBesuPluginConfig() { return new BesuConfigurationImpl(); } - - /** - * Creates a BesuPluginContextImpl, used for plugin service discovery. - * - * @param pluginConfig the BesuConfigurationImpl - * @return the BesuPluginContext - */ - @Provides - @Singleton - public BesuPluginContextImpl provideBesuPluginContext(final BesuConfigurationImpl pluginConfig) { - BesuPluginContextImpl retval = new BesuPluginContextImpl(); - retval.addService(BesuConfiguration.class, pluginConfig); - return retval; - } } 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 6bb3fb117c..bded2a38ac 100644 --- a/besu/src/main/java/org/hyperledger/besu/controller/BesuControllerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/controller/BesuControllerBuilder.java @@ -552,7 +552,7 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides checkNotNull(evmConfiguration, "Missing evm config"); checkNotNull(networkingConfiguration, "Missing network configuration"); checkNotNull(dataStorageConfiguration, "Missing data storage configuration"); - + checkNotNull(besuComponent, "Must supply a BesuComponent"); prepForBuild(); final ProtocolSchedule protocolSchedule = createProtocolSchedule(); 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 7d11a4a8e9..5b1274389d 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/CommandTestAbstract.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/CommandTestAbstract.java @@ -42,6 +42,7 @@ 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; import org.hyperledger.besu.config.GenesisConfigOptions; import org.hyperledger.besu.controller.BesuController; import org.hyperledger.besu.controller.BesuControllerBuilder; @@ -69,6 +70,7 @@ import org.hyperledger.besu.ethereum.permissioning.PermissioningConfiguration; import org.hyperledger.besu.ethereum.storage.StorageProvider; import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; +import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration; import org.hyperledger.besu.plugin.services.PicoCLIOptions; import org.hyperledger.besu.plugin.services.StorageService; @@ -204,6 +206,9 @@ public abstract class CommandTestAbstract { @Mock(lenient = true) protected BesuController mockController; + @Mock(lenient = true) + protected BesuComponent mockBesuComponent; + @Mock protected RlpBlockExporter rlpBlockExporter; @Mock protected JsonBlockImporter jsonBlockImporter; @Mock protected RlpBlockImporter rlpBlockImporter; @@ -344,6 +349,7 @@ public abstract class CommandTestAbstract { when(mockRunnerBuilder.allowedSubnets(any())).thenReturn(mockRunnerBuilder); when(mockRunnerBuilder.poaDiscoveryRetryBootnodes(anyBoolean())).thenReturn(mockRunnerBuilder); when(mockRunnerBuilder.build()).thenReturn(mockRunner); + when(mockBesuComponent.getMetricsSystem()).thenReturn(new NoOpMetricsSystem()); final SignatureAlgorithm signatureAlgorithm = SignatureAlgorithmFactory.getInstance(); @@ -451,6 +457,7 @@ public abstract class CommandTestAbstract { besuCommand.parameterExceptionHandler(), besuCommand.executionExceptionHandler(), in, + mockBesuComponent, args); return besuCommand; } diff --git a/besu/src/test/java/org/hyperledger/besu/components/MockBesuCommandModule.java b/besu/src/test/java/org/hyperledger/besu/components/MockBesuCommandModule.java index 743b4ee8de..3695fe54f7 100644 --- a/besu/src/test/java/org/hyperledger/besu/components/MockBesuCommandModule.java +++ b/besu/src/test/java/org/hyperledger/besu/components/MockBesuCommandModule.java @@ -18,6 +18,9 @@ import static org.mockito.Mockito.mock; import org.hyperledger.besu.cli.BesuCommand; import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration; +import org.hyperledger.besu.plugin.services.BesuConfiguration; +import org.hyperledger.besu.services.BesuConfigurationImpl; +import org.hyperledger.besu.services.BesuPluginContextImpl; import javax.inject.Named; import javax.inject.Singleton; @@ -47,4 +50,17 @@ public class MockBesuCommandModule { Logger provideBesuCommandLogger() { return LoggerFactory.getLogger(MockBesuCommandModule.class); } + + /** + * Creates a BesuPluginContextImpl, used for plugin service discovery. + * + * @return the BesuPluginContext + */ + @Provides + @Singleton + public BesuPluginContextImpl provideBesuPluginContext() { + BesuPluginContextImpl retval = new BesuPluginContextImpl(); + retval.addService(BesuConfiguration.class, new BesuConfigurationImpl()); + return retval; + } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/cache/BonsaiCachedMerkleTrieLoaderModule.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/cache/BonsaiCachedMerkleTrieLoaderModule.java index 8ed7daa35f..b506d5a5ff 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/cache/BonsaiCachedMerkleTrieLoaderModule.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/cache/BonsaiCachedMerkleTrieLoaderModule.java @@ -15,6 +15,7 @@ package org.hyperledger.besu.ethereum.trie.diffbased.bonsai.cache; import org.hyperledger.besu.metrics.ObservableMetricsSystem; +import org.hyperledger.besu.plugin.services.MetricsSystem; import dagger.Module; import dagger.Provides; @@ -24,7 +25,7 @@ public class BonsaiCachedMerkleTrieLoaderModule { @Provides BonsaiCachedMerkleTrieLoader provideCachedMerkleTrieLoaderModule( - final ObservableMetricsSystem metricsSystem) { - return new BonsaiCachedMerkleTrieLoader(metricsSystem); + final MetricsSystem metricsSystem) { + return new BonsaiCachedMerkleTrieLoader((ObservableMetricsSystem) metricsSystem); } } diff --git a/metrics/core/src/main/java/org/hyperledger/besu/metrics/MetricsSystemModule.java b/metrics/core/src/main/java/org/hyperledger/besu/metrics/MetricsSystemModule.java index 044085ef42..1347d6faaa 100644 --- a/metrics/core/src/main/java/org/hyperledger/besu/metrics/MetricsSystemModule.java +++ b/metrics/core/src/main/java/org/hyperledger/besu/metrics/MetricsSystemModule.java @@ -36,10 +36,4 @@ public class MetricsSystemModule { MetricsSystem provideMetricsSystem(final MetricsConfiguration metricsConfig) { return MetricsSystemFactory.create(metricsConfig); } - - @Provides - @Singleton - ObservableMetricsSystem provideObservableMetricsSystem(final MetricsConfiguration metricsConfig) { - return MetricsSystemFactory.create(metricsConfig); - } } diff --git a/metrics/core/src/main/java/org/hyperledger/besu/metrics/opentelemetry/OpenTelemetrySystem.java b/metrics/core/src/main/java/org/hyperledger/besu/metrics/opentelemetry/OpenTelemetrySystem.java index ca1dc5dd3a..a399b28373 100644 --- a/metrics/core/src/main/java/org/hyperledger/besu/metrics/opentelemetry/OpenTelemetrySystem.java +++ b/metrics/core/src/main/java/org/hyperledger/besu/metrics/opentelemetry/OpenTelemetrySystem.java @@ -41,6 +41,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; import java.util.function.DoubleSupplier; import java.util.stream.Stream; +import javax.inject.Singleton; import com.google.common.collect.ImmutableSet; import io.opentelemetry.api.common.AttributeKey; @@ -67,6 +68,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** Metrics system relying on the native OpenTelemetry format. */ +@Singleton public class OpenTelemetrySystem implements ObservableMetricsSystem { private static final Logger LOG = LoggerFactory.getLogger(OpenTelemetrySystem.class); From 96e9873dd9624200f3a78cc6759a70b159c01d80 Mon Sep 17 00:00:00 2001 From: Bhanu Pulluri <59369753+pullurib@users.noreply.github.com> Date: Wed, 18 Sep 2024 13:53:11 -0400 Subject: [PATCH 217/259] Handle hadolint check failure with proper risk assessment (#7637) Signed-off-by: Bhanu Pulluri Co-authored-by: Bhanu Pulluri Co-authored-by: Fabio Di Fabio --- docker/Dockerfile | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docker/Dockerfile b/docker/Dockerfile index a45a3ac73d..fe91c7026f 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -44,6 +44,12 @@ ENV OTEL_RESOURCE_ATTRIBUTES="service.name=besu,service.version=$VERSION" ENV OLDPATH="${PATH}" ENV PATH="/opt/besu/bin:${OLDPATH}" + +# The entry script just sets permissions as needed based on besu config +# and is replaced by the besu process running as besu user. +# Suppressing this warning as there's no risk here because the root user +# only sets permissions and does not continue running the main process. +# hadolint ignore=DL3002 USER root RUN chmod +x /opt/besu/bin/besu-entry.sh From beaee59212f18ca8767498fbb018381af7531893 Mon Sep 17 00:00:00 2001 From: Suyash Nayan <89125422+7suyash7@users.noreply.github.com> Date: Thu, 19 Sep 2024 20:27:06 +0530 Subject: [PATCH 218/259] Add BlobMetrics (#7622) * Add BlobMetrics Signed-off-by: 7suyash7 * refactor Signed-off-by: 7suyash7 * remove unused blob_storage Signed-off-by: 7suyash7 * add .size() to BlobCache Signed-off-by: 7suyash7 * Add to Changelog Signed-off-by: 7suyash7 --------- Signed-off-by: 7suyash7 Co-authored-by: Fabio Di Fabio --- CHANGELOG.md | 1 + .../ethereum/eth/transactions/BlobCache.java | 4 ++++ .../eth/transactions/TransactionPool.java | 14 ++++++++++++++ .../transactions/TransactionPoolMetrics.java | 17 +++++++++++++++++ 4 files changed, 36 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ff4d7cfbf9..c1ecca978e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ ### 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) ### Bug fixes - Fix mounted data path directory permissions for besu user [#7575](https://github.com/hyperledger/besu/pull/7575) diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/BlobCache.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/BlobCache.java index 3d3a435f1f..1cca3f5ee2 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/BlobCache.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/BlobCache.java @@ -91,4 +91,8 @@ public class BlobCache { public BlobsWithCommitments.BlobQuad get(final VersionedHash vh) { return cache.getIfPresent(vh); } + + public long size() { + return cache.estimatedSize(); + } } 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 315f82921b..7bbf1abe3b 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 @@ -129,6 +129,7 @@ public class TransactionPool implements BlockAddedObserver { this.blockAddedEventOrderedProcessor = ethContext.getScheduler().createOrderedProcessor(this::processBlockAddedEvent); this.cacheForBlobsOfTransactionsAddedToABlock = blobCache; + initializeBlobMetrics(); initLogForReplay(); subscribePendingTransactions(this::mapBlobsOnTransactionAdded); subscribeDroppedTransactions(this::unmapBlobsOnTransactionDropped); @@ -686,6 +687,19 @@ public class TransactionPool implements BlockAddedObserver { return isPoolEnabled.get(); } + public int getBlobCacheSize() { + return (int) cacheForBlobsOfTransactionsAddedToABlock.size(); + } + + public int getBlobMapSize() { + return mapOfBlobsInTransactionPool.size(); + } + + private void initializeBlobMetrics() { + metrics.createBlobCacheSizeMetric(this::getBlobCacheSize); + metrics.createBlobMapSizeMetric(this::getBlobMapSize); + } + class PendingTransactionsListenersProxy { private final Subscribers onAddedListeners = Subscribers.create(); diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolMetrics.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolMetrics.java index e08805551f..fac9b3174d 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolMetrics.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolMetrics.java @@ -28,6 +28,7 @@ import org.hyperledger.besu.plugin.services.metrics.LabelledMetric; import java.util.HashMap; import java.util.Map; import java.util.function.DoubleSupplier; +import java.util.function.IntSupplier; import org.apache.commons.lang3.tuple.Pair; import org.slf4j.Logger; @@ -285,4 +286,20 @@ public class TransactionPoolMetrics { private String priority(final boolean hasPriority) { return hasPriority ? "yes" : "no"; } + + public void createBlobCacheSizeMetric(final IntSupplier sizeSupplier) { + metricsSystem.createIntegerGauge( + BesuMetricCategory.TRANSACTION_POOL, + "blob_cache_size", + "Current size of the blob cache", + sizeSupplier); + } + + public void createBlobMapSizeMetric(final IntSupplier sizeSupplier) { + metricsSystem.createIntegerGauge( + BesuMetricCategory.TRANSACTION_POOL, + "blob_map_size", + "Current size of the blob map", + sizeSupplier); + } } From 25186d322110313d89c7cf9e77301f8e2671b8c0 Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Thu, 19 Sep 2024 17:30:49 -0600 Subject: [PATCH 219/259] Remove Danno Ferrin as maintainer (#7644) I am no longer aligned with the Governance policies and practices of LFDT and resign my position as maintainer. Signed-off-by: Danno Ferrin --- MAINTAINERS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS.md b/MAINTAINERS.md index 1bd4f851f5..f699321efb 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -28,7 +28,6 @@ | Matthew Whitehead| matthew1001 | matthew.whitehead | | Meredith Baxter | mbaxter | mbaxter | | Stefan Pingel | pinges | pinges | -| Danno Ferrin | shemnon | shemnon | | Simon Dudley | siladu | siladu | | Usman Saleem | usmansaleem | usmansaleem | @@ -52,6 +51,7 @@ | Rai Sur | RatanRSur | ratanraisur | | Rob Dawson | rojotek | RobDawson | | Sajida Zouarhi | sajz | SajidaZ | +| Danno Ferrin | shemnon | shemnon | | Taccat Isid | taccatisid | taccatisid | | Tim Beiko | timbeiko | timbeiko | | Vijay Michalik | vmichalik | VijayMichalik | From cb1e36a992bdf455916f604edfc22039b64f071e Mon Sep 17 00:00:00 2001 From: daniellehrner Date: Fri, 20 Sep 2024 03:56:25 +0200 Subject: [PATCH 220/259] Fix 7702 signature bound checks (#7641) * create separate signature class for code delegations as they have different bound checks Signed-off-by: Daniel Lehrner * test if increasing xmx let's failing acceptance test pass Signed-off-by: Daniel Lehrner * javadoc Signed-off-by: Sally MacFarlane --------- Signed-off-by: Daniel Lehrner Signed-off-by: Sally MacFarlane Co-authored-by: Sally MacFarlane --- .github/workflows/acceptance-tests.yml | 2 +- .../besu/crypto/AbstractSECP256.java | 6 ++ .../besu/crypto/CodeDelegationSignature.java | 59 ++++++++++++ .../besu/crypto/SignatureAlgorithm.java | 11 +++ .../crypto/CodeDelegationSignatureTest.java | 93 +++++++++++++++++++ .../CodeDelegationTransactionDecoder.java | 5 +- .../mainnet/MainnetTransactionValidator.java | 8 ++ .../encoding/CodeDelegationDecoderTest.java | 12 +++ 8 files changed, 193 insertions(+), 3 deletions(-) create mode 100644 crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/CodeDelegationSignature.java create mode 100644 crypto/algorithms/src/test/java/org/hyperledger/besu/crypto/CodeDelegationSignatureTest.java diff --git a/.github/workflows/acceptance-tests.yml b/.github/workflows/acceptance-tests.yml index 287f402bce..a8f6981d89 100644 --- a/.github/workflows/acceptance-tests.yml +++ b/.github/workflows/acceptance-tests.yml @@ -11,7 +11,7 @@ concurrency: cancel-in-progress: true env: - GRADLE_OPTS: "-Xmx6g" + GRADLE_OPTS: "-Xmx7g" total-runners: 12 jobs: diff --git a/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/AbstractSECP256.java b/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/AbstractSECP256.java index b10e654626..ce37651266 100644 --- a/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/AbstractSECP256.java +++ b/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/AbstractSECP256.java @@ -212,6 +212,12 @@ public abstract class AbstractSECP256 implements SignatureAlgorithm { return SECPSignature.create(r, s, recId, curveOrder); } + @Override + public CodeDelegationSignature createCodeDelegationSignature( + final BigInteger r, final BigInteger s, final long yParity) { + return CodeDelegationSignature.create(r, s, yParity); + } + @Override public SECPSignature decodeSignature(final Bytes bytes) { return SECPSignature.decode(bytes, curveOrder); diff --git a/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/CodeDelegationSignature.java b/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/CodeDelegationSignature.java new file mode 100644 index 0000000000..4bb2e4653e --- /dev/null +++ b/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/CodeDelegationSignature.java @@ -0,0 +1,59 @@ +/* + * 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.crypto; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.math.BigInteger; + +/** Secp signature with code delegation. */ +public class CodeDelegationSignature extends SECPSignature { + private static final BigInteger TWO_POW_256 = BigInteger.TWO.pow(256); + + /** + * Instantiates a new SECPSignature. + * + * @param r the r part of the signature + * @param s the s part of the signature + * @param yParity the parity of the y coordinate of the public key + */ + public CodeDelegationSignature(final BigInteger r, final BigInteger s, final byte yParity) { + super(r, s, yParity); + } + + /** + * Create a new CodeDelegationSignature. + * + * @param r the r part of the signature + * @param s the s part of the signature + * @param yParity the parity of the y coordinate of the public key + * @return the new CodeDelegationSignature + */ + public static CodeDelegationSignature create( + final BigInteger r, final BigInteger s, final long yParity) { + checkNotNull(r); + checkNotNull(s); + + if (r.compareTo(TWO_POW_256) >= 0) { + throw new IllegalArgumentException("Invalid 'r' value, should be < 2^256 but got " + r); + } + + if (s.compareTo(TWO_POW_256) >= 0) { + throw new IllegalArgumentException("Invalid 's' value, should be < 2^256 but got " + s); + } + + return new CodeDelegationSignature(r, s, (byte) yParity); + } +} diff --git a/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/SignatureAlgorithm.java b/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/SignatureAlgorithm.java index db9565d18d..8e19b60854 100644 --- a/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/SignatureAlgorithm.java +++ b/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/SignatureAlgorithm.java @@ -215,6 +215,17 @@ public interface SignatureAlgorithm { */ SECPSignature createSignature(final BigInteger r, final BigInteger s, final byte recId); + /** + * Create code delegation signature which have different bounds than transaction signatures. + * + * @param r the r part of the signature + * @param s the s part of the signature + * @param yParity the parity of the y coordinate of the public key + * @return the code delegation signature + */ + CodeDelegationSignature createCodeDelegationSignature( + final BigInteger r, final BigInteger s, final long yParity); + /** * Decode secp signature. * diff --git a/crypto/algorithms/src/test/java/org/hyperledger/besu/crypto/CodeDelegationSignatureTest.java b/crypto/algorithms/src/test/java/org/hyperledger/besu/crypto/CodeDelegationSignatureTest.java new file mode 100644 index 0000000000..1cc66966a7 --- /dev/null +++ b/crypto/algorithms/src/test/java/org/hyperledger/besu/crypto/CodeDelegationSignatureTest.java @@ -0,0 +1,93 @@ +/* + * 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.crypto; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; + +import java.math.BigInteger; + +import org.junit.jupiter.api.Test; + +class CodeDelegationSignatureTest { + + private static final BigInteger TWO_POW_256 = BigInteger.valueOf(2).pow(256); + + @Test + void testValidInputs() { + BigInteger r = BigInteger.ONE; + BigInteger s = BigInteger.TEN; + long yParity = 1L; + + CodeDelegationSignature result = CodeDelegationSignature.create(r, s, yParity); + + assertThat(r).isEqualTo(result.getR()); + assertThat(s).isEqualTo(result.getS()); + assertThat((byte) yParity).isEqualTo(result.getRecId()); + } + + @Test + void testNullRValue() { + BigInteger s = BigInteger.TEN; + long yParity = 0L; + + assertThatExceptionOfType(NullPointerException.class) + .isThrownBy(() -> CodeDelegationSignature.create(null, s, yParity)); + } + + @Test + void testNullSValue() { + BigInteger r = BigInteger.ONE; + long yParity = 0L; + + assertThatExceptionOfType(NullPointerException.class) + .isThrownBy(() -> CodeDelegationSignature.create(r, null, yParity)); + } + + @Test + void testRValueExceedsTwoPow256() { + BigInteger r = TWO_POW_256; + BigInteger s = BigInteger.TEN; + long yParity = 0L; + + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> CodeDelegationSignature.create(r, s, yParity)) + .withMessageContainingAll("Invalid 'r' value, should be < 2^256"); + } + + @Test + void testSValueExceedsTwoPow256() { + BigInteger r = BigInteger.ONE; + BigInteger s = TWO_POW_256; + long yParity = 0L; + + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> CodeDelegationSignature.create(r, s, yParity)) + .withMessageContainingAll("Invalid 's' value, should be < 2^256"); + } + + @Test + void testValidYParityZero() { + BigInteger r = BigInteger.ONE; + BigInteger s = BigInteger.TEN; + long yParity = 0L; + + CodeDelegationSignature result = CodeDelegationSignature.create(r, s, yParity); + + assertThat(r).isEqualTo(result.getR()); + assertThat(s).isEqualTo(result.getS()); + assertThat((byte) yParity).isEqualTo(result.getRecId()); + } +} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/CodeDelegationTransactionDecoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/CodeDelegationTransactionDecoder.java index 8961431c9c..d3ef60bfc4 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/CodeDelegationTransactionDecoder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/CodeDelegationTransactionDecoder.java @@ -81,13 +81,14 @@ public class CodeDelegationTransactionDecoder { final Address address = Address.wrap(input.readBytes()); final long nonce = input.readLongScalar(); - final byte yParity = (byte) input.readUnsignedByteScalar(); + final long yParity = input.readUnsignedIntScalar(); final BigInteger r = input.readUInt256Scalar().toUnsignedBigInteger(); final BigInteger s = input.readUInt256Scalar().toUnsignedBigInteger(); input.leaveList(); - final SECPSignature signature = SIGNATURE_ALGORITHM.get().createSignature(r, s, yParity); + final SECPSignature signature = + SIGNATURE_ALGORITHM.get().createCodeDelegationSignature(r, s, yParity); return new org.hyperledger.besu.ethereum.core.CodeDelegation( chainId, address, nonce, signature); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionValidator.java index e67ccbb4c6..0e86b6b878 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionValidator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionValidator.java @@ -52,6 +52,8 @@ import org.bouncycastle.crypto.digests.SHA256Digest; */ public class MainnetTransactionValidator implements TransactionValidator { + public static final BigInteger TWO_POW_256 = BigInteger.TWO.pow(256); + private final GasCalculator gasCalculator; private final GasLimitCalculator gasLimitCalculator; private final FeeMarket feeMarket; @@ -163,6 +165,12 @@ public class MainnetTransactionValidator implements TransactionValidator { .map( codeDelegations -> { for (CodeDelegation codeDelegation : codeDelegations) { + if (codeDelegation.chainId().compareTo(TWO_POW_256) >= 0) { + throw new IllegalArgumentException( + "Invalid 'chainId' value, should be < 2^256 but got " + + codeDelegation.chainId()); + } + if (codeDelegation.signature().getS().compareTo(halfCurveOrder) > 0) { return ValidationResult.invalid( TransactionInvalidReason.INVALID_SIGNATURE, diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/CodeDelegationDecoderTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/CodeDelegationDecoderTest.java index d6ff585b4f..a0c7689bc7 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/CodeDelegationDecoderTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/CodeDelegationDecoderTest.java @@ -99,4 +99,16 @@ class CodeDelegationDecoderTest { assertThat(signature.getS().toString(16)) .isEqualTo("3c8a25b2becd6e666f69803d1ae3322f2e137b7745c2c7f19da80f993ffde4df"); } + + @Test + void shouldDecodeInnerPayloadWhenSignatureIsZero() { + final BytesValueRLPInput input = + new BytesValueRLPInput( + Bytes.fromHexString( + "0xdf8501a1f0ff5a947a40026a3b9a41754a95eec8c92c6b99886f440c5b808080"), + true); + final CodeDelegation authorization = CodeDelegationTransactionDecoder.decodeInnerPayload(input); + + assertThat(authorization.chainId()).isEqualTo(new BigInteger("01a1f0ff5a", 16)); + } } From 637ebcb9c57107656b9a8e1cc261a2cd10a2e829 Mon Sep 17 00:00:00 2001 From: Gabriel Fukushima Date: Fri, 20 Sep 2024 12:25:16 +1000 Subject: [PATCH 221/259] add Teku EL-bootnode to holesky genesis (#7648) Signed-off-by: Gabriel Fukushima --- config/src/main/resources/holesky.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/config/src/main/resources/holesky.json b/config/src/main/resources/holesky.json index d91971b351..ea83279953 100644 --- a/config/src/main/resources/holesky.json +++ b/config/src/main/resources/holesky.json @@ -21,7 +21,8 @@ "bootnodes": [ "enode://ac906289e4b7f12df423d654c5a962b6ebe5b3a74cc9e06292a85221f9a64a6f1cfdd6b714ed6dacef51578f92b34c60ee91e9ede9c7f8fadc4d347326d95e2b@146.190.13.128:30303", "enode://a3435a0155a3e837c02f5e7f5662a2f1fbc25b48e4dc232016e1c51b544cb5b4510ef633ea3278c0e970fa8ad8141e2d4d0f9f95456c537ff05fdf9b31c15072@178.128.136.233:30303", - "enode://7fa09f1e8bb179ab5e73f45d3a7169a946e7b3de5ef5cea3a0d4546677e4435ee38baea4dd10b3ddfdc1f1c5e869052932af8b8aeb6f9738598ec4590d0b11a6@65.109.94.124:30303" + "enode://7fa09f1e8bb179ab5e73f45d3a7169a946e7b3de5ef5cea3a0d4546677e4435ee38baea4dd10b3ddfdc1f1c5e869052932af8b8aeb6f9738598ec4590d0b11a6@65.109.94.124:30303", + "enode://3524632a412f42dee4b9cc899b946912359bb20103d7596bddb9c8009e7683b7bff39ea20040b7ab64d23105d4eac932d86b930a605e632357504df800dba100@172.174.35.249:30303" ] } }, From e1f44897411eaa8a11a87c23c381090bb6ed18b1 Mon Sep 17 00:00:00 2001 From: Jason Frame Date: Fri, 20 Sep 2024 16:07:27 +1000 Subject: [PATCH 222/259] Disable body validation for POS networks during sync (#7646) Signed-off-by: Jason Frame Co-authored-by: Stefan Pingel <16143240+pinges@users.noreply.github.com> --- .../besu/ethereum/BlockValidator.java | 11 +- .../besu/ethereum/MainnetBlockValidator.java | 8 +- .../besu/ethereum/core/BlockImporter.java | 6 +- .../mainnet/BaseFeeBlockBodyValidator.java | 6 +- .../ethereum/mainnet/BlockBodyValidator.java | 3 +- .../ethereum/mainnet/BodyValidationMode.java | 26 ++++ .../mainnet/MainnetBlockBodyValidator.java | 34 +++-- .../mainnet/MainnetBlockImporter.java | 10 +- .../ethereum/MainnetBlockValidatorTest.java | 44 ++++--- .../MainnetBlockBodyValidatorTest.java | 123 +++++++++++++++++- .../mainnet/PragueRequestsValidatorTest.java | 3 +- .../FastSyncDownloadPipelineFactory.java | 8 +- .../eth/sync/fastsync/ImportBlocksStep.java | 14 +- .../sync/fastsync/ImportBlocksStepTest.java | 18 ++- 14 files changed, 255 insertions(+), 59 deletions(-) create mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/BodyValidationMode.java 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 e8136062bb..8cfafee730 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 @@ -17,6 +17,7 @@ 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; @@ -83,8 +84,8 @@ public interface BlockValidator { final boolean shouldRecordBadBlock); /** - * Performs fast block validation with the given context, block, transaction receipts, requests, - * header validation mode, and ommer validation mode. + * Performs fast block validation appropriate for use during syncing skipping transaction receipt + * roots and receipts roots as these are done during the download of the blocks. * * @param context the protocol context * @param block the block to validate @@ -92,13 +93,15 @@ public interface BlockValidator { * @param requests the requests * @param headerValidationMode the header validation mode * @param ommerValidationMode the ommer validation mode + * @param bodyValidationMode the body validation mode * @return true if the block is valid, false otherwise */ - boolean fastBlockValidation( + boolean validateBlockForSyncing( final ProtocolContext context, final Block block, final List receipts, final Optional> requests, final HeaderValidationMode headerValidationMode, - final HeaderValidationMode ommerValidationMode); + 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 5d80a95150..0c56a419e3 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 @@ -25,6 +25,7 @@ import org.hyperledger.besu.ethereum.core.TransactionReceipt; import org.hyperledger.besu.ethereum.mainnet.BlockBodyValidator; import org.hyperledger.besu.ethereum.mainnet.BlockHeaderValidator; import org.hyperledger.besu.ethereum.mainnet.BlockProcessor; +import org.hyperledger.besu.ethereum.mainnet.BodyValidationMode; import org.hyperledger.besu.ethereum.mainnet.HeaderValidationMode; import org.hyperledger.besu.ethereum.trie.MerkleTrieException; import org.hyperledger.besu.plugin.services.exception.StorageException; @@ -247,13 +248,14 @@ public class MainnetBlockValidator implements BlockValidator { } @Override - public boolean fastBlockValidation( + public boolean validateBlockForSyncing( final ProtocolContext context, final Block block, final List receipts, final Optional> requests, final HeaderValidationMode headerValidationMode, - final HeaderValidationMode ommerValidationMode) { + final HeaderValidationMode ommerValidationMode, + final BodyValidationMode bodyValidationMode) { final BlockHeader header = block.getHeader(); if (!blockHeaderValidator.validateHeader(header, context, headerValidationMode)) { String description = String.format("Failed header validation (%s)", headerValidationMode); @@ -262,7 +264,7 @@ public class MainnetBlockValidator implements BlockValidator { } if (!blockBodyValidator.validateBodyLight( - context, block, receipts, requests, ommerValidationMode)) { + context, block, receipts, requests, 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/core/BlockImporter.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockImporter.java index ce5c849e3a..468485b9fd 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockImporter.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockImporter.java @@ -16,6 +16,7 @@ package org.hyperledger.besu.ethereum.core; import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.mainnet.BlockImportResult; +import org.hyperledger.besu.ethereum.mainnet.BodyValidationMode; import org.hyperledger.besu.ethereum.mainnet.HeaderValidationMode; import java.util.List; @@ -73,10 +74,11 @@ public interface BlockImporter { * @return {@code BlockImportResult} * @see BlockImportResult */ - BlockImportResult fastImportBlock( + BlockImportResult importBlockForSyncing( ProtocolContext context, Block block, List receipts, HeaderValidationMode headerValidationMode, - HeaderValidationMode ommerValidationMode); + HeaderValidationMode ommerValidationMode, + BodyValidationMode bodyValidationMode); } 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 0e288185cf..aabc4ee5d0 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 @@ -43,9 +43,11 @@ public class BaseFeeBlockBodyValidator extends MainnetBlockBodyValidator { final Block block, final List receipts, final Optional> requests, - final HeaderValidationMode ommerValidationMode) { + final HeaderValidationMode ommerValidationMode, + final BodyValidationMode bodyValidationMode) { - return super.validateBodyLight(context, block, receipts, requests, ommerValidationMode) + return super.validateBodyLight( + context, block, receipts, requests, 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 62b4985f5c..c84be3771b 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 @@ -59,5 +59,6 @@ public interface BlockBodyValidator { Block block, List receipts, final Optional> requests, - final HeaderValidationMode ommerValidationMode); + final HeaderValidationMode ommerValidationMode, + final BodyValidationMode bodyValidationMode); } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/BodyValidationMode.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/BodyValidationMode.java new file mode 100644 index 0000000000..344a950e36 --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/BodyValidationMode.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.mainnet; + +public enum BodyValidationMode { + /** No Validation. data must be pre-validated */ + NONE, + + /** Skip receipts and transactions root validation */ + LIGHT, + + /** Fully validate the body */ + FULL; +} 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 3202440dd8..68951f9f2a 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 @@ -29,6 +29,7 @@ import java.util.List; import java.util.Optional; import java.util.Set; +import com.google.common.annotations.VisibleForTesting; import org.apache.tuweni.bytes.Bytes32; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -55,7 +56,8 @@ public class MainnetBlockBodyValidator implements BlockBodyValidator { final Hash worldStateRootHash, final HeaderValidationMode ommerValidationMode) { - if (!validateBodyLight(context, block, receipts, requests, ommerValidationMode)) { + if (!validateBodyLight( + context, block, receipts, requests, ommerValidationMode, BodyValidationMode.FULL)) { return false; } @@ -77,18 +79,26 @@ public class MainnetBlockBodyValidator implements BlockBodyValidator { final Block block, final List receipts, final Optional> requests, - final HeaderValidationMode ommerValidationMode) { + final HeaderValidationMode ommerValidationMode, + final BodyValidationMode bodyValidationMode) { + if (bodyValidationMode == BodyValidationMode.NONE) { + return true; + } + final BlockHeader header = block.getHeader(); final BlockBody body = block.getBody(); - final Bytes32 transactionsRoot = BodyValidation.transactionsRoot(body.getTransactions()); - if (!validateTransactionsRoot(header, header.getTransactionsRoot(), transactionsRoot)) { - return false; - } + // these checks are only needed for full validation and can be skipped for light validation + if (bodyValidationMode == BodyValidationMode.FULL) { + final Bytes32 transactionsRoot = BodyValidation.transactionsRoot(body.getTransactions()); + if (!validateTransactionsRoot(header, header.getTransactionsRoot(), transactionsRoot)) { + return false; + } - final Bytes32 receiptsRoot = BodyValidation.receiptsRoot(receipts); - if (!validateReceiptsRoot(header, header.getReceiptsRoot(), receiptsRoot)) { - return false; + final Bytes32 receiptsRoot = BodyValidation.receiptsRoot(receipts); + if (!validateReceiptsRoot(header, header.getReceiptsRoot(), receiptsRoot)) { + return false; + } } final long gasUsed = @@ -115,7 +125,8 @@ public class MainnetBlockBodyValidator implements BlockBodyValidator { return true; } - private static boolean validateTransactionsRoot( + @VisibleForTesting + protected boolean validateTransactionsRoot( final BlockHeader header, final Bytes32 expected, final Bytes32 actual) { if (!expected.equals(actual)) { LOG.info( @@ -157,7 +168,8 @@ public class MainnetBlockBodyValidator implements BlockBodyValidator { return true; } - private static boolean validateReceiptsRoot( + @VisibleForTesting + protected boolean validateReceiptsRoot( final BlockHeader header, final Bytes32 expected, final Bytes32 actual) { if (!expected.equals(actual)) { LOG.warn( 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 62b708d33e..8646467a28 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 @@ -57,20 +57,22 @@ public class MainnetBlockImporter implements BlockImporter { } @Override - public BlockImportResult fastImportBlock( + public BlockImportResult importBlockForSyncing( final ProtocolContext context, final Block block, final List receipts, final HeaderValidationMode headerValidationMode, - final HeaderValidationMode ommerValidationMode) { + final HeaderValidationMode ommerValidationMode, + final BodyValidationMode bodyValidationMode) { - if (blockValidator.fastBlockValidation( + if (blockValidator.validateBlockForSyncing( context, block, receipts, block.getBody().getRequests(), headerValidationMode, - ommerValidationMode)) { + ommerValidationMode, + bodyValidationMode)) { context.getBlockchain().appendBlock(block, receipts); return new BlockImportResult(true); } 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 361353ee2b..40573ee8d6 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 @@ -34,6 +34,7 @@ import org.hyperledger.besu.ethereum.core.MutableWorldState; import org.hyperledger.besu.ethereum.mainnet.BlockBodyValidator; import org.hyperledger.besu.ethereum.mainnet.BlockHeaderValidator; import org.hyperledger.besu.ethereum.mainnet.BlockProcessor; +import org.hyperledger.besu.ethereum.mainnet.BodyValidationMode; import org.hyperledger.besu.ethereum.mainnet.HeaderValidationMode; import org.hyperledger.besu.ethereum.trie.MerkleTrieException; import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; @@ -98,7 +99,8 @@ public class MainnetBlockValidatorTest { 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())).thenReturn(true); + when(blockBodyValidator.validateBodyLight(any(), any(), any(), any(), any(), any())) + .thenReturn(true); when(blockProcessor.processBlock(any(), any(), any())).thenReturn(successfulProcessingResult); when(blockProcessor.processBlock(any(), any(), any(), any())) .thenReturn(successfulProcessingResult); @@ -343,55 +345,65 @@ public class MainnetBlockValidatorTest { } @Test - public void fastBlockValidation_onSuccess() { + public void validateBlockForSyncing_onSuccess() { final boolean isValid = - mainnetBlockValidator.fastBlockValidation( + mainnetBlockValidator.validateBlockForSyncing( protocolContext, block, Collections.emptyList(), block.getBody().getRequests(), HeaderValidationMode.FULL, - HeaderValidationMode.FULL); + HeaderValidationMode.FULL, + BodyValidationMode.FULL); assertThat(isValid).isTrue(); assertNoBadBlocks(); } @Test - public void fastBlockValidation_onFailedHeaderValidation() { - final HeaderValidationMode validationMode = HeaderValidationMode.FULL; + public void validateBlockValidation_onFailedHeaderForSyncing() { + final HeaderValidationMode headerValidationMode = HeaderValidationMode.FULL; when(blockHeaderValidator.validateHeader( - any(BlockHeader.class), eq(protocolContext), eq(validationMode))) + any(BlockHeader.class), eq(protocolContext), eq(headerValidationMode))) .thenReturn(false); + final BodyValidationMode bodyValidationMode = BodyValidationMode.FULL; final boolean isValid = - mainnetBlockValidator.fastBlockValidation( + mainnetBlockValidator.validateBlockForSyncing( protocolContext, block, Collections.emptyList(), block.getBody().getRequests(), - validationMode, - validationMode); + headerValidationMode, + headerValidationMode, + bodyValidationMode); assertThat(isValid).isFalse(); assertBadBlockIsTracked(block); } @Test - public void fastBlockValidation_onFailedBodyValidation() { - final HeaderValidationMode validationMode = HeaderValidationMode.FULL; + public void validateBlockValidation_onFailedBodyForSyncing() { + final HeaderValidationMode headerValidationMode = HeaderValidationMode.FULL; + final BodyValidationMode bodyValidationMode = BodyValidationMode.FULL; when(blockBodyValidator.validateBodyLight( - eq(protocolContext), eq(block), any(), any(), eq(validationMode))) + eq(protocolContext), + eq(block), + any(), + any(), + eq(headerValidationMode), + eq(bodyValidationMode))) .thenReturn(false); final boolean isValid = - mainnetBlockValidator.fastBlockValidation( + mainnetBlockValidator.validateBlockForSyncing( protocolContext, block, Collections.emptyList(), block.getBody().getRequests(), - validationMode, - validationMode); + headerValidationMode, + headerValidationMode, + bodyValidationMode); assertThat(isValid).isFalse(); assertBadBlockIsTracked(block); 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 c116d545d8..c412a30756 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 @@ -19,14 +19,22 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.hyperledger.besu.ethereum.mainnet.HeaderValidationMode.NONE; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.lenient; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; import static org.mockito.Mockito.when; import org.hyperledger.besu.datatypes.Address; 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.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; @@ -93,7 +101,12 @@ class MainnetBlockBodyValidatorTest { assertThat( new MainnetBlockBodyValidator(protocolSchedule) .validateBodyLight( - blockchainSetupUtil.getProtocolContext(), block, emptyList(), any(), NONE)) + blockchainSetupUtil.getProtocolContext(), + block, + emptyList(), + any(), + NONE, + BodyValidationMode.FULL)) .isTrue(); } @@ -117,7 +130,12 @@ class MainnetBlockBodyValidatorTest { assertThat( new MainnetBlockBodyValidator(protocolSchedule) .validateBodyLight( - blockchainSetupUtil.getProtocolContext(), block, emptyList(), any(), NONE)) + blockchainSetupUtil.getProtocolContext(), + block, + emptyList(), + any(), + NONE, + BodyValidationMode.FULL)) .isFalse(); } @@ -141,7 +159,12 @@ class MainnetBlockBodyValidatorTest { assertThat( new MainnetBlockBodyValidator(protocolSchedule) .validateBodyLight( - blockchainSetupUtil.getProtocolContext(), block, emptyList(), any(), NONE)) + blockchainSetupUtil.getProtocolContext(), + block, + emptyList(), + any(), + NONE, + BodyValidationMode.FULL)) .isFalse(); } @@ -165,7 +188,99 @@ class MainnetBlockBodyValidatorTest { assertThat( new MainnetBlockBodyValidator(protocolSchedule) .validateBodyLight( - blockchainSetupUtil.getProtocolContext(), block, emptyList(), any(), NONE)) + blockchainSetupUtil.getProtocolContext(), + block, + emptyList(), + any(), + NONE, + BodyValidationMode.FULL)) .isFalse(); } + + @Test + @SuppressWarnings("unchecked") + public void noneValidationModeDoesNothing() { + final Block block = mock(Block.class); + final List receipts = mock(List.class); + + final MainnetBlockBodyValidator bodyValidator = new MainnetBlockBodyValidator(protocolSchedule); + + assertThat( + bodyValidator.validateBodyLight( + blockchainSetupUtil.getProtocolContext(), + block, + receipts, + Optional.empty(), + NONE, + BodyValidationMode.NONE)) + .isTrue(); + verifyNoInteractions(block); + verifyNoInteractions(receipts); + } + + @Test + public void lightValidationDoesNotCheckTransactionRootOrReceiptRoot() { + 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()) + .setWithdrawals(Optional.of(withdrawals))); + blockchainSetupUtil.getBlockchain().appendBlock(block, Collections.emptyList()); + + final MainnetBlockBodyValidator bodyValidator = new MainnetBlockBodyValidator(protocolSchedule); + final MainnetBlockBodyValidator bodyValidatorSpy = spy(bodyValidator); + + assertThat( + bodyValidatorSpy.validateBodyLight( + blockchainSetupUtil.getProtocolContext(), + block, + emptyList(), + Optional.empty(), + NONE, + BodyValidationMode.LIGHT)) + .isTrue(); + verify(bodyValidatorSpy, never()).validateReceiptsRoot(any(), any(), any()); + verify(bodyValidatorSpy, never()).validateTransactionsRoot(any(), any(), any()); + } + + @Test + public void fullValidationChecksTransactionRootAndReceiptRoot() { + 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()) + .setWithdrawals(Optional.of(withdrawals))); + blockchainSetupUtil.getBlockchain().appendBlock(block, Collections.emptyList()); + + final MainnetBlockBodyValidator bodyValidator = new MainnetBlockBodyValidator(protocolSchedule); + final MainnetBlockBodyValidator bodyValidatorSpy = spy(bodyValidator); + + assertThat( + bodyValidatorSpy.validateBodyLight( + blockchainSetupUtil.getProtocolContext(), + block, + emptyList(), + Optional.empty(), + NONE, + BodyValidationMode.FULL)) + .isTrue(); + final Hash receiptsRoot = BodyValidation.receiptsRoot(emptyList()); + final Hash transactionsRoot = BodyValidation.transactionsRoot(emptyList()); + verify(bodyValidatorSpy, times(1)) + .validateReceiptsRoot(block.getHeader(), receiptsRoot, receiptsRoot); + verify(bodyValidatorSpy, times(1)) + .validateTransactionsRoot(block.getHeader(), transactionsRoot, transactionsRoot); + } } 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 index 833e692d7f..6c325b70a8 100644 --- 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 @@ -106,7 +106,8 @@ class PragueRequestsValidatorTest { block, emptyList(), expectedRequests, - NONE)) + NONE, + BodyValidationMode.FULL)) .isFalse(); } } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncDownloadPipelineFactory.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncDownloadPipelineFactory.java index 07e964426c..87032b76e5 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncDownloadPipelineFactory.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncDownloadPipelineFactory.java @@ -37,6 +37,7 @@ import org.hyperledger.besu.ethereum.eth.sync.range.SyncTargetRange; import org.hyperledger.besu.ethereum.eth.sync.range.SyncTargetRangeSource; import org.hyperledger.besu.ethereum.eth.sync.state.SyncState; import org.hyperledger.besu.ethereum.eth.sync.state.SyncTarget; +import org.hyperledger.besu.ethereum.mainnet.BodyValidationMode; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.metrics.BesuMetricCategory; import org.hyperledger.besu.plugin.services.MetricsSystem; @@ -117,6 +118,10 @@ public class FastSyncDownloadPipelineFactory implements DownloadPipelineFactory final int downloaderParallelism = syncConfig.getDownloaderParallelism(); final int headerRequestSize = syncConfig.getDownloaderHeaderRequestSize(); final int singleHeaderBufferSize = headerRequestSize * downloaderParallelism; + final BodyValidationMode bodyValidationMode = + protocolSchedule.anyMatch(scheduledProtocolSpec -> scheduledProtocolSpec.spec().isPoS()) + ? BodyValidationMode.NONE + : BodyValidationMode.LIGHT; final SyncTargetRangeSource checkpointRangeSource = new SyncTargetRangeSource( new RangeHeadersFetcher( @@ -148,7 +153,8 @@ public class FastSyncDownloadPipelineFactory implements DownloadPipelineFactory attachedValidationPolicy, ommerValidationPolicy, ethContext, - fastSyncState.getPivotBlockHeader().get()); + fastSyncState.getPivotBlockHeader().get(), + bodyValidationMode); return PipelineBuilder.createPipelineFrom( "fetchCheckpoints", diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/ImportBlocksStep.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/ImportBlocksStep.java index c6945964cf..20b9d84916 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/ImportBlocksStep.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/ImportBlocksStep.java @@ -22,6 +22,7 @@ import org.hyperledger.besu.ethereum.eth.manager.EthContext; import org.hyperledger.besu.ethereum.eth.sync.ValidationPolicy; import org.hyperledger.besu.ethereum.eth.sync.tasks.exceptions.InvalidBlockException; import org.hyperledger.besu.ethereum.mainnet.BlockImportResult; +import org.hyperledger.besu.ethereum.mainnet.BodyValidationMode; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import java.util.List; @@ -45,6 +46,7 @@ public class ImportBlocksStep implements Consumer> { private long accumulatedTime = 0L; private OptionalLong logStartBlock = OptionalLong.empty(); private final BlockHeader pivotHeader; + private final BodyValidationMode bodyValidationMode; public ImportBlocksStep( final ProtocolSchedule protocolSchedule, @@ -52,13 +54,15 @@ public class ImportBlocksStep implements Consumer> { final ValidationPolicy headerValidationPolicy, final ValidationPolicy ommerValidationPolicy, final EthContext ethContext, - final BlockHeader pivotHeader) { + final BlockHeader pivotHeader, + final BodyValidationMode bodyValidationMode) { this.protocolSchedule = protocolSchedule; this.protocolContext = protocolContext; this.headerValidationPolicy = headerValidationPolicy; this.ommerValidationPolicy = ommerValidationPolicy; this.ethContext = ethContext; this.pivotHeader = pivotHeader; + this.bodyValidationMode = bodyValidationMode; } @Override @@ -106,20 +110,20 @@ public class ImportBlocksStep implements Consumer> { if (totalBlocks == 0) { return 0; } - final long blocksPercent = (100 * lastBlock / totalBlocks); - return blocksPercent; + return (100 * lastBlock / totalBlocks); } protected boolean importBlock(final BlockWithReceipts blockWithReceipts) { final BlockImporter importer = protocolSchedule.getByBlockHeader(blockWithReceipts.getHeader()).getBlockImporter(); final BlockImportResult blockImportResult = - importer.fastImportBlock( + importer.importBlockForSyncing( protocolContext, blockWithReceipts.getBlock(), blockWithReceipts.getReceipts(), headerValidationPolicy.getValidationModeForNextBlock(), - ommerValidationPolicy.getValidationModeForNextBlock()); + ommerValidationPolicy.getValidationModeForNextBlock(), + bodyValidationMode); return blockImportResult.isImported(); } } diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/ImportBlocksStepTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/ImportBlocksStepTest.java index 70c9e10eba..af4f45f690 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/ImportBlocksStepTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/ImportBlocksStepTest.java @@ -33,6 +33,7 @@ import org.hyperledger.besu.ethereum.core.BlockWithReceipts; import org.hyperledger.besu.ethereum.eth.sync.ValidationPolicy; import org.hyperledger.besu.ethereum.eth.sync.tasks.exceptions.InvalidBlockException; import org.hyperledger.besu.ethereum.mainnet.BlockImportResult; +import org.hyperledger.besu.ethereum.mainnet.BodyValidationMode; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; @@ -72,7 +73,8 @@ public class ImportBlocksStepTest { validationPolicy, ommerValidationPolicy, null, - pivotHeader); + pivotHeader, + BodyValidationMode.FULL); } @Test @@ -84,12 +86,13 @@ public class ImportBlocksStepTest { .collect(toList()); for (final BlockWithReceipts blockWithReceipts : blocksWithReceipts) { - when(blockImporter.fastImportBlock( + when(blockImporter.importBlockForSyncing( protocolContext, blockWithReceipts.getBlock(), blockWithReceipts.getReceipts(), FULL, - LIGHT)) + LIGHT, + BodyValidationMode.FULL)) .thenReturn(new BlockImportResult(true)); } importBlocksStep.accept(blocksWithReceipts); @@ -105,8 +108,13 @@ public class ImportBlocksStepTest { final Block block = gen.block(); final BlockWithReceipts blockWithReceipts = new BlockWithReceipts(block, gen.receipts(block)); - when(blockImporter.fastImportBlock( - protocolContext, block, blockWithReceipts.getReceipts(), FULL, LIGHT)) + when(blockImporter.importBlockForSyncing( + protocolContext, + block, + blockWithReceipts.getReceipts(), + FULL, + LIGHT, + BodyValidationMode.FULL)) .thenReturn(new BlockImportResult(false)); assertThatThrownBy(() -> importBlocksStep.accept(singletonList(blockWithReceipts))) .isInstanceOf(InvalidBlockException.class); From e721237c26b518d9b4f100b695df8ab7290034ee Mon Sep 17 00:00:00 2001 From: Matt Whitehead Date: Fri, 20 Sep 2024 09:38:57 +0100 Subject: [PATCH 223/259] Don't persist IBFT2 proposal blocks, just validate them (#7631) * Don't persist IBFT2 proposal blocks, just validate them Signed-off-by: Matthew Whitehead * Tidy up changelog Signed-off-by: Matthew Whitehead --------- Signed-off-by: Matthew Whitehead Signed-off-by: Matt Whitehead --- CHANGELOG.md | 2 +- .../hyperledger/besu/consensus/common/bft/RoundTimer.java | 2 +- .../besu/consensus/ibft/validation/MessageValidator.java | 8 +++++--- .../consensus/ibft/validation/MessageValidatorTest.java | 4 ++-- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c1ecca978e..246df1d91c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,7 @@ - Fix mounted data path directory permissions for besu user [#7575](https://github.com/hyperledger/besu/pull/7575) - Fix for `debug_traceCall` to handle transactions without specified gas price. [#7510](https://github.com/hyperledger/besu/pull/7510) - 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) ## 24.9.1 diff --git a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/RoundTimer.java b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/RoundTimer.java index 6a8b02991d..a01dc652cf 100644 --- a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/RoundTimer.java +++ b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/RoundTimer.java @@ -81,7 +81,7 @@ public class RoundTimer { // Once we are up to round 2 start logging round expiries if (round.getRoundNumber() >= 2) { LOG.info( - "QBFT round {} expired. Moved to round {} which will expire in {} seconds", + "BFT round {} expired. Moved to round {} which will expire in {} seconds", round.getRoundNumber() - 1, round.getRoundNumber(), (expiryTime / 1000)); diff --git a/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/validation/MessageValidator.java b/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/validation/MessageValidator.java index 783861cdfe..1d7b3da9d6 100644 --- a/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/validation/MessageValidator.java +++ b/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/validation/MessageValidator.java @@ -78,7 +78,9 @@ public class MessageValidator { return false; } - if (!validateBlock(msg.getBlock())) { + // We want to validate the block but not persist it yet as it's just a proposal. If it turns + // out to be an accepted block it will be persisted at block import time + if (!validateBlockWithoutPersisting(msg.getBlock())) { return false; } @@ -93,14 +95,14 @@ public class MessageValidator { msg.getSignedPayload(), msg.getBlock(), blockInterface); } - private boolean validateBlock(final Block block) { + private boolean validateBlockWithoutPersisting(final Block block) { final BlockValidator blockValidator = protocolSchedule.getByBlockHeader(block.getHeader()).getBlockValidator(); final var validationResult = blockValidator.validateAndProcessBlock( - protocolContext, block, HeaderValidationMode.LIGHT, HeaderValidationMode.FULL); + protocolContext, block, HeaderValidationMode.LIGHT, HeaderValidationMode.FULL, false); if (validationResult.isFailed()) { LOG.info( diff --git a/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/validation/MessageValidatorTest.java b/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/validation/MessageValidatorTest.java index f7fb7af3e9..2352642b87 100644 --- a/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/validation/MessageValidatorTest.java +++ b/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/validation/MessageValidatorTest.java @@ -113,7 +113,7 @@ public class MessageValidatorTest { when(protocolSpec.getBlockValidator()).thenReturn(blockValidator); when(protocolSchedule.getByBlockHeader(any())).thenReturn(protocolSpec); - when(blockValidator.validateAndProcessBlock(any(), any(), any(), any())) + when(blockValidator.validateAndProcessBlock(any(), any(), any(), any(), eq(false))) .thenReturn(new BlockProcessingResult(Optional.empty())); when(roundChangeCertificateValidator.validateProposalMessageMatchesLatestPrepareCertificate( @@ -168,7 +168,7 @@ public class MessageValidatorTest { @Test public void blockValidationFailureFailsValidation() { - when(blockValidator.validateAndProcessBlock(any(), any(), any(), any())) + when(blockValidator.validateAndProcessBlock(any(), any(), any(), any(), eq(false))) .thenReturn(new BlockProcessingResult("Failed")); final Proposal proposalMsg = From 19d3ca84b282f4db26f95497187209ea7fb6c72d Mon Sep 17 00:00:00 2001 From: Matt Whitehead Date: Fri, 20 Sep 2024 10:12:11 +0100 Subject: [PATCH 224/259] Dev/test option for short BFT block periods (#7588) * Dev mode for short BFT block periods Signed-off-by: Matthew Whitehead * Refactoring Signed-off-by: Matthew Whitehead * Fix comment Signed-off-by: Matthew Whitehead * Refactor to make BFT block milliseconds an experimental QBFT config option Signed-off-by: Matthew Whitehead * Update Json BFT config options Signed-off-by: Matthew Whitehead --------- Signed-off-by: Matthew Whitehead --- .../controller/IbftBesuControllerBuilder.java | 6 +- .../controller/QbftBesuControllerBuilder.java | 6 +- .../besu/config/BftConfigOptions.java | 7 +++ .../org/hyperledger/besu/config/BftFork.java | 13 +++++ .../besu/config/JsonBftConfigOptions.java | 10 ++++ .../besu/consensus/common/bft/BlockTimer.java | 29 ++++++++-- .../common/bft/MutableBftConfigOptions.java | 17 ++++++ .../besu/consensus/common/bft/RoundTimer.java | 12 ++-- .../consensus/common/bft/RoundTimerTest.java | 3 +- .../ibft/support/TestContextBuilder.java | 3 +- ...ftBlockHeaderValidationRulesetFactory.java | 58 +++++++++++-------- .../ibft/IbftProtocolScheduleBuilder.java | 6 +- ...ockHeaderValidationRulesetFactoryTest.java | 6 +- .../blockcreation/BftBlockCreatorTest.java | 5 +- .../qbft/support/TestContextBuilder.java | 3 +- ...ftBlockHeaderValidationRulesetFactory.java | 50 ++++++++++------ .../qbft/QbftForksSchedulesFactory.java | 1 + .../qbft/QbftProtocolScheduleBuilder.java | 5 +- ...ockHeaderValidationRulesetFactoryTest.java | 6 +- 19 files changed, 181 insertions(+), 65 deletions(-) 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 b8d4d2645e..58412029fc 100644 --- a/besu/src/main/java/org/hyperledger/besu/controller/IbftBesuControllerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/controller/IbftBesuControllerBuilder.java @@ -74,6 +74,7 @@ import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; import org.hyperledger.besu.plugin.services.BesuEvents; import org.hyperledger.besu.util.Subscribers; +import java.time.Duration; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -182,7 +183,10 @@ public class IbftBesuControllerBuilder extends BftBesuControllerBuilder { Util.publicKeyToAddress(nodeKey.getPublicKey()), proposerSelector, uniqueMessageMulticaster, - new RoundTimer(bftEventQueue, bftConfig.getRequestTimeoutSeconds(), bftExecutors), + new RoundTimer( + bftEventQueue, + Duration.ofSeconds(bftConfig.getRequestTimeoutSeconds()), + bftExecutors), new BlockTimer(bftEventQueue, forksSchedule, bftExecutors, clock), blockCreatorFactory, clock); 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 7961305c48..3d3412d486 100644 --- a/besu/src/main/java/org/hyperledger/besu/controller/QbftBesuControllerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/controller/QbftBesuControllerBuilder.java @@ -84,6 +84,7 @@ import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; import org.hyperledger.besu.plugin.services.BesuEvents; import org.hyperledger.besu.util.Subscribers; +import java.time.Duration; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -222,7 +223,10 @@ public class QbftBesuControllerBuilder extends BftBesuControllerBuilder { Util.publicKeyToAddress(nodeKey.getPublicKey()), proposerSelector, uniqueMessageMulticaster, - new RoundTimer(bftEventQueue, qbftConfig.getRequestTimeoutSeconds(), bftExecutors), + new RoundTimer( + bftEventQueue, + Duration.ofSeconds(qbftConfig.getRequestTimeoutSeconds()), + bftExecutors), new BlockTimer(bftEventQueue, qbftForksSchedule, bftExecutors, clock), blockCreatorFactory, clock); diff --git a/config/src/main/java/org/hyperledger/besu/config/BftConfigOptions.java b/config/src/main/java/org/hyperledger/besu/config/BftConfigOptions.java index c94752b598..58df7be849 100644 --- a/config/src/main/java/org/hyperledger/besu/config/BftConfigOptions.java +++ b/config/src/main/java/org/hyperledger/besu/config/BftConfigOptions.java @@ -37,6 +37,13 @@ public interface BftConfigOptions { */ int getBlockPeriodSeconds(); + /** + * Gets block period milliseconds. For TESTING only. If set then blockperiodseconds is ignored. + * + * @return the block period milliseconds + */ + long getBlockPeriodMilliseconds(); + /** * Gets request timeout seconds. * diff --git a/config/src/main/java/org/hyperledger/besu/config/BftFork.java b/config/src/main/java/org/hyperledger/besu/config/BftFork.java index 30f8e1c5d5..fdaa8f2fa9 100644 --- a/config/src/main/java/org/hyperledger/besu/config/BftFork.java +++ b/config/src/main/java/org/hyperledger/besu/config/BftFork.java @@ -21,6 +21,7 @@ import java.util.List; import java.util.Locale; import java.util.Optional; import java.util.OptionalInt; +import java.util.OptionalLong; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.databind.node.ArrayNode; @@ -40,6 +41,9 @@ public class BftFork implements Fork { /** The constant BLOCK_PERIOD_SECONDS_KEY. */ public static final String BLOCK_PERIOD_SECONDS_KEY = "blockperiodseconds"; + /** The constant BLOCK_PERIOD_MILLISECONDS_KEY. */ + public static final String BLOCK_PERIOD_MILLISECONDS_KEY = "xblockperiodmilliseconds"; + /** The constant BLOCK_REWARD_KEY. */ public static final String BLOCK_REWARD_KEY = "blockreward"; @@ -82,6 +86,15 @@ public class BftFork implements Fork { return JsonUtil.getPositiveInt(forkConfigRoot, BLOCK_PERIOD_SECONDS_KEY); } + /** + * Gets block period milliseconds. Experimental for test scenarios only. + * + * @return the block period milliseconds + */ + public OptionalLong getBlockPeriodMilliseconds() { + return JsonUtil.getLong(forkConfigRoot, BLOCK_PERIOD_MILLISECONDS_KEY); + } + /** * Gets block reward wei. * diff --git a/config/src/main/java/org/hyperledger/besu/config/JsonBftConfigOptions.java b/config/src/main/java/org/hyperledger/besu/config/JsonBftConfigOptions.java index 95f2d9f7ce..b1c8630b39 100644 --- a/config/src/main/java/org/hyperledger/besu/config/JsonBftConfigOptions.java +++ b/config/src/main/java/org/hyperledger/besu/config/JsonBftConfigOptions.java @@ -34,6 +34,7 @@ public class JsonBftConfigOptions implements BftConfigOptions { private static final long DEFAULT_EPOCH_LENGTH = 30_000; private static final int DEFAULT_BLOCK_PERIOD_SECONDS = 1; + private static final int DEFAULT_BLOCK_PERIOD_MILLISECONDS = 0; // Experimental for test only private static final int DEFAULT_ROUND_EXPIRY_SECONDS = 1; // In a healthy network this can be very small. This default limit will allow for suitable // protection for on a typical 20 node validator network with multiple rounds @@ -66,6 +67,12 @@ public class JsonBftConfigOptions implements BftConfigOptions { bftConfigRoot, "blockperiodseconds", DEFAULT_BLOCK_PERIOD_SECONDS); } + @Override + public long getBlockPeriodMilliseconds() { + return JsonUtil.getLong( + bftConfigRoot, "xblockperiodmilliseconds", DEFAULT_BLOCK_PERIOD_MILLISECONDS); + } + @Override public int getRequestTimeoutSeconds() { return JsonUtil.getInt(bftConfigRoot, "requesttimeoutseconds", DEFAULT_ROUND_EXPIRY_SECONDS); @@ -133,6 +140,9 @@ public class JsonBftConfigOptions implements BftConfigOptions { if (bftConfigRoot.has("blockperiodseconds")) { builder.put("blockPeriodSeconds", getBlockPeriodSeconds()); } + if (bftConfigRoot.has("xblockperiodmilliseconds")) { + builder.put("xBlockPeriodMilliSeconds", getBlockPeriodMilliseconds()); + } if (bftConfigRoot.has("requesttimeoutseconds")) { builder.put("requestTimeoutSeconds", getRequestTimeoutSeconds()); } diff --git a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BlockTimer.java b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BlockTimer.java index 5649b69e8f..49ef94e008 100644 --- a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BlockTimer.java +++ b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BlockTimer.java @@ -24,9 +24,14 @@ import java.util.Optional; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** Class for starting and keeping organised block timers */ public class BlockTimer { + private static final Logger LOG = LoggerFactory.getLogger(BlockTimer.class); + private final ForksSchedule forksSchedule; private final BftExecutors bftExecutors; private Optional> currentTimerTask; @@ -79,12 +84,26 @@ public class BlockTimer { cancelTimer(); final long now = clock.millis(); + final long expiryTime; + + // Experimental option for test scenarios only. Not for production use. + final long blockPeriodMilliseconds = + forksSchedule.getFork(round.getSequenceNumber()).getValue().getBlockPeriodMilliseconds(); - // absolute time when the timer is supposed to expire - final int blockPeriodSeconds = - forksSchedule.getFork(round.getSequenceNumber()).getValue().getBlockPeriodSeconds(); - final long minimumTimeBetweenBlocksMillis = blockPeriodSeconds * 1000L; - final long expiryTime = chainHeadHeader.getTimestamp() * 1_000 + minimumTimeBetweenBlocksMillis; + if (blockPeriodMilliseconds > 0) { + // Experimental mode for setting < 1 second block periods e.g. for CI/CD pipelines + // running tests against Besu + expiryTime = clock.millis() + blockPeriodMilliseconds; + LOG.warn( + "Test-mode only xblockperiodmilliseconds has been set to {} millisecond blocks. Do not use in a production system.", + blockPeriodMilliseconds); + } else { + // absolute time when the timer is supposed to expire + final int blockPeriodSeconds = + forksSchedule.getFork(round.getSequenceNumber()).getValue().getBlockPeriodSeconds(); + final long minimumTimeBetweenBlocksMillis = blockPeriodSeconds * 1000L; + expiryTime = chainHeadHeader.getTimestamp() * 1_000 + minimumTimeBetweenBlocksMillis; + } if (expiryTime > now) { final long delay = expiryTime - now; diff --git a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/MutableBftConfigOptions.java b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/MutableBftConfigOptions.java index fd406ea5e1..7b27c7b4c4 100644 --- a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/MutableBftConfigOptions.java +++ b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/MutableBftConfigOptions.java @@ -31,6 +31,7 @@ import java.util.Optional; public class MutableBftConfigOptions implements BftConfigOptions { private long epochLength; private int blockPeriodSeconds; + private long blockPeriodMilliseconds; private int requestTimeoutSeconds; private int gossipedHistoryLimit; private int messageQueueLimit; @@ -48,6 +49,7 @@ public class MutableBftConfigOptions implements BftConfigOptions { public MutableBftConfigOptions(final BftConfigOptions bftConfigOptions) { this.epochLength = bftConfigOptions.getEpochLength(); this.blockPeriodSeconds = bftConfigOptions.getBlockPeriodSeconds(); + this.blockPeriodMilliseconds = bftConfigOptions.getBlockPeriodMilliseconds(); this.requestTimeoutSeconds = bftConfigOptions.getRequestTimeoutSeconds(); this.gossipedHistoryLimit = bftConfigOptions.getGossipedHistoryLimit(); this.messageQueueLimit = bftConfigOptions.getMessageQueueLimit(); @@ -68,6 +70,11 @@ public class MutableBftConfigOptions implements BftConfigOptions { return blockPeriodSeconds; } + @Override + public long getBlockPeriodMilliseconds() { + return blockPeriodMilliseconds; + } + @Override public int getRequestTimeoutSeconds() { return requestTimeoutSeconds; @@ -131,6 +138,16 @@ public class MutableBftConfigOptions implements BftConfigOptions { this.blockPeriodSeconds = blockPeriodSeconds; } + /** + * Sets block period milliseconds. Experimental for test scenarios. Not for use on production + * systems. + * + * @param blockPeriodMilliseconds the block period milliseconds + */ + public void setBlockPeriodMilliseconds(final long blockPeriodMilliseconds) { + this.blockPeriodMilliseconds = blockPeriodMilliseconds; + } + /** * Sets request timeout seconds. * diff --git a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/RoundTimer.java b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/RoundTimer.java index a01dc652cf..0302943fc1 100644 --- a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/RoundTimer.java +++ b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/RoundTimer.java @@ -16,6 +16,7 @@ package org.hyperledger.besu.consensus.common.bft; import org.hyperledger.besu.consensus.common.bft.events.RoundExpiry; +import java.time.Duration; import java.util.Optional; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; @@ -31,21 +32,21 @@ public class RoundTimer { private final BftExecutors bftExecutors; private Optional> currentTimerTask; private final BftEventQueue queue; - private final long baseExpiryMillis; + private final Duration baseExpiryPeriod; /** * Construct a RoundTimer with primed executor service ready to start timers * * @param queue The queue in which to put round expiry events - * @param baseExpirySeconds The initial round length for round 0 + * @param baseExpiryPeriod The initial round length for round 0 * @param bftExecutors executor service that timers can be scheduled with */ public RoundTimer( - final BftEventQueue queue, final long baseExpirySeconds, final BftExecutors bftExecutors) { + final BftEventQueue queue, final Duration baseExpiryPeriod, final BftExecutors bftExecutors) { this.queue = queue; this.bftExecutors = bftExecutors; this.currentTimerTask = Optional.empty(); - this.baseExpiryMillis = baseExpirySeconds * 1000; + this.baseExpiryPeriod = baseExpiryPeriod; } /** Cancels the current running round timer if there is one */ @@ -71,7 +72,8 @@ public class RoundTimer { public synchronized void startTimer(final ConsensusRoundIdentifier round) { cancelTimer(); - final long expiryTime = baseExpiryMillis * (long) Math.pow(2, round.getRoundNumber()); + final long expiryTime = + baseExpiryPeriod.toMillis() * (long) Math.pow(2, round.getRoundNumber()); final Runnable newTimerRunnable = () -> queue.add(new RoundExpiry(round)); diff --git a/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/RoundTimerTest.java b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/RoundTimerTest.java index 0ebca51c9e..8f43739547 100644 --- a/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/RoundTimerTest.java +++ b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/RoundTimerTest.java @@ -25,6 +25,7 @@ import static org.mockito.Mockito.when; import org.hyperledger.besu.consensus.common.bft.events.RoundExpiry; +import java.time.Duration; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; @@ -46,7 +47,7 @@ public class RoundTimerTest { bftExecutors = mock(BftExecutors.class); queue = new BftEventQueue(1000); queue.start(); - timer = new RoundTimer(queue, 1, bftExecutors); + timer = new RoundTimer(queue, Duration.ofSeconds(1), bftExecutors); } @Test diff --git a/consensus/ibft/src/integration-test/java/org/hyperledger/besu/consensus/ibft/support/TestContextBuilder.java b/consensus/ibft/src/integration-test/java/org/hyperledger/besu/consensus/ibft/support/TestContextBuilder.java index 5d2b02b1a7..8896733548 100644 --- a/consensus/ibft/src/integration-test/java/org/hyperledger/besu/consensus/ibft/support/TestContextBuilder.java +++ b/consensus/ibft/src/integration-test/java/org/hyperledger/besu/consensus/ibft/support/TestContextBuilder.java @@ -100,6 +100,7 @@ import org.hyperledger.besu.testutil.TestClock; import org.hyperledger.besu.util.Subscribers; import java.time.Clock; +import java.time.Duration; import java.time.Instant; import java.time.ZoneId; import java.util.ArrayList; @@ -403,7 +404,7 @@ public class TestContextBuilder { Util.publicKeyToAddress(nodeKey.getPublicKey()), proposerSelector, multicaster, - new RoundTimer(bftEventQueue, ROUND_TIMER_SEC, bftExecutors), + new RoundTimer(bftEventQueue, Duration.ofSeconds(ROUND_TIMER_SEC), bftExecutors), new BlockTimer(bftEventQueue, forksSchedule, bftExecutors, TestClock.fixed()), blockCreatorFactory, clock); diff --git a/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/IbftBlockHeaderValidationRulesetFactory.java b/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/IbftBlockHeaderValidationRulesetFactory.java index 0e71fe8121..2367f90e2b 100644 --- a/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/IbftBlockHeaderValidationRulesetFactory.java +++ b/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/IbftBlockHeaderValidationRulesetFactory.java @@ -32,6 +32,7 @@ import org.hyperledger.besu.ethereum.mainnet.headervalidationrules.GasUsageValid import org.hyperledger.besu.ethereum.mainnet.headervalidationrules.TimestampBoundedByFutureParameter; import org.hyperledger.besu.ethereum.mainnet.headervalidationrules.TimestampMoreRecentThanParent; +import java.time.Duration; import java.util.Optional; import org.apache.tuweni.units.bigints.UInt256; @@ -45,32 +46,43 @@ public class IbftBlockHeaderValidationRulesetFactory { * Produces a BlockHeaderValidator configured for assessing bft block headers which are to form * part of the BlockChain (i.e. not proposed blocks, which do not contain commit seals) * - * @param secondsBetweenBlocks the minimum number of seconds which must elapse between blocks. + * @param minimumTimeBetweenBlocks the minimum time which must elapse between blocks. * @param baseFeeMarket an {@link Optional} wrapping {@link BaseFeeMarket} class if appropriate. * @return BlockHeaderValidator configured for assessing bft block headers */ public static BlockHeaderValidator.Builder blockHeaderValidator( - final long secondsBetweenBlocks, final Optional baseFeeMarket) { - return new BlockHeaderValidator.Builder() - .addRule(new AncestryValidationRule()) - .addRule(new GasUsageValidationRule()) - .addRule( - new GasLimitRangeAndDeltaValidationRule( - DEFAULT_MIN_GAS_LIMIT, DEFAULT_MAX_GAS_LIMIT, baseFeeMarket)) - .addRule(new TimestampBoundedByFutureParameter(1)) - .addRule(new TimestampMoreRecentThanParent(secondsBetweenBlocks)) - .addRule( - new ConstantFieldValidationRule<>( - "MixHash", BlockHeader::getMixHash, BftHelpers.EXPECTED_MIX_HASH)) - .addRule( - new ConstantFieldValidationRule<>( - "OmmersHash", BlockHeader::getOmmersHash, Hash.EMPTY_LIST_HASH)) - .addRule( - new ConstantFieldValidationRule<>( - "Difficulty", BlockHeader::getDifficulty, UInt256.ONE)) - .addRule(new ConstantFieldValidationRule<>("Nonce", BlockHeader::getNonce, 0L)) - .addRule(new BftValidatorsValidationRule()) - .addRule(new BftCoinbaseValidationRule()) - .addRule(new BftCommitSealsValidationRule()); + final Duration minimumTimeBetweenBlocks, final Optional baseFeeMarket) { + final BlockHeaderValidator.Builder ruleBuilder = + new BlockHeaderValidator.Builder() + .addRule(new AncestryValidationRule()) + .addRule(new GasUsageValidationRule()) + .addRule( + new GasLimitRangeAndDeltaValidationRule( + DEFAULT_MIN_GAS_LIMIT, DEFAULT_MAX_GAS_LIMIT, baseFeeMarket)) + .addRule(new TimestampBoundedByFutureParameter(1)) + .addRule( + new ConstantFieldValidationRule<>( + "MixHash", BlockHeader::getMixHash, BftHelpers.EXPECTED_MIX_HASH)) + .addRule( + new ConstantFieldValidationRule<>( + "OmmersHash", BlockHeader::getOmmersHash, Hash.EMPTY_LIST_HASH)) + .addRule( + new ConstantFieldValidationRule<>( + "Difficulty", BlockHeader::getDifficulty, UInt256.ONE)) + .addRule(new ConstantFieldValidationRule<>("Nonce", BlockHeader::getNonce, 0L)) + .addRule(new BftValidatorsValidationRule()) + .addRule(new BftCoinbaseValidationRule()) + .addRule(new BftCommitSealsValidationRule()); + + // Currently the minimum acceptable time between blocks is 1 second. The timestamp of an + // Ethereum header is stored as seconds since Unix epoch so blocks being produced more + // frequently than once a second cannot pass this validator. For non-production scenarios + // (e.g. for testing block production much more frequently than once a second) Besu has + // an experimental 'xblockperiodmilliseconds' option for BFT chains. If this is enabled + // we cannot apply the TimestampMoreRecentThanParent validation rule so we do not add it + if (minimumTimeBetweenBlocks.compareTo(Duration.ofSeconds(1)) >= 0) { + ruleBuilder.addRule(new TimestampMoreRecentThanParent(minimumTimeBetweenBlocks.getSeconds())); + } + return ruleBuilder; } } diff --git a/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/IbftProtocolScheduleBuilder.java b/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/IbftProtocolScheduleBuilder.java index 0789f2e898..3adf571895 100644 --- a/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/IbftProtocolScheduleBuilder.java +++ b/consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/IbftProtocolScheduleBuilder.java @@ -29,6 +29,7 @@ import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.plugin.services.MetricsSystem; +import java.time.Duration; import java.util.Optional; /** Defines the protocol behaviours for a blockchain using a BFT consensus mechanism. */ @@ -120,6 +121,9 @@ public class IbftProtocolScheduleBuilder extends BaseBftProtocolScheduleBuilder Optional.of(feeMarket).filter(FeeMarket::implementsBaseFee).map(BaseFeeMarket.class::cast); return IbftBlockHeaderValidationRulesetFactory.blockHeaderValidator( - config.getBlockPeriodSeconds(), baseFeeMarket); + config.getBlockPeriodMilliseconds() > 0 + ? Duration.ofMillis(config.getBlockPeriodMilliseconds()) + : Duration.ofSeconds(config.getBlockPeriodSeconds()), + baseFeeMarket); } } diff --git a/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/IbftBlockHeaderValidationRulesetFactoryTest.java b/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/IbftBlockHeaderValidationRulesetFactoryTest.java index a7deb9e197..160fc2a2f3 100644 --- a/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/IbftBlockHeaderValidationRulesetFactoryTest.java +++ b/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/IbftBlockHeaderValidationRulesetFactoryTest.java @@ -38,6 +38,7 @@ import org.hyperledger.besu.ethereum.mainnet.BlockHeaderValidator; import org.hyperledger.besu.ethereum.mainnet.HeaderValidationMode; import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; +import java.time.Duration; import java.util.Collection; import java.util.List; import java.util.Optional; @@ -93,7 +94,7 @@ public class IbftBlockHeaderValidationRulesetFactoryTest { final BlockHeaderValidator validator = IbftBlockHeaderValidationRulesetFactory.blockHeaderValidator( - 5, Optional.of(FeeMarket.london(1))) + Duration.ofSeconds(5), Optional.of(FeeMarket.london(1))) .build(); assertThat( @@ -372,7 +373,8 @@ public class IbftBlockHeaderValidationRulesetFactoryTest { } public BlockHeaderValidator getBlockHeaderValidator() { - return IbftBlockHeaderValidationRulesetFactory.blockHeaderValidator(5, Optional.empty()) + return IbftBlockHeaderValidationRulesetFactory.blockHeaderValidator( + Duration.ofSeconds(5), Optional.empty()) .build(); } } diff --git a/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/blockcreation/BftBlockCreatorTest.java b/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/blockcreation/BftBlockCreatorTest.java index 8b8406b638..5469717b13 100644 --- a/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/blockcreation/BftBlockCreatorTest.java +++ b/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/blockcreation/BftBlockCreatorTest.java @@ -64,6 +64,7 @@ import org.hyperledger.besu.plugin.services.MetricsSystem; import org.hyperledger.besu.testutil.DeterministicEthScheduler; import org.hyperledger.besu.testutil.TestClock; +import java.time.Duration; import java.time.ZoneId; import java.util.Collections; import java.util.List; @@ -105,7 +106,7 @@ public class BftBlockCreatorTest { public BlockHeaderValidator.Builder createBlockHeaderRuleset( final BftConfigOptions config, final FeeMarket feeMarket) { return IbftBlockHeaderValidationRulesetFactory.blockHeaderValidator( - 5, Optional.empty()); + Duration.ofSeconds(5), Optional.empty()); } }; final GenesisConfigOptions configOptions = @@ -200,7 +201,7 @@ public class BftBlockCreatorTest { final BlockHeaderValidator rules = IbftBlockHeaderValidationRulesetFactory.blockHeaderValidator( - secondsBetweenBlocks, Optional.empty()) + Duration.ofSeconds(secondsBetweenBlocks), Optional.empty()) .build(); // NOTE: The header will not contain commit seals, so can only do light validation on header. diff --git a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/TestContextBuilder.java b/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/TestContextBuilder.java index 8906f0de7f..d90d5a1527 100644 --- a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/TestContextBuilder.java +++ b/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/TestContextBuilder.java @@ -118,6 +118,7 @@ import org.hyperledger.besu.util.Subscribers; import java.io.IOException; import java.nio.file.Path; import java.time.Clock; +import java.time.Duration; import java.time.Instant; import java.time.ZoneId; import java.util.ArrayList; @@ -512,7 +513,7 @@ public class TestContextBuilder { Util.publicKeyToAddress(nodeKey.getPublicKey()), proposerSelector, multicaster, - new RoundTimer(bftEventQueue, ROUND_TIMER_SEC, bftExecutors), + new RoundTimer(bftEventQueue, Duration.ofSeconds(ROUND_TIMER_SEC), bftExecutors), new BlockTimer(bftEventQueue, forksSchedule, bftExecutors, TestClock.fixed()), blockCreatorFactory, clock); diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/QbftBlockHeaderValidationRulesetFactory.java b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/QbftBlockHeaderValidationRulesetFactory.java index 7320dfaaf7..ac5ba3ac23 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/QbftBlockHeaderValidationRulesetFactory.java +++ b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/QbftBlockHeaderValidationRulesetFactory.java @@ -31,6 +31,7 @@ import org.hyperledger.besu.ethereum.mainnet.headervalidationrules.GasUsageValid import org.hyperledger.besu.ethereum.mainnet.headervalidationrules.TimestampBoundedByFutureParameter; import org.hyperledger.besu.ethereum.mainnet.headervalidationrules.TimestampMoreRecentThanParent; +import java.time.Duration; import java.util.Optional; import org.apache.tuweni.units.bigints.UInt256; @@ -44,31 +45,42 @@ public class QbftBlockHeaderValidationRulesetFactory { * Produces a BlockHeaderValidator configured for assessing bft block headers which are to form * part of the BlockChain (i.e. not proposed blocks, which do not contain commit seals) * - * @param secondsBetweenBlocks the minimum number of seconds which must elapse between blocks. + * @param minimumTimeBetweenBlocks the minimum amount of time that must elapse between blocks. * @param useValidatorContract whether validator selection is using a validator contract * @param baseFeeMarket an {@link Optional} wrapping {@link BaseFeeMarket} class if appropriate. * @return BlockHeaderValidator configured for assessing bft block headers */ public static BlockHeaderValidator.Builder blockHeaderValidator( - final long secondsBetweenBlocks, + final Duration minimumTimeBetweenBlocks, final boolean useValidatorContract, final Optional baseFeeMarket) { - return new BlockHeaderValidator.Builder() - .addRule(new AncestryValidationRule()) - .addRule(new GasUsageValidationRule()) - .addRule( - new GasLimitRangeAndDeltaValidationRule( - DEFAULT_MIN_GAS_LIMIT, DEFAULT_MAX_GAS_LIMIT, baseFeeMarket)) - .addRule(new TimestampBoundedByFutureParameter(1)) - .addRule(new TimestampMoreRecentThanParent(secondsBetweenBlocks)) - .addRule( - new ConstantFieldValidationRule<>( - "MixHash", BlockHeader::getMixHash, BftHelpers.EXPECTED_MIX_HASH)) - .addRule( - new ConstantFieldValidationRule<>( - "Difficulty", BlockHeader::getDifficulty, UInt256.ONE)) - .addRule(new QbftValidatorsValidationRule(useValidatorContract)) - .addRule(new BftCoinbaseValidationRule()) - .addRule(new BftCommitSealsValidationRule()); + BlockHeaderValidator.Builder ruleBuilder = + new BlockHeaderValidator.Builder() + .addRule(new AncestryValidationRule()) + .addRule(new GasUsageValidationRule()) + .addRule( + new GasLimitRangeAndDeltaValidationRule( + DEFAULT_MIN_GAS_LIMIT, DEFAULT_MAX_GAS_LIMIT, baseFeeMarket)) + .addRule(new TimestampBoundedByFutureParameter(1)) + .addRule( + new ConstantFieldValidationRule<>( + "MixHash", BlockHeader::getMixHash, BftHelpers.EXPECTED_MIX_HASH)) + .addRule( + new ConstantFieldValidationRule<>( + "Difficulty", BlockHeader::getDifficulty, UInt256.ONE)) + .addRule(new QbftValidatorsValidationRule(useValidatorContract)) + .addRule(new BftCoinbaseValidationRule()) + .addRule(new BftCommitSealsValidationRule()); + + // Currently the minimum acceptable time between blocks is 1 second. The timestamp of an + // Ethereum header is stored as seconds since Unix epoch so blocks being produced more + // frequently than once a second cannot pass this validator. For non-production scenarios + // (e.g. for testing block production much more frequently than once a second) Besu has + // an experimental 'xblockperiodmilliseconds' option for BFT chains. If this is enabled + // we cannot apply the TimestampMoreRecentThanParent validation rule so we do not add it + if (minimumTimeBetweenBlocks.compareTo(Duration.ofSeconds(1)) >= 0) { + ruleBuilder.addRule(new TimestampMoreRecentThanParent(minimumTimeBetweenBlocks.getSeconds())); + } + return ruleBuilder; } } diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/QbftForksSchedulesFactory.java b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/QbftForksSchedulesFactory.java index 90448f6201..0f0d467de3 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/QbftForksSchedulesFactory.java +++ b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/QbftForksSchedulesFactory.java @@ -49,6 +49,7 @@ public class QbftForksSchedulesFactory { new MutableQbftConfigOptions(lastSpec.getValue()); fork.getBlockPeriodSeconds().ifPresent(bftConfigOptions::setBlockPeriodSeconds); + fork.getBlockPeriodMilliseconds().ifPresent(bftConfigOptions::setBlockPeriodMilliseconds); fork.getBlockRewardWei().ifPresent(bftConfigOptions::setBlockRewardWei); if (fork.isMiningBeneficiaryConfigured()) { diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/QbftProtocolScheduleBuilder.java b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/QbftProtocolScheduleBuilder.java index 44c7ddfba8..e1cbc134b6 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/QbftProtocolScheduleBuilder.java +++ b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/QbftProtocolScheduleBuilder.java @@ -33,6 +33,7 @@ import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.plugin.services.MetricsSystem; +import java.time.Duration; import java.util.Optional; /** Defines the protocol behaviours for a blockchain using a QBFT consensus mechanism. */ @@ -164,7 +165,9 @@ public class QbftProtocolScheduleBuilder extends BaseBftProtocolScheduleBuilder Optional.of(feeMarket).filter(FeeMarket::implementsBaseFee).map(BaseFeeMarket.class::cast); return QbftBlockHeaderValidationRulesetFactory.blockHeaderValidator( - qbftConfigOptions.getBlockPeriodSeconds(), + qbftConfigOptions.getBlockPeriodMilliseconds() > 0 + ? Duration.ofMillis(qbftConfigOptions.getBlockPeriodMilliseconds()) + : Duration.ofSeconds(qbftConfigOptions.getBlockPeriodSeconds()), qbftConfigOptions.isValidatorContractMode(), baseFeeMarket); } diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/QbftBlockHeaderValidationRulesetFactoryTest.java b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/QbftBlockHeaderValidationRulesetFactoryTest.java index 4771cf91cb..ae1fbc0f19 100644 --- a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/QbftBlockHeaderValidationRulesetFactoryTest.java +++ b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/QbftBlockHeaderValidationRulesetFactoryTest.java @@ -34,6 +34,7 @@ import org.hyperledger.besu.ethereum.mainnet.BlockHeaderValidator; import org.hyperledger.besu.ethereum.mainnet.HeaderValidationMode; import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; +import java.time.Duration; import java.util.Collection; import java.util.List; import java.util.Optional; @@ -92,7 +93,7 @@ public class QbftBlockHeaderValidationRulesetFactoryTest { final BlockHeaderValidator validator = QbftBlockHeaderValidationRulesetFactory.blockHeaderValidator( - 5, false, Optional.of(FeeMarket.london(1))) + Duration.ofSeconds(5), false, Optional.of(FeeMarket.london(1))) .build(); assertThat( @@ -366,7 +367,8 @@ public class QbftBlockHeaderValidationRulesetFactoryTest { } public BlockHeaderValidator getBlockHeaderValidator() { - return QbftBlockHeaderValidationRulesetFactory.blockHeaderValidator(5, false, Optional.empty()) + return QbftBlockHeaderValidationRulesetFactory.blockHeaderValidator( + Duration.ofSeconds(5), false, Optional.empty()) .build(); } } From 3dbe60617249446222fa786e9bb82ea3311a361a Mon Sep 17 00:00:00 2001 From: Fabio Di Fabio Date: Fri, 20 Sep 2024 15:10:59 +0200 Subject: [PATCH 225/259] Wait for Besu to be up before running Goss Docker test 02 (#7655) Signed-off-by: Fabio Di Fabio --- docker/tests/02/goss_wait.yaml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 docker/tests/02/goss_wait.yaml diff --git a/docker/tests/02/goss_wait.yaml b/docker/tests/02/goss_wait.yaml new file mode 100644 index 0000000000..f6b397c618 --- /dev/null +++ b/docker/tests/02/goss_wait.yaml @@ -0,0 +1,7 @@ +--- +# runtime docker tests for interfaces & ports +port: + tcp:30303: + listening: true + ip: + - 0.0.0.0 From 676e1f8c1344edd3009eba6f22a46287b4e98bdb Mon Sep 17 00:00:00 2001 From: Fabio Di Fabio Date: Fri, 20 Sep 2024 15:52:12 +0200 Subject: [PATCH 226/259] Rebalance GHA runners to reduce ATs failure and speedup unit tests (#7656) Signed-off-by: Fabio Di Fabio --- .github/workflows/acceptance-tests.yml | 2 +- .github/workflows/pre-review.yml | 2 +- .github/workflows/reference-tests.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/acceptance-tests.yml b/.github/workflows/acceptance-tests.yml index a8f6981d89..27d0020b2c 100644 --- a/.github/workflows/acceptance-tests.yml +++ b/.github/workflows/acceptance-tests.yml @@ -12,7 +12,7 @@ concurrency: env: GRADLE_OPTS: "-Xmx7g" - total-runners: 12 + total-runners: 14 jobs: acceptanceTestEthereum: diff --git a/.github/workflows/pre-review.yml b/.github/workflows/pre-review.yml index cba13f1ebd..35e8956f1d 100644 --- a/.github/workflows/pre-review.yml +++ b/.github/workflows/pre-review.yml @@ -12,7 +12,7 @@ concurrency: env: GRADLE_OPTS: "-Xmx6g -Dorg.gradle.parallel=true" - total-runners: 8 + total-runners: 10 jobs: repolint: diff --git a/.github/workflows/reference-tests.yml b/.github/workflows/reference-tests.yml index 4e458e057e..435cbba0f8 100644 --- a/.github/workflows/reference-tests.yml +++ b/.github/workflows/reference-tests.yml @@ -8,7 +8,7 @@ on: env: GRADLE_OPTS: "-Xmx6g -Dorg.gradle.daemon=false -Dorg.gradle.parallel=true -Dorg.gradle.caching=true" - total-runners: 10 + total-runners: 8 concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} From f1da4e77e6fc7bd9eefc61b0f82d367962debb1b Mon Sep 17 00:00:00 2001 From: Fabio Di Fabio Date: Fri, 20 Sep 2024 16:31:37 +0200 Subject: [PATCH 227/259] Rebalance GHA runners to reduce ATs failure and speedup unit tests [part 2] (#7658) Signed-off-by: Fabio Di Fabio --- .github/workflows/acceptance-tests.yml | 2 +- .github/workflows/pre-review.yml | 2 +- .github/workflows/reference-tests.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/acceptance-tests.yml b/.github/workflows/acceptance-tests.yml index 27d0020b2c..e1549b2357 100644 --- a/.github/workflows/acceptance-tests.yml +++ b/.github/workflows/acceptance-tests.yml @@ -24,7 +24,7 @@ jobs: strategy: fail-fast: true matrix: - runner_index: [0,1,2,3,4,5,6,7,8,9,10,11] + runner_index: [0,1,2,3,4,5,6,7,8,9,10,11,12,13] steps: - name: Checkout Repo uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 diff --git a/.github/workflows/pre-review.yml b/.github/workflows/pre-review.yml index 35e8956f1d..93bfcfa9f5 100644 --- a/.github/workflows/pre-review.yml +++ b/.github/workflows/pre-review.yml @@ -83,7 +83,7 @@ jobs: strategy: fail-fast: true matrix: - runner_index: [0,1,2,3,4,5,6,7] + runner_index: [0,1,2,3,4,5,6,7,8,9] steps: - name: Checkout Repo uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 diff --git a/.github/workflows/reference-tests.yml b/.github/workflows/reference-tests.yml index 435cbba0f8..d27114ebc1 100644 --- a/.github/workflows/reference-tests.yml +++ b/.github/workflows/reference-tests.yml @@ -24,7 +24,7 @@ jobs: strategy: fail-fast: true matrix: - runner_index: [1,2,3,4,5,6,7,8,9,10] + runner_index: [1,2,3,4,5,6,7,8] steps: - name: Checkout Repo uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 From 3e0e5cdc1ffa0888ebba96e0edb3a9bdf18eb17e Mon Sep 17 00:00:00 2001 From: Fabio Di Fabio Date: Fri, 20 Sep 2024 17:11:56 +0200 Subject: [PATCH 228/259] Fix reading tx-pool-min-score option from configuration file (#7623) Signed-off-by: Fabio Di Fabio --- CHANGELOG.md | 1 + .../util/TomlConfigurationDefaultProvider.java | 6 +++++- .../options/TransactionPoolOptionsTest.java | 18 ++++++++++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 246df1d91c..96e1511eea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ - Fix for `debug_traceCall` to handle transactions without specified gas price. [#7510](https://github.com/hyperledger/besu/pull/7510) - 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) ## 24.9.1 diff --git a/besu/src/main/java/org/hyperledger/besu/cli/util/TomlConfigurationDefaultProvider.java b/besu/src/main/java/org/hyperledger/besu/cli/util/TomlConfigurationDefaultProvider.java index ca76b40b68..636be329d4 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/util/TomlConfigurationDefaultProvider.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/util/TomlConfigurationDefaultProvider.java @@ -120,7 +120,11 @@ public class TomlConfigurationDefaultProvider implements IDefaultValueProvider { } private boolean isNumericType(final Class type) { - return type.equals(Integer.class) + return type.equals(Byte.class) + || type.equals(byte.class) + || type.equals(Short.class) + || type.equals(short.class) + || type.equals(Integer.class) || type.equals(int.class) || type.equals(Long.class) || type.equals(long.class) diff --git a/besu/src/test/java/org/hyperledger/besu/cli/options/TransactionPoolOptionsTest.java b/besu/src/test/java/org/hyperledger/besu/cli/options/TransactionPoolOptionsTest.java index eb48a3f2a5..37acbe167f 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/options/TransactionPoolOptionsTest.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/options/TransactionPoolOptionsTest.java @@ -427,6 +427,24 @@ public class TransactionPoolOptionsTest Byte.toString(minScore)); } + @Test + public void minScoreWorksConfigFile() throws IOException { + final byte minScore = -10; + final Path tempConfigFilePath = + createTempFile( + "config", + String.format( + """ + tx-pool-min-score=%s + """, + minScore)); + + internalTestSuccess( + config -> assertThat(config.getMinScore()).isEqualTo(minScore), + "--config-file", + tempConfigFilePath.toString()); + } + @Test public void minScoreNonByteValueReturnError() { final var overflowMinScore = Integer.toString(-300); From 6e246ca4b0be04fe14f67a25cde895c127feeec4 Mon Sep 17 00:00:00 2001 From: Cooper Mosawi Date: Sat, 21 Sep 2024 05:13:16 +1200 Subject: [PATCH 229/259] fix opentelemetry (#7649) Signed-off-by: Blue Co-authored-by: Fabio Di Fabio --- docs/tracing/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tracing/README.md b/docs/tracing/README.md index 77deadd16a..3a3f9fa435 100644 --- a/docs/tracing/README.md +++ b/docs/tracing/README.md @@ -1,6 +1,6 @@ # Tracing -Hyperledger Besu integrates with the [open-telemetry](https://open-telemetry.io) project to integrate tracing reporting. +Hyperledger Besu integrates with the [open-telemetry](https://opentelemetry.io/) project to integrate tracing reporting. This allows to report all JSON-RPC traffic as traces. From 1751a77f98cc6cdf218cd80f429e15ccd8e01e67 Mon Sep 17 00:00:00 2001 From: daniellehrner Date: Sat, 21 Sep 2024 13:28:01 +0200 Subject: [PATCH 230/259] 7702 validation checks v2 (#7653) * yParity is valid up to 2**256 as well Signed-off-by: Daniel Lehrner --- .../besu/crypto/AbstractSECP256.java | 2 +- .../besu/crypto/CodeDelegationSignature.java | 15 ++++++++--- .../besu/crypto/SignatureAlgorithm.java | 2 +- .../crypto/CodeDelegationSignatureTest.java | 27 +++++++++++++------ .../CodeDelegationTransactionDecoder.java | 2 +- 5 files changed, 33 insertions(+), 15 deletions(-) diff --git a/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/AbstractSECP256.java b/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/AbstractSECP256.java index ce37651266..bd450b206e 100644 --- a/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/AbstractSECP256.java +++ b/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/AbstractSECP256.java @@ -214,7 +214,7 @@ public abstract class AbstractSECP256 implements SignatureAlgorithm { @Override public CodeDelegationSignature createCodeDelegationSignature( - final BigInteger r, final BigInteger s, final long yParity) { + final BigInteger r, final BigInteger s, final BigInteger yParity) { return CodeDelegationSignature.create(r, s, yParity); } diff --git a/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/CodeDelegationSignature.java b/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/CodeDelegationSignature.java index 4bb2e4653e..06ec72bf0a 100644 --- a/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/CodeDelegationSignature.java +++ b/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/CodeDelegationSignature.java @@ -42,18 +42,25 @@ public class CodeDelegationSignature extends SECPSignature { * @return the new CodeDelegationSignature */ public static CodeDelegationSignature create( - final BigInteger r, final BigInteger s, final long yParity) { + final BigInteger r, final BigInteger s, final BigInteger yParity) { checkNotNull(r); checkNotNull(s); if (r.compareTo(TWO_POW_256) >= 0) { - throw new IllegalArgumentException("Invalid 'r' value, should be < 2^256 but got " + r); + throw new IllegalArgumentException( + "Invalid 'r' value, should be < 2^256 but got " + r.toString(16)); } if (s.compareTo(TWO_POW_256) >= 0) { - throw new IllegalArgumentException("Invalid 's' value, should be < 2^256 but got " + s); + throw new IllegalArgumentException( + "Invalid 's' value, should be < 2^256 but got " + s.toString(16)); } - return new CodeDelegationSignature(r, s, (byte) yParity); + if (yParity.compareTo(TWO_POW_256) >= 0) { + throw new IllegalArgumentException( + "Invalid 'yParity' value, should be < 2^256 but got " + yParity.toString(16)); + } + + return new CodeDelegationSignature(r, s, yParity.byteValue()); } } diff --git a/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/SignatureAlgorithm.java b/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/SignatureAlgorithm.java index 8e19b60854..4bf8d89c82 100644 --- a/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/SignatureAlgorithm.java +++ b/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/SignatureAlgorithm.java @@ -224,7 +224,7 @@ public interface SignatureAlgorithm { * @return the code delegation signature */ CodeDelegationSignature createCodeDelegationSignature( - final BigInteger r, final BigInteger s, final long yParity); + final BigInteger r, final BigInteger s, final BigInteger yParity); /** * Decode secp signature. diff --git a/crypto/algorithms/src/test/java/org/hyperledger/besu/crypto/CodeDelegationSignatureTest.java b/crypto/algorithms/src/test/java/org/hyperledger/besu/crypto/CodeDelegationSignatureTest.java index 1cc66966a7..332aa14893 100644 --- a/crypto/algorithms/src/test/java/org/hyperledger/besu/crypto/CodeDelegationSignatureTest.java +++ b/crypto/algorithms/src/test/java/org/hyperledger/besu/crypto/CodeDelegationSignatureTest.java @@ -29,19 +29,19 @@ class CodeDelegationSignatureTest { void testValidInputs() { BigInteger r = BigInteger.ONE; BigInteger s = BigInteger.TEN; - long yParity = 1L; + BigInteger yParity = BigInteger.ONE; CodeDelegationSignature result = CodeDelegationSignature.create(r, s, yParity); assertThat(r).isEqualTo(result.getR()); assertThat(s).isEqualTo(result.getS()); - assertThat((byte) yParity).isEqualTo(result.getRecId()); + assertThat(yParity.byteValue()).isEqualTo(result.getRecId()); } @Test void testNullRValue() { BigInteger s = BigInteger.TEN; - long yParity = 0L; + BigInteger yParity = BigInteger.ZERO; assertThatExceptionOfType(NullPointerException.class) .isThrownBy(() -> CodeDelegationSignature.create(null, s, yParity)); @@ -50,7 +50,7 @@ class CodeDelegationSignatureTest { @Test void testNullSValue() { BigInteger r = BigInteger.ONE; - long yParity = 0L; + BigInteger yParity = BigInteger.ZERO; assertThatExceptionOfType(NullPointerException.class) .isThrownBy(() -> CodeDelegationSignature.create(r, null, yParity)); @@ -60,7 +60,7 @@ class CodeDelegationSignatureTest { void testRValueExceedsTwoPow256() { BigInteger r = TWO_POW_256; BigInteger s = BigInteger.TEN; - long yParity = 0L; + BigInteger yParity = BigInteger.ZERO; assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> CodeDelegationSignature.create(r, s, yParity)) @@ -71,23 +71,34 @@ class CodeDelegationSignatureTest { void testSValueExceedsTwoPow256() { BigInteger r = BigInteger.ONE; BigInteger s = TWO_POW_256; - long yParity = 0L; + BigInteger yParity = BigInteger.ZERO; assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> CodeDelegationSignature.create(r, s, yParity)) .withMessageContainingAll("Invalid 's' value, should be < 2^256"); } + @Test + void testYParityExceedsTwoPow256() { + BigInteger r = BigInteger.ONE; + BigInteger s = BigInteger.TWO; + BigInteger yParity = TWO_POW_256; + + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> CodeDelegationSignature.create(r, s, yParity)) + .withMessageContainingAll("Invalid 'yParity' value, should be < 2^256"); + } + @Test void testValidYParityZero() { BigInteger r = BigInteger.ONE; BigInteger s = BigInteger.TEN; - long yParity = 0L; + BigInteger yParity = BigInteger.ZERO; CodeDelegationSignature result = CodeDelegationSignature.create(r, s, yParity); assertThat(r).isEqualTo(result.getR()); assertThat(s).isEqualTo(result.getS()); - assertThat((byte) yParity).isEqualTo(result.getRecId()); + assertThat(yParity.byteValue()).isEqualTo(result.getRecId()); } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/CodeDelegationTransactionDecoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/CodeDelegationTransactionDecoder.java index d3ef60bfc4..6448940d8d 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/CodeDelegationTransactionDecoder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/CodeDelegationTransactionDecoder.java @@ -81,7 +81,7 @@ public class CodeDelegationTransactionDecoder { final Address address = Address.wrap(input.readBytes()); final long nonce = input.readLongScalar(); - final long yParity = input.readUnsignedIntScalar(); + final BigInteger yParity = input.readUInt256Scalar().toUnsignedBigInteger(); final BigInteger r = input.readUInt256Scalar().toUnsignedBigInteger(); final BigInteger s = input.readUInt256Scalar().toUnsignedBigInteger(); From 9d689b940134b4f7a9b80020829d506417c2065e Mon Sep 17 00:00:00 2001 From: Sally MacFarlane Date: Sun, 22 Sep 2024 06:45:09 +1000 Subject: [PATCH 231/259] remove integration tests related to privacy (#7645) * remove integration tests related to privacy Signed-off-by: Sally MacFarlane --------- Signed-off-by: Sally MacFarlane --- .../hyperledger/besu/enclave/EnclaveTest.java | 215 --------------- .../enclave/TlsCertificateDefinition.java | 52 ---- .../besu/enclave/TlsEnabledEnclaveTest.java | 144 ----------- .../enclave/TlsEnabledHttpServerFactory.java | 109 -------- .../hyperledger/besu/enclave/TlsHelpers.java | 98 ------- ...vGetPrivateTransactionIntegrationTest.java | 192 -------------- ...acyPrecompiledContractIntegrationTest.java | 244 ------------------ testutil/src/main/resources/enclave_key_0.key | 1 - 8 files changed, 1055 deletions(-) delete mode 100644 enclave/src/integration-test/java/org/hyperledger/besu/enclave/EnclaveTest.java delete mode 100644 enclave/src/integration-test/java/org/hyperledger/besu/enclave/TlsCertificateDefinition.java delete mode 100644 enclave/src/integration-test/java/org/hyperledger/besu/enclave/TlsEnabledEnclaveTest.java delete mode 100644 enclave/src/integration-test/java/org/hyperledger/besu/enclave/TlsEnabledHttpServerFactory.java delete mode 100644 enclave/src/integration-test/java/org/hyperledger/besu/enclave/TlsHelpers.java delete mode 100644 ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/frontier/PrivGetPrivateTransactionIntegrationTest.java delete mode 100644 ethereum/core/src/integration-test/java/org/hyperledger/besu/ethereum/mainnet/precompiles/privacy/PrivacyPrecompiledContractIntegrationTest.java delete mode 100644 testutil/src/main/resources/enclave_key_0.key diff --git a/enclave/src/integration-test/java/org/hyperledger/besu/enclave/EnclaveTest.java b/enclave/src/integration-test/java/org/hyperledger/besu/enclave/EnclaveTest.java deleted file mode 100644 index b9b657e668..0000000000 --- a/enclave/src/integration-test/java/org/hyperledger/besu/enclave/EnclaveTest.java +++ /dev/null @@ -1,215 +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.enclave; - -import static java.nio.charset.StandardCharsets.UTF_8; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.catchThrowable; - -import org.hyperledger.besu.enclave.types.PrivacyGroup; -import org.hyperledger.besu.enclave.types.ReceiveResponse; -import org.hyperledger.besu.enclave.types.SendResponse; -import org.hyperledger.enclave.testutil.EnclaveEncryptorType; -import org.hyperledger.enclave.testutil.EnclaveKeyConfiguration; -import org.hyperledger.enclave.testutil.TesseraTestHarness; -import org.hyperledger.enclave.testutil.TesseraTestHarnessFactory; - -import java.net.URI; -import java.net.URISyntaxException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.List; -import java.util.Optional; -import java.util.concurrent.TimeUnit; - -import com.google.common.collect.Lists; -import io.vertx.core.Vertx; -import org.awaitility.Awaitility; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.io.TempDir; - -public class EnclaveTest { - - @TempDir private static Path folder; - - private static final String PAYLOAD = "a wonderful transaction"; - private static final String MOCK_KEY = "iOCzoGo5kwtZU0J41Z9xnGXHN6ZNukIa9MspvHtu3Jk="; - private Enclave enclave; - private Vertx vertx; - private EnclaveFactory factory; - - private TesseraTestHarness testHarness; - - @BeforeEach - public void setUp() throws Exception { - vertx = Vertx.vertx(); - factory = new EnclaveFactory(vertx); - - testHarness = - TesseraTestHarnessFactory.create( - "enclave", - Files.createTempDirectory(folder, "enclave"), - new EnclaveKeyConfiguration( - new String[] {"enclave_key_0.pub"}, - new String[] {"enclave_key_0.key"}, - EnclaveEncryptorType.NOOP), - Optional.empty()); - - testHarness.start(); - - enclave = factory.createVertxEnclave(testHarness.clientUrl()); - } - - @AfterEach - public void tearDown() { - testHarness.close(); - vertx.close(); - } - - @Test - public void testUpCheck() { - assertThat(enclave.upCheck()).isTrue(); - } - - @Test - public void testReceiveThrowsWhenPayloadDoesNotExist() { - final String publicKey = testHarness.getDefaultPublicKey(); - - final Throwable t = catchThrowable(() -> enclave.receive(MOCK_KEY, publicKey)); - - assertThat(t.getMessage()).isEqualTo("Message with hash was not found"); - } - - @Test - public void testSendAndReceive() { - final List publicKeys = testHarness.getPublicKeys(); - - final SendResponse sr = - enclave.send(PAYLOAD, publicKeys.get(0), Lists.newArrayList(publicKeys.get(0))); - - final ReceiveResponse rr = enclave.receive(sr.getKey(), publicKeys.get(0)); - assertThat(rr).isNotNull(); - assertThat(new String(rr.getPayload(), UTF_8)).isEqualTo(PAYLOAD); - assertThat(rr.getPrivacyGroupId()).isNotNull(); - } - - @Test - public void testSendWithPrivacyGroupAndReceive() { - final List publicKeys = testHarness.getPublicKeys(); - - final PrivacyGroup privacyGroupResponse = - enclave.createPrivacyGroup(publicKeys, publicKeys.get(0), "", ""); - - final SendResponse sr = - enclave.send(PAYLOAD, publicKeys.get(0), privacyGroupResponse.getPrivacyGroupId()); - - final ReceiveResponse rr = enclave.receive(sr.getKey(), publicKeys.get(0)); - assertThat(rr).isNotNull(); - assertThat(new String(rr.getPayload(), UTF_8)).isEqualTo(PAYLOAD); - assertThat(rr.getPrivacyGroupId()).isNotNull(); - } - - @Test - public void testCreateAndDeletePrivacyGroup() { - final List publicKeys = testHarness.getPublicKeys(); - final String name = "testName"; - final String description = "testDesc"; - - final PrivacyGroup privacyGroupResponse = - enclave.createPrivacyGroup(publicKeys, publicKeys.get(0), name, description); - - assertThat(privacyGroupResponse.getPrivacyGroupId()).isNotNull(); - assertThat(privacyGroupResponse.getName()).isEqualTo(name); - assertThat(privacyGroupResponse.getDescription()).isEqualTo(description); - assertThat(privacyGroupResponse.getType()).isEqualByComparingTo(PrivacyGroup.Type.PANTHEON); - - final String response = - enclave.deletePrivacyGroup(privacyGroupResponse.getPrivacyGroupId(), publicKeys.get(0)); - - assertThat(privacyGroupResponse.getPrivacyGroupId()).isEqualTo(response); - } - - @Test - public void testCreateFindDeleteFindPrivacyGroup() { - final List publicKeys = testHarness.getPublicKeys(); - final String name = "name"; - final String description = "desc"; - - final PrivacyGroup privacyGroupResponse = - enclave.createPrivacyGroup(publicKeys, publicKeys.get(0), name, description); - - assertThat(privacyGroupResponse.getPrivacyGroupId()).isNotNull(); - assertThat(privacyGroupResponse.getName()).isEqualTo(name); - assertThat(privacyGroupResponse.getDescription()).isEqualTo(description); - assertThat(privacyGroupResponse.getType()).isEqualTo(PrivacyGroup.Type.PANTHEON); - - Awaitility.await() - .atMost(5, TimeUnit.SECONDS) - .untilAsserted( - () -> { - final PrivacyGroup[] findPrivacyGroupResponse = enclave.findPrivacyGroup(publicKeys); - - assertThat(findPrivacyGroupResponse.length).isEqualTo(1); - assertThat(findPrivacyGroupResponse[0].getPrivacyGroupId()) - .isEqualTo(privacyGroupResponse.getPrivacyGroupId()); - }); - - final String response = - enclave.deletePrivacyGroup(privacyGroupResponse.getPrivacyGroupId(), publicKeys.get(0)); - - assertThat(privacyGroupResponse.getPrivacyGroupId()).isEqualTo(response); - - Awaitility.await() - .atMost(5, TimeUnit.SECONDS) - .untilAsserted( - () -> { - final PrivacyGroup[] findPrivacyGroupResponse = enclave.findPrivacyGroup(publicKeys); - - assertThat(findPrivacyGroupResponse.length).isEqualTo(0); - }); - } - - @Test - public void testCreateDeleteRetrievePrivacyGroup() { - final List publicKeys = testHarness.getPublicKeys(); - final String name = "name"; - final String description = "desc"; - - final PrivacyGroup privacyGroupResponse = - enclave.createPrivacyGroup(publicKeys, publicKeys.get(0), name, description); - - assertThat(privacyGroupResponse.getPrivacyGroupId()).isNotNull(); - assertThat(privacyGroupResponse.getName()).isEqualTo(name); - assertThat(privacyGroupResponse.getDescription()).isEqualTo(description); - assertThat(privacyGroupResponse.getType()).isEqualTo(PrivacyGroup.Type.PANTHEON); - - final PrivacyGroup retrievePrivacyGroup = - enclave.retrievePrivacyGroup(privacyGroupResponse.getPrivacyGroupId()); - - assertThat(retrievePrivacyGroup).usingRecursiveComparison().isEqualTo(privacyGroupResponse); - - final String response = - enclave.deletePrivacyGroup(privacyGroupResponse.getPrivacyGroupId(), publicKeys.get(0)); - - assertThat(privacyGroupResponse.getPrivacyGroupId()).isEqualTo(response); - } - - @Test - public void upcheckReturnsFalseIfNoResponseReceived() throws URISyntaxException { - assertThat(factory.createVertxEnclave(new URI("http://8.8.8.8:65535")).upCheck()).isFalse(); - } -} diff --git a/enclave/src/integration-test/java/org/hyperledger/besu/enclave/TlsCertificateDefinition.java b/enclave/src/integration-test/java/org/hyperledger/besu/enclave/TlsCertificateDefinition.java deleted file mode 100644 index ad1271e920..0000000000 --- a/enclave/src/integration-test/java/org/hyperledger/besu/enclave/TlsCertificateDefinition.java +++ /dev/null @@ -1,52 +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.enclave; - -import java.io.File; -import java.net.URL; -import java.nio.file.Path; - -import com.google.common.io.Resources; - -public class TlsCertificateDefinition { - - private final File pkcs12File; - private final String password; - - public static TlsCertificateDefinition loadFromResource( - final String resourcePath, final String password) { - try { - final URL sslCertificate = Resources.getResource(resourcePath); - final Path keystorePath = Path.of(sslCertificate.getPath()); - - return new TlsCertificateDefinition(keystorePath.toFile(), password); - } catch (final Exception e) { - throw new RuntimeException("Failed to load TLS certificates", e); - } - } - - public TlsCertificateDefinition(final File pkcs12File, final String password) { - this.pkcs12File = pkcs12File; - this.password = password; - } - - public File getPkcs12File() { - return pkcs12File; - } - - public String getPassword() { - return password; - } -} diff --git a/enclave/src/integration-test/java/org/hyperledger/besu/enclave/TlsEnabledEnclaveTest.java b/enclave/src/integration-test/java/org/hyperledger/besu/enclave/TlsEnabledEnclaveTest.java deleted file mode 100644 index b594779306..0000000000 --- a/enclave/src/integration-test/java/org/hyperledger/besu/enclave/TlsEnabledEnclaveTest.java +++ /dev/null @@ -1,144 +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.enclave; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.fail; -import static org.hyperledger.besu.enclave.TlsHelpers.populateFingerprintFile; - -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.nio.charset.Charset; -import java.nio.file.Files; -import java.nio.file.Path; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.cert.CertificateException; -import java.util.Optional; - -import io.vertx.core.Vertx; -import io.vertx.core.http.HttpServer; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -public class TlsEnabledEnclaveTest { - - private TlsEnabledHttpServerFactory serverFactory; - private Vertx vertx; - - final TlsCertificateDefinition httpServerCert = - TlsCertificateDefinition.loadFromResource("tls/cert1.pfx", "password"); - final TlsCertificateDefinition besuCert = - TlsCertificateDefinition.loadFromResource("tls/cert2.pfx", "password2"); - - public void shutdown() { - vertx.close(); - } - - @BeforeEach - public void setup() { - serverFactory = new TlsEnabledHttpServerFactory(); - this.vertx = Vertx.vertx(); - } - - @AfterEach - public void cleanup() { - serverFactory.shutdown(); - this.shutdown(); - } - - private Enclave createEnclave( - final int httpServerPort, final Path workDir, final boolean tlsEnabled) throws IOException { - - final Path serverFingerprintFile = workDir.resolve("server_known_clients"); - final Path besuCertPasswordFile = workDir.resolve("password_file"); - try { - populateFingerprintFile(serverFingerprintFile, httpServerCert, Optional.of(httpServerPort)); - Files.write(besuCertPasswordFile, besuCert.getPassword().getBytes(Charset.defaultCharset())); - - final EnclaveFactory factory = new EnclaveFactory(vertx); - if (tlsEnabled) { - final URI httpServerUri = new URI("https://localhost:" + httpServerPort); - return factory.createVertxEnclave( - httpServerUri, - besuCert.getPkcs12File().toPath(), - besuCertPasswordFile, - serverFingerprintFile); - } else { - return factory.createVertxEnclave(new URI("http://localhost:" + httpServerPort)); - } - } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException e) { - fail("unable to populate fingerprint file"); - return null; - } catch (URISyntaxException e) { - fail("unable to create URI"); - return null; - } - } - - @Test - public void nonTlsEnclaveCannotConnectToTlsServer() throws IOException { - - Path workDir = Files.createTempDirectory("test-certs"); - - // Note: the HttpServer always responds with a JsonRpcSuccess, result="I'm up". - final HttpServer httpServer = serverFactory.create(httpServerCert, besuCert, workDir, true); - - final Enclave enclave = createEnclave(httpServer.actualPort(), workDir, false); - - assertThat(enclave.upCheck()).isEqualTo(false); - } - - @Test - public void nonTlsEnclaveCanConnectToNonTlsServer() throws IOException { - - Path workDir = Files.createTempDirectory("test-certs"); - - // Note: the HttpServer always responds with a JsonRpcSuccess, result="I'm up". - final HttpServer httpServer = serverFactory.create(httpServerCert, besuCert, workDir, false); - - final Enclave enclave = createEnclave(httpServer.actualPort(), workDir, false); - - assertThat(enclave.upCheck()).isEqualTo(true); - } - - @Test - public void tlsEnclaveCannotConnectToNonTlsServer() throws IOException { - - Path workDir = Files.createTempDirectory("test-certs"); - - // Note: the HttpServer always responds with a JsonRpcSuccess, result="I'm up!". - final HttpServer httpServer = serverFactory.create(httpServerCert, besuCert, workDir, false); - - final Enclave enclave = createEnclave(httpServer.actualPort(), workDir, true); - - assertThat(enclave.upCheck()).isEqualTo(false); - } - - @Test - public void tlsEnclaveCanConnectToTlsServer() throws IOException { - - Path workDir = Files.createTempDirectory("test-certs"); - - // Note: the HttpServer always responds with a JsonRpcSuccess, result="I'm up". - final HttpServer httpServer = serverFactory.create(httpServerCert, besuCert, workDir, true); - - final Enclave enclave = createEnclave(httpServer.actualPort(), workDir, true); - - assertThat(enclave.upCheck()).isEqualTo(true); - } -} diff --git a/enclave/src/integration-test/java/org/hyperledger/besu/enclave/TlsEnabledHttpServerFactory.java b/enclave/src/integration-test/java/org/hyperledger/besu/enclave/TlsEnabledHttpServerFactory.java deleted file mode 100644 index 7c67aeb7b9..0000000000 --- a/enclave/src/integration-test/java/org/hyperledger/besu/enclave/TlsEnabledHttpServerFactory.java +++ /dev/null @@ -1,109 +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.enclave; - -import static org.hyperledger.besu.enclave.TlsHelpers.populateFingerprintFile; - -import java.io.IOException; -import java.nio.file.Path; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.cert.CertificateException; -import java.util.List; -import java.util.Optional; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; - -import com.google.common.collect.Lists; -import io.netty.handler.codec.http.HttpHeaderValues; -import io.vertx.core.Vertx; -import io.vertx.core.http.ClientAuth; -import io.vertx.core.http.HttpMethod; -import io.vertx.core.http.HttpServer; -import io.vertx.core.http.HttpServerOptions; -import io.vertx.core.http.HttpServerResponse; -import io.vertx.core.net.PfxOptions; -import io.vertx.ext.web.Router; -import io.vertx.ext.web.RoutingContext; -import org.apache.tuweni.net.tls.VertxTrustOptions; - -class TlsEnabledHttpServerFactory { - - private final Vertx vertx; - private final List serversCreated = Lists.newArrayList(); - - TlsEnabledHttpServerFactory() { - this.vertx = Vertx.vertx(); - } - - void shutdown() { - serversCreated.forEach(HttpServer::close); - vertx.close(); - } - - HttpServer create( - final TlsCertificateDefinition serverCert, - final TlsCertificateDefinition acceptedClientCerts, - final Path workDir, - final boolean tlsEnabled) { - try { - - final Path serverFingerprintFile = workDir.resolve("server_known_clients"); - populateFingerprintFile(serverFingerprintFile, acceptedClientCerts, Optional.empty()); - - final HttpServerOptions web3HttpServerOptions = new HttpServerOptions(); - web3HttpServerOptions.setPort(0); - if (tlsEnabled) { - web3HttpServerOptions.setSsl(true); - web3HttpServerOptions.setClientAuth(ClientAuth.REQUIRED); - web3HttpServerOptions.setTrustOptions( - VertxTrustOptions.allowlistClients(serverFingerprintFile)); - web3HttpServerOptions.setPfxKeyCertOptions( - new PfxOptions() - .setPath(serverCert.getPkcs12File().toString()) - .setPassword(serverCert.getPassword())); - } - final Router router = Router.router(vertx); - router - .route(HttpMethod.GET, "/upcheck") - .produces(HttpHeaderValues.APPLICATION_JSON.toString()) - .handler(TlsEnabledHttpServerFactory::handleRequest); - - final HttpServer mockOrionHttpServer = vertx.createHttpServer(web3HttpServerOptions); - - final CompletableFuture serverConfigured = new CompletableFuture<>(); - mockOrionHttpServer.requestHandler(router).listen(result -> serverConfigured.complete(true)); - - serverConfigured.get(); - - serversCreated.add(mockOrionHttpServer); - return mockOrionHttpServer; - } catch (final KeyStoreException - | NoSuchAlgorithmException - | CertificateException - | IOException - | ExecutionException - | InterruptedException e) { - throw new RuntimeException("Failed to construct a TLS Enabled Server", e); - } - } - - private static void handleRequest(final RoutingContext context) { - final HttpServerResponse response = context.response(); - if (!response.closed()) { - response.end("I'm up!"); - } - } -} diff --git a/enclave/src/integration-test/java/org/hyperledger/besu/enclave/TlsHelpers.java b/enclave/src/integration-test/java/org/hyperledger/besu/enclave/TlsHelpers.java deleted file mode 100644 index 09002f8115..0000000000 --- a/enclave/src/integration-test/java/org/hyperledger/besu/enclave/TlsHelpers.java +++ /dev/null @@ -1,98 +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.enclave; - -import org.hyperledger.besu.crypto.MessageDigestFactory; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.nio.file.Files; -import java.nio.file.Path; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.security.cert.CertificateEncodingException; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; -import java.util.Enumeration; -import java.util.List; -import java.util.Locale; -import java.util.Optional; -import java.util.StringJoiner; - -import com.google.common.collect.Lists; - -public class TlsHelpers { - - private TlsHelpers() {} - - private static KeyStore loadP12KeyStore(final File pkcsFile, final String password) - throws KeyStoreException, NoSuchAlgorithmException, CertificateException { - final KeyStore store = KeyStore.getInstance("pkcs12"); - try (final InputStream keystoreStream = new FileInputStream(pkcsFile)) { - store.load(keystoreStream, password.toCharArray()); - } catch (IOException e) { - throw new RuntimeException("Unable to load keystore.", e); - } - return store; - } - - public static void populateFingerprintFile( - final Path knownClientsPath, - final TlsCertificateDefinition certDef, - final Optional serverPortToAppendToHostname) - throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException { - - final List certs = getCertsFromPkcs12(certDef); - final StringBuilder fingerprintsToAdd = new StringBuilder(); - final String portFragment = serverPortToAppendToHostname.map(port -> ":" + port).orElse(""); - for (final X509Certificate cert : certs) { - final String fingerprint = generateFingerprint(cert); - fingerprintsToAdd.append(String.format("localhost%s %s%n", portFragment, fingerprint)); - fingerprintsToAdd.append(String.format("127.0.0.1%s %s%n", portFragment, fingerprint)); - } - Files.writeString(knownClientsPath, fingerprintsToAdd.toString()); - } - - @SuppressWarnings("JdkObsolete") // java.util.Enumeration is baked into the Keystore API - public static List getCertsFromPkcs12(final TlsCertificateDefinition certDef) - throws KeyStoreException, NoSuchAlgorithmException, CertificateException { - final List results = Lists.newArrayList(); - - final KeyStore p12 = loadP12KeyStore(certDef.getPkcs12File(), certDef.getPassword()); - final Enumeration aliases = p12.aliases(); - while (aliases.hasMoreElements()) { - results.add((X509Certificate) p12.getCertificate(aliases.nextElement())); - } - return results; - } - - private static String generateFingerprint(final X509Certificate cert) - throws NoSuchAlgorithmException, CertificateEncodingException { - final MessageDigest md = MessageDigestFactory.create(MessageDigestFactory.SHA256_ALG); - md.update(cert.getEncoded()); - final byte[] digest = md.digest(); - - final StringJoiner joiner = new StringJoiner(":"); - for (final byte b : digest) { - joiner.add(String.format("%02X", b)); - } - - return joiner.toString().toLowerCase(Locale.ROOT); - } -} diff --git a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/frontier/PrivGetPrivateTransactionIntegrationTest.java b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/frontier/PrivGetPrivateTransactionIntegrationTest.java deleted file mode 100644 index 9bb10629f3..0000000000 --- a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/frontier/PrivGetPrivateTransactionIntegrationTest.java +++ /dev/null @@ -1,192 +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.ethereum.api.jsonrpc.methods.fork.frontier; - -import static java.nio.charset.StandardCharsets.UTF_8; -import static org.assertj.core.api.Assertions.assertThat; -import static org.hyperledger.besu.ethereum.core.PrivateTransactionDataFixture.privateMarkerTransaction; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.when; - -import org.hyperledger.besu.crypto.KeyPair; -import org.hyperledger.besu.crypto.SignatureAlgorithm; -import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.datatypes.Wei; -import org.hyperledger.besu.enclave.Enclave; -import org.hyperledger.besu.enclave.EnclaveFactory; -import org.hyperledger.besu.enclave.types.SendResponse; -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.privacy.methods.PrivacyIdProvider; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv.PrivGetPrivateTransaction; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.privacy.PrivateTransactionLegacyResult; -import org.hyperledger.besu.ethereum.chain.Blockchain; -import org.hyperledger.besu.ethereum.chain.TransactionLocation; -import org.hyperledger.besu.ethereum.core.BlockHeader; -import org.hyperledger.besu.ethereum.core.Transaction; -import org.hyperledger.besu.ethereum.privacy.PrivacyController; -import org.hyperledger.besu.ethereum.privacy.PrivateTransaction; -import org.hyperledger.besu.ethereum.privacy.RestrictedDefaultPrivacyController; -import org.hyperledger.besu.ethereum.privacy.storage.PrivateStateStorage; -import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; -import org.hyperledger.besu.plugin.data.Restriction; -import org.hyperledger.enclave.testutil.EnclaveEncryptorType; -import org.hyperledger.enclave.testutil.EnclaveKeyConfiguration; -import org.hyperledger.enclave.testutil.TesseraTestHarness; -import org.hyperledger.enclave.testutil.TesseraTestHarnessFactory; - -import java.math.BigInteger; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Base64; -import java.util.Optional; - -import com.google.common.collect.Lists; -import io.vertx.core.Vertx; -import org.apache.tuweni.bytes.Bytes; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.io.TempDir; - -public class PrivGetPrivateTransactionIntegrationTest { - - @TempDir private static Path folder; - private static final String ENCLAVE_PUBLIC_KEY = "A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo="; - - private final PrivacyIdProvider privacyIdProvider = (user) -> ENCLAVE_PUBLIC_KEY; - private final PrivateStateStorage privateStateStorage = mock(PrivateStateStorage.class); - private final Blockchain blockchain = mock(Blockchain.class); - - private final Address sender = - Address.fromHexString("0x0000000000000000000000000000000000000003"); - - private final SignatureAlgorithm signatureAlgorithm = SignatureAlgorithmFactory.getInstance(); - - private final KeyPair KEY_PAIR = - signatureAlgorithm.createKeyPair( - signatureAlgorithm.createPrivateKey( - new BigInteger( - "8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63", 16))); - - private final PrivateTransaction privateTransaction = - PrivateTransaction.builder() - .nonce(0) - .gasPrice(Wei.of(1000)) - .gasLimit(3000000) - .to(null) - .value(Wei.ZERO) - .payload( - Bytes.fromHexString( - "0x608060405234801561001057600080fd5b5060d08061001f60003960" - + "00f3fe60806040526004361060485763ffffffff7c01000000" - + "00000000000000000000000000000000000000000000000000" - + "60003504166360fe47b18114604d5780636d4ce63c14607557" - + "5b600080fd5b348015605857600080fd5b5060736004803603" - + "6020811015606d57600080fd5b50356099565b005b34801560" - + "8057600080fd5b506087609e565b6040805191825251908190" - + "0360200190f35b600055565b6000549056fea165627a7a7230" - + "5820cb1d0935d14b589300b12fcd0ab849a7e9019c81da24d6" - + "daa4f6b2f003d1b0180029")) - .sender(sender) - .chainId(BigInteger.valueOf(2018)) - .privateFrom(Bytes.wrap(ENCLAVE_PUBLIC_KEY.getBytes(UTF_8))) - .privateFor( - Lists.newArrayList( - Bytes.wrap("A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo=".getBytes(UTF_8)))) - .restriction(Restriction.RESTRICTED) - .signAndBuild(KEY_PAIR); - - private Vertx vertx = Vertx.vertx(); - private TesseraTestHarness testHarness; - private Enclave enclave; - private PrivacyController privacyController; - - @BeforeEach - public void setUp() throws Exception { - vertx = Vertx.vertx(); - - testHarness = - TesseraTestHarnessFactory.create( - "enclave", - Files.createTempDirectory(folder, "enclave"), - new EnclaveKeyConfiguration( - new String[] {"enclave_key_0.pub"}, - new String[] {"enclave_key_0.key"}, - EnclaveEncryptorType.NOOP), - Optional.empty()); - - testHarness.start(); - - final EnclaveFactory factory = new EnclaveFactory(vertx); - enclave = factory.createVertxEnclave(testHarness.clientUrl()); - - privacyController = - new RestrictedDefaultPrivacyController( - blockchain, privateStateStorage, enclave, null, null, null, null, null); - } - - @AfterEach - public void tearDown() { - testHarness.close(); - vertx.close(); - } - - @Test - public void returnsStoredPrivateTransaction() { - final PrivGetPrivateTransaction privGetPrivateTransaction = - new PrivGetPrivateTransaction(privacyController, privacyIdProvider); - - final Hash blockHash = Hash.ZERO; - final Transaction pmt = spy(privateMarkerTransaction()); - when(blockchain.getTransactionByHash(eq(pmt.getHash()))).thenReturn(Optional.of(pmt)); - when(blockchain.getTransactionLocation(eq(pmt.getHash()))) - .thenReturn(Optional.of(new TransactionLocation(blockHash, 0))); - - final BlockHeader blockHeader = mock(BlockHeader.class); - when(blockHeader.getHash()).thenReturn(blockHash); - when(blockchain.getBlockHeader(eq(blockHash))).thenReturn(Optional.of(blockHeader)); - - final BytesValueRLPOutput bvrlp = new BytesValueRLPOutput(); - privateTransaction.writeTo(bvrlp); - - final String payload = Base64.getEncoder().encodeToString(bvrlp.encoded().toArrayUnsafe()); - final ArrayList to = Lists.newArrayList("A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo="); - final SendResponse sendResponse = enclave.send(payload, ENCLAVE_PUBLIC_KEY, to); - - final Bytes hexKey = Bytes.fromBase64String(sendResponse.getKey()); - when(pmt.getPayload()).thenReturn(hexKey); - - final Object[] params = new Object[] {pmt.getHash()}; - - final JsonRpcRequestContext request = - new JsonRpcRequestContext(new JsonRpcRequest("1", "priv_getPrivateTransaction", params)); - - final JsonRpcSuccessResponse response = - (JsonRpcSuccessResponse) privGetPrivateTransaction.response(request); - final PrivateTransactionLegacyResult result = - (PrivateTransactionLegacyResult) response.getResult(); - - assertThat(new PrivateTransactionLegacyResult(this.privateTransaction)) - .usingRecursiveComparison() - .isEqualTo(result); - } -} diff --git a/ethereum/core/src/integration-test/java/org/hyperledger/besu/ethereum/mainnet/precompiles/privacy/PrivacyPrecompiledContractIntegrationTest.java b/ethereum/core/src/integration-test/java/org/hyperledger/besu/ethereum/mainnet/precompiles/privacy/PrivacyPrecompiledContractIntegrationTest.java deleted file mode 100644 index a5ee5f068e..0000000000 --- a/ethereum/core/src/integration-test/java/org/hyperledger/besu/ethereum/mainnet/precompiles/privacy/PrivacyPrecompiledContractIntegrationTest.java +++ /dev/null @@ -1,244 +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.ethereum.mainnet.precompiles.privacy; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.catchThrowable; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyBoolean; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.ArgumentMatchers.nullable; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.enclave.Enclave; -import org.hyperledger.besu.enclave.EnclaveFactory; -import org.hyperledger.besu.enclave.types.SendResponse; -import org.hyperledger.besu.ethereum.core.Block; -import org.hyperledger.besu.ethereum.core.BlockDataGenerator; -import org.hyperledger.besu.ethereum.core.MutableWorldState; -import org.hyperledger.besu.ethereum.core.PrivateTransactionDataFixture; -import org.hyperledger.besu.ethereum.core.ProcessableBlockHeader; -import org.hyperledger.besu.ethereum.mainnet.PrivateStateUtils; -import org.hyperledger.besu.ethereum.privacy.PrivateStateGenesisAllocator; -import org.hyperledger.besu.ethereum.privacy.PrivateStateRootResolver; -import org.hyperledger.besu.ethereum.privacy.PrivateTransaction; -import org.hyperledger.besu.ethereum.privacy.PrivateTransactionProcessor; -import org.hyperledger.besu.ethereum.privacy.storage.PrivacyGroupHeadBlockMap; -import org.hyperledger.besu.ethereum.privacy.storage.PrivateMetadataUpdater; -import org.hyperledger.besu.ethereum.privacy.storage.PrivateStateStorage; -import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult; -import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; -import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; -import org.hyperledger.besu.evm.frame.MessageFrame; -import org.hyperledger.besu.evm.gascalculator.SpuriousDragonGasCalculator; -import org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup; -import org.hyperledger.besu.evm.precompile.PrecompiledContract; -import org.hyperledger.besu.evm.tracing.OperationTracer; -import org.hyperledger.besu.evm.worldstate.WorldUpdater; -import org.hyperledger.enclave.testutil.EnclaveEncryptorType; -import org.hyperledger.enclave.testutil.EnclaveKeyConfiguration; -import org.hyperledger.enclave.testutil.TesseraTestHarness; -import org.hyperledger.enclave.testutil.TesseraTestHarnessFactory; - -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Collections; -import java.util.List; -import java.util.Optional; - -import com.google.common.collect.Lists; -import io.vertx.core.Vertx; -import org.apache.tuweni.bytes.Bytes; -import org.apache.tuweni.bytes.Bytes32; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.io.TempDir; - -public class PrivacyPrecompiledContractIntegrationTest { - - // this tempDir is deliberately static - @TempDir private static Path folder; - - private static final Bytes VALID_PRIVATE_TRANSACTION_RLP = - Bytes.fromHexString( - "0xf90113800182520894095e7baea6a6c7c4c2dfeb977efac326af552d87" - + "a0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - + "ffff801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d" - + "495a36649353a01fffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab94" - + "9f53faa07bd2c804ac41316156744d784c4355486d425648586f5a7a7a4267" - + "5062572f776a3561784470573958386c393153476f3df85aac41316156744d" - + "784c4355486d425648586f5a7a7a42675062572f776a356178447057395838" - + "6c393153476f3dac4b6f32625671442b6e4e6c4e594c35454537793349644f" - + "6e766966746a69697a706a52742b4854754642733d8a726573747269637465" - + "64"); - private static final String DEFAULT_OUTPUT = "0x01"; - - private static Enclave enclave; - private static MessageFrame messageFrame; - - private static TesseraTestHarness testHarness; - private static WorldStateArchive worldStateArchive; - private static PrivateStateStorage privateStateStorage; - private static final Vertx vertx = Vertx.vertx(); - - private PrivateTransactionProcessor mockPrivateTxProcessor() { - final PrivateTransactionProcessor mockPrivateTransactionProcessor = - mock(PrivateTransactionProcessor.class); - final TransactionProcessingResult result = - TransactionProcessingResult.successful( - null, 0, 0, Bytes.fromHexString(DEFAULT_OUTPUT), null); - when(mockPrivateTransactionProcessor.processTransaction( - nullable(WorldUpdater.class), - nullable(WorldUpdater.class), - nullable(ProcessableBlockHeader.class), - nullable(Hash.class), - nullable(PrivateTransaction.class), - nullable(Address.class), - nullable(OperationTracer.class), - nullable(BlockHashLookup.class), - nullable(Bytes.class))) - .thenReturn(result); - - return mockPrivateTransactionProcessor; - } - - @BeforeAll - public static void setUpOnce() throws Exception { - - testHarness = - TesseraTestHarnessFactory.create( - "enclave", - Files.createTempDirectory(folder, "enclave"), - new EnclaveKeyConfiguration( - new String[] {"enclave_key_0.pub"}, - new String[] {"enclave_key_1.key"}, - EnclaveEncryptorType.NOOP), - Optional.empty()); - - testHarness.start(); - - final EnclaveFactory factory = new EnclaveFactory(vertx); - enclave = factory.createVertxEnclave(testHarness.clientUrl()); - messageFrame = mock(MessageFrame.class); - final BlockDataGenerator blockGenerator = new BlockDataGenerator(); - final Block genesis = blockGenerator.genesisBlock(); - final Block block = - blockGenerator.block( - new BlockDataGenerator.BlockOptions().setParentHash(genesis.getHeader().getHash())); - when(messageFrame.getBlockValues()).thenReturn(block.getHeader()); - final PrivateMetadataUpdater privateMetadataUpdater = mock(PrivateMetadataUpdater.class); - when(privateMetadataUpdater.getPrivateBlockMetadata(any())).thenReturn(null); - when(privateMetadataUpdater.getPrivacyGroupHeadBlockMap()) - .thenReturn(PrivacyGroupHeadBlockMap.empty()); - when(messageFrame.getContextVariable( - eq(PrivateStateUtils.KEY_IS_PERSISTING_PRIVATE_STATE), anyBoolean())) - .thenReturn(false); - when(messageFrame.getContextVariable(eq(PrivateStateUtils.KEY_PRIVATE_METADATA_UPDATER))) - .thenReturn(privateMetadataUpdater); - when(messageFrame.hasContextVariable(eq(PrivateStateUtils.KEY_PRIVATE_METADATA_UPDATER))) - .thenReturn(true); - - worldStateArchive = mock(WorldStateArchive.class); - final MutableWorldState mutableWorldState = mock(MutableWorldState.class); - when(mutableWorldState.updater()).thenReturn(mock(WorldUpdater.class)); - when(worldStateArchive.getMutable()).thenReturn(mutableWorldState); - when(worldStateArchive.getMutable(any(), any())).thenReturn(Optional.of(mutableWorldState)); - - privateStateStorage = mock(PrivateStateStorage.class); - final PrivateStateStorage.Updater storageUpdater = mock(PrivateStateStorage.Updater.class); - when(privateStateStorage.getPrivacyGroupHeadBlockMap(any())) - .thenReturn(Optional.of(PrivacyGroupHeadBlockMap.empty())); - when(storageUpdater.putPrivateBlockMetadata( - nullable(Bytes32.class), nullable(Bytes32.class), any())) - .thenReturn(storageUpdater); - when(storageUpdater.putTransactionReceipt( - nullable(Bytes32.class), nullable(Bytes32.class), any())) - .thenReturn(storageUpdater); - when(privateStateStorage.updater()).thenReturn(storageUpdater); - } - - @AfterAll - public static void tearDownOnce() { - testHarness.stop(); - vertx.close(); - } - - @Test - public void testUpCheck() { - assertThat(enclave.upCheck()).isTrue(); - } - - @Test - public void testSendAndReceive() { - final List publicKeys = testHarness.getPublicKeys(); - - final PrivateTransaction privateTransaction = - PrivateTransactionDataFixture.privateContractDeploymentTransactionBesu(publicKeys.get(0)); - final BytesValueRLPOutput bytesValueRLPOutput = new BytesValueRLPOutput(); - privateTransaction.writeTo(bytesValueRLPOutput); - - final String s = bytesValueRLPOutput.encoded().toBase64String(); - final SendResponse sr = - enclave.send(s, publicKeys.get(0), Lists.newArrayList(publicKeys.get(0))); - - final PrivacyPrecompiledContract privacyPrecompiledContract = - new PrivacyPrecompiledContract( - new SpuriousDragonGasCalculator(), - enclave, - worldStateArchive, - new PrivateStateRootResolver(privateStateStorage), - new PrivateStateGenesisAllocator( - false, (privacyGroupId, blockNumber) -> Collections::emptyList), - false, - "IntegrationTest"); - - privacyPrecompiledContract.setPrivateTransactionProcessor(mockPrivateTxProcessor()); - - final PrecompiledContract.PrecompileContractResult result = - privacyPrecompiledContract.computePrecompile( - Bytes.fromBase64String(sr.getKey()), messageFrame); - final Bytes actual = result.getOutput(); - - assertThat(actual).isEqualTo(Bytes.fromHexString(DEFAULT_OUTPUT)); - } - - @Test - public void testNoPrivateKeyError() throws RuntimeException { - final List publicKeys = testHarness.getPublicKeys(); - publicKeys.add("noPrivateKey"); - - final String s = VALID_PRIVATE_TRANSACTION_RLP.toBase64String(); - - final Throwable thrown = catchThrowable(() -> enclave.send(s, publicKeys.get(0), publicKeys)); - - assertThat(thrown).hasMessageContaining("Index 9 out of bounds for length 9"); - } - - @Test - public void testWrongPrivateKeyError() throws RuntimeException { - final List publicKeys = testHarness.getPublicKeys(); - publicKeys.add("noPrivateKenoPrivateKenoPrivateKenoPrivateK"); - - final String s = VALID_PRIVATE_TRANSACTION_RLP.toBase64String(); - - final Throwable thrown = catchThrowable(() -> enclave.send(s, publicKeys.get(0), publicKeys)); - - assertThat(thrown).hasMessageContaining("Recipient not found for key:"); - } -} diff --git a/testutil/src/main/resources/enclave_key_0.key b/testutil/src/main/resources/enclave_key_0.key deleted file mode 100644 index eaae9b0867..0000000000 --- a/testutil/src/main/resources/enclave_key_0.key +++ /dev/null @@ -1 +0,0 @@ -{"data":{"bytes":"hBsuQsGJzx4QHmFmBkNoI7YGnTmaZP4P+wBOdu56ljk="},"type":"unlocked"} \ No newline at end of file From 874cba016db3ef3c64df9d2ccf0b2b4a32d5d0f8 Mon Sep 17 00:00:00 2001 From: Matt Whitehead Date: Mon, 23 Sep 2024 11:58:47 +0100 Subject: [PATCH 232/259] Update protobuf to 32.25.5 to resolve CVE-2024-7254 (#7664) Signed-off-by: Matthew Whitehead --- gradle/verification-metadata.xml | 36 ++++++++++++++++++++++++++++++++ gradle/versions.gradle | 2 ++ 2 files changed, 38 insertions(+) diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index 3778a2d60a..7f6a58b66e 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -1023,6 +1023,11 @@ + + + + + @@ -1033,6 +1038,11 @@ + + + + + @@ -1049,6 +1059,14 @@ + + + + + + + + @@ -1062,6 +1080,14 @@ + + + + + + + + @@ -1080,6 +1106,11 @@ + + + + + @@ -1090,6 +1121,11 @@ + + + + + diff --git a/gradle/versions.gradle b/gradle/versions.gradle index b7a286e69a..634c29b1e1 100644 --- a/gradle/versions.gradle +++ b/gradle/versions.gradle @@ -25,6 +25,8 @@ dependencyManagement { 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' From 0d6395515890280c29ee2402c03b1ee81bde3bab Mon Sep 17 00:00:00 2001 From: Rafael Matias Date: Mon, 23 Sep 2024 14:34:20 +0200 Subject: [PATCH 233/259] Docker: Only switch user if the current user is root (#7654) * Update entrypoint script for Dockerfile to only switch user if its running as root Signed-off-by: Rafael Matias * make root user check at the beginning Signed-off-by: Rafael Matias --------- Signed-off-by: Rafael Matias --- besu/src/main/scripts/besu-entry.sh | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/besu/src/main/scripts/besu-entry.sh b/besu/src/main/scripts/besu-entry.sh index ed3687b229..ee11bfbffc 100755 --- a/besu/src/main/scripts/besu-entry.sh +++ b/besu/src/main/scripts/besu-entry.sh @@ -14,6 +14,14 @@ ## SPDX-License-Identifier: Apache-2.0 ## +# Construct the command as a single string +COMMAND="/opt/besu/bin/besu $@" + +# Check if current user is not root. If not, run the command as is. +if [ "$(id -u)" -ne 0 ]; then + exec /bin/bash -c "$COMMAND" +fi + # Run Besu first to get paths needing permission adjustment output=$(/opt/besu/bin/besu --print-paths-and-exit $BESU_USER_NAME "$@") @@ -41,9 +49,5 @@ echo "$output" | while IFS=: read -r prefix path accessType; do fi done -# Finally, run Besu with the actual arguments passed to the container -# Construct the command as a single string -COMMAND="/opt/besu/bin/besu $@" - # Switch to the besu user and execute the command -exec su -s /bin/bash $BESU_USER_NAME -c "$COMMAND" +exec su -s /bin/bash "$BESU_USER_NAME" -c "$COMMAND" From 4f07e76a6c26b294bcc8f50deefefc78438636dd Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Tue, 24 Sep 2024 13:04:03 +1000 Subject: [PATCH 234/259] 7311: Add feature toggle for enabling use of the peertask system where available (#7633) Signed-off-by: Matilda Clerke --- .../options/unstable/SynchronizerOptions.java | 18 +++++++++++++++++- besu/src/test/resources/everything_config.toml | 1 + .../eth/sync/SynchronizerConfiguration.java | 18 ++++++++++++++++-- 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/besu/src/main/java/org/hyperledger/besu/cli/options/unstable/SynchronizerOptions.java b/besu/src/main/java/org/hyperledger/besu/cli/options/unstable/SynchronizerOptions.java index 95bbe0a2b1..816d9df00a 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/options/unstable/SynchronizerOptions.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/options/unstable/SynchronizerOptions.java @@ -314,6 +314,13 @@ public class SynchronizerOptions implements CLIOptions

getDepositContractAddress(); + + /** + * The consolidation request contract address + * + * @return the consolidation request contract address + */ + Optional
getConsolidationRequestContractAddress(); } 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 67114b29bf..83b1f48fb4 100644 --- a/config/src/main/java/org/hyperledger/besu/config/JsonGenesisConfigOptions.java +++ b/config/src/main/java/org/hyperledger/besu/config/JsonGenesisConfigOptions.java @@ -52,6 +52,8 @@ public class JsonGenesisConfigOptions implements GenesisConfigOptions { private static final String WITHDRAWAL_REQUEST_CONTRACT_ADDRESS_KEY = "withdrawalrequestcontractaddress"; private static final String DEPOSIT_CONTRACT_ADDRESS_KEY = "depositcontractaddress"; + private static final String CONSOLIDATION_REQUEST_CONTRACT_ADDRESS_KEY = + "consolidationrequestcontractaddress"; private final ObjectNode configRoot; private final Map configOverrides = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); @@ -453,6 +455,13 @@ public class JsonGenesisConfigOptions implements GenesisConfigOptions { return inputAddress.map(Address::fromHexString); } + @Override + public Optional
getConsolidationRequestContractAddress() { + Optional inputAddress = + JsonUtil.getString(configRoot, CONSOLIDATION_REQUEST_CONTRACT_ADDRESS_KEY); + return inputAddress.map(Address::fromHexString); + } + @Override public Map asMap() { final ImmutableMap.Builder builder = ImmutableMap.builder(); @@ -504,6 +513,8 @@ public class JsonGenesisConfigOptions implements GenesisConfigOptions { getWithdrawalRequestContractAddress() .ifPresent(l -> builder.put("withdrawalRequestContractAddress", l)); getDepositContractAddress().ifPresent(l -> builder.put("depositContractAddress", l)); + getConsolidationRequestContractAddress() + .ifPresent(l -> builder.put("consolidationRequestContractAddress", l)); if (isClique()) { builder.put("clique", getCliqueConfigOptions().asMap()); 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 efe56a086d..ee9584fd3a 100644 --- a/config/src/main/java/org/hyperledger/besu/config/StubGenesisConfigOptions.java +++ b/config/src/main/java/org/hyperledger/besu/config/StubGenesisConfigOptions.java @@ -467,6 +467,11 @@ public class StubGenesisConfigOptions implements GenesisConfigOptions, Cloneable return Optional.empty(); } + @Override + public Optional
getConsolidationRequestContractAddress() { + return Optional.empty(); + } + /** * Homestead block stub genesis config options. * 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 219ea4fcf8..69494a9c9c 100644 --- a/config/src/test/java/org/hyperledger/besu/config/GenesisConfigOptionsTest.java +++ b/config/src/test/java/org/hyperledger/besu/config/GenesisConfigOptionsTest.java @@ -382,6 +382,33 @@ class GenesisConfigOptionsTest { .containsValue(Address.ZERO); } + @Test + void shouldGetConsolidationRequestContractAddress() { + final GenesisConfigOptions config = + fromConfigOptions( + singletonMap( + "consolidationRequestContractAddress", + "0x00000000219ab540356cbb839cbe05303d7705fa")); + assertThat(config.getConsolidationRequestContractAddress()) + .hasValue(Address.fromHexString("0x00000000219ab540356cbb839cbe05303d7705fa")); + } + + @Test + void shouldNotHaveConsolidationRequestContractAddressWhenEmpty() { + final GenesisConfigOptions config = fromConfigOptions(emptyMap()); + assertThat(config.getConsolidationRequestContractAddress()).isEmpty(); + } + + @Test + void asMapIncludesConsolidationRequestContractAddress() { + final GenesisConfigOptions config = + fromConfigOptions(Map.of("consolidationRequestContractAddress", "0x0")); + + assertThat(config.asMap()) + .containsOnlyKeys("consolidationRequestContractAddress") + .containsValue(Address.ZERO); + } + private GenesisConfigOptions fromConfigOptions(final Map configOptions) { final ObjectNode rootNode = JsonUtil.createEmptyObjectNode(); final ObjectNode options = JsonUtil.objectNodeFromMap(configOptions); 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 e6d7a88cbd..b5b2f678d6 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,10 +14,8 @@ */ package org.hyperledger.besu.ethereum.mainnet; -import static org.hyperledger.besu.ethereum.mainnet.requests.DepositRequestProcessor.DEFAULT_DEPOSIT_CONTRACT_ADDRESS; 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.WithdrawalRequestProcessor.DEFAULT_WITHDRAWAL_REQUEST_CONTRACT_ADDRESS; import org.hyperledger.besu.config.GenesisConfigOptions; import org.hyperledger.besu.config.PowAlgorithm; @@ -41,6 +39,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.RequestContractAddresses; import org.hyperledger.besu.ethereum.privacy.PrivateTransactionProcessor; import org.hyperledger.besu.ethereum.privacy.PrivateTransactionValidator; import org.hyperledger.besu.ethereum.privacy.storage.PrivateMetadataUpdater; @@ -767,12 +766,8 @@ public abstract class MainnetProtocolSpecs { final boolean isParallelTxProcessingEnabled, final MetricsSystem metricsSystem) { - final Address withdrawalRequestContractAddress = - genesisConfigOptions - .getWithdrawalRequestContractAddress() - .orElse(DEFAULT_WITHDRAWAL_REQUEST_CONTRACT_ADDRESS); - final Address depositContractAddress = - genesisConfigOptions.getDepositContractAddress().orElse(DEFAULT_DEPOSIT_CONTRACT_ADDRESS); + RequestContractAddresses requestContractAddresses = + RequestContractAddresses.fromGenesis(genesisConfigOptions); return cancunDefinition( chainId, @@ -794,10 +789,9 @@ public abstract class MainnetProtocolSpecs { .precompileContractRegistryBuilder(MainnetPrecompiledContractRegistries::prague) // EIP-7002 Withdrawals / EIP-6610 Deposits / EIP-7685 Requests - .requestsValidator(pragueRequestsValidator(depositContractAddress)) + .requestsValidator(pragueRequestsValidator(requestContractAddresses)) // EIP-7002 Withdrawals / EIP-6610 Deposits / EIP-7685 Requests - .requestProcessorCoordinator( - pragueRequestsProcessors(withdrawalRequestContractAddress, depositContractAddress)) + .requestProcessorCoordinator(pragueRequestsProcessors(requestContractAddresses)) // change to accept EIP-7702 transactions .transactionValidatorFactoryBuilder( 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 index 0a48d8278c..641720670f 100644 --- 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 @@ -22,13 +22,18 @@ import org.apache.tuweni.bytes.Bytes; public class ConsolidationRequestProcessor extends AbstractSystemCallRequestProcessor { - public static final Address CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS = + 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. @@ -37,7 +42,7 @@ public class ConsolidationRequestProcessor */ @Override protected Address getCallAddress() { - return CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS; + return consolidationRequestContractAddress; } /** 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 6e61a0343c..9c86d18f7a 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,27 +14,34 @@ */ package org.hyperledger.besu.ethereum.mainnet.requests; -import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.RequestType; public class MainnetRequestsValidator { public static RequestsValidatorCoordinator pragueRequestsValidator( - final Address depositContractAddress) { + final RequestContractAddresses requestContractAddresses) { return new RequestsValidatorCoordinator.Builder() .addValidator(RequestType.WITHDRAWAL, new WithdrawalRequestValidator()) .addValidator(RequestType.CONSOLIDATION, new ConsolidationRequestValidator()) - .addValidator(RequestType.DEPOSIT, new DepositRequestValidator(depositContractAddress)) + .addValidator( + RequestType.DEPOSIT, + new DepositRequestValidator(requestContractAddresses.getDepositContractAddress())) .build(); } public static RequestProcessorCoordinator pragueRequestsProcessors( - final Address withdrawalRequestContractAddress, final Address depositContractAddress) { + final RequestContractAddresses requestContractAddresses) { return new RequestProcessorCoordinator.Builder() .addProcessor( RequestType.WITHDRAWAL, - new WithdrawalRequestProcessor(withdrawalRequestContractAddress)) - .addProcessor(RequestType.CONSOLIDATION, new ConsolidationRequestProcessor()) - .addProcessor(RequestType.DEPOSIT, new DepositRequestProcessor(depositContractAddress)) + new WithdrawalRequestProcessor( + requestContractAddresses.getWithdrawalRequestContractAddress())) + .addProcessor( + RequestType.CONSOLIDATION, + new ConsolidationRequestProcessor( + requestContractAddresses.getConsolidationRequestContractAddress())) + .addProcessor( + RequestType.DEPOSIT, + new DepositRequestProcessor(requestContractAddresses.getDepositContractAddress())) .build(); } } 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 new file mode 100644 index 0000000000..b75677dda7 --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/RequestContractAddresses.java @@ -0,0 +1,61 @@ +/* + * 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.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; + +public class RequestContractAddresses { + private final Address withdrawalRequestContractAddress; + private final Address depositContractAddress; + private final Address consolidationRequestContractAddress; + + public RequestContractAddresses( + final Address withdrawalRequestContractAddress, + final Address depositContractAddress, + final Address consolidationRequestContractAddress) { + this.withdrawalRequestContractAddress = withdrawalRequestContractAddress; + this.depositContractAddress = depositContractAddress; + this.consolidationRequestContractAddress = consolidationRequestContractAddress; + } + + public static RequestContractAddresses fromGenesis( + final GenesisConfigOptions genesisConfigOptions) { + return new RequestContractAddresses( + genesisConfigOptions + .getWithdrawalRequestContractAddress() + .orElse(DEFAULT_WITHDRAWAL_REQUEST_CONTRACT_ADDRESS), + genesisConfigOptions.getDepositContractAddress().orElse(DEFAULT_DEPOSIT_CONTRACT_ADDRESS), + genesisConfigOptions + .getConsolidationRequestContractAddress() + .orElse(CONSOLIDATION_REQUEST_CONTRACT_ADDRESS)); + } + + public Address getWithdrawalRequestContractAddress() { + return withdrawalRequestContractAddress; + } + + public Address getDepositContractAddress() { + return depositContractAddress; + } + + public Address getConsolidationRequestContractAddress() { + return consolidationRequestContractAddress; + } +} 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 index 6c325b70a8..6158ba44c3 100644 --- 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 @@ -17,8 +17,10 @@ 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; @@ -31,6 +33,7 @@ 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; @@ -52,9 +55,13 @@ class PragueRequestsValidatorTest { @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(DEFAULT_DEPOSIT_CONTRACT_ADDRESS); + RequestsValidatorCoordinator requestValidator = pragueRequestsValidator(requestContractAddresses); @BeforeEach public void setUp() { From 2aa3848950c86bbe720531539bdb990ab1fcaa7b Mon Sep 17 00:00:00 2001 From: Fabio Di Fabio Date: Tue, 24 Sep 2024 11:49:17 +0200 Subject: [PATCH 236/259] Enable logging during unit tests (#7672) Signed-off-by: Fabio Di Fabio --- testutil/src/main/resources/{log4j2.xml => log4j2-test.xml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename testutil/src/main/resources/{log4j2.xml => log4j2-test.xml} (100%) diff --git a/testutil/src/main/resources/log4j2.xml b/testutil/src/main/resources/log4j2-test.xml similarity index 100% rename from testutil/src/main/resources/log4j2.xml rename to testutil/src/main/resources/log4j2-test.xml From e0518c6d94bf1ae4f0e3742a9e3e51aac7e15fb3 Mon Sep 17 00:00:00 2001 From: Gabriel-Trintinalia Date: Tue, 24 Sep 2024 20:50:19 +1000 Subject: [PATCH 237/259] Force besu to stop on plugin initialization errors (#7662) Signed-off-by: Gabriel-Trintinalia --- CHANGELOG.md | 1 + .../dsl/node/ThreadBesuNodeRunner.java | 3 +- .../acceptance/plugins/TestPicoCLIPlugin.java | 51 +++- .../services/BesuPluginContextImplTest.java | 266 +++++++++++++++--- .../org/hyperledger/besu/cli/BesuCommand.java | 6 +- .../besu/cli/DefaultCommandValues.java | 3 + .../stable/PluginsConfigurationOptions.java | 30 +- .../besu/services/BesuPluginContextImpl.java | 91 ++++-- .../besu/cli/PluginsOptionsTest.java | 51 +++- .../src/test/resources/everything_config.toml | 3 +- .../core/plugins/PluginConfiguration.java | 18 +- 11 files changed, 424 insertions(+), 99 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ce29955d1..bb867af945 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ - k8s (KUBERNETES) Nat method is now deprecated and will be removed in a future release ### 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) ### Additions and Improvements - Remove privacy test classes support [#7569](https://github.com/hyperledger/besu/pull/7569) 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 5d78f1460c..90de0b0e95 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 @@ -503,8 +503,9 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner { besuPluginContext.addService(PermissioningService.class, permissioningService); besuPluginContext.addService(PrivacyPluginService.class, new PrivacyPluginServiceImpl()); - besuPluginContext.registerPlugins( + besuPluginContext.initialize( new PluginConfiguration.Builder().pluginsDir(pluginsPath).build()); + besuPluginContext.registerPlugins(); commandLine.parseArgs(extraCLIOptions.toArray(new String[0])); // register built-in plugins diff --git a/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestPicoCLIPlugin.java b/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestPicoCLIPlugin.java index 0db5281537..375fbd490e 100644 --- a/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestPicoCLIPlugin.java +++ b/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestPicoCLIPlugin.java @@ -1,5 +1,5 @@ /* - * Copyright ConsenSys AG. + * 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 @@ -32,16 +32,25 @@ import picocli.CommandLine.Option; public class TestPicoCLIPlugin implements BesuPlugin { private static final Logger LOG = LoggerFactory.getLogger(TestPicoCLIPlugin.class); + private static final String UNSET = "UNSET"; + private static final String FAIL_REGISTER = "FAILREGISTER"; + private static final String FAIL_BEFORE_EXTERNAL_SERVICES = "FAILBEFOREEXTERNALSERVICES"; + private static final String FAIL_START = "FAILSTART"; + private static final String FAIL_AFTER_EXTERNAL_SERVICE_POST_MAIN_LOOP = + "FAILAFTEREXTERNALSERVICEPOSTMAINLOOP"; + private static final String FAIL_STOP = "FAILSTOP"; + private static final String PLUGIN_LIFECYCLE_PREFIX = "pluginLifecycle."; + @Option( names = {"--Xplugin-test-option"}, hidden = true, - defaultValue = "UNSET") + defaultValue = UNSET) String testOption = System.getProperty("testPicoCLIPlugin.testOption"); @Option( names = {"--plugin-test-stable-option"}, hidden = true, - defaultValue = "UNSET") + defaultValue = UNSET) String stableOption = ""; private String state = "uninited"; @@ -52,7 +61,7 @@ public class TestPicoCLIPlugin implements BesuPlugin { LOG.info("Registering. Test Option is '{}'", testOption); state = "registering"; - if ("FAILREGISTER".equals(testOption)) { + if (FAIL_REGISTER.equals(testOption)) { state = "failregister"; throw new RuntimeException("I was told to fail at registration"); } @@ -66,12 +75,26 @@ public class TestPicoCLIPlugin implements BesuPlugin { state = "registered"; } + @Override + public void beforeExternalServices() { + LOG.info("Before external services. Test Option is '{}'", testOption); + state = "beforeExternalServices"; + + if (FAIL_BEFORE_EXTERNAL_SERVICES.equals(testOption)) { + state = "failbeforeExternalServices"; + throw new RuntimeException("I was told to fail before external services"); + } + + writeSignal("beforeExternalServices"); + state = "beforeExternalServicesFinished"; + } + @Override public void start() { LOG.info("Starting. Test Option is '{}'", testOption); state = "starting"; - if ("FAILSTART".equals(testOption)) { + if (FAIL_START.equals(testOption)) { state = "failstart"; throw new RuntimeException("I was told to fail at startup"); } @@ -80,12 +103,26 @@ public class TestPicoCLIPlugin implements BesuPlugin { state = "started"; } + @Override + public void afterExternalServicePostMainLoop() { + LOG.info("After external services post main loop. Test Option is '{}'", testOption); + state = "afterExternalServicePostMainLoop"; + + if (FAIL_AFTER_EXTERNAL_SERVICE_POST_MAIN_LOOP.equals(testOption)) { + state = "failafterExternalServicePostMainLoop"; + throw new RuntimeException("I was told to fail after external services post main loop"); + } + + writeSignal("afterExternalServicePostMainLoop"); + state = "afterExternalServicePostMainLoopFinished"; + } + @Override public void stop() { LOG.info("Stopping. Test Option is '{}'", testOption); state = "stopping"; - if ("FAILSTOP".equals(testOption)) { + if (FAIL_STOP.equals(testOption)) { state = "failstop"; throw new RuntimeException("I was told to fail at stop"); } @@ -103,7 +140,7 @@ public class TestPicoCLIPlugin implements BesuPlugin { @SuppressWarnings("ResultOfMethodCallIgnored") private void writeSignal(final String signal) { try { - final File callbackFile = new File(callbackDir, "pluginLifecycle." + signal); + final File callbackFile = new File(callbackDir, PLUGIN_LIFECYCLE_PREFIX + signal); if (!callbackFile.getParentFile().exists()) { callbackFile.getParentFile().mkdirs(); callbackFile.getParentFile().deleteOnExit(); diff --git a/acceptance-tests/test-plugins/src/test/java/org/hyperledger/besu/services/BesuPluginContextImplTest.java b/acceptance-tests/test-plugins/src/test/java/org/hyperledger/besu/services/BesuPluginContextImplTest.java index 7e27704177..a6d167665f 100644 --- a/acceptance-tests/test-plugins/src/test/java/org/hyperledger/besu/services/BesuPluginContextImplTest.java +++ b/acceptance-tests/test-plugins/src/test/java/org/hyperledger/besu/services/BesuPluginContextImplTest.java @@ -1,5 +1,5 @@ /* - * Copyright ConsenSys AG. + * 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 @@ -40,8 +40,31 @@ import org.junit.jupiter.api.Test; public class BesuPluginContextImplTest { private static final Path DEFAULT_PLUGIN_DIRECTORY = Paths.get("."); + private static final String TEST_PICO_CLI_PLUGIN = "TestPicoCLIPlugin"; + private static final String TEST_PICO_CLI_PLUGIN_TEST_OPTION = "testPicoCLIPlugin.testOption"; + private static final String FAIL_REGISTER = "FAILREGISTER"; + private static final String FAIL_START = "FAILSTART"; + private static final String FAIL_STOP = "FAILSTOP"; + private static final String FAIL_BEFORE_EXTERNAL_SERVICES = "FAILBEFOREEXTERNALSERVICES"; + private static final String FAIL_BEFORE_MAIN_LOOP = "FAILBEFOREMAINLOOP"; + private static final String FAIL_AFTER_EXTERNAL_SERVICE_POST_MAIN_LOOP = + "FAILAFTEREXTERNALSERVICEPOSTMAINLOOP"; + private static final String NON_EXISTENT_PLUGIN = "NonExistentPlugin"; + private static final String REGISTERED = "registered"; + private static final String STARTED = "started"; + private static final String STOPPED = "stopped"; + private static final String FAIL_START_STATE = "failstart"; + private static final String FAIL_STOP_STATE = "failstop"; + private BesuPluginContextImpl contextImpl; + private static final PluginConfiguration DEFAULT_CONFIGURATION = + PluginConfiguration.builder() + .pluginsDir(DEFAULT_PLUGIN_DIRECTORY) + .externalPluginsEnabled(true) + .continueOnPluginError(true) + .build(); + @BeforeAll public static void createFakePluginDir() throws IOException { if (System.getProperty("besu.plugins.dir") == null) { @@ -53,7 +76,7 @@ public class BesuPluginContextImplTest { @AfterEach public void clearTestPluginState() { - System.clearProperty("testPicoCLIPlugin.testOption"); + System.clearProperty(TEST_PICO_CLI_PLUGIN_TEST_OPTION); } @BeforeEach @@ -64,31 +87,31 @@ public class BesuPluginContextImplTest { @Test public void verifyEverythingGoesSmoothly() { assertThat(contextImpl.getRegisteredPlugins()).isEmpty(); - contextImpl.registerPlugins( - PluginConfiguration.builder().pluginsDir(DEFAULT_PLUGIN_DIRECTORY).build()); + contextImpl.initialize(DEFAULT_CONFIGURATION); + contextImpl.registerPlugins(); assertThat(contextImpl.getRegisteredPlugins()).isNotEmpty(); final Optional testPluginOptional = findTestPlugin(contextImpl.getRegisteredPlugins(), TestPicoCLIPlugin.class); assertThat(testPluginOptional).isPresent(); final TestPicoCLIPlugin testPicoCLIPlugin = testPluginOptional.get(); - assertThat(testPicoCLIPlugin.getState()).isEqualTo("registered"); + assertThat(testPicoCLIPlugin.getState()).isEqualTo(REGISTERED); contextImpl.beforeExternalServices(); contextImpl.startPlugins(); - assertThat(testPicoCLIPlugin.getState()).isEqualTo("started"); + assertThat(testPicoCLIPlugin.getState()).isEqualTo(STARTED); contextImpl.stopPlugins(); - assertThat(testPicoCLIPlugin.getState()).isEqualTo("stopped"); + assertThat(testPicoCLIPlugin.getState()).isEqualTo(STOPPED); } @Test public void registrationErrorsHandledSmoothly() { - System.setProperty("testPicoCLIPlugin.testOption", "FAILREGISTER"); + System.setProperty(TEST_PICO_CLI_PLUGIN_TEST_OPTION, FAIL_REGISTER); assertThat(contextImpl.getRegisteredPlugins()).isEmpty(); - contextImpl.registerPlugins( - PluginConfiguration.builder().pluginsDir(DEFAULT_PLUGIN_DIRECTORY).build()); + contextImpl.initialize(DEFAULT_CONFIGURATION); + contextImpl.registerPlugins(); assertThat(contextImpl.getRegisteredPlugins()).isNotInstanceOfAny(TestPicoCLIPlugin.class); contextImpl.beforeExternalServices(); @@ -103,11 +126,11 @@ public class BesuPluginContextImplTest { @Test public void startErrorsHandledSmoothly() { - System.setProperty("testPicoCLIPlugin.testOption", "FAILSTART"); + System.setProperty(TEST_PICO_CLI_PLUGIN_TEST_OPTION, FAIL_START); assertThat(contextImpl.getRegisteredPlugins()).isEmpty(); - contextImpl.registerPlugins( - PluginConfiguration.builder().pluginsDir(DEFAULT_PLUGIN_DIRECTORY).build()); + contextImpl.initialize(DEFAULT_CONFIGURATION); + contextImpl.registerPlugins(); assertThat(contextImpl.getRegisteredPlugins()) .extracting("class") .contains(TestPicoCLIPlugin.class); @@ -116,11 +139,11 @@ public class BesuPluginContextImplTest { findTestPlugin(contextImpl.getRegisteredPlugins(), TestPicoCLIPlugin.class); assertThat(testPluginOptional).isPresent(); final TestPicoCLIPlugin testPicoCLIPlugin = testPluginOptional.get(); - assertThat(testPicoCLIPlugin.getState()).isEqualTo("registered"); + assertThat(testPicoCLIPlugin.getState()).isEqualTo(REGISTERED); contextImpl.beforeExternalServices(); contextImpl.startPlugins(); - assertThat(testPicoCLIPlugin.getState()).isEqualTo("failstart"); + assertThat(testPicoCLIPlugin.getState()).isEqualTo(FAIL_START_STATE); assertThat(contextImpl.getRegisteredPlugins()).isNotInstanceOfAny(TestPicoCLIPlugin.class); contextImpl.stopPlugins(); @@ -129,11 +152,11 @@ public class BesuPluginContextImplTest { @Test public void stopErrorsHandledSmoothly() { - System.setProperty("testPicoCLIPlugin.testOption", "FAILSTOP"); + System.setProperty(TEST_PICO_CLI_PLUGIN_TEST_OPTION, FAIL_STOP); assertThat(contextImpl.getRegisteredPlugins()).isEmpty(); - contextImpl.registerPlugins( - PluginConfiguration.builder().pluginsDir(DEFAULT_PLUGIN_DIRECTORY).build()); + contextImpl.initialize(DEFAULT_CONFIGURATION); + contextImpl.registerPlugins(); assertThat(contextImpl.getRegisteredPlugins()) .extracting("class") .contains(TestPicoCLIPlugin.class); @@ -142,22 +165,20 @@ public class BesuPluginContextImplTest { findTestPlugin(contextImpl.getRegisteredPlugins(), TestPicoCLIPlugin.class); assertThat(testPluginOptional).isPresent(); final TestPicoCLIPlugin testPicoCLIPlugin = testPluginOptional.get(); - assertThat(testPicoCLIPlugin.getState()).isEqualTo("registered"); + assertThat(testPicoCLIPlugin.getState()).isEqualTo(REGISTERED); contextImpl.beforeExternalServices(); contextImpl.startPlugins(); - assertThat(testPicoCLIPlugin.getState()).isEqualTo("started"); + assertThat(testPicoCLIPlugin.getState()).isEqualTo(STARTED); contextImpl.stopPlugins(); - assertThat(testPicoCLIPlugin.getState()).isEqualTo("failstop"); + assertThat(testPicoCLIPlugin.getState()).isEqualTo(FAIL_STOP_STATE); } @Test public void lifecycleExceptions() throws Throwable { - final ThrowableAssert.ThrowingCallable registerPlugins = - () -> - contextImpl.registerPlugins( - PluginConfiguration.builder().pluginsDir(DEFAULT_PLUGIN_DIRECTORY).build()); + contextImpl.initialize(DEFAULT_CONFIGURATION); + final ThrowableAssert.ThrowingCallable registerPlugins = () -> contextImpl.registerPlugins(); assertThatExceptionOfType(IllegalStateException.class).isThrownBy(contextImpl::startPlugins); assertThatExceptionOfType(IllegalStateException.class).isThrownBy(contextImpl::stopPlugins); @@ -179,30 +200,27 @@ public class BesuPluginContextImplTest { @Test public void shouldRegisterAllPluginsWhenNoPluginsOption() { - final PluginConfiguration config = - PluginConfiguration.builder().pluginsDir(DEFAULT_PLUGIN_DIRECTORY).build(); - assertThat(contextImpl.getRegisteredPlugins()).isEmpty(); - contextImpl.registerPlugins(config); + contextImpl.initialize(DEFAULT_CONFIGURATION); + contextImpl.registerPlugins(); final Optional testPluginOptional = findTestPlugin(contextImpl.getRegisteredPlugins(), TestPicoCLIPlugin.class); assertThat(testPluginOptional).isPresent(); final TestPicoCLIPlugin testPicoCLIPlugin = testPluginOptional.get(); - assertThat(testPicoCLIPlugin.getState()).isEqualTo("registered"); + assertThat(testPicoCLIPlugin.getState()).isEqualTo(REGISTERED); } @Test public void shouldRegisterOnlySpecifiedPluginWhenPluginsOptionIsSet() { - final PluginConfiguration config = createConfigurationForSpecificPlugin("TestPicoCLIPlugin"); - assertThat(contextImpl.getRegisteredPlugins()).isEmpty(); - contextImpl.registerPlugins(config); + contextImpl.initialize(createConfigurationForSpecificPlugin(TEST_PICO_CLI_PLUGIN)); + contextImpl.registerPlugins(); final Optional requestedPlugin = findTestPlugin(contextImpl.getRegisteredPlugins(), TestPicoCLIPlugin.class); assertThat(requestedPlugin).isPresent(); - assertThat(requestedPlugin.get().getState()).isEqualTo("registered"); + assertThat(requestedPlugin.get().getState()).isEqualTo(REGISTERED); final Optional nonRequestedPlugin = findTestPlugin(contextImpl.getRegisteredPlugins(), TestBesuEventsPlugin.class); @@ -212,9 +230,9 @@ public class BesuPluginContextImplTest { @Test public void shouldNotRegisterUnspecifiedPluginsWhenPluginsOptionIsSet() { - final PluginConfiguration config = createConfigurationForSpecificPlugin("TestPicoCLIPlugin"); assertThat(contextImpl.getRegisteredPlugins()).isEmpty(); - contextImpl.registerPlugins(config); + contextImpl.initialize(createConfigurationForSpecificPlugin(TEST_PICO_CLI_PLUGIN)); + contextImpl.registerPlugins(); final Optional nonRequestedPlugin = findTestPlugin(contextImpl.getRegisteredPlugins(), TestBesuEventsPlugin.class); @@ -223,13 +241,12 @@ public class BesuPluginContextImplTest { @Test void shouldThrowExceptionIfExplicitlySpecifiedPluginNotFound() { - PluginConfiguration config = createConfigurationForSpecificPlugin("NonExistentPlugin"); - + contextImpl.initialize(createConfigurationForSpecificPlugin(NON_EXISTENT_PLUGIN)); String exceptionMessage = - assertThrows(NoSuchElementException.class, () -> contextImpl.registerPlugins(config)) + assertThrows(NoSuchElementException.class, () -> contextImpl.registerPlugins()) .getMessage(); final String expectedMessage = - "The following requested plugins were not found: NonExistentPlugin"; + "The following requested plugins were not found: " + NON_EXISTENT_PLUGIN; assertThat(exceptionMessage).isEqualTo(expectedMessage); assertThat(contextImpl.getRegisteredPlugins()).isEmpty(); } @@ -241,19 +258,180 @@ public class BesuPluginContextImplTest { .pluginsDir(DEFAULT_PLUGIN_DIRECTORY) .externalPluginsEnabled(false) .build(); - contextImpl.registerPlugins(config); + contextImpl.initialize(config); + contextImpl.registerPlugins(); assertThat(contextImpl.getRegisteredPlugins().isEmpty()).isTrue(); } @Test void shouldRegisterPluginsIfExternalPluginsEnabled() { + contextImpl.initialize(DEFAULT_CONFIGURATION); + contextImpl.registerPlugins(); + assertThat(contextImpl.getRegisteredPlugins().isEmpty()).isFalse(); + } + + @Test + void shouldHaltOnRegisterErrorWhenFlagIsFalse() { + System.setProperty(TEST_PICO_CLI_PLUGIN_TEST_OPTION, FAIL_REGISTER); + PluginConfiguration config = PluginConfiguration.builder() + .requestedPlugins(List.of(new PluginInfo(TEST_PICO_CLI_PLUGIN))) .pluginsDir(DEFAULT_PLUGIN_DIRECTORY) - .externalPluginsEnabled(true) + .continueOnPluginError(false) .build(); - contextImpl.registerPlugins(config); - assertThat(contextImpl.getRegisteredPlugins().isEmpty()).isFalse(); + + contextImpl.initialize(config); + + String errorMessage = + String.format("Error registering plugin of type %s", TestPicoCLIPlugin.class.getName()); + assertThatExceptionOfType(RuntimeException.class) + .isThrownBy(() -> contextImpl.registerPlugins()) + .withMessageContaining(errorMessage); + } + + @Test + void shouldNotHaltOnRegisterErrorWhenFlagIsTrue() { + System.setProperty(TEST_PICO_CLI_PLUGIN_TEST_OPTION, FAIL_REGISTER); + + PluginConfiguration config = + PluginConfiguration.builder() + .pluginsDir(DEFAULT_PLUGIN_DIRECTORY) + .continueOnPluginError(true) + .build(); + + contextImpl.initialize(config); + contextImpl.registerPlugins(); + assertThat(contextImpl.getRegisteredPlugins()).isNotInstanceOfAny(TestPicoCLIPlugin.class); + } + + @Test + void shouldHaltOnBeforeExternalServicesErrorWhenFlagIsFalse() { + System.setProperty(TEST_PICO_CLI_PLUGIN_TEST_OPTION, FAIL_BEFORE_EXTERNAL_SERVICES); + + PluginConfiguration config = + PluginConfiguration.builder() + .requestedPlugins(List.of(new PluginInfo(TEST_PICO_CLI_PLUGIN))) + .pluginsDir(DEFAULT_PLUGIN_DIRECTORY) + .continueOnPluginError(false) + .build(); + + contextImpl.initialize(config); + contextImpl.registerPlugins(); + + String errorMessage = + String.format( + "Error calling `beforeExternalServices` on plugin of type %s", + TestPicoCLIPlugin.class.getName()); + assertThatExceptionOfType(RuntimeException.class) + .isThrownBy(() -> contextImpl.beforeExternalServices()) + .withMessageContaining(errorMessage); + } + + @Test + void shouldNotHaltOnBeforeExternalServicesErrorWhenFlagIsTrue() { + System.setProperty(TEST_PICO_CLI_PLUGIN_TEST_OPTION, FAIL_BEFORE_EXTERNAL_SERVICES); + + PluginConfiguration config = + PluginConfiguration.builder() + .requestedPlugins(List.of(new PluginInfo(TEST_PICO_CLI_PLUGIN))) + .pluginsDir(DEFAULT_PLUGIN_DIRECTORY) + .continueOnPluginError(true) + .build(); + + contextImpl.initialize(config); + contextImpl.registerPlugins(); + contextImpl.beforeExternalServices(); + + assertThat(contextImpl.getRegisteredPlugins()).isNotInstanceOfAny(TestPicoCLIPlugin.class); + } + + @Test + void shouldHaltOnBeforeMainLoopErrorWhenFlagIsFalse() { + System.setProperty(TEST_PICO_CLI_PLUGIN_TEST_OPTION, FAIL_START); + + PluginConfiguration config = + PluginConfiguration.builder() + .requestedPlugins(List.of(new PluginInfo(TEST_PICO_CLI_PLUGIN))) + .pluginsDir(DEFAULT_PLUGIN_DIRECTORY) + .continueOnPluginError(false) + .build(); + + contextImpl.initialize(config); + contextImpl.registerPlugins(); + contextImpl.beforeExternalServices(); + + String errorMessage = + String.format("Error starting plugin of type %s", TestPicoCLIPlugin.class.getName()); + assertThatExceptionOfType(RuntimeException.class) + .isThrownBy(() -> contextImpl.startPlugins()) + .withMessageContaining(errorMessage); + } + + @Test + void shouldNotHaltOnBeforeMainLoopErrorWhenFlagIsTrue() { + System.setProperty(TEST_PICO_CLI_PLUGIN_TEST_OPTION, FAIL_BEFORE_MAIN_LOOP); + + PluginConfiguration config = + PluginConfiguration.builder() + .requestedPlugins(List.of(new PluginInfo(TEST_PICO_CLI_PLUGIN))) + .pluginsDir(DEFAULT_PLUGIN_DIRECTORY) + .continueOnPluginError(true) + .build(); + + contextImpl.initialize(config); + contextImpl.registerPlugins(); + contextImpl.beforeExternalServices(); + contextImpl.startPlugins(); + + assertThat(contextImpl.getRegisteredPlugins()).isNotInstanceOfAny(TestPicoCLIPlugin.class); + } + + @Test + void shouldHaltOnAfterExternalServicePostMainLoopErrorWhenFlagIsFalse() { + System.setProperty( + TEST_PICO_CLI_PLUGIN_TEST_OPTION, FAIL_AFTER_EXTERNAL_SERVICE_POST_MAIN_LOOP); + + PluginConfiguration config = + PluginConfiguration.builder() + .requestedPlugins(List.of(new PluginInfo(TEST_PICO_CLI_PLUGIN))) + .pluginsDir(DEFAULT_PLUGIN_DIRECTORY) + .continueOnPluginError(false) + .build(); + + contextImpl.initialize(config); + contextImpl.registerPlugins(); + contextImpl.beforeExternalServices(); + contextImpl.startPlugins(); + + String errorMessage = + String.format( + "Error calling `afterExternalServicePostMainLoop` on plugin of type %s", + TestPicoCLIPlugin.class.getName()); + assertThatExceptionOfType(RuntimeException.class) + .isThrownBy(() -> contextImpl.afterExternalServicesMainLoop()) + .withMessageContaining(errorMessage); + } + + @Test + void shouldNotHaltOnAfterExternalServicePostMainLoopErrorWhenFlagIsTrue() { + System.setProperty( + TEST_PICO_CLI_PLUGIN_TEST_OPTION, FAIL_AFTER_EXTERNAL_SERVICE_POST_MAIN_LOOP); + + PluginConfiguration config = + PluginConfiguration.builder() + .requestedPlugins(List.of(new PluginInfo(TEST_PICO_CLI_PLUGIN))) + .pluginsDir(DEFAULT_PLUGIN_DIRECTORY) + .continueOnPluginError(true) + .build(); + + contextImpl.initialize(config); + contextImpl.registerPlugins(); + contextImpl.beforeExternalServices(); + contextImpl.startPlugins(); + contextImpl.afterExternalServicesMainLoop(); + + assertThat(contextImpl.getRegisteredPlugins()).isNotInstanceOfAny(TestPicoCLIPlugin.class); } private PluginConfiguration createConfigurationForSpecificPlugin(final String pluginName) { 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 79879538bd..e93518cad4 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java @@ -118,7 +118,6 @@ import org.hyperledger.besu.ethereum.core.MiningParameters; import org.hyperledger.besu.ethereum.core.MiningParametersMetrics; import org.hyperledger.besu.ethereum.core.PrivacyParameters; import org.hyperledger.besu.ethereum.core.VersionMetadata; -import org.hyperledger.besu.ethereum.core.plugins.PluginConfiguration; import org.hyperledger.besu.ethereum.eth.sync.SyncMode; import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration; import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration; @@ -1080,9 +1079,8 @@ public class BesuCommand implements DefaultCommandValues, Runnable { private IExecutionStrategy createPluginRegistrationTask(final IExecutionStrategy nextStep) { return parseResult -> { - PluginConfiguration configuration = - PluginsConfigurationOptions.fromCommandLine(parseResult.commandSpec().commandLine()); - besuPluginContext.registerPlugins(configuration); + besuPluginContext.initialize(PluginsConfigurationOptions.fromCommandLine(commandLine)); + besuPluginContext.registerPlugins(); commandLine.setExecutionStrategy(nextStep); return commandLine.execute(parseResult.originalArgs().toArray(new String[0])); }; diff --git a/besu/src/main/java/org/hyperledger/besu/cli/DefaultCommandValues.java b/besu/src/main/java/org/hyperledger/besu/cli/DefaultCommandValues.java index ba05f45524..8f83c71a78 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/DefaultCommandValues.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/DefaultCommandValues.java @@ -128,6 +128,9 @@ public interface DefaultCommandValues { /** The constant DEFAULT_PLUGINS_OPTION_NAME. */ String DEFAULT_PLUGINS_OPTION_NAME = "--plugins"; + /** The constant DEFAULT_CONTINUE_ON_PLUGIN_ERROR_OPTION_NAME. */ + String DEFAULT_CONTINUE_ON_PLUGIN_ERROR_OPTION_NAME = "--plugin-continue-on-error"; + /** The constant DEFAULT_PLUGINS_EXTERNAL_ENABLED_OPTION_NAME. */ String DEFAULT_PLUGINS_EXTERNAL_ENABLED_OPTION_NAME = "--Xplugins-external-enabled"; diff --git a/besu/src/main/java/org/hyperledger/besu/cli/options/stable/PluginsConfigurationOptions.java b/besu/src/main/java/org/hyperledger/besu/cli/options/stable/PluginsConfigurationOptions.java index 47df831c57..25893fff89 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/options/stable/PluginsConfigurationOptions.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/options/stable/PluginsConfigurationOptions.java @@ -14,6 +14,7 @@ */ package org.hyperledger.besu.cli.options.stable; +import static org.hyperledger.besu.cli.DefaultCommandValues.DEFAULT_CONTINUE_ON_PLUGIN_ERROR_OPTION_NAME; import static org.hyperledger.besu.cli.DefaultCommandValues.DEFAULT_PLUGINS_EXTERNAL_ENABLED_OPTION_NAME; import static org.hyperledger.besu.cli.DefaultCommandValues.DEFAULT_PLUGINS_OPTION_NAME; @@ -27,7 +28,7 @@ import java.util.List; import picocli.CommandLine; -/** The Plugins Options options. */ +/** The Plugins options. */ public class PluginsConfigurationOptions implements CLIOptions { @CommandLine.Option( @@ -44,9 +45,17 @@ public class PluginsConfigurationOptions implements CLIOptions

The command's functionality is defined in the run() method, which is overridden from the + * Runnable interface. + */ +@Command( + name = COMMAND_NAME, + description = "Execute an Ethereum Blockchain Test.", + mixinStandardHelpOptions = true, + versionProvider = VersionProvider.class) +public class BlockchainTestSubCommand implements Runnable { + /** + * The name of the command for the BlockchainTestSubCommand. This constant is used as the name + * parameter in the @CommandLine.Command annotation. It defines the command name that users should + * enter on the command line to invoke this command. + */ + public static final String COMMAND_NAME = "block-test"; + + static final Supplier referenceTestProtocolSchedules = + Suppliers.memoize(ReferenceTestProtocolSchedules::create); + + @Option( + names = {"--test-name"}, + description = "Limit execution to one named test.") + private String testName = null; + + @ParentCommand private final EvmToolCommand parentCommand; + + // picocli does it magically + @Parameters private final List blockchainTestFiles = new ArrayList<>(); + + /** + * Default constructor for the BlockchainTestSubCommand class. This constructor doesn't take any + * arguments and initializes the parentCommand to null. PicoCLI requires this constructor. + */ + @SuppressWarnings("unused") + public BlockchainTestSubCommand() { + // PicoCLI requires this + this(null); + } + + BlockchainTestSubCommand(final EvmToolCommand parentCommand) { + this.parentCommand = parentCommand; + } + + @Override + public void run() { + // presume ethereum mainnet for reference and state tests + SignatureAlgorithmFactory.setDefaultInstance(); + final ObjectMapper blockchainTestMapper = JsonUtils.createObjectMapper(); + + final JavaType javaType = + blockchainTestMapper + .getTypeFactory() + .constructParametricType( + Map.class, String.class, BlockchainReferenceTestCaseSpec.class); + try { + if (blockchainTestFiles.isEmpty()) { + // if no state tests were specified, use standard input to get filenames + final BufferedReader in = + new BufferedReader(new InputStreamReader(parentCommand.in, UTF_8)); + while (true) { + final String fileName = in.readLine(); + if (fileName == null) { + // Reached end-of-file. Stop the loop. + break; + } + final File file = new File(fileName); + if (file.isFile()) { + final Map blockchainTests = + blockchainTestMapper.readValue(file, javaType); + executeBlockchainTest(blockchainTests); + } else { + parentCommand.out.println("File not found: " + fileName); + } + } + } else { + for (final Path blockchainTestFile : blockchainTestFiles) { + final Map blockchainTests; + if ("stdin".equals(blockchainTestFile.toString())) { + blockchainTests = blockchainTestMapper.readValue(parentCommand.in, javaType); + } else { + blockchainTests = blockchainTestMapper.readValue(blockchainTestFile.toFile(), javaType); + } + executeBlockchainTest(blockchainTests); + } + } + } catch (final JsonProcessingException jpe) { + parentCommand.out.println("File content error: " + jpe); + } catch (final IOException e) { + System.err.println("Unable to read state file"); + e.printStackTrace(System.err); + } + } + + private void executeBlockchainTest( + final Map blockchainTests) { + blockchainTests.forEach(this::traceTestSpecs); + } + + private void traceTestSpecs(final String test, final BlockchainReferenceTestCaseSpec spec) { + if (testName != null && !testName.equals(test)) { + parentCommand.out.println("Skipping test: " + test); + return; + } + parentCommand.out.println("Considering " + test); + + final BlockHeader genesisBlockHeader = spec.getGenesisBlockHeader(); + final MutableWorldState worldState = + spec.getWorldStateArchive() + .getMutable(genesisBlockHeader.getStateRoot(), genesisBlockHeader.getHash()) + .orElseThrow(); + + final ProtocolSchedule schedule = + referenceTestProtocolSchedules.get().getByName(spec.getNetwork()); + + final MutableBlockchain blockchain = spec.getBlockchain(); + final ProtocolContext context = spec.getProtocolContext(); + + for (final BlockchainReferenceTestCaseSpec.CandidateBlock candidateBlock : + spec.getCandidateBlocks()) { + if (!candidateBlock.isExecutable()) { + return; + } + + try { + final Block block = candidateBlock.getBlock(); + + final ProtocolSpec protocolSpec = schedule.getByBlockHeader(block.getHeader()); + final BlockImporter blockImporter = protocolSpec.getBlockImporter(); + + verifyJournaledEVMAccountCompatability(worldState, protocolSpec); + + final HeaderValidationMode validationMode = + "NoProof".equalsIgnoreCase(spec.getSealEngine()) + ? HeaderValidationMode.LIGHT + : HeaderValidationMode.FULL; + final BlockImportResult importResult = + blockImporter.importBlock(context, block, validationMode, validationMode); + + if (importResult.isImported() != candidateBlock.isValid()) { + parentCommand.out.printf( + "Block %d (%s) %s%n", + block.getHeader().getNumber(), + block.getHash(), + importResult.isImported() ? "Failed to be rejected" : "Failed to import"); + } else { + parentCommand.out.printf( + "Block %d (%s) %s%n", + block.getHeader().getNumber(), + block.getHash(), + importResult.isImported() ? "Imported" : "Rejected (correctly)"); + } + } catch (final RLPException e) { + if (candidateBlock.isValid()) { + parentCommand.out.printf( + "Block %d (%s) should have imported but had an RLP exception %s%n", + candidateBlock.getBlock().getHeader().getNumber(), + candidateBlock.getBlock().getHash(), + e.getMessage()); + } + } + } + if (!blockchain.getChainHeadHash().equals(spec.getLastBlockHash())) { + parentCommand.out.printf( + "Chain header mismatch, have %s want %s - %s%n", + blockchain.getChainHeadHash(), spec.getLastBlockHash(), test); + } else { + parentCommand.out.println("Chain import successful - " + test); + } + } + + void verifyJournaledEVMAccountCompatability( + final MutableWorldState worldState, final ProtocolSpec protocolSpec) { + EVM evm = protocolSpec.getEvm(); + if (evm.getEvmConfiguration().worldUpdaterMode() == WorldUpdaterMode.JOURNALED) { + if (worldState + .streamAccounts(Bytes32.ZERO, Integer.MAX_VALUE) + .anyMatch(AccountState::isEmpty)) { + parentCommand.out.println("Journaled account configured and empty account detected"); + } + + if (EvmSpecVersion.SPURIOUS_DRAGON.compareTo(evm.getEvmVersion()) > 0) { + parentCommand.out.println( + "Journaled account configured and fork prior to the merge specified"); + } + } + } +} 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 a3bed6b54b..898f1dd4b6 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 @@ -101,6 +101,7 @@ import picocli.CommandLine.Option; subcommands = { BenchmarkSubCommand.class, B11rSubCommand.class, + BlockchainTestSubCommand.class, CodeValidateSubCommand.class, EOFTestSubCommand.class, PrettyPrintSubCommand.class, @@ -370,15 +371,18 @@ public class EvmToolCommand implements Runnable { public void run() { LogConfigurator.setLevel("", "OFF"); try { + GenesisFileModule genesisFileModule; + if (network != null) { + genesisFileModule = GenesisFileModule.createGenesisModule(network); + } else if (genesisFile != null) { + genesisFileModule = GenesisFileModule.createGenesisModule(genesisFile); + } else { + genesisFileModule = GenesisFileModule.createGenesisModule(NetworkName.DEV); + } final EvmToolComponent component = DaggerEvmToolComponent.builder() .dataStoreModule(new DataStoreModule()) - .genesisFileModule( - network == null - ? genesisFile == null - ? GenesisFileModule.createGenesisModule(NetworkName.DEV) - : GenesisFileModule.createGenesisModule(genesisFile) - : GenesisFileModule.createGenesisModule(network)) + .genesisFileModule(genesisFileModule) .evmToolCommandOptionsModule(daggerOptions) .metricsSystemModule(new MetricsSystemModule()) .build(); diff --git a/ethereum/evmtool/src/test/java/org/hyperledger/besu/evmtool/EvmToolSpecTests.java b/ethereum/evmtool/src/test/java/org/hyperledger/besu/evmtool/EvmToolSpecTests.java index 1892a472b0..66efb574fe 100644 --- a/ethereum/evmtool/src/test/java/org/hyperledger/besu/evmtool/EvmToolSpecTests.java +++ b/ethereum/evmtool/src/test/java/org/hyperledger/besu/evmtool/EvmToolSpecTests.java @@ -53,6 +53,10 @@ public class EvmToolSpecTests { static final ObjectMapper objectMapper = new ObjectMapper(); static final ObjectReader specReader = objectMapper.reader(); + public static Object[][] blocktestTests() { + return findSpecFiles(new String[] {"block-test"}); + } + public static Object[][] b11rTests() { return findSpecFiles(new String[] {"b11r"}); } @@ -114,7 +118,14 @@ public class EvmToolSpecTests { } @ParameterizedTest(name = "{0}") - @MethodSource({"b11rTests", "prettyPrintTests", "stateTestTests", "t8nTests", "traceTests"}) + @MethodSource({ + "blocktestTests", + "b11rTests", + "prettyPrintTests", + "stateTestTests", + "t8nTests", + "traceTests" + }) void testBySpec( final String file, final JsonNode cliNode, 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/prague-eof-rjump.json new file mode 100644 index 0000000000..b9d2e54179 --- /dev/null +++ b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/block-test/prague-eof-rjump.json @@ -0,0 +1,250 @@ +{ + "cli": [ + "block-test", + "stdin" + ], + "stdin": { + "tests/prague/eip7692_eof_v1/eip4200_relative_jumps/test_rjump.py::test_rjump_zero[fork_PragueEIP7692-blockchain_test]": { + "network": "Prague", + "genesisBlockHeader": { + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "uncleHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "coinbase": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x34ccf8774a5b8833da9451a3f7f8a0af0147956c058f0831dab07c348d7ac0d9", + "transactionsTrie": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "receiptTrie": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "difficulty": "0x00", + "number": "0x00", + "gasLimit": "0x016345785d8a0000", + "gasUsed": "0x00", + "timestamp": "0x00", + "extraData": "0x00", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "nonce": "0x0000000000000000", + "baseFeePerGas": "0x07", + "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "blobGasUsed": "0x00", + "excessBlobGas": "0x00", + "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", + "requestsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "hash": "0xc9397e8a1b99cbb2b885852fde56de8fa686091a4f4430163f5237d7aaf33a14" + }, + "pre": { + "0x00000000219ab540356cbb839cbe05303d7705fa": { + "nonce": "0x01", + "balance": "0x00", + "code": "0x60806040526004361061003f5760003560e01c806301ffc9a71461004457806322895118146100a4578063621fd130146101ba578063c5f2892f14610244575b600080fd5b34801561005057600080fd5b506100906004803603602081101561006757600080fd5b50357fffffffff000000000000000000000000000000000000000000000000000000001661026b565b604080519115158252519081900360200190f35b6101b8600480360360808110156100ba57600080fd5b8101906020810181356401000000008111156100d557600080fd5b8201836020820111156100e757600080fd5b8035906020019184600183028401116401000000008311171561010957600080fd5b91939092909160208101903564010000000081111561012757600080fd5b82018360208201111561013957600080fd5b8035906020019184600183028401116401000000008311171561015b57600080fd5b91939092909160208101903564010000000081111561017957600080fd5b82018360208201111561018b57600080fd5b803590602001918460018302840111640100000000831117156101ad57600080fd5b919350915035610304565b005b3480156101c657600080fd5b506101cf6110b5565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102095781810151838201526020016101f1565b50505050905090810190601f1680156102365780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561025057600080fd5b506102596110c7565b60408051918252519081900360200190f35b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a70000000000000000000000000000000000000000000000000000000014806102fe57507fffffffff0000000000000000000000000000000000000000000000000000000082167f8564090700000000000000000000000000000000000000000000000000000000145b92915050565b6030861461035d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118056026913960400191505060405180910390fd5b602084146103b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603681526020018061179c6036913960400191505060405180910390fd5b6060821461040f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260298152602001806118786029913960400191505060405180910390fd5b670de0b6b3a7640000341015610470576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118526026913960400191505060405180910390fd5b633b9aca003406156104cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260338152602001806117d26033913960400191505060405180910390fd5b633b9aca00340467ffffffffffffffff811115610535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602781526020018061182b6027913960400191505060405180910390fd5b6060610540826114ba565b90507f649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c589898989858a8a6105756020546114ba565b6040805160a0808252810189905290819060208201908201606083016080840160c085018e8e80828437600083820152601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690910187810386528c815260200190508c8c808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690920188810386528c5181528c51602091820193918e019250908190849084905b83811015610648578181015183820152602001610630565b50505050905090810190601f1680156106755780820380516001836020036101000a031916815260200191505b5086810383528881526020018989808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169092018881038452895181528951602091820193918b019250908190849084905b838110156106ef5781810151838201526020016106d7565b50505050905090810190601f16801561071c5780820380516001836020036101000a031916815260200191505b509d505050505050505050505050505060405180910390a1600060028a8a600060801b604051602001808484808284377fffffffffffffffffffffffffffffffff0000000000000000000000000000000090941691909301908152604080517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0818403018152601090920190819052815191955093508392506020850191508083835b602083106107fc57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016107bf565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610859573d6000803e3d6000fd5b5050506040513d602081101561086e57600080fd5b5051905060006002806108846040848a8c6116fe565b6040516020018083838082843780830192505050925050506040516020818303038152906040526040518082805190602001908083835b602083106108f857805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016108bb565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610955573d6000803e3d6000fd5b5050506040513d602081101561096a57600080fd5b5051600261097b896040818d6116fe565b60405160009060200180848480828437919091019283525050604080518083038152602092830191829052805190945090925082918401908083835b602083106109f457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016109b7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610a51573d6000803e3d6000fd5b5050506040513d6020811015610a6657600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610ada57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610a9d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610b37573d6000803e3d6000fd5b5050506040513d6020811015610b4c57600080fd5b50516040805160208101858152929350600092600292839287928f928f92018383808284378083019250505093505050506040516020818303038152906040526040518082805190602001908083835b60208310610bd957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610b9c565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610c36573d6000803e3d6000fd5b5050506040513d6020811015610c4b57600080fd5b50516040518651600291889160009188916020918201918291908601908083835b60208310610ca957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610c6c565b6001836020036101000a0380198251168184511680821785525050505050509050018367ffffffffffffffff191667ffffffffffffffff1916815260180182815260200193505050506040516020818303038152906040526040518082805190602001908083835b60208310610d4e57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610d11565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610dab573d6000803e3d6000fd5b5050506040513d6020811015610dc057600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610e3457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610df7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610e91573d6000803e3d6000fd5b5050506040513d6020811015610ea657600080fd5b50519050858114610f02576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260548152602001806117486054913960600191505060405180910390fd5b60205463ffffffff11610f60576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806117276021913960400191505060405180910390fd5b602080546001019081905560005b60208110156110a9578160011660011415610fa0578260008260208110610f9157fe5b0155506110ac95505050505050565b600260008260208110610faf57fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061102557805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610fe8565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015611082573d6000803e3d6000fd5b5050506040513d602081101561109757600080fd5b50519250600282049150600101610f6e565b50fe5b50505050505050565b60606110c26020546114ba565b905090565b6020546000908190815b60208110156112f05781600116600114156111e6576002600082602081106110f557fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061116b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161112e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156111c8573d6000803e3d6000fd5b5050506040513d60208110156111dd57600080fd5b505192506112e2565b600283602183602081106111f657fe5b015460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061126b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161122e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156112c8573d6000803e3d6000fd5b5050506040513d60208110156112dd57600080fd5b505192505b6002820491506001016110d1565b506002826112ff6020546114ba565b600060401b6040516020018084815260200183805190602001908083835b6020831061135a57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161131d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790527fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000095909516920191825250604080518083037ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8018152601890920190819052815191955093508392850191508083835b6020831061143f57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611402565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa15801561149c573d6000803e3d6000fd5b5050506040513d60208110156114b157600080fd5b50519250505090565b60408051600880825281830190925260609160208201818036833701905050905060c082901b8060071a60f81b826000815181106114f457fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060061a60f81b8260018151811061153757fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060051a60f81b8260028151811061157a57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060041a60f81b826003815181106115bd57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060031a60f81b8260048151811061160057fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060021a60f81b8260058151811061164357fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060011a60f81b8260068151811061168657fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060001a60f81b826007815181106116c957fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535050919050565b6000808585111561170d578182fd5b83861115611719578182fd5b505082019391909203915056fe4465706f736974436f6e74726163743a206d65726b6c6520747265652066756c6c4465706f736974436f6e74726163743a207265636f6e7374727563746564204465706f7369744461746120646f6573206e6f74206d6174636820737570706c696564206465706f7369745f646174615f726f6f744465706f736974436f6e74726163743a20696e76616c6964207769746864726177616c5f63726564656e7469616c73206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c7565206e6f74206d756c7469706c65206f6620677765694465706f736974436f6e74726163743a20696e76616c6964207075626b6579206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f20686967684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f206c6f774465706f736974436f6e74726163743a20696e76616c6964207369676e6174757265206c656e677468a2646970667358221220dceca8706b29e917dacf25fceef95acac8d90d765ac926663ce4096195952b6164736f6c634300060b0033", + "storage": { + "0x22": "0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b", + "0x23": "0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71", + "0x24": "0xc78009fdf07fc56a11f122370658a353aaa542ed63e44c4bc15ff4cd105ab33c", + "0x25": "0x536d98837f2dd165a55d5eeae91485954472d56f246df256bf3cae19352a123c", + "0x26": "0x9efde052aa15429fae05bad4d0b1d7c64da64d03d7a1854a588c2cb8430c0d30", + "0x27": "0xd88ddfeed400a8755596b21942c1497e114c302e6118290f91e6772976041fa1", + "0x28": "0x87eb0ddba57e35f6d286673802a4af5975e22506c7cf4c64bb6be5ee11527f2c", + "0x29": "0x26846476fd5fc54a5d43385167c95144f2643f533cc85bb9d16b782f8d7db193", + "0x2a": "0x506d86582d252405b840018792cad2bf1259f1ef5aa5f887e13cb2f0094f51e1", + "0x2b": "0xffff0ad7e659772f9534c195c815efc4014ef1e1daed4404c06385d11192e92b", + "0x2c": "0x6cf04127db05441cd833107a52be852868890e4317e6a02ab47683aa75964220", + "0x2d": "0xb7d05f875f140027ef5118a2247bbb84ce8f2f0f1123623085daf7960c329f5f", + "0x2e": "0xdf6af5f5bbdb6be9ef8aa618e4bf8073960867171e29676f8b284dea6a08a85e", + "0x2f": "0xb58d900f5e182e3c50ef74969ea16c7726c549757cc23523c369587da7293784", + "0x30": "0xd49a7502ffcfb0340b1d7885688500ca308161a7f96b62df9d083b71fcc8f2bb", + "0x31": "0x8fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb", + "0x32": "0x8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab", + "0x33": "0x95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4", + "0x34": "0xf893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17f", + "0x35": "0xcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa", + "0x36": "0x8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9c", + "0x37": "0xfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167", + "0x38": "0xe71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d7", + "0x39": "0x31206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc0", + "0x3a": "0x21352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544", + "0x3b": "0x619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a46765", + "0x3c": "0x7cdd2986268250628d0c10e385c58c6191e6fbe05191bcc04f133f2cea72c1c4", + "0x3d": "0x848930bd7ba8cac54661072113fb278869e07bb8587f91392933374d017bcbe1", + "0x3e": "0x8869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636", + "0x3f": "0xb5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c", + "0x40": "0x985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7" + } + }, + "0x00a3ca265ebcb825b45f985a16cefb49958ce017": { + "nonce": "0x01", + "balance": "0x00", + "code": "0x3373fffffffffffffffffffffffffffffffffffffffe146090573615156028575f545f5260205ff35b366038141561012e5760115f54600182026001905f5b5f82111560595781019083028483029004916001019190603e565b90939004341061012e57600154600101600155600354806003026004013381556001015f3581556001016020359055600101600355005b6003546002548082038060101160a4575060105b5f5b81811460dd5780604c02838201600302600401805490600101805490600101549160601b83528260140152906034015260010160a6565b910180921460ed579060025560f8565b90505f6002555f6003555b5f548061049d141561010757505f5b60015460028282011161011c5750505f610122565b01600290035b5f555f600155604c025ff35b5f5ffd", + "storage": {} + }, + "0x0aae40965e6800cd9b1f4b05ff21581047e3f91e": { + "nonce": "0x01", + "balance": "0x00", + "code": "0x3373fffffffffffffffffffffffffffffffffffffffe1460575767ffffffffffffffff5f3511605357600143035f3511604b575f35612000014311604b57611fff5f3516545f5260205ff35b5f5f5260205ff35b5f5ffd5b5f35611fff60014303165500", + "storage": {} + }, + "0x000f3df6d732807ef1319fb7b8bb8522d0beac02": { + "nonce": "0x01", + "balance": "0x00", + "code": "0x3373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500", + "storage": {} + }, + "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": { + "nonce": "0x00", + "balance": "0x3635c9adc5dea00000", + "code": "0x", + "storage": {} + }, + "0x0000000000000000000000000000000000001000": { + "nonce": "0x01", + "balance": "0x00", + "code": "0xef0001010004020001000a0400000000800002e0000061201560015500", + "storage": {} + } + }, + "postState": { + "0x0000000000000000000000000000000000001000": { + "nonce": "0x01", + "balance": "0x00", + "code": "0xef0001010004020001000a0400000000800002e0000061201560015500", + "storage": { + "0x01": "0x2015" + } + }, + "0x00000000219ab540356cbb839cbe05303d7705fa": { + "nonce": "0x01", + "balance": "0x00", + "code": "0x60806040526004361061003f5760003560e01c806301ffc9a71461004457806322895118146100a4578063621fd130146101ba578063c5f2892f14610244575b600080fd5b34801561005057600080fd5b506100906004803603602081101561006757600080fd5b50357fffffffff000000000000000000000000000000000000000000000000000000001661026b565b604080519115158252519081900360200190f35b6101b8600480360360808110156100ba57600080fd5b8101906020810181356401000000008111156100d557600080fd5b8201836020820111156100e757600080fd5b8035906020019184600183028401116401000000008311171561010957600080fd5b91939092909160208101903564010000000081111561012757600080fd5b82018360208201111561013957600080fd5b8035906020019184600183028401116401000000008311171561015b57600080fd5b91939092909160208101903564010000000081111561017957600080fd5b82018360208201111561018b57600080fd5b803590602001918460018302840111640100000000831117156101ad57600080fd5b919350915035610304565b005b3480156101c657600080fd5b506101cf6110b5565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102095781810151838201526020016101f1565b50505050905090810190601f1680156102365780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561025057600080fd5b506102596110c7565b60408051918252519081900360200190f35b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a70000000000000000000000000000000000000000000000000000000014806102fe57507fffffffff0000000000000000000000000000000000000000000000000000000082167f8564090700000000000000000000000000000000000000000000000000000000145b92915050565b6030861461035d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118056026913960400191505060405180910390fd5b602084146103b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603681526020018061179c6036913960400191505060405180910390fd5b6060821461040f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260298152602001806118786029913960400191505060405180910390fd5b670de0b6b3a7640000341015610470576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118526026913960400191505060405180910390fd5b633b9aca003406156104cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260338152602001806117d26033913960400191505060405180910390fd5b633b9aca00340467ffffffffffffffff811115610535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602781526020018061182b6027913960400191505060405180910390fd5b6060610540826114ba565b90507f649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c589898989858a8a6105756020546114ba565b6040805160a0808252810189905290819060208201908201606083016080840160c085018e8e80828437600083820152601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690910187810386528c815260200190508c8c808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690920188810386528c5181528c51602091820193918e019250908190849084905b83811015610648578181015183820152602001610630565b50505050905090810190601f1680156106755780820380516001836020036101000a031916815260200191505b5086810383528881526020018989808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169092018881038452895181528951602091820193918b019250908190849084905b838110156106ef5781810151838201526020016106d7565b50505050905090810190601f16801561071c5780820380516001836020036101000a031916815260200191505b509d505050505050505050505050505060405180910390a1600060028a8a600060801b604051602001808484808284377fffffffffffffffffffffffffffffffff0000000000000000000000000000000090941691909301908152604080517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0818403018152601090920190819052815191955093508392506020850191508083835b602083106107fc57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016107bf565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610859573d6000803e3d6000fd5b5050506040513d602081101561086e57600080fd5b5051905060006002806108846040848a8c6116fe565b6040516020018083838082843780830192505050925050506040516020818303038152906040526040518082805190602001908083835b602083106108f857805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016108bb565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610955573d6000803e3d6000fd5b5050506040513d602081101561096a57600080fd5b5051600261097b896040818d6116fe565b60405160009060200180848480828437919091019283525050604080518083038152602092830191829052805190945090925082918401908083835b602083106109f457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016109b7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610a51573d6000803e3d6000fd5b5050506040513d6020811015610a6657600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610ada57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610a9d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610b37573d6000803e3d6000fd5b5050506040513d6020811015610b4c57600080fd5b50516040805160208101858152929350600092600292839287928f928f92018383808284378083019250505093505050506040516020818303038152906040526040518082805190602001908083835b60208310610bd957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610b9c565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610c36573d6000803e3d6000fd5b5050506040513d6020811015610c4b57600080fd5b50516040518651600291889160009188916020918201918291908601908083835b60208310610ca957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610c6c565b6001836020036101000a0380198251168184511680821785525050505050509050018367ffffffffffffffff191667ffffffffffffffff1916815260180182815260200193505050506040516020818303038152906040526040518082805190602001908083835b60208310610d4e57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610d11565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610dab573d6000803e3d6000fd5b5050506040513d6020811015610dc057600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610e3457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610df7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610e91573d6000803e3d6000fd5b5050506040513d6020811015610ea657600080fd5b50519050858114610f02576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260548152602001806117486054913960600191505060405180910390fd5b60205463ffffffff11610f60576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806117276021913960400191505060405180910390fd5b602080546001019081905560005b60208110156110a9578160011660011415610fa0578260008260208110610f9157fe5b0155506110ac95505050505050565b600260008260208110610faf57fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061102557805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610fe8565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015611082573d6000803e3d6000fd5b5050506040513d602081101561109757600080fd5b50519250600282049150600101610f6e565b50fe5b50505050505050565b60606110c26020546114ba565b905090565b6020546000908190815b60208110156112f05781600116600114156111e6576002600082602081106110f557fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061116b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161112e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156111c8573d6000803e3d6000fd5b5050506040513d60208110156111dd57600080fd5b505192506112e2565b600283602183602081106111f657fe5b015460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061126b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161122e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156112c8573d6000803e3d6000fd5b5050506040513d60208110156112dd57600080fd5b505192505b6002820491506001016110d1565b506002826112ff6020546114ba565b600060401b6040516020018084815260200183805190602001908083835b6020831061135a57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161131d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790527fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000095909516920191825250604080518083037ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8018152601890920190819052815191955093508392850191508083835b6020831061143f57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611402565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa15801561149c573d6000803e3d6000fd5b5050506040513d60208110156114b157600080fd5b50519250505090565b60408051600880825281830190925260609160208201818036833701905050905060c082901b8060071a60f81b826000815181106114f457fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060061a60f81b8260018151811061153757fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060051a60f81b8260028151811061157a57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060041a60f81b826003815181106115bd57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060031a60f81b8260048151811061160057fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060021a60f81b8260058151811061164357fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060011a60f81b8260068151811061168657fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060001a60f81b826007815181106116c957fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535050919050565b6000808585111561170d578182fd5b83861115611719578182fd5b505082019391909203915056fe4465706f736974436f6e74726163743a206d65726b6c6520747265652066756c6c4465706f736974436f6e74726163743a207265636f6e7374727563746564204465706f7369744461746120646f6573206e6f74206d6174636820737570706c696564206465706f7369745f646174615f726f6f744465706f736974436f6e74726163743a20696e76616c6964207769746864726177616c5f63726564656e7469616c73206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c7565206e6f74206d756c7469706c65206f6620677765694465706f736974436f6e74726163743a20696e76616c6964207075626b6579206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f20686967684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f206c6f774465706f736974436f6e74726163743a20696e76616c6964207369676e6174757265206c656e677468a2646970667358221220dceca8706b29e917dacf25fceef95acac8d90d765ac926663ce4096195952b6164736f6c634300060b0033", + "storage": { + "0x22": "0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b", + "0x23": "0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71", + "0x24": "0xc78009fdf07fc56a11f122370658a353aaa542ed63e44c4bc15ff4cd105ab33c", + "0x25": "0x536d98837f2dd165a55d5eeae91485954472d56f246df256bf3cae19352a123c", + "0x26": "0x9efde052aa15429fae05bad4d0b1d7c64da64d03d7a1854a588c2cb8430c0d30", + "0x27": "0xd88ddfeed400a8755596b21942c1497e114c302e6118290f91e6772976041fa1", + "0x28": "0x87eb0ddba57e35f6d286673802a4af5975e22506c7cf4c64bb6be5ee11527f2c", + "0x29": "0x26846476fd5fc54a5d43385167c95144f2643f533cc85bb9d16b782f8d7db193", + "0x2a": "0x506d86582d252405b840018792cad2bf1259f1ef5aa5f887e13cb2f0094f51e1", + "0x2b": "0xffff0ad7e659772f9534c195c815efc4014ef1e1daed4404c06385d11192e92b", + "0x2c": "0x6cf04127db05441cd833107a52be852868890e4317e6a02ab47683aa75964220", + "0x2d": "0xb7d05f875f140027ef5118a2247bbb84ce8f2f0f1123623085daf7960c329f5f", + "0x2e": "0xdf6af5f5bbdb6be9ef8aa618e4bf8073960867171e29676f8b284dea6a08a85e", + "0x2f": "0xb58d900f5e182e3c50ef74969ea16c7726c549757cc23523c369587da7293784", + "0x30": "0xd49a7502ffcfb0340b1d7885688500ca308161a7f96b62df9d083b71fcc8f2bb", + "0x31": "0x8fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb", + "0x32": "0x8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab", + "0x33": "0x95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4", + "0x34": "0xf893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17f", + "0x35": "0xcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa", + "0x36": "0x8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9c", + "0x37": "0xfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167", + "0x38": "0xe71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d7", + "0x39": "0x31206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc0", + "0x3a": "0x21352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544", + "0x3b": "0x619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a46765", + "0x3c": "0x7cdd2986268250628d0c10e385c58c6191e6fbe05191bcc04f133f2cea72c1c4", + "0x3d": "0x848930bd7ba8cac54661072113fb278869e07bb8587f91392933374d017bcbe1", + "0x3e": "0x8869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636", + "0x3f": "0xb5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c", + "0x40": "0x985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7" + } + }, + "0x000f3df6d732807ef1319fb7b8bb8522d0beac02": { + "nonce": "0x01", + "balance": "0x00", + "code": "0x3373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500", + "storage": { + "0x03e8": "0x03e8" + } + }, + "0x00a3ca265ebcb825b45f985a16cefb49958ce017": { + "nonce": "0x01", + "balance": "0x00", + "code": "0x3373fffffffffffffffffffffffffffffffffffffffe146090573615156028575f545f5260205ff35b366038141561012e5760115f54600182026001905f5b5f82111560595781019083028483029004916001019190603e565b90939004341061012e57600154600101600155600354806003026004013381556001015f3581556001016020359055600101600355005b6003546002548082038060101160a4575060105b5f5b81811460dd5780604c02838201600302600401805490600101805490600101549160601b83528260140152906034015260010160a6565b910180921460ed579060025560f8565b90505f6002555f6003555b5f548061049d141561010757505f5b60015460028282011161011c5750505f610122565b01600290035b5f555f600155604c025ff35b5f5ffd", + "storage": {} + }, + "0x0aae40965e6800cd9b1f4b05ff21581047e3f91e": { + "nonce": "0x01", + "balance": "0x00", + "code": "0x3373fffffffffffffffffffffffffffffffffffffffe1460575767ffffffffffffffff5f3511605357600143035f3511604b575f35612000014311604b57611fff5f3516545f5260205ff35b5f5f5260205ff35b5f5ffd5b5f35611fff60014303165500", + "storage": { + "0x00": "0xc9397e8a1b99cbb2b885852fde56de8fa686091a4f4430163f5237d7aaf33a14" + } + }, + "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba": { + "nonce": "0x00", + "balance": "0x01f92c", + "code": "0x", + "storage": {} + }, + "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": { + "nonce": "0x01", + "balance": "0x3635c9adc5de996c18", + "code": "0x", + "storage": {} + } + }, + "genesisRLP": "0xf90262f9025ba00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a034ccf8774a5b8833da9451a3f7f8a0af0147956c058f0831dab07c348d7ac0d9a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000808088016345785d8a0000808000a0000000000000000000000000000000000000000000000000000000000000000088000000000000000007a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421c0c0c0c0", + "blocks": [ + { + "blockHeader": { + "parentHash": "0xc9397e8a1b99cbb2b885852fde56de8fa686091a4f4430163f5237d7aaf33a14", + "uncleHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "coinbase": "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "stateRoot": "0x1a4885d1f64bac16e5ab17fb13e23fb5d1a0ec2ca4519c81714683f69c8d9a84", + "transactionsTrie": "0xec9d10cff79619f2df45db8c66526ef3fbd32d283fdd2dcc9b55c0efe643d8c3", + "receiptTrie": "0x9593f56abf23bcbb26d27b0c6e46a56415d9103ed6b4d8ac7b4182f9f250cafa", + "bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "difficulty": "0x00", + "number": "0x01", + "gasLimit": "0x016345785d8a0000", + "gasUsed": "0xa864", + "timestamp": "0x03e8", + "extraData": "0x00", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "nonce": "0x0000000000000000", + "baseFeePerGas": "0x07", + "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "blobGasUsed": "0x00", + "excessBlobGas": "0x00", + "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", + "requestsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "hash": "0x879cf54bf493b6585db592b1b24ec30a8a7fbe3b9146d3fb20ca36200f2aca87" + }, + "transactions": [ + { + "type": "0x00", + "chainId": "0x01", + "nonce": "0x00", + "gasPrice": "0x0a", + "gasLimit": "0x989680", + "to": "0x0000000000000000000000000000000000001000", + "value": "0x00", + "data": "0x", + "v": "0x26", + "r": "0xe5d462429669f661291a8dc4c49a092cfd4922b6f3f31c9189a2f4adf5ecd730", + "s": "0x01494afaf472fbb80bcb107ffeb918a2b9115f454027840615d6d20d63c69ac0", + "sender": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b" + } + ], + "uncleHeaders": [], + "withdrawals": [], + "depositRequests": [], + "withdrawalRequests": [], + "rlp": "0xf902c9f9025fa0c9397e8a1b99cbb2b885852fde56de8fa686091a4f4430163f5237d7aaf33a14a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa01a4885d1f64bac16e5ab17fb13e23fb5d1a0ec2ca4519c81714683f69c8d9a84a0ec9d10cff79619f2df45db8c66526ef3fbd32d283fdd2dcc9b55c0efe643d8c3a09593f56abf23bcbb26d27b0c6e46a56415d9103ed6b4d8ac7b4182f9f250cafab9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800188016345785d8a000082a8648203e800a0000000000000000000000000000000000000000000000000000000000000000088000000000000000007a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421f862f860800a83989680940000000000000000000000000000000000001000808026a0e5d462429669f661291a8dc4c49a092cfd4922b6f3f31c9189a2f4adf5ecd730a001494afaf472fbb80bcb107ffeb918a2b9115f454027840615d6d20d63c69ac0c0c0c0", + "blocknumber": "1" + } + ], + "lastblockhash": "0x879cf54bf493b6585db592b1b24ec30a8a7fbe3b9146d3fb20ca36200f2aca87", + "sealEngine": "NoProof", + "_info": { + "hash": "0xbfd1223f9b5b8dbf202178f7c1f18dc089cb24e54c9cb7fc9831907547e937c4", + "comment": "`execution-spec-tests` generated test", + "filling-transition-tool": "Hyperledger Besu evm 24.7-develop-8ca7129", + "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", + "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" +} diff --git a/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/EOFTestCaseSpec.java b/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/EOFTestCaseSpec.java index e67ec2091f..48fae5277d 100644 --- a/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/EOFTestCaseSpec.java +++ b/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/EOFTestCaseSpec.java @@ -25,7 +25,8 @@ public class EOFTestCaseSpec { public record TestVector( @JsonProperty("code") String code, - @JsonProperty("results") NavigableMap results) {} + @JsonProperty("results") NavigableMap results, + @JsonProperty("containerKind") String containerKind) {} public record TestResult( @JsonProperty("exception") String exception, @JsonProperty("result") boolean result) { From d35c6d787521949f4991cb278217c3555adb1be6 Mon Sep 17 00:00:00 2001 From: Stefan Pingel <16143240+pinges@users.noreply.github.com> Date: Fri, 12 Jul 2024 15:29:19 +1000 Subject: [PATCH 030/259] Make the retrying snap tasks switching (#7307) * make snap tasks switching Signed-off-by: stefan.pingel@consensys.net --- .../RetryingGetAccountRangeFromPeerTask.java | 15 +++++++-------- .../snap/RetryingGetBytecodeFromPeerTask.java | 15 ++++++++------- .../RetryingGetStorageRangeFromPeerTask.java | 19 ++++++++++++------- .../snap/RetryingGetTrieNodeFromPeerTask.java | 15 ++++++++------- .../pipeline/AsyncOperationProcessor.java | 6 +++++- 5 files changed, 40 insertions(+), 30 deletions(-) diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/RetryingGetAccountRangeFromPeerTask.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/RetryingGetAccountRangeFromPeerTask.java index 0624a90589..ef48dcf952 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/RetryingGetAccountRangeFromPeerTask.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/RetryingGetAccountRangeFromPeerTask.java @@ -17,18 +17,17 @@ package org.hyperledger.besu.ethereum.eth.manager.snap; import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.eth.manager.EthContext; import org.hyperledger.besu.ethereum.eth.manager.EthPeer; -import org.hyperledger.besu.ethereum.eth.manager.task.AbstractRetryingPeerTask; +import org.hyperledger.besu.ethereum.eth.manager.task.AbstractRetryingSwitchingPeerTask; import org.hyperledger.besu.ethereum.eth.manager.task.EthTask; import org.hyperledger.besu.ethereum.eth.messages.snap.AccountRangeMessage; import org.hyperledger.besu.plugin.services.MetricsSystem; -import java.util.Optional; import java.util.concurrent.CompletableFuture; import org.apache.tuweni.bytes.Bytes32; public class RetryingGetAccountRangeFromPeerTask - extends AbstractRetryingPeerTask { + extends AbstractRetryingSwitchingPeerTask { public static final int MAX_RETRIES = 4; @@ -46,9 +45,9 @@ public class RetryingGetAccountRangeFromPeerTask final MetricsSystem metricsSystem) { super( ethContext, - MAX_RETRIES, + metricsSystem, data -> data.accounts().isEmpty() && data.proofs().isEmpty(), - metricsSystem); + MAX_RETRIES); this.ethContext = ethContext; this.startKeyHash = startKeyHash; this.endKeyHash = endKeyHash; @@ -67,12 +66,12 @@ public class RetryingGetAccountRangeFromPeerTask } @Override - protected CompletableFuture executePeerTask( - final Optional assignedPeer) { + protected CompletableFuture executeTaskOnCurrentPeer( + final EthPeer peer) { final GetAccountRangeFromPeerTask task = GetAccountRangeFromPeerTask.forAccountRange( ethContext, startKeyHash, endKeyHash, blockHeader, metricsSystem); - assignedPeer.ifPresent(task::assignPeer); + task.assignPeer(peer); return executeSubTask(task::run) .thenApply( peerResult -> { diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/RetryingGetBytecodeFromPeerTask.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/RetryingGetBytecodeFromPeerTask.java index 3258298f2c..e30d062597 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/RetryingGetBytecodeFromPeerTask.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/RetryingGetBytecodeFromPeerTask.java @@ -17,19 +17,21 @@ package org.hyperledger.besu.ethereum.eth.manager.snap; import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.eth.manager.EthContext; import org.hyperledger.besu.ethereum.eth.manager.EthPeer; -import org.hyperledger.besu.ethereum.eth.manager.task.AbstractRetryingPeerTask; +import org.hyperledger.besu.ethereum.eth.manager.task.AbstractRetryingSwitchingPeerTask; import org.hyperledger.besu.ethereum.eth.manager.task.EthTask; import org.hyperledger.besu.plugin.services.MetricsSystem; import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.concurrent.CompletableFuture; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; -public class RetryingGetBytecodeFromPeerTask extends AbstractRetryingPeerTask> { +public class RetryingGetBytecodeFromPeerTask + extends AbstractRetryingSwitchingPeerTask> { + + public static final int MAX_RETRIES = 4; private final EthContext ethContext; private final List codeHashes; @@ -41,7 +43,7 @@ public class RetryingGetBytecodeFromPeerTask extends AbstractRetryingPeerTask codeHashes, final BlockHeader blockHeader, final MetricsSystem metricsSystem) { - super(ethContext, 4, Map::isEmpty, metricsSystem); + super(ethContext, metricsSystem, Map::isEmpty, MAX_RETRIES); this.ethContext = ethContext; this.codeHashes = codeHashes; this.blockHeader = blockHeader; @@ -57,11 +59,10 @@ public class RetryingGetBytecodeFromPeerTask extends AbstractRetryingPeerTask> executePeerTask( - final Optional assignedPeer) { + protected CompletableFuture> executeTaskOnCurrentPeer(final EthPeer peer) { final GetBytecodeFromPeerTask task = GetBytecodeFromPeerTask.forBytecode(ethContext, codeHashes, blockHeader, metricsSystem); - assignedPeer.ifPresent(task::assignPeer); + task.assignPeer(peer); return executeSubTask(task::run) .thenApply( peerResult -> { diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/RetryingGetStorageRangeFromPeerTask.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/RetryingGetStorageRangeFromPeerTask.java index 731b0b7623..6e977bb4e7 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/RetryingGetStorageRangeFromPeerTask.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/RetryingGetStorageRangeFromPeerTask.java @@ -17,19 +17,20 @@ package org.hyperledger.besu.ethereum.eth.manager.snap; import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.eth.manager.EthContext; import org.hyperledger.besu.ethereum.eth.manager.EthPeer; -import org.hyperledger.besu.ethereum.eth.manager.task.AbstractRetryingPeerTask; +import org.hyperledger.besu.ethereum.eth.manager.task.AbstractRetryingSwitchingPeerTask; import org.hyperledger.besu.ethereum.eth.manager.task.EthTask; import org.hyperledger.besu.ethereum.eth.messages.snap.StorageRangeMessage; import org.hyperledger.besu.plugin.services.MetricsSystem; import java.util.List; -import java.util.Optional; import java.util.concurrent.CompletableFuture; import org.apache.tuweni.bytes.Bytes32; public class RetryingGetStorageRangeFromPeerTask - extends AbstractRetryingPeerTask { + extends AbstractRetryingSwitchingPeerTask { + + public static final int MAX_RETRIES = 4; private final EthContext ethContext; private final List accountHashes; @@ -45,7 +46,11 @@ public class RetryingGetStorageRangeFromPeerTask final Bytes32 endKeyHash, final BlockHeader blockHeader, final MetricsSystem metricsSystem) { - super(ethContext, 4, data -> data.proofs().isEmpty() && data.slots().isEmpty(), metricsSystem); + super( + ethContext, + metricsSystem, + data -> data.proofs().isEmpty() && data.slots().isEmpty(), + MAX_RETRIES); this.ethContext = ethContext; this.accountHashes = accountHashes; this.startKeyHash = startKeyHash; @@ -66,12 +71,12 @@ public class RetryingGetStorageRangeFromPeerTask } @Override - protected CompletableFuture executePeerTask( - final Optional assignedPeer) { + protected CompletableFuture executeTaskOnCurrentPeer( + final EthPeer peer) { final GetStorageRangeFromPeerTask task = GetStorageRangeFromPeerTask.forStorageRange( ethContext, accountHashes, startKeyHash, endKeyHash, blockHeader, metricsSystem); - assignedPeer.ifPresent(task::assignPeer); + task.assignPeer(peer); return executeSubTask(task::run) .thenApply( peerResult -> { diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/RetryingGetTrieNodeFromPeerTask.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/RetryingGetTrieNodeFromPeerTask.java index 1abf0d7230..152fd91712 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/RetryingGetTrieNodeFromPeerTask.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/RetryingGetTrieNodeFromPeerTask.java @@ -17,18 +17,20 @@ package org.hyperledger.besu.ethereum.eth.manager.snap; import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.eth.manager.EthContext; import org.hyperledger.besu.ethereum.eth.manager.EthPeer; -import org.hyperledger.besu.ethereum.eth.manager.task.AbstractRetryingPeerTask; +import org.hyperledger.besu.ethereum.eth.manager.task.AbstractRetryingSwitchingPeerTask; import org.hyperledger.besu.ethereum.eth.manager.task.EthTask; import org.hyperledger.besu.plugin.services.MetricsSystem; import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.concurrent.CompletableFuture; import org.apache.tuweni.bytes.Bytes; -public class RetryingGetTrieNodeFromPeerTask extends AbstractRetryingPeerTask> { +public class RetryingGetTrieNodeFromPeerTask + extends AbstractRetryingSwitchingPeerTask> { + + public static final int MAX_RETRIES = 4; private final EthContext ethContext; private final Map> paths; @@ -40,7 +42,7 @@ public class RetryingGetTrieNodeFromPeerTask extends AbstractRetryingPeerTask> paths, final BlockHeader blockHeader, final MetricsSystem metricsSystem) { - super(ethContext, 4, Map::isEmpty, metricsSystem); + super(ethContext, metricsSystem, Map::isEmpty, MAX_RETRIES); this.ethContext = ethContext; this.paths = paths; this.blockHeader = blockHeader; @@ -56,11 +58,10 @@ public class RetryingGetTrieNodeFromPeerTask extends AbstractRetryingPeerTask> executePeerTask( - final Optional assignedPeer) { + protected CompletableFuture> executeTaskOnCurrentPeer(final EthPeer peer) { final GetTrieNodeFromPeerTask task = GetTrieNodeFromPeerTask.forTrieNodes(ethContext, paths, blockHeader, metricsSystem); - assignedPeer.ifPresent(task::assignPeer); + task.assignPeer(peer); return executeSubTask(task::run) .thenApply( peerResult -> { diff --git a/services/pipeline/src/main/java/org/hyperledger/besu/services/pipeline/AsyncOperationProcessor.java b/services/pipeline/src/main/java/org/hyperledger/besu/services/pipeline/AsyncOperationProcessor.java index c8c7e5905d..e17296c026 100644 --- a/services/pipeline/src/main/java/org/hyperledger/besu/services/pipeline/AsyncOperationProcessor.java +++ b/services/pipeline/src/main/java/org/hyperledger/besu/services/pipeline/AsyncOperationProcessor.java @@ -83,7 +83,11 @@ class AsyncOperationProcessor implements Processor { waitForAnyFutureToComplete(); outputCompletedTasks(outputPipe); } catch (final InterruptedException e) { - LOG.trace("Interrupted while waiting for processing to complete", e.getMessage()); + LOG.atTrace() + .setMessage("Interrupted while waiting for processing to complete: Message=({})") + .addArgument(e.getMessage()) + .setCause(e) + .log(); } catch (final ExecutionException e) { throw new AsyncOperationException("Async operation failed. " + e.getMessage(), e); } catch (final TimeoutException e) { From 41f007fb804e0ac8fb4fd11f2e2801035cce514c Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Fri, 12 Jul 2024 16:28:56 +1000 Subject: [PATCH 031/259] 6612: Remove deprecated sync modes and related helper methods (#7309) * 6612: Remove deprecated sync modes and related helper methods Signed-off-by: Matilda-Clerke --- .../org/hyperledger/besu/cli/BesuCommand.java | 10 +++---- .../besu/controller/BesuController.java | 4 +-- .../controller/BesuControllerBuilder.java | 6 ++--- .../hyperledger/besu/cli/BesuCommandTest.java | 2 +- .../besu/ethereum/eth/manager/EthPeers.java | 2 +- .../eth/sync/DefaultSynchronizer.java | 6 ++--- .../besu/ethereum/eth/sync/SyncMode.java | 26 ++----------------- 7 files changed, 16 insertions(+), 40 deletions(-) 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 427cac9248..118e586b17 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java @@ -1566,11 +1566,11 @@ public class BesuCommand implements DefaultCommandValues, Runnable { || genesisConfigOptionsSupplier.get().isQbft()) && !unstableSynchronizerOptions.isSnapSyncBftEnabled()) { final String errorSuffix = "can't be used with BFT networks"; - if (SyncMode.CHECKPOINT.equals(syncMode) || SyncMode.X_CHECKPOINT.equals(syncMode)) { + if (SyncMode.CHECKPOINT.equals(syncMode)) { throw new ParameterException( commandLine, String.format("%s %s", "Checkpoint sync", errorSuffix)); } - if (syncMode == SyncMode.SNAP || syncMode == SyncMode.X_SNAP) { + if (syncMode == SyncMode.SNAP) { throw new ParameterException(commandLine, String.format("%s %s", "Snap sync", errorSuffix)); } } @@ -1753,7 +1753,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { CommandLineUtils.failIfOptionDoesntMeetRequirement( commandLine, "--Xcheckpoint-post-merge-enabled can only be used with CHECKPOINT sync-mode", - SyncMode.isCheckpointSync(getDefaultSyncModeIfNotSet()), + getDefaultSyncModeIfNotSet() == SyncMode.CHECKPOINT, singletonList("--Xcheckpoint-post-merge-enabled")); CommandLineUtils.failIfOptionDoesntMeetRequirement( @@ -2043,10 +2043,10 @@ public class BesuCommand implements DefaultCommandValues, Runnable { if (syncMode == SyncMode.FAST) { throw new ParameterException(commandLine, String.format("%s %s", "Fast sync", errorSuffix)); } - if (syncMode == SyncMode.SNAP || syncMode == SyncMode.X_SNAP) { + if (syncMode == SyncMode.SNAP) { throw new ParameterException(commandLine, String.format("%s %s", "Snap sync", errorSuffix)); } - if (syncMode == SyncMode.CHECKPOINT || syncMode == SyncMode.X_CHECKPOINT) { + if (syncMode == SyncMode.CHECKPOINT) { throw new ParameterException( commandLine, String.format("%s %s", "Checkpoint sync", errorSuffix)); } diff --git a/besu/src/main/java/org/hyperledger/besu/controller/BesuController.java b/besu/src/main/java/org/hyperledger/besu/controller/BesuController.java index 6942fda316..fb99318905 100644 --- a/besu/src/main/java/org/hyperledger/besu/controller/BesuController.java +++ b/besu/src/main/java/org/hyperledger/besu/controller/BesuController.java @@ -14,8 +14,6 @@ */ package org.hyperledger.besu.controller; -import static org.hyperledger.besu.ethereum.eth.sync.SyncMode.isCheckpointSync; - import org.hyperledger.besu.cli.config.EthNetworkConfig; import org.hyperledger.besu.config.GenesisConfigFile; import org.hyperledger.besu.config.GenesisConfigOptions; @@ -361,7 +359,7 @@ public class BesuController implements java.io.Closeable { // wrap with TransitionBesuControllerBuilder if we have a terminal total difficulty: if (configOptions.getTerminalTotalDifficulty().isPresent()) { // Enable start with vanilla MergeBesuControllerBuilder for PoS checkpoint block - if (isCheckpointSync(syncMode) && isCheckpointPoSBlock(configOptions)) { + if (syncMode == SyncMode.CHECKPOINT && isCheckpointPoSBlock(configOptions)) { return new MergeBesuControllerBuilder().genesisConfigFile(genesisConfigFile); } else { // TODO this should be changed to vanilla MergeBesuControllerBuilder and the Transition* 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 6123535f63..73bc76608b 100644 --- a/besu/src/main/java/org/hyperledger/besu/controller/BesuControllerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/controller/BesuControllerBuilder.java @@ -708,8 +708,8 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides ethPeers.setTrailingPeerRequirementsSupplier(synchronizer::calculateTrailingPeerRequirements); - if (SyncMode.isSnapSync(syncConfig.getSyncMode()) - || SyncMode.isCheckpointSync(syncConfig.getSyncMode())) { + if (syncConfig.getSyncMode() == SyncMode.SNAP + || syncConfig.getSyncMode() == SyncMode.CHECKPOINT) { synchronizer.subscribeInSync((b) -> ethPeers.snapServerPeersNeeded(!b)); ethPeers.snapServerPeersNeeded(true); } else { @@ -1157,7 +1157,7 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides final CheckpointConfigOptions checkpointConfigOptions = genesisConfigOptions.getCheckpointOptions(); - if (SyncMode.isCheckpointSync(syncConfig.getSyncMode()) && checkpointConfigOptions.isValid()) { + if (syncConfig.getSyncMode() == SyncMode.CHECKPOINT && checkpointConfigOptions.isValid()) { validators.add( new CheckpointBlocksPeerValidator( protocolSchedule, 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 c6ffbdc175..efeff412d6 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java @@ -1107,7 +1107,7 @@ public class BesuCommandTest extends CommandTestAbstract { assertThat(commandOutput.toString(UTF_8)).isEmpty(); assertThat(commandErrorOutput.toString(UTF_8)) .contains( - "Invalid value for option '--sync-mode': expected one of [FULL, FAST, SNAP, CHECKPOINT, X_SNAP, X_CHECKPOINT] (case-insensitive) but was 'bogus'"); + "Invalid value for option '--sync-mode': expected one of [FULL, FAST, SNAP, CHECKPOINT] (case-insensitive) but was 'bogus'"); } @Test 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 851c075290..d1a54d4d3d 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 @@ -525,7 +525,7 @@ public class EthPeers { peer.chainState().updateHeightEstimate(peerHeadBlockHeader.getNumber()); CompletableFuture isServingSnapFuture; - if (SyncMode.isCheckpointSync(syncMode) || SyncMode.isSnapSync(syncMode)) { + if (syncMode == SyncMode.SNAP || syncMode == SyncMode.CHECKPOINT) { // even if we have finished the snap sync, we still want to know if the peer is a snap // server isServingSnapFuture = 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 7605754a65..a41ad1812b 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 @@ -99,8 +99,8 @@ public class DefaultSynchronizer implements Synchronizer, UnverifiedForkchoiceLi this::calculateTrailingPeerRequirements, metricsSystem); - if (SyncMode.isSnapSync(syncConfig.getSyncMode()) - || SyncMode.isCheckpointSync(syncConfig.getSyncMode())) { + if (syncConfig.getSyncMode() == SyncMode.SNAP + || syncConfig.getSyncMode() == SyncMode.CHECKPOINT) { SnapServerChecker.createAndSetSnapServerChecker(ethContext, metricsSystem); } @@ -145,7 +145,7 @@ public class DefaultSynchronizer implements Synchronizer, UnverifiedForkchoiceLi worldStateStorageCoordinator, syncState, clock); - } else if (SyncMode.isCheckpointSync(syncConfig.getSyncMode())) { + } else if (syncConfig.getSyncMode() == SyncMode.CHECKPOINT) { this.fastSyncFactory = () -> CheckpointDownloaderFactory.createCheckpointDownloader( diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/SyncMode.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/SyncMode.java index 4f3affbe55..c69a128c54 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/SyncMode.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/SyncMode.java @@ -27,35 +27,13 @@ public enum SyncMode { // Perform snapsync SNAP, // Perform snapsync but starting from a checkpoint instead of starting from genesis - CHECKPOINT, - // Deprecated and will be removed in 24.4.0 (X_SNAP and X_CHECKPOINT) - X_SNAP, - X_CHECKPOINT; + CHECKPOINT; public String normalize() { - if (this.toString().startsWith("X_")) { - // removes X_ at the beginning - return StringUtils.capitalize(this.toString().substring(2).toLowerCase(Locale.ROOT)); - } - return StringUtils.capitalize(this.toString().toLowerCase(Locale.ROOT)); } public static boolean isFullSync(final SyncMode syncMode) { - return !EnumSet.of( - SyncMode.FAST, - SyncMode.SNAP, - SyncMode.X_SNAP, - SyncMode.CHECKPOINT, - SyncMode.X_CHECKPOINT) - .contains(syncMode); - } - - public static boolean isCheckpointSync(final SyncMode syncMode) { - return X_CHECKPOINT.equals(syncMode) || CHECKPOINT.equals(syncMode); - } - - public static boolean isSnapSync(final SyncMode syncMode) { - return X_SNAP.equals(syncMode) || SNAP.equals(syncMode); + return !EnumSet.of(SyncMode.FAST, SyncMode.SNAP, SyncMode.CHECKPOINT).contains(syncMode); } } From 965e757d81072f31d2a44bb5757ff46f7d102e36 Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Fri, 12 Jul 2024 08:43:44 -0600 Subject: [PATCH 032/259] EOF Reference Test Fixes (#7306) Fix a number of issues found in reference tests and evmone tests. - Be tolerant of more nulls in json - Support ContainerKind in reference tests - re-order EXTCALL oeprands - correct return value for REVERT in EXT*CALL - re-order EOFCREATE code validation Signed-off-by: Danno Ferrin --- .../GeneralStateTestCaseSpec.java | 6 +- .../ReferenceTestProtocolSchedules.java | 5 ++ .../ethereum/eof/EOFReferenceTestTools.java | 72 +++++++++++++------ .../templates/EOFReferenceTest.java.template | 3 +- .../besu/evm/code/CodeFactory.java | 4 ++ .../org/hyperledger/besu/evm/code/CodeV1.java | 2 +- .../hyperledger/besu/evm/code/EOFLayout.java | 12 +++- .../operation/AbstractCreateOperation.java | 28 ++++---- .../operation/AbstractExtCallOperation.java | 6 ++ .../besu/evm/operation/ExtCallOperation.java | 4 +- .../operation/ExtDelegateCallOperation.java | 3 - .../evm/operation/ExtStaticCallOperation.java | 3 - .../evm/operations/ExtCallOperationTest.java | 2 +- .../besu/testutil/JsonTestParameters.java | 8 ++- 14 files changed, 107 insertions(+), 51 deletions(-) diff --git a/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/GeneralStateTestCaseSpec.java b/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/GeneralStateTestCaseSpec.java index 73735fdb0e..affc6e4601 100644 --- a/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/GeneralStateTestCaseSpec.java +++ b/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/GeneralStateTestCaseSpec.java @@ -56,10 +56,12 @@ public class GeneralStateTestCaseSpec { final ReferenceTestWorldState initialWorldState, final Map> postSections, final StateTestVersionedTransaction versionedTransaction) { - + if (initialWorldState == null) { + return Map.of(); + } initialWorldState.persist(null); final Map> res = - new LinkedHashMap<>(postSections.size()); + LinkedHashMap.newLinkedHashMap(postSections.size()); for (final Map.Entry> entry : postSections.entrySet()) { final String eip = entry.getKey(); final List post = entry.getValue(); 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 4d62c314ae..8ac419f7a6 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 @@ -91,6 +91,11 @@ public class ReferenceTestProtocolSchedules { "CancunToPragueAtTime15k", createSchedule(genesisStub.clone().cancunTime(0).pragueTime(15000))); builder.put("Prague", createSchedule(genesisStub.clone().pragueEOFTime(0))); + builder.put("Osaka", createSchedule(genesisStub.clone().futureEipsTime(0))); + builder.put("Amsterdam", createSchedule(genesisStub.clone().futureEipsTime(0))); + builder.put("Bogota", createSchedule(genesisStub.clone().futureEipsTime(0))); + builder.put("Polis", createSchedule(genesisStub.clone().futureEipsTime(0))); + builder.put("Bangkok", createSchedule(genesisStub.clone().futureEipsTime(0))); builder.put("Future_EIPs", createSchedule(genesisStub.clone().futureEipsTime(0))); builder.put("Experimental_EIPs", createSchedule(genesisStub.clone().experimentalEipsTime(0))); return new ReferenceTestProtocolSchedules(builder.build()); 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 58f8c02529..a15bcb2418 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 @@ -21,13 +21,19 @@ import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.Map; +import java.util.Map.Entry; + import org.apache.tuweni.bytes.Bytes; + import org.hyperledger.besu.ethereum.referencetests.EOFTestCaseSpec; +import org.hyperledger.besu.ethereum.referencetests.EOFTestCaseSpec.TestResult; import org.hyperledger.besu.ethereum.referencetests.ReferenceTestProtocolSchedules; 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.evm.code.EOFLayout.EOFContainerMode; import org.hyperledger.besu.testutil.JsonTestParameters; public class EOFReferenceTestTools { @@ -43,13 +49,18 @@ public class EOFReferenceTestTools { JsonTestParameters.create(EOFTestCaseSpec.class, EOFTestCaseSpec.TestResult.class) .generator( (testName, fullPath, eofSpec, collector) -> { + if (eofSpec.getVector() == null) { + return; + } final Path path = Path.of(fullPath).getParent().getFileName(); final String prefix = path + "/" + testName + "-"; for (final Map.Entry entry : eofSpec.getVector().entrySet()) { final String name = entry.getKey(); final Bytes code = Bytes.fromHexString(entry.getValue().code()); - for (final var result : entry.getValue().results().entrySet()) { + final String containerKind = entry.getValue().containerKind(); + for (final Entry result : + entry.getValue().results().entrySet()) { final String eip = result.getKey(); final boolean runTest = EIPS_TO_RUN.contains(eip); collector.add( @@ -57,6 +68,7 @@ public class EOFReferenceTestTools { fullPath, eip, code, + containerKind, result.getValue(), runTest); } @@ -72,7 +84,7 @@ public class EOFReferenceTestTools { params.ignore("EOF1_undefined_opcodes_186"); // embedded containers rules changed - params.ignore("efValidation/EOF1_embedded_container-Prague\\[EOF1_embedded_container_\\d+\\]"); + params.ignore("efValidation/EOF1_embedded_container-Prague\\[EOF1_embedded_container_\\d+\\]"); // truncated data is only allowed in embedded containers params.ignore("ori/validInvalid-Prague\\[validInvalid_48\\]"); @@ -101,7 +113,10 @@ public class EOFReferenceTestTools { @SuppressWarnings("java:S5960") // This is not production code, this is testing code. public static void executeTest( - final String fork, final Bytes code, final EOFTestCaseSpec.TestResult expected) { + final String fork, + final Bytes code, + final String containerKind, + final EOFTestCaseSpec.TestResult expected) { EVM evm = ReferenceTestProtocolSchedules.create().geSpecByName(fork).getEvm(); assertThat(evm).isNotNull(); @@ -112,23 +127,40 @@ public class EOFReferenceTestTools { EOFLayout layout = EOFLayout.parseEOF(code); if (layout.isValid()) { - Code parsedCode = evm.getCodeUncached(code); - assertThat(parsedCode.isValid()) - .withFailMessage( - () -> - EOFLayout.parseEOF(code).prettyPrint() - + "\nExpected exception :" - + expected.exception() - + " actual exception :" - + (parsedCode.isValid() - ? null - : ((CodeInvalid) parsedCode).getInvalidReason())) - .isEqualTo(expected.result()); - - if (expected.result()) { - assertThat(code) - .withFailMessage("Container round trip failed") - .isEqualTo(layout.writeContainer(null)); + Code parsedCode; + if ("INITCODE".equals(containerKind)) { + parsedCode = evm.getCodeForCreation(code); + } else { + parsedCode = evm.getCodeUncached(code); + } + if ("EOF_IncompatibleContainerKind".equals(expected.exception()) && parsedCode.isValid()) { + EOFContainerMode expectedMode = + EOFContainerMode.valueOf(containerKind == null ? "RUNTIME" : containerKind); + EOFContainerMode containerMode = + ((CodeV1) parsedCode).getEofLayout().containerMode().get(); + EOFContainerMode actualMode = + containerMode == null ? EOFContainerMode.RUNTIME : containerMode; + assertThat(actualMode) + .withFailMessage("Code did not parse to valid containerKind of " + expectedMode) + .isNotEqualTo(expectedMode); + } else { + assertThat(parsedCode.isValid()) + .withFailMessage( + () -> + EOFLayout.parseEOF(code).prettyPrint() + + "\nExpected exception :" + + expected.exception() + + " actual exception :" + + (parsedCode.isValid() + ? null + : ((CodeInvalid) parsedCode).getInvalidReason())) + .isEqualTo(expected.result()); + + if (expected.result()) { + assertThat(code) + .withFailMessage("Container round trip failed") + .isEqualTo(layout.writeContainer(null)); + } } } else { assertThat(layout.isValid()) diff --git a/ethereum/referencetests/src/reference-test/templates/EOFReferenceTest.java.template b/ethereum/referencetests/src/reference-test/templates/EOFReferenceTest.java.template index 5f5cafd676..d9e52403d7 100644 --- a/ethereum/referencetests/src/reference-test/templates/EOFReferenceTest.java.template +++ b/ethereum/referencetests/src/reference-test/templates/EOFReferenceTest.java.template @@ -34,9 +34,10 @@ public class %%TESTS_NAME%% { final String name, final String fork, final Bytes code, + final String containerKind, final EOFTestCaseSpec.TestResult results, final boolean runTest) { assumeTrue(runTest, "Test " + name + " was ignored"); - executeTest(fork, code, results); + executeTest(fork, code, containerKind, results); } } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/code/CodeFactory.java b/evm/src/main/java/org/hyperledger/besu/evm/code/CodeFactory.java index a0bba70371..1856100120 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/code/CodeFactory.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/code/CodeFactory.java @@ -15,6 +15,7 @@ package org.hyperledger.besu.evm.code; import org.hyperledger.besu.evm.Code; +import org.hyperledger.besu.evm.code.EOFLayout.EOFContainerMode; import javax.annotation.Nonnull; @@ -94,6 +95,9 @@ public class CodeFactory { } final EOFLayout layout = EOFLayout.parseEOF(bytes, !createTransaction); + if (createTransaction) { + layout.containerMode().set(EOFContainerMode.INITCODE); + } return createCode(layout); } else { return new CodeV0(bytes); diff --git a/evm/src/main/java/org/hyperledger/besu/evm/code/CodeV1.java b/evm/src/main/java/org/hyperledger/besu/evm/code/CodeV1.java index 50ffdd4106..a1517d1d7f 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/code/CodeV1.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/code/CodeV1.java @@ -111,7 +111,7 @@ public class CodeV1 implements Code { codeToLoad = subcontainerLayout.container(); } - Code subContainerCode = evm.getCodeForCreation(codeToLoad); + Code subContainerCode = evm.getCodeUncached(codeToLoad); return subContainerCode.isValid() && subContainerCode.getEofVersion() > 0 ? Optional.of(subContainerCode) diff --git a/evm/src/main/java/org/hyperledger/besu/evm/code/EOFLayout.java b/evm/src/main/java/org/hyperledger/besu/evm/code/EOFLayout.java index 8b41a97923..401308715a 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/code/EOFLayout.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/code/EOFLayout.java @@ -57,9 +57,16 @@ public record EOFLayout( String invalidReason, AtomicReference containerMode) { - enum EOFContainerMode { + /** + * Enum tracking the useage mode of an EOF container. Detected either by opcode usage or + * determined by the source. + */ + public enum EOFContainerMode { + /** Usage mode is unknown */ UNKNOWN, + /** Usage mode is as init code */ INITCODE, + /** Usage mode is as deployed or runtime code */ RUNTIME } @@ -324,6 +331,9 @@ public record EOFLayout( Bytes subcontainer = container.slice(pos, subcontianerSize); pos += subcontianerSize; EOFLayout subLayout = EOFLayout.parseEOF(subcontainer, false); + if (subLayout.container.size() < subcontainer.size()) { + return invalidLayout(container, version, "excess data in subcontainer"); + } if (!subLayout.isValid()) { String invalidSubReason = subLayout.invalidReason; return invalidLayout( diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCreateOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCreateOperation.java index f026fd7110..f20c2914a0 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCreateOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCreateOperation.java @@ -214,32 +214,32 @@ public abstract class AbstractCreateOperation extends AbstractOperation { private void complete(final MessageFrame frame, final MessageFrame childFrame, final EVM evm) { frame.setState(MessageFrame.State.CODE_EXECUTING); - Code outputCode = - (childFrame.getCreatedCode() != null) - ? childFrame.getCreatedCode() - : evm.getCodeForCreation(childFrame.getOutputData()); + frame.incrementRemainingGas(childFrame.getRemainingGas()); + frame.addLogs(childFrame.getLogs()); + frame.addSelfDestructs(childFrame.getSelfDestructs()); + frame.addCreates(childFrame.getCreates()); frame.popStackItems(getStackItemsConsumed()); - if (outputCode.isValid()) { - frame.incrementRemainingGas(childFrame.getRemainingGas()); - frame.addLogs(childFrame.getLogs()); - frame.addSelfDestructs(childFrame.getSelfDestructs()); - frame.addCreates(childFrame.getCreates()); - - if (childFrame.getState() == MessageFrame.State.COMPLETED_SUCCESS) { + if (childFrame.getState() == MessageFrame.State.COMPLETED_SUCCESS) { + Code outputCode = + (childFrame.getCreatedCode() != null) + ? childFrame.getCreatedCode() + : evm.getCodeForCreation(childFrame.getOutputData()); + if (outputCode.isValid()) { Address createdAddress = childFrame.getContractAddress(); frame.pushStackItem(Words.fromAddress(createdAddress)); + frame.setReturnData(Bytes.EMPTY); onSuccess(frame, createdAddress); } else { + frame.getWorldUpdater().deleteAccount(childFrame.getRecipientAddress()); frame.setReturnData(childFrame.getOutputData()); frame.pushStackItem(LEGACY_FAILURE_STACK_ITEM); - onFailure(frame, childFrame.getExceptionalHaltReason()); + onInvalid(frame, (CodeInvalid) outputCode); } } else { - frame.getWorldUpdater().deleteAccount(childFrame.getRecipientAddress()); frame.setReturnData(childFrame.getOutputData()); frame.pushStackItem(LEGACY_FAILURE_STACK_ITEM); - onInvalid(frame, (CodeInvalid) outputCode); + onFailure(frame, childFrame.getExceptionalHaltReason()); } final int currentPC = frame.getPC(); 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 2c0535b197..43d7e343ff 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 @@ -38,6 +38,8 @@ import org.apache.tuweni.bytes.Bytes; public abstract class AbstractExtCallOperation extends AbstractCallOperation { static final int STACK_TO = 0; + static final int STACK_INPUT_OFFSET = 1; + static final int STACK_INPUT_LENGTH = 2; /** EXT*CALL response indicating success */ public static final Bytes EOF1_SUCCESS_STACK_ITEM = Bytes.EMPTY; @@ -195,6 +197,10 @@ public abstract class AbstractExtCallOperation extends AbstractCallOperation { return switch (childFrame.getState()) { case COMPLETED_SUCCESS -> EOF1_SUCCESS_STACK_ITEM; case EXCEPTIONAL_HALT -> EOF1_EXCEPTION_STACK_ITEM; + case COMPLETED_FAILED -> + childFrame.getExceptionalHaltReason().isPresent() + ? EOF1_FAILURE_STACK_ITEM + : EOF1_EXCEPTION_STACK_ITEM; default -> EOF1_FAILURE_STACK_ITEM; }; } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtCallOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtCallOperation.java index bf986a572e..5914f0e966 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtCallOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtCallOperation.java @@ -24,9 +24,7 @@ import org.hyperledger.besu.evm.gascalculator.GasCalculator; /** The Call operation. */ public class ExtCallOperation extends AbstractExtCallOperation { - static final int STACK_VALUE = 1; - static final int STACK_INPUT_OFFSET = 2; - static final int STACK_INPUT_LENGTH = 3; + static final int STACK_VALUE = 3; /** * Instantiates a new Call operation. diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtDelegateCallOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtDelegateCallOperation.java index bddb337c73..db851ee5a0 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtDelegateCallOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtDelegateCallOperation.java @@ -24,9 +24,6 @@ import org.hyperledger.besu.evm.gascalculator.GasCalculator; /** The Delegate call operation. */ public class ExtDelegateCallOperation extends AbstractExtCallOperation { - static final int STACK_INPUT_OFFSET = 1; - static final int STACK_INPUT_LENGTH = 2; - /** * Instantiates a new Delegate call operation. * diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtStaticCallOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtStaticCallOperation.java index 3a202f46e7..ef3dc042d9 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtStaticCallOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/ExtStaticCallOperation.java @@ -24,9 +24,6 @@ import org.hyperledger.besu.evm.gascalculator.GasCalculator; /** The Static call operation. */ public class ExtStaticCallOperation extends AbstractExtCallOperation { - static final int STACK_INPUT_OFFSET = 1; - static final int STACK_INPUT_LENGTH = 2; - /** * Instantiates a new Static call operation. * diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operations/ExtCallOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operations/ExtCallOperationTest.java index 984ce28027..946dd0b52e 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operations/ExtCallOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operations/ExtCallOperationTest.java @@ -211,9 +211,9 @@ public class ExtCallOperationTest { new TestMessageFrameBuilder() .initialGas(parentGas) .pushStackItem(CONTRACT_ADDRESS) // canary for non-returning + .pushStackItem(valueSent) .pushStackItem(Bytes.EMPTY) .pushStackItem(Bytes.EMPTY) - .pushStackItem(valueSent) .pushStackItem(CONTRACT_ADDRESS) .worldUpdater(worldUpdater) .isStatic(isStatic) 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 062e14cfc7..f95ac9348e 100644 --- a/testutil/src/main/java/org/hyperledger/besu/testutil/JsonTestParameters.java +++ b/testutil/src/main/java/org/hyperledger/besu/testutil/JsonTestParameters.java @@ -96,6 +96,7 @@ public class JsonTestParameters { * @param fullPath the full path of the test * @param fork the fork to be tested * @param code the code to be tested + * @param containerKind the containerKind, if specified * @param value the value * @param runTest the run test */ @@ -104,10 +105,13 @@ public class JsonTestParameters { final String fullPath, final String fork, final Bytes code, + final String containerKind, final S value, final boolean runTest) { testParameters.add( - new Object[] {name, fork, code, value, runTest && includes(name) && includes(fullPath)}); + new Object[] { + name, fork, code, containerKind, value, runTest && includes(name) && includes(fullPath) + }); } private boolean includes(final String name) { @@ -304,7 +308,7 @@ public class JsonTestParameters { final List files = new ArrayList<>(); for (final String path : paths) { final URL url = classLoader.getResource(path); - checkState(url != null, "Cannot find test directory " + path); + checkState(url != null, "Cannot find test directory %s", path); final Path dir; try { dir = Paths.get(url.toURI()); From dfee65665dcd021b81aa02a3557692df2949d99a Mon Sep 17 00:00:00 2001 From: garyschulte Date: Fri, 12 Jul 2024 10:53:16 -0700 Subject: [PATCH 033/259] test template refactor, bump besu-native to 0.9.2 (#7315) Signed-off-by: garyschulte --- ethereum/evmtool/build.gradle | 2 +- ethereum/referencetests/build.gradle | 32 ++- .../BlockchainReferenceTest.java.template | 2 +- .../ExecutionSpecStateTest.java.template | 37 --- .../templates/ExecutionSpecTest.java.template | 36 --- .../GeneralStateReferenceTest.java.template | 2 +- evm/build.gradle | 1 + gradle/verification-metadata.xml | 248 +++++++----------- gradle/versions.gradle | 3 +- 9 files changed, 122 insertions(+), 241 deletions(-) delete mode 100644 ethereum/referencetests/src/reference-test/templates/ExecutionSpecStateTest.java.template delete mode 100644 ethereum/referencetests/src/reference-test/templates/ExecutionSpecTest.java.template diff --git a/ethereum/evmtool/build.gradle b/ethereum/evmtool/build.gradle index aaddc354d5..5712e7174a 100644 --- a/ethereum/evmtool/build.gradle +++ b/ethereum/evmtool/build.gradle @@ -15,7 +15,7 @@ */ plugins { - id 'org.graalvm.buildtools.native' version '0.9.17' + id 'org.graalvm.buildtools.native' version '0.10.2' } apply plugin: 'java-library' diff --git a/ethereum/referencetests/build.gradle b/ethereum/referencetests/build.gradle index c023dcd699..11db6b8eee 100644 --- a/ethereum/referencetests/build.gradle +++ b/ethereum/referencetests/build.gradle @@ -34,6 +34,7 @@ def blockchainReferenceTests = tasks.register("blockchainReferenceTests") { "BlockchainTests", "$generatedTestsPath/org/hyperledger/besu/ethereum/vm/blockchain", "BlockchainReferenceTest", + "org.hyperledger.besu.ethereum.vm.blockchain", ("BlockchainTests/InvalidBlocks/bcExpectSection") // exclude test for test filling tool ) } @@ -50,6 +51,7 @@ def eipBlockchainReferenceTests = tasks.register("eipBlockchainReferenceTests") "EIPTests${File.separatorChar}BlockchainTests", "$generatedTestsPath/org/hyperledger/besu/ethereum/vm/eip", "EIPBlockchainReferenceTest", + "org.hyperledger.besu.ethereum.vm.eip", ) } @@ -65,6 +67,7 @@ def eipStateReferenceTests = tasks.register("eipStateReferenceTests") { "EIPTests${File.separatorChar}StateTests", "$generatedTestsPath/org/hyperledger/besu/ethereum/vm/eip", "EIPStateReferenceTest", + "org.hyperledger.besu.ethereum.vm.eip", ) } @@ -83,19 +86,21 @@ def executionSpecTests = tasks.register("executionSpecTests") { // generate blockchain_tests: generateTestFiles( fileTree(referenceTestsPath + "/fixtures/blockchain_tests"), - file("src/reference-test/templates/ExecutionSpecTest.java.template"), + file("src/reference-test/templates/BlockchainReferenceTest.java.template"), "fixtures", "$generatedTestsPath/org/hyperledger/besu/ethereum/vm/executionspec", - "ExecutionSpecBlockchainTest" + "ExecutionSpecBlockchainTest", + "org.hyperledger.besu.ethereum.vm.executionspec", ) // generate state_tests: generateTestFiles( fileTree(referenceTestsPath + "/fixtures/state_tests"), - file("src/reference-test/templates/ExecutionSpecStateTest.java.template"), + file("src/reference-test/templates/GeneralStateReferenceTest.java.template"), "fixtures", "$generatedTestsPath/org/hyperledger/besu/ethereum/vm/executionspec", - "ExecutionSpecStateTest" + "ExecutionSpecStateTest", + "org.hyperledger.besu.ethereum.vm.executionspec", ) } @@ -110,7 +115,8 @@ def generalstateReferenceTests = tasks.register("generalstateReferenceTests") { file("src/reference-test/templates/GeneralStateReferenceTest.java.template"), "GeneralStateTests", "$generatedTestsPath/org/hyperledger/besu/ethereum/vm/generalstate", - "GeneralStateReferenceTest" + "GeneralStateReferenceTest", + "org.hyperledger.besu.ethereum.vm.generalstate", ) } @@ -125,7 +131,8 @@ def generalstateRegressionReferenceTests = tasks.register("generalstateRegressio file("src/reference-test/templates/GeneralStateReferenceTest.java.template"), "regressions", "$generatedTestsPath/org/hyperledger/besu/ethereum/vm/generalstate", - "GeneralStateRegressionReferenceTest" + "GeneralStateRegressionReferenceTest", + "org.hyperledger.besu.ethereum.vm.generalstate" ) } @@ -140,7 +147,8 @@ def eofReferenceTests = tasks.register("eofReferenceTests") { file("src/reference-test/templates/EOFReferenceTest.java.template"), "EOFTests", "$generatedTestsPath/org/hyperledger/besu/ethereum/vm/eof", - "EOFReferenceTest" + "EOFReferenceTest", + "org.hyperledger.besu.ethereum.vm.eof" ) } @@ -259,7 +267,14 @@ following commands: } processResources.dependsOn('validateReferenceTestSubmodule') -def generateTestFiles(FileTree jsonPath, File templateFile, String pathstrip, String destination, String namePrefix, String ... excludedPath) { +def generateTestFiles( + FileTree jsonPath, + File templateFile, + String pathstrip, + String destination, + String namePrefix, + String packageString, + String ... excludedPath) { mkdir(destination) def referenceTestTemplate = templateFile.text @@ -281,6 +296,7 @@ def generateTestFiles(FileTree jsonPath, File templateFile, String pathstrip, St def testFileContents = referenceTestTemplate .replaceAll("%%TESTS_FILE%%", allPaths) .replaceAll("%%TESTS_NAME%%", namePrefix + "_" + idx) + .replaceAll("%%PACKAGE_NAME%%", packageString) testFile.newWriter().withWriter { w -> w << testFileContents } } } diff --git a/ethereum/referencetests/src/reference-test/templates/BlockchainReferenceTest.java.template b/ethereum/referencetests/src/reference-test/templates/BlockchainReferenceTest.java.template index 387fb0cc18..e7789905b3 100644 --- a/ethereum/referencetests/src/reference-test/templates/BlockchainReferenceTest.java.template +++ b/ethereum/referencetests/src/reference-test/templates/BlockchainReferenceTest.java.template @@ -1,4 +1,4 @@ -package org.hyperledger.besu.ethereum.vm.blockchain; +package %%PACKAGE_NAME%%; import static org.hyperledger.besu.ethereum.vm.BlockchainReferenceTestTools.executeTest; import static org.hyperledger.besu.ethereum.vm.BlockchainReferenceTestTools.generateTestParametersForConfig; diff --git a/ethereum/referencetests/src/reference-test/templates/ExecutionSpecStateTest.java.template b/ethereum/referencetests/src/reference-test/templates/ExecutionSpecStateTest.java.template deleted file mode 100644 index 76da5d64f9..0000000000 --- a/ethereum/referencetests/src/reference-test/templates/ExecutionSpecStateTest.java.template +++ /dev/null @@ -1,37 +0,0 @@ -package org.hyperledger.besu.ethereum.vm.executionspec; - -import static org.hyperledger.besu.ethereum.vm.GeneralStateReferenceTestTools.executeTest; -import static org.hyperledger.besu.ethereum.vm.GeneralStateReferenceTestTools.generateTestParametersForConfig; -import static org.junit.jupiter.api.Assumptions.assumeTrue; - -import org.hyperledger.besu.ethereum.referencetests.GeneralStateTestCaseEipSpec; - -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; - -import static org.junit.jupiter.api.Assumptions.assumeTrue; - -/** The general state test operation testing framework entry point. */ -public class %%TESTS_NAME%% { - - private static final String[] TEST_CONFIG_FILE_DIR_PATH = new String[] {%%TESTS_FILE%%}; - - public static Stream getTestParametersForConfig() { - return generateTestParametersForConfig(TEST_CONFIG_FILE_DIR_PATH).stream().map(params -> - Arguments.of(params[0], params[1], params[2]) - ); - } - - @ParameterizedTest(name = "Name: {0}") - @MethodSource("getTestParametersForConfig") - public void execution( - final String name, - final GeneralStateTestCaseEipSpec spec, - final boolean runTest) { - assumeTrue(runTest, "Test " + name + " was ignored"); - executeTest(spec); - } -} diff --git a/ethereum/referencetests/src/reference-test/templates/ExecutionSpecTest.java.template b/ethereum/referencetests/src/reference-test/templates/ExecutionSpecTest.java.template deleted file mode 100644 index d56115f123..0000000000 --- a/ethereum/referencetests/src/reference-test/templates/ExecutionSpecTest.java.template +++ /dev/null @@ -1,36 +0,0 @@ -package org.hyperledger.besu.ethereum.vm.executionspec; - -import static org.hyperledger.besu.ethereum.vm.BlockchainReferenceTestTools.executeTest; -import static org.hyperledger.besu.ethereum.vm.BlockchainReferenceTestTools.generateTestParametersForConfig; - -import org.hyperledger.besu.ethereum.referencetests.BlockchainReferenceTestCaseSpec; - -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; - -import static org.junit.jupiter.api.Assumptions.assumeTrue; - -/** The blockchain test operation testing framework entry point. */ -public class %%TESTS_NAME%% { - - private static final String[] TEST_CONFIG_FILE_DIR_PATH = new String[] {%%TESTS_FILE%%}; - - public static Stream getTestParametersForConfig() { - return generateTestParametersForConfig(TEST_CONFIG_FILE_DIR_PATH).stream().map(params -> - Arguments.of(params[0], params[1], params[2]) - ); - } - - @ParameterizedTest(name = "Name: {0}") - @MethodSource("getTestParametersForConfig") - public void execution( - final String name, - final BlockchainReferenceTestCaseSpec spec, - final boolean runTest) { - assumeTrue(runTest, "Test " + name + " was ignored"); - executeTest(spec); - } -} diff --git a/ethereum/referencetests/src/reference-test/templates/GeneralStateReferenceTest.java.template b/ethereum/referencetests/src/reference-test/templates/GeneralStateReferenceTest.java.template index 3d5976aff2..139766a4b8 100644 --- a/ethereum/referencetests/src/reference-test/templates/GeneralStateReferenceTest.java.template +++ b/ethereum/referencetests/src/reference-test/templates/GeneralStateReferenceTest.java.template @@ -1,4 +1,4 @@ -package org.hyperledger.besu.ethereum.vm.generalstate; +package %%PACKAGE_NAME%%; import static org.hyperledger.besu.ethereum.vm.GeneralStateReferenceTestTools.executeTest; import static org.hyperledger.besu.ethereum.vm.GeneralStateReferenceTestTools.generateTestParametersForConfig; diff --git a/evm/build.gradle b/evm/build.gradle index efcab24b71..b6f8ea3618 100644 --- a/evm/build.gradle +++ b/evm/build.gradle @@ -44,6 +44,7 @@ dependencies { implementation 'io.tmio:tuweni-units' implementation 'org.hyperledger.besu:arithmetic' implementation 'org.hyperledger.besu:bls12-381' + implementation'org.hyperledger.besu:gnark' implementation 'tech.pegasys:jc-kzg-4844' compileOnly 'com.fasterxml.jackson.core:jackson-databind' diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index 86f65970e6..bd437c3a4e 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -114,9 +114,9 @@ - - - + + + @@ -134,9 +134,9 @@ - - - + + + @@ -189,12 +189,12 @@ - - - + + + - - + + @@ -221,12 +221,12 @@ - - - + + + - - + + @@ -253,12 +253,12 @@ - - - + + + - - + + @@ -1361,14 +1361,6 @@ - - - - - - - - @@ -2507,14 +2499,6 @@ - - - - - - - - @@ -2531,22 +2515,6 @@ - - - - - - - - - - - - - - - - @@ -2765,14 +2733,6 @@ - - - - - - - - @@ -3139,11 +3099,6 @@ - - - - - @@ -4603,41 +4558,41 @@ - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + @@ -4677,12 +4632,12 @@ - - - + + + - - + + @@ -4693,44 +4648,52 @@ - - - + + + + + + + + + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + - - - + + + - - + + @@ -5060,17 +5023,6 @@ - - - - - - - - - - - @@ -5177,14 +5129,6 @@ - - - - - - - - @@ -5193,14 +5137,6 @@ - - - - - - - - @@ -5304,6 +5240,11 @@ + + + + + @@ -5312,11 +5253,6 @@ - - - - - @@ -5336,6 +5272,11 @@ + + + + + @@ -5352,11 +5293,6 @@ - - - - - diff --git a/gradle/versions.gradle b/gradle/versions.gradle index db29cfd589..0c2289233d 100644 --- a/gradle/versions.gradle +++ b/gradle/versions.gradle @@ -156,13 +156,14 @@ dependencyManagement { dependency 'org.openjdk.jol:jol-core:0.17' dependency 'tech.pegasys:jc-kzg-4844:1.0.0' - dependencySet(group: 'org.hyperledger.besu', version: '0.8.5') { + dependencySet(group: 'org.hyperledger.besu', version: '0.9.2') { entry 'arithmetic' entry 'ipa-multipoint' entry 'bls12-381' entry 'secp256k1' entry 'secp256r1' entry 'blake2bf' + entry 'gnark' } dependencySet(group: 'org.immutables', version: '2.10.0') { From 45dbc8a9a3778c48a0228215533fb9a75eeb3313 Mon Sep 17 00:00:00 2001 From: garyschulte Date: Sun, 14 Jul 2024 15:46:44 -0700 Subject: [PATCH 034/259] Feature/use gnark-crypto for eip-2537 (#7316) * use gnark-crypto for bls precompiles Signed-off-by: garyschulte --- CHANGELOG.md | 1 + ethereum/core/build.gradle | 1 - .../AbstractBLS12PrecompiledContract.java | 20 +- .../BLS12G1AddPrecompiledContract.java | 4 +- .../BLS12G1MulPrecompiledContract.java | 4 +- .../BLS12G1MultiExpPrecompiledContract.java | 4 +- .../BLS12G2AddPrecompiledContract.java | 4 +- .../BLS12G2MulPrecompiledContract.java | 4 +- .../BLS12G2MultiExpPrecompiledContract.java | 4 +- .../BLS12MapFp2ToG2PrecompiledContract.java | 4 +- .../BLS12MapFpToG1PrecompiledContract.java | 4 +- .../BLS12PairingPrecompiledContract.java | 4 +- .../besu/evm/precompile/g1_add.csv | 4 +- .../besu/evm/precompile/g1_mul.csv | 4 +- .../besu/evm/precompile/g1_multiexp.csv | 8 +- .../besu/evm/precompile/g2_add.csv | 4 +- .../besu/evm/precompile/g2_mul.csv | 8 +- .../besu/evm/precompile/g2_multiexp.csv | 12 +- .../invalid_subgroup_for_pairing.csv | 200 +++++++++--------- .../besu/evm/precompile/pairing.csv | 12 +- 20 files changed, 156 insertions(+), 154 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b783b1dc3..c8a6730a96 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ - Add support to load external profiles using `--profile` [#7265](https://github.com/hyperledger/besu/issues/7265) - `privacy-nonce-always-increments` option enables private transactions to always increment the nonce, even if the transaction is invalid [#6593](https://github.com/hyperledger/besu/pull/6593) - Added `block-test` subcommand to the evmtool which runs blockchain reference tests [#7293](https://github.com/hyperledger/besu/pull/7293) +- implement gnark-crypto for eip-2537 [#7316](https://github.com/hyperledger/besu/pull/7316) ### Bug fixes diff --git a/ethereum/core/build.gradle b/ethereum/core/build.gradle index 4abde77ace..0a25fa1a42 100644 --- a/ethereum/core/build.gradle +++ b/ethereum/core/build.gradle @@ -61,7 +61,6 @@ dependencies { implementation 'io.tmio:tuweni-concurrent' implementation 'io.tmio:tuweni-units' implementation 'io.tmio:tuweni-rlp' - implementation 'org.hyperledger.besu:bls12-381' implementation 'org.immutables:value-annotations' implementation 'tech.pegasys:jc-kzg-4844' 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 21eab01f97..67fecb92aa 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 @@ -18,7 +18,7 @@ import static java.nio.charset.StandardCharsets.UTF_8; import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; import org.hyperledger.besu.evm.frame.MessageFrame; -import org.hyperledger.besu.nativelib.bls12_381.LibEthPairings; +import org.hyperledger.besu.nativelib.gnark.LibGnarkEIP2537; import java.util.Optional; import javax.annotation.Nonnull; @@ -52,7 +52,7 @@ public abstract class AbstractBLS12PrecompiledContract implements PrecompiledCon private final String name; private final byte operationId; - private final int inputLen; + private final int inputLimit; /** * Instantiates a new Abstract BLS12 precompiled contract. @@ -64,7 +64,7 @@ public abstract class AbstractBLS12PrecompiledContract implements PrecompiledCon AbstractBLS12PrecompiledContract(final String name, final byte operationId, final int inputLen) { this.name = name; this.operationId = operationId; - this.inputLen = inputLen + 1; + this.inputLimit = inputLen + 1; } @Override @@ -76,16 +76,17 @@ public abstract class AbstractBLS12PrecompiledContract implements PrecompiledCon @Override public PrecompileContractResult computePrecompile( final Bytes input, @Nonnull final MessageFrame messageFrame) { - final byte[] result = new byte[LibEthPairings.EIP2537_PREALLOCATE_FOR_RESULT_BYTES]; - final byte[] error = new byte[LibEthPairings.EIP2537_PREALLOCATE_FOR_ERROR_BYTES]; + final byte[] result = new byte[LibGnarkEIP2537.EIP2537_PREALLOCATE_FOR_RESULT_BYTES]; + final byte[] error = new byte[LibGnarkEIP2537.EIP2537_PREALLOCATE_FOR_ERROR_BYTES]; final IntByReference o_len = - new IntByReference(LibEthPairings.EIP2537_PREALLOCATE_FOR_RESULT_BYTES); + new IntByReference(LibGnarkEIP2537.EIP2537_PREALLOCATE_FOR_RESULT_BYTES); final IntByReference err_len = - new IntByReference(LibEthPairings.EIP2537_PREALLOCATE_FOR_ERROR_BYTES); - final int inputSize = Math.min(inputLen, input.size()); + new IntByReference(LibGnarkEIP2537.EIP2537_PREALLOCATE_FOR_ERROR_BYTES); + + final int inputSize = Math.min(inputLimit, input.size()); final int errorNo = - LibEthPairings.eip2537_perform_operation( + LibGnarkEIP2537.eip2537_perform_operation( operationId, input.slice(0, inputSize).toArrayUnsafe(), inputSize, @@ -93,6 +94,7 @@ public abstract class AbstractBLS12PrecompiledContract implements PrecompiledCon o_len, error, err_len); + if (errorNo == 0) { return PrecompileContractResult.success(Bytes.wrap(result, 0, o_len.getValue())); } else { diff --git a/evm/src/main/java/org/hyperledger/besu/evm/precompile/BLS12G1AddPrecompiledContract.java b/evm/src/main/java/org/hyperledger/besu/evm/precompile/BLS12G1AddPrecompiledContract.java index 8f04c2d69e..59e4336a09 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/precompile/BLS12G1AddPrecompiledContract.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/precompile/BLS12G1AddPrecompiledContract.java @@ -14,7 +14,7 @@ */ package org.hyperledger.besu.evm.precompile; -import org.hyperledger.besu.nativelib.bls12_381.LibEthPairings; +import org.hyperledger.besu.nativelib.gnark.LibGnarkEIP2537; import org.apache.tuweni.bytes.Bytes; @@ -25,7 +25,7 @@ public class BLS12G1AddPrecompiledContract extends AbstractBLS12PrecompiledContr /** Instantiates a new BLS12G1 Add precompiled contract. */ public BLS12G1AddPrecompiledContract() { - super("BLS12_G1ADD", LibEthPairings.BLS12_G1ADD_OPERATION_RAW_VALUE, PARAMETER_LENGTH); + super("BLS12_G1ADD", LibGnarkEIP2537.BLS12_G1ADD_OPERATION_SHIM_VALUE, PARAMETER_LENGTH); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/precompile/BLS12G1MulPrecompiledContract.java b/evm/src/main/java/org/hyperledger/besu/evm/precompile/BLS12G1MulPrecompiledContract.java index baf1ed35fc..8c76571e1c 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/precompile/BLS12G1MulPrecompiledContract.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/precompile/BLS12G1MulPrecompiledContract.java @@ -14,7 +14,7 @@ */ package org.hyperledger.besu.evm.precompile; -import org.hyperledger.besu.nativelib.bls12_381.LibEthPairings; +import org.hyperledger.besu.nativelib.gnark.LibGnarkEIP2537; import org.apache.tuweni.bytes.Bytes; @@ -25,7 +25,7 @@ public class BLS12G1MulPrecompiledContract extends AbstractBLS12PrecompiledContr /** Instantiates a new BLS12G1 Mul precompiled contract. */ public BLS12G1MulPrecompiledContract() { - super("BLS12_G1MUL", LibEthPairings.BLS12_G1MUL_OPERATION_RAW_VALUE, PARAMETER_LENGTH); + super("BLS12_G1MUL", LibGnarkEIP2537.BLS12_G1MUL_OPERATION_SHIM_VALUE, PARAMETER_LENGTH); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/precompile/BLS12G1MultiExpPrecompiledContract.java b/evm/src/main/java/org/hyperledger/besu/evm/precompile/BLS12G1MultiExpPrecompiledContract.java index e3366f491d..353bb203ee 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/precompile/BLS12G1MultiExpPrecompiledContract.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/precompile/BLS12G1MultiExpPrecompiledContract.java @@ -14,7 +14,7 @@ */ package org.hyperledger.besu.evm.precompile; -import org.hyperledger.besu.nativelib.bls12_381.LibEthPairings; +import org.hyperledger.besu.nativelib.gnark.LibGnarkEIP2537; import org.apache.tuweni.bytes.Bytes; @@ -27,7 +27,7 @@ public class BLS12G1MultiExpPrecompiledContract extends AbstractBLS12Precompiled public BLS12G1MultiExpPrecompiledContract() { super( "BLS12_G1MULTIEXP", - LibEthPairings.BLS12_G1MULTIEXP_OPERATION_RAW_VALUE, + LibGnarkEIP2537.BLS12_G1MULTIEXP_OPERATION_SHIM_VALUE, Integer.MAX_VALUE / PARAMETER_LENGTH * PARAMETER_LENGTH); } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/precompile/BLS12G2AddPrecompiledContract.java b/evm/src/main/java/org/hyperledger/besu/evm/precompile/BLS12G2AddPrecompiledContract.java index ec6a1bea34..3e12b5c8b2 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/precompile/BLS12G2AddPrecompiledContract.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/precompile/BLS12G2AddPrecompiledContract.java @@ -14,7 +14,7 @@ */ package org.hyperledger.besu.evm.precompile; -import org.hyperledger.besu.nativelib.bls12_381.LibEthPairings; +import org.hyperledger.besu.nativelib.gnark.LibGnarkEIP2537; import org.apache.tuweni.bytes.Bytes; @@ -25,7 +25,7 @@ public class BLS12G2AddPrecompiledContract extends AbstractBLS12PrecompiledContr /** Instantiates a new BLS12_G2 Add precompiled contract. */ public BLS12G2AddPrecompiledContract() { - super("BLS12_G2ADD", LibEthPairings.BLS12_G2ADD_OPERATION_RAW_VALUE, PARAMETER_LENGTH); + super("BLS12_G2ADD", LibGnarkEIP2537.BLS12_G2ADD_OPERATION_SHIM_VALUE, PARAMETER_LENGTH); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/precompile/BLS12G2MulPrecompiledContract.java b/evm/src/main/java/org/hyperledger/besu/evm/precompile/BLS12G2MulPrecompiledContract.java index a33f4dc4a3..441b59c5ae 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/precompile/BLS12G2MulPrecompiledContract.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/precompile/BLS12G2MulPrecompiledContract.java @@ -14,7 +14,7 @@ */ package org.hyperledger.besu.evm.precompile; -import org.hyperledger.besu.nativelib.bls12_381.LibEthPairings; +import org.hyperledger.besu.nativelib.gnark.LibGnarkEIP2537; import org.apache.tuweni.bytes.Bytes; @@ -25,7 +25,7 @@ public class BLS12G2MulPrecompiledContract extends AbstractBLS12PrecompiledContr /** Instantiates a new BLS12_G2Mul precompiled contract. */ public BLS12G2MulPrecompiledContract() { - super("BLS12_G2MUL", LibEthPairings.BLS12_G2MUL_OPERATION_RAW_VALUE, PARAMETER_LENGTH); + super("BLS12_G2MUL", LibGnarkEIP2537.BLS12_G2MUL_OPERATION_SHIM_VALUE, PARAMETER_LENGTH); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/precompile/BLS12G2MultiExpPrecompiledContract.java b/evm/src/main/java/org/hyperledger/besu/evm/precompile/BLS12G2MultiExpPrecompiledContract.java index ee4448d40d..3344f075ad 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/precompile/BLS12G2MultiExpPrecompiledContract.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/precompile/BLS12G2MultiExpPrecompiledContract.java @@ -14,7 +14,7 @@ */ package org.hyperledger.besu.evm.precompile; -import org.hyperledger.besu.nativelib.bls12_381.LibEthPairings; +import org.hyperledger.besu.nativelib.gnark.LibGnarkEIP2537; import org.apache.tuweni.bytes.Bytes; @@ -27,7 +27,7 @@ public class BLS12G2MultiExpPrecompiledContract extends AbstractBLS12Precompiled public BLS12G2MultiExpPrecompiledContract() { super( "BLS12_G2MULTIEXP", - LibEthPairings.BLS12_G2MULTIEXP_OPERATION_RAW_VALUE, + LibGnarkEIP2537.BLS12_G2MULTIEXP_OPERATION_SHIM_VALUE, Integer.MAX_VALUE / PARAMETER_LENGTH * PARAMETER_LENGTH); } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/precompile/BLS12MapFp2ToG2PrecompiledContract.java b/evm/src/main/java/org/hyperledger/besu/evm/precompile/BLS12MapFp2ToG2PrecompiledContract.java index 6500683875..ddac7627ac 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/precompile/BLS12MapFp2ToG2PrecompiledContract.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/precompile/BLS12MapFp2ToG2PrecompiledContract.java @@ -14,7 +14,7 @@ */ package org.hyperledger.besu.evm.precompile; -import org.hyperledger.besu.nativelib.bls12_381.LibEthPairings; +import org.hyperledger.besu.nativelib.gnark.LibGnarkEIP2537; import org.apache.tuweni.bytes.Bytes; @@ -27,7 +27,7 @@ public class BLS12MapFp2ToG2PrecompiledContract extends AbstractBLS12Precompiled public BLS12MapFp2ToG2PrecompiledContract() { super( "BLS12_MAP_FIELD_TO_CURVE", - LibEthPairings.BLS12_MAP_FP2_TO_G2_OPERATION_RAW_VALUE, + LibGnarkEIP2537.BLS12_MAP_FP2_TO_G2_OPERATION_SHIM_VALUE, PARAMETER_LENGTH); } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/precompile/BLS12MapFpToG1PrecompiledContract.java b/evm/src/main/java/org/hyperledger/besu/evm/precompile/BLS12MapFpToG1PrecompiledContract.java index a512b24966..c2598358d7 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/precompile/BLS12MapFpToG1PrecompiledContract.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/precompile/BLS12MapFpToG1PrecompiledContract.java @@ -14,7 +14,7 @@ */ package org.hyperledger.besu.evm.precompile; -import org.hyperledger.besu.nativelib.bls12_381.LibEthPairings; +import org.hyperledger.besu.nativelib.gnark.LibGnarkEIP2537; import org.apache.tuweni.bytes.Bytes; @@ -27,7 +27,7 @@ public class BLS12MapFpToG1PrecompiledContract extends AbstractBLS12PrecompiledC public BLS12MapFpToG1PrecompiledContract() { super( "BLS12_MAP_FIELD_TO_CURVE", - LibEthPairings.BLS12_MAP_FP_TO_G1_OPERATION_RAW_VALUE, + LibGnarkEIP2537.BLS12_MAP_FP_TO_G1_OPERATION_SHIM_VALUE, PARAMETER_LENGTH); } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/precompile/BLS12PairingPrecompiledContract.java b/evm/src/main/java/org/hyperledger/besu/evm/precompile/BLS12PairingPrecompiledContract.java index d275db3f90..e0e5681887 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/precompile/BLS12PairingPrecompiledContract.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/precompile/BLS12PairingPrecompiledContract.java @@ -14,7 +14,7 @@ */ package org.hyperledger.besu.evm.precompile; -import org.hyperledger.besu.nativelib.bls12_381.LibEthPairings; +import org.hyperledger.besu.nativelib.gnark.LibGnarkEIP2537; import org.apache.tuweni.bytes.Bytes; @@ -27,7 +27,7 @@ public class BLS12PairingPrecompiledContract extends AbstractBLS12PrecompiledCon public BLS12PairingPrecompiledContract() { super( "BLS12_PAIRING", - LibEthPairings.BLS12_PAIR_OPERATION_RAW_VALUE, + LibGnarkEIP2537.BLS12_PAIR_OPERATION_SHIM_VALUE, Integer.MAX_VALUE / PARAMETER_LENGTH * PARAMETER_LENGTH); } diff --git a/evm/src/test/resources/org/hyperledger/besu/evm/precompile/g1_add.csv b/evm/src/test/resources/org/hyperledger/besu/evm/precompile/g1_add.csv index 7b83f95daa..b6714c2fcd 100644 --- a/evm/src/test/resources/org/hyperledger/besu/evm/precompile/g1_add.csv +++ b/evm/src/test/resources/org/hyperledger/besu/evm/precompile/g1_add.csv @@ -101,5 +101,5 @@ input,result,gas,notes 000000000000000000000000000000000106df8eba767e90cce0eabdaacc24d8e226c6865012ef8cb1460de5a319d443fdc6b4f4e58fb668943e0528b1809da10000000000000000000000000000000019789f464c95c179af18704c0b67b881991880f75ee7b03b9feafa3eafcd0f7d30a17fdd9cf439ff7fe683adca2083b50000000000000000000000000000000017a81b957a12adf474a2913e8636f169ea9cd10be62c16b88f95f5caf661f158a032a9f7d249fdf2765caa1564bed0570000000000000000000000000000000017fbf2abc62dc2678b65d509e19c9c9c5d961c72565649a078da8dff98be6236ef314e9ff8022f639ff565353345c230,00000000000000000000000000000000002c8bc5f39b2c9fea01372429e92a9c945fad152da67174f4e478fdead734d50f6e2da867c235f1f2f11bdfee67d2a7000000000000000000000000000000000c1dd27aad9f5d48c4824da3071daedf0c7a0e2a0b0ed39c50c9d25e61334a9c96765e049542ccaa00e0eccb316eec08,500, 000000000000000000000000000000000012196c5a43d69224d8713389285f26b98f86ee910ab3dd668e413738282003cc5b7357af9a7af54bb713d62255e80f560000000000000000000000000000000006ba8102bfbeea4416b710c73e8cce3032c31c6269c44906f8ac4f7874ce99fb17559992486528963884ce429a992fee000000000000000000000000000000000001101098f5c39893765766af4512a0c74e1bb89bc7e6fdf14e3e7337d257cc0f94658179d83320b99f31ff94cd2bac0000000000000000000000000000000003e1a9f9f44ca2cdab4f43a1a3ee3470fdf90b2fc228eb3b709fcd72f014838ac82a6d797aeefed9a0804b22ed1ce8f7,,,invalid input parameters, invalid input length for G1 addition 00000000000000000000000000000012196c5a43d69224d8713389285f26b98f86ee910ab3dd668e413738282003cc5b7357af9a7af54bb713d62255e80f560000000000000000000000000000000006ba8102bfbeea4416b710c73e8cce3032c31c6269c44906f8ac4f7874ce99fb17559992486528963884ce429a992fee000000000000000000000000000000000001101098f5c39893765766af4512a0c74e1bb89bc7e6fdf14e3e7337d257cc0f94658179d83320b99f31ff94cd2bac0000000000000000000000000000000003e1a9f9f44ca2cdab4f43a1a3ee3470fdf90b2fc228eb3b709fcd72f014838ac82a6d797aeefed9a0804b22ed1ce8f7,,,invalid input parameters, invalid input length for G1 addition -0000000000000000000000000000000012196c5a43d69224d8713389285f26b98f86ee910ab3dd668e413738282003cc5b7357af9a7af54bb713d62255e80f570000000000000000000000000000000006ba8102bfbeea4416b710c73e8cce3032c31c6269c44906f8ac4f7874ce99fb17559992486528963884ce429a992fee000000000000000000000000000000000001101098f5c39893765766af4512a0c74e1bb89bc7e6fdf14e3e7337d257cc0f94658179d83320b99f31ff94cd2bac0000000000000000000000000000000003e1a9f9f44ca2cdab4f43a1a3ee3470fdf90b2fc228eb3b709fcd72f014838ac82a6d797aeefed9a0804b22ed1ce8f7,,,invalid input parameters, Point 0 is not on curve -0000000000000000000000000000000012196c5a43d69224d8713389285f26b98f86ee910ab3dd668e413738282003cc5b7357af9a7af54bb713d62255e80f560000000000000000000000000000000006ba8102bfbeea4416b710c73e8cce3032c31c6269c44906f8ac4f7874ce99fb17559992486528963884ce429a992fee000000000000000000000000000000000001101098f5c39893765766af4512a0c74e1bb89bc7e6fdf14e3e7337d257cc0f94658179d83320b99f31ff94cd2bad0000000000000000000000000000000003e1a9f9f44ca2cdab4f43a1a3ee3470fdf90b2fc228eb3b709fcd72f014838ac82a6d797aeefed9a0804b22ed1ce8f7,,,invalid input parameters, Point 1 is not on curve +0000000000000000000000000000000012196c5a43d69224d8713389285f26b98f86ee910ab3dd668e413738282003cc5b7357af9a7af54bb713d62255e80f570000000000000000000000000000000006ba8102bfbeea4416b710c73e8cce3032c31c6269c44906f8ac4f7874ce99fb17559992486528963884ce429a992fee000000000000000000000000000000000001101098f5c39893765766af4512a0c74e1bb89bc7e6fdf14e3e7337d257cc0f94658179d83320b99f31ff94cd2bac0000000000000000000000000000000003e1a9f9f44ca2cdab4f43a1a3ee3470fdf90b2fc228eb3b709fcd72f014838ac82a6d797aeefed9a0804b22ed1ce8f7,,,invalid point: point is not on curve +0000000000000000000000000000000012196c5a43d69224d8713389285f26b98f86ee910ab3dd668e413738282003cc5b7357af9a7af54bb713d62255e80f560000000000000000000000000000000006ba8102bfbeea4416b710c73e8cce3032c31c6269c44906f8ac4f7874ce99fb17559992486528963884ce429a992fee000000000000000000000000000000000001101098f5c39893765766af4512a0c74e1bb89bc7e6fdf14e3e7337d257cc0f94658179d83320b99f31ff94cd2bad0000000000000000000000000000000003e1a9f9f44ca2cdab4f43a1a3ee3470fdf90b2fc228eb3b709fcd72f014838ac82a6d797aeefed9a0804b22ed1ce8f7,,,invalid point: point is not on curve diff --git a/evm/src/test/resources/org/hyperledger/besu/evm/precompile/g1_mul.csv b/evm/src/test/resources/org/hyperledger/besu/evm/precompile/g1_mul.csv index 4ec77982a2..3eb702f114 100644 --- a/evm/src/test/resources/org/hyperledger/besu/evm/precompile/g1_mul.csv +++ b/evm/src/test/resources/org/hyperledger/besu/evm/precompile/g1_mul.csv @@ -101,5 +101,5 @@ input,result,gas,notes 000000000000000000000000000000000106df8eba767e90cce0eabdaacc24d8e226c6865012ef8cb1460de5a319d443fdc6b4f4e58fb668943e0528b1809da10000000000000000000000000000000019789f464c95c179af18704c0b67b881991880f75ee7b03b9feafa3eafcd0f7d30a17fdd9cf439ff7fe683adca2083b57cf23dee8d95d94046678f3bdb4b0ea3d4e3a1a2f07f582e2a98ad6eb7562cbf,000000000000000000000000000000000bf700422a382546a74376b0292f3a49ceff5597f0d2b726b1ff099bcda7ba92238a21db12eff5c314a29dd2387bec850000000000000000000000000000000005e22e3c772f3634b1ccf4e311241977eb20e7269540ef22d379de26ab80c58461dfa3b67848e0d584fb11de1917949a,12000, 00000000000000000000000000000012196c5a43d69224d8713389285f26b98f86ee910ab3dd668e413738282003cc5b7357af9a7af54bb713d62255e80f560000000000000000000000000000000006ba8102bfbeea4416b710c73e8cce3032c31c6269c44906f8ac4f7874ce99fb17559992486528963884ce429a992feeb3c940fe79b6966489b527955de7599194a9ac69a6ff58b8d99e7b1084f0464e,,,invalid input parameters, invalid input length for G1 multiplication 000000000000000000000000000000000012196c5a43d69224d8713389285f26b98f86ee910ab3dd668e413738282003cc5b7357af9a7af54bb713d62255e80f560000000000000000000000000000000006ba8102bfbeea4416b710c73e8cce3032c31c6269c44906f8ac4f7874ce99fb17559992486528963884ce429a992feeb3c940fe79b6966489b527955de7599194a9ac69a6ff58b8d99e7b1084f0464e,,,invalid input parameters, invalid input length for G1 multiplication -0000000000000000000000000000000012196c5a43d69224d8713389285f26b98f86ee910ab3dd668e413738282003cc5b7357af9a7af54bb713d62255e80f570000000000000000000000000000000006ba8102bfbeea4416b710c73e8cce3032c31c6269c44906f8ac4f7874ce99fb17559992486528963884ce429a992feeb3c940fe79b6966489b527955de7599194a9ac69a6ff58b8d99e7b1084f0464e,,,invalid input parameters, Point is not on curve -000000000000000000000000000000000123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef00000000000000000000000000000000193fb7cedb32b2c3adc06ec11a96bc0d661869316f5e4a577a9f7c179593987beb4fb2ee424dbb2f5dd891e228b46c4a0000000000000000000000000000000000000000000000000000000000000002,,,Point is not in the expected subgroup \ No newline at end of file +0000000000000000000000000000000012196c5a43d69224d8713389285f26b98f86ee910ab3dd668e413738282003cc5b7357af9a7af54bb713d62255e80f570000000000000000000000000000000006ba8102bfbeea4416b710c73e8cce3032c31c6269c44906f8ac4f7874ce99fb17559992486528963884ce429a992feeb3c940fe79b6966489b527955de7599194a9ac69a6ff58b8d99e7b1084f0464e,,,invalid point: point is not on curve +000000000000000000000000000000000123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef00000000000000000000000000000000193fb7cedb32b2c3adc06ec11a96bc0d661869316f5e4a577a9f7c179593987beb4fb2ee424dbb2f5dd891e228b46c4a0000000000000000000000000000000000000000000000000000000000000002,,,invalid point: subgroup check failed diff --git a/evm/src/test/resources/org/hyperledger/besu/evm/precompile/g1_multiexp.csv b/evm/src/test/resources/org/hyperledger/besu/evm/precompile/g1_multiexp.csv index 413d51ee7f..20ed990e61 100644 --- a/evm/src/test/resources/org/hyperledger/besu/evm/precompile/g1_multiexp.csv +++ b/evm/src/test/resources/org/hyperledger/besu/evm/precompile/g1_multiexp.csv @@ -101,8 +101,8 @@ input,result,gas,notes 0000000000000000000000000000000004acd4cb6bcfed3219c3aee9368feeb58d77a7ec81d19bea11402015f4bd0ee2d7afd86fa7ae9dd320910ca28eb6d98f0000000000000000000000000000000009fe1b0094c0c2ae80a3c5accfed5d212ce39f867aa2150b781c193a0053aecb04d06e005fbfa0a24595e5968d024be18a71abe11a893fce872f6b8a020b6d84241df03eb934b50cbf3571df4800a8330000000000000000000000000000000018cf9bf39549c35e94211b4e2d0a0157d73e1ce8a17cd724eb33c38281dac07e12eec61b27b440b220c4f21915a73a52000000000000000000000000000000000fca6d956989db84dcfe58b0310fc21b5bdc82a32838c8d9cae912d683dd9c67f68e15b3fbf9d7b430ba239c8904fdd2bbf28e5bca314391550d3a0fce50b1220965860e72c8c3865a2d4c599d31d3f1000000000000000000000000000000001897956bc232fd5a9b0ed1b533bebef8ddd9e97002513eec71d67ce1086ba8473f2c013af7d8ac548290453d9f71bd5a000000000000000000000000000000000796da5c8ac165d416c8fa36d84e11bcaa80c1bbfe18efde4b4b2c71d6d00fa24f3d51eac312cad9e854f094dcb6ec7458b208a6845aeb2bf31999042c59b7b130a7ce5297e88023953b1aef63616fe4000000000000000000000000000000000302240769257e92899da03fcc4abe1ad3944b74c3046e790e4e950f2958426b5fdc691401a1c8a531f42185d382fe5b000000000000000000000000000000000053750b58b6d2fbacae94e22b397261e541eb4abf4715b3f528dbfc3388122918b1b4b506f2fef89ea936efdef0105b3b53b6cf9e0ce1661c4960283be790abf956c2d6433529b8f3a32b92b227aebe000000000000000000000000000000000168a635a14f61734372f4bdd2fd564d77afa8588e1828d88c4c90bb50f57473b2c20585dc0e93726b84e73c61f29ef1000000000000000000000000000000000e6e92355e59304ad35b1dbfbb98db803d5fadabdef4fb1b2a54080ec9a33a7147ebb4d5219acabd949337bebbffa793b049228435ade4c4c565e65f39f13a84c747c312afcdaff352560b9fb3cfebcc000000000000000000000000000000001797bf2ac9b490cd43a346fdc64bfb22301a0a0e371bb4df8ec02342b4fcc99af43b4735665c6b1386fa04a3dc5406e3000000000000000000000000000000000fcc20f4aec04b7896ddfd86f58c2e1e9dc6f863ec3b477572c073c0f4fb07ee8dc0d5a843321446445b6e7846fbc5d556197f5ad17062d2ecbdc8887bcdd32e5ed4c48cefd9e14d622a0b800d9703300000000000000000000000000000000013ddb8ff149222a5a0a997c0b89aeee36a6ff2540de3cba8bfe6a2a64fb505f13ad956a3882082ab85bfbe72f3a3a6b600000000000000000000000000000000102c1a1085f60cd5326966a2dda0872290e1658002ff3ed95c47cc0345565076bdecdeab7082bcfb439cf7f3e445faaf721d9d7fe10104cafcad71307e785321ab87b2b69593535caecbf0e166cfda5b00000000000000000000000000000000189515e637d404ce6db58d24774609cf946074aa22066d808dc022824a26b381bf09148005c61156a976154b025d71c90000000000000000000000000000000009102e313c4517cdd3d07a66e0013eeafc996c21fbf5f0f3e7d232ad5adb781cce1657bd5750193cfc0357ff55bd012a461531ecb61365908019c1e8074a4c322df2b356eea3f3eea9aa1e0e1fc5525e0000000000000000000000000000000002e166e475ff083faad64667b683e546b2358f945b8656f9c2f3f6e87a40dc3fc087dd94874bec1c4bd5929b7c96024a00000000000000000000000000000000022bb4ba4be638d8c14a16c94522c41cd3b3ad917daa454f820b8fa35e5a48c676266feece6986e8fe920b2a5e43e4b3569c1c1ae2d18bbe36ed50db1bf30957802b09a982fbed49d4968815552e010d0000000000000000000000000000000004947bd8ea8cc3b116fb7320c573fff0f107913c18cfdba2e7e9a4c8715e334a431156f384548508df8950d681163aee0000000000000000000000000000000001e9e7494c295248184503344b8ac7bfcff41a4561de03d78691ac47980f14aa47c1eaa3cca80103f0f2ba14a2842aea2061d33b2f7e786effbd2e93101a56ba1bb62c1a773a08b72ca82f5183bea35b0000000000000000000000000000000004789b01538cfc54cad0e99538e874d13eaa7f07199af29d460927c3e622c74e0bb4185afa12c53446f56033348c332f00000000000000000000000000000000154291a8bdefbc91445ef1fe123f326b8aad652c8c54502920d4dfa912c2f42d784fbc5a16d08468d2d6ee56e7e8eaa24129b150752d2d5551a622231ab067931678454aaeb23f76168219406f0d50ee00000000000000000000000000000000029048f227fe8d1b7247a82cfd3e1b4b60cdce6b52de42c4b96641bf8fc5ba9b077e33bd4c4fce9a51b63a6a2451b427000000000000000000000000000000000c83518e1b7700d68966d592cb2e3295a2db5226eb6fef972c8a84721d1e49a30e4a8ee3494ed4bbcd2a6877e1ba597d366c32d5d3c132f32a6ac3cfe1dabb649c59ae224338f747ad98b193e83467290000000000000000000000000000000003e96431aae4330d3d204093b7af21343ace4f1960de951eeaebea51e778b1fee43ecddc46667d096edbc5ff4735586400000000000000000000000000000000183a282f4b0513be661b1b38eb5f02b51aadc591745e0bd5d2d4e5545739e26470a9ec20d78ec284268d9c54c8e4f7b6d997516cac28a3968ac6946b5bffaace0856a52e38fdcca11ddfa16cf5a568f5000000000000000000000000000000000904c85edd36dfa18ddb4e1809607708142f3c0861570f2bc8fff14c462675661f2111c10a01557fb21f7f38957bdd840000000000000000000000000000000012a3a37f34ebb23d4c9268ec9e1d53aed4747aaace497695e6ea8fdbdedd58031cb479003e8bec0d14aa1d062fa30f2ce881ec65fdc2f58e46d3ee45a06d0c5ac844ee5b62872c7ba21f6b48621a337100000000000000000000000000000000148532bffbbf8bb1688f6448854214b4273b9d5adf132aa9142c1605d1882879678b6cc70638713b9438532d427f447c0000000000000000000000000000000010971ee30d83719e10e91aad3f1f201fe35ba1a057531b1905bca3a8391a3786cd077ee0f104305eafb3c94f4546da9edcd9b95e49473277a665ca0f9a8309df9ed6ee4f25d803aa967fb8f688273e65000000000000000000000000000000000f73574aa5a06ea569de88e48fcb96e822039af296684933c1b417dde95e08d2ac9c6ad4d525b0734e24807ee99ba88a000000000000000000000000000000000523deae09e75121a6d89b45161f69f0733a9e43d88d8527a03cca8cc126aeb7a680cfaf291554403723e20440b79437334582482a9038ab906880e43a4a9d39e73b6c63604eba0c8f6399eb5c288638,000000000000000000000000000000000db91871e4cd84b3b58216b6c2e77a9521f3080182e78d3f66fe33f313013f06aec2dc5a6d483f35fadebde873bff9490000000000000000000000000000000003b9685de062b09b9e277ad5cd664d28af59064448af2b1b2b2357df6fc88e3ee7e0ac837100e0b7593944e8db43ab0f,64128, 00000000000000000000000000000012196c5a43d69224d8713389285f26b98f86ee910ab3dd668e413738282003cc5b7357af9a7af54bb713d62255e80f560000000000000000000000000000000006ba8102bfbeea4416b710c73e8cce3032c31c6269c44906f8ac4f7874ce99fb17559992486528963884ce429a992feeb3c940fe79b6966489b527955de7599194a9ac69a6ff58b8d99e7b1084f0464e00000000000000000000000000000000117dbe419018f67844f6a5e1b78a1e597283ad7b8ee7ac5e58846f5a5fd68d0da99ce235a91db3ec1cf340fe6b7afcdb0000000000000000000000000000000013316f23de032d25e912ae8dc9b54c8dba1be7cecdbb9d2228d7e8f652011d46be79089dd0a6080a73c82256ce5e4ed24d0e25bf3f6fc9f4da25d21fdc71773f1947b7a8a775b8177f7eca990b05b71d0000000000000000000000000000000008ab7b556c672db7883ec47efa6d98bb08cec7902ebb421aac1c31506b177ac444ffa2d9b400a6f1cbdc6240c607ee110000000000000000000000000000000016b7fa9adf4addc2192271ce7ad3c8d8f902d061c43b7d2e8e26922009b777855bffabe7ed1a09155819eabfa87f276f973f40c12c92b703d7b7848ef8b4466d40823aad3943a312b57432b91ff68be10000000000000000000000000000000015ff9a232d9b5a8020a85d5fe08a1dcfb73ece434258fe0e2fddf10ddef0906c42dcb5f5d62fc97f934ba900f17beb330000000000000000000000000000000009cfe4ee2241d9413c616462d7bac035a6766aeaab69c81e094d75b840df45d7e0dfac0265608b93efefb9a8728b98e44c51f97bcdda93904ae26991b471e9ea942e2b5b8ed26055da11c58bc7b5002a0000000000000000000000000000000017a17b82e3bfadf3250210d8ef572c02c3610d65ab4d7366e0b748768a28ee6a1b51f77ed686a64f087f36f641e7dca900000000000000000000000000000000077ea73d233ccea51dc4d5acecf6d9332bf17ae51598f4b394a5f62fb387e9c9aa1d6823b64a074f5873422ca57545d38964d5867927bc3e35a0b4c457482373969bff5edff8a781d65573e07fd87b89000000000000000000000000000000000c1243478f4fbdc21ea9b241655947a28accd058d0cdb4f9f0576d32f09dddaf0850464550ff07cab5927b3e4c863ce90000000000000000000000000000000015fb54db10ffac0b6cd374eb7168a8cb3df0a7d5f872d8e98c1f623deb66df5dd08ff4c3658f2905ec8bd02598bd4f90787c38b944eadbd03fd3187f450571740f6cd00e5b2e560165846eb800e5c944000000000000000000000000000000000328f09584b6d6c98a709fc22e184123994613aca95a28ac53df8523b92273eb6f4e2d9b2a7dcebb474604d54a210719000000000000000000000000000000001220ebde579911fe2e707446aaad8d3789fae96ae2e23670a4fd856ed82daaab704779eb4224027c1ed9460f39951a1baaee7ae2a237e8e53560c79e7baa9adf9c00a0ea4d6f514e7a6832eb15cef1e10000000000000000000000000000000002ebfa98aa92c32a29ebe17fcb1819ba82e686abd9371fcee8ea793b4c72b6464085044f818f1f5902396df0122830cb00000000000000000000000000000000001184715b8432ed190b459113977289a890f68f6085ea111466af15103c9c02467da33e01d6bff87fd57db6ccba442adac6ed3ef45c1d7d3028f0f89e5458797996d3294b95bebe049b76c7d0db317c0000000000000000000000000000000009d6424e002439998e91cd509f85751ad25e574830c564e7568347d19e3f38add0cab067c0b4b0801785a78bcbeaf246000000000000000000000000000000000ef6d7db03ee654503b46ff0dbc3297536a422e963bda9871a8da8f4eeb98dedebd6071c4880b4636198f4c2375dc795bb30985756c3ca075114c92f231575d6befafe4084517f1166a47376867bd1080000000000000000000000000000000002d1cdb93191d1f9f0308c2c55d0208a071f5520faca7c52ab0311dbc9ba563bd33b5dd6baa77bf45ac2c3269e945f4800000000000000000000000000000000072a52106e6d7b92c594c4dacd20ef5fab7141e45c231457cd7e71463b2254ee6e72689e516fa6a8f29f2a173ce0a190fb730105809f64ea522983d6bbb62f7e2e8cbf702685e9be10e2ef71f81876720000000000000000000000000000000000641642f6801d39a09a536f506056f72a619c50d043673d6d39aa4af11d8e3ded38b9c3bbc970dbc1bd55d68f94b50d0000000000000000000000000000000009ab050de356a24aea90007c6b319614ba2f2ed67223b972767117769e3c8e31ee4056494628fb2892d3d37afb6ac943b6a9408625b0ca8fcbfb21d34eec2d8e24e9a30d2d3b32d7a37d110b13afbfea000000000000000000000000000000000fd4893addbd58fb1bf30b8e62bef068da386edbab9541d198e8719b2de5beb9223d87387af82e8b55bd521ff3e47e2d000000000000000000000000000000000f3a923b76473d5b5a53501790cb02597bb778bdacb3805a9002b152d22241ad131d0f0d6a260739cbab2c2fe602870e3b77283d0a7bb9e17a27e66851792fdd605cc0a339028b8985390fd024374c760000000000000000000000000000000002cb4b24c8aa799fd7cb1e4ab1aab1372113200343d8526ea7bc64dfaf926baf5d90756a40e35617854a2079cd07fba40000000000000000000000000000000003327ca22bd64ebd673cc6d5b02b2a8804d5353c9d251637c4273ad08d581cc0d58da9bea27c37a0b3f4961dbafd276bdd994eae929aee7428fdda2e44f8cb12b10b91c83b22abc8bbb561310b62257c00000000000000000000000000000000024ad70f2b2105ca37112858e84c6f5e3ffd4a8b064522faae1ecba38fabd52a6274cb46b00075deb87472f11f2e67d90000000000000000000000000000000010a502c8b2a68aa30d2cb719273550b9a3c283c35b2e18a01b0b765344ffaaa5cb30a1e3e6ecd3a53ab67658a57876817010b134989c8368c7f831f9dd9f9a890e2c1435681107414f2e8637153bbf6a0000000000000000000000000000000000704cc57c8e0944326ddc7c747d9e7347a7f6918977132eea269f161461eb64066f773352f293a3ac458dc3ccd5026a000000000000000000000000000000001099d3c2bb2d082f2fdcbed013f7ac69e8624f4fcf6dfab3ee9dcf7fbbdb8c49ee79de40e887c0b6828d2496e3a6f76894c68bc8d91ac8c489ee87dbfc4b94c93c8bbd5fc04c27db8b02303f3a65905400000000000000000000000000000000130535a29392c77f045ac90e47f2e7b3cffff94494fe605aad345b41043f6663ada8e2e7ecd3d06f3b8854ef92212f42000000000000000000000000000000001699a3cc1f10cd2ed0dc68eb916b4402e4f12bf4746893bf70e26e209e605ea89e3d53e7ac52bd07713d3c8fc671931db3682accc3939283b870357cf83683350baf73aa0d3d68bda82a0f6ae7e51746,,,invalid input parameters, invalid input length for G1 multiplication 000000000000000000000000000000000012196c5a43d69224d8713389285f26b98f86ee910ab3dd668e413738282003cc5b7357af9a7af54bb713d62255e80f560000000000000000000000000000000006ba8102bfbeea4416b710c73e8cce3032c31c6269c44906f8ac4f7874ce99fb17559992486528963884ce429a992feeb3c940fe79b6966489b527955de7599194a9ac69a6ff58b8d99e7b1084f0464e00000000000000000000000000000000117dbe419018f67844f6a5e1b78a1e597283ad7b8ee7ac5e58846f5a5fd68d0da99ce235a91db3ec1cf340fe6b7afcdb0000000000000000000000000000000013316f23de032d25e912ae8dc9b54c8dba1be7cecdbb9d2228d7e8f652011d46be79089dd0a6080a73c82256ce5e4ed24d0e25bf3f6fc9f4da25d21fdc71773f1947b7a8a775b8177f7eca990b05b71d0000000000000000000000000000000008ab7b556c672db7883ec47efa6d98bb08cec7902ebb421aac1c31506b177ac444ffa2d9b400a6f1cbdc6240c607ee110000000000000000000000000000000016b7fa9adf4addc2192271ce7ad3c8d8f902d061c43b7d2e8e26922009b777855bffabe7ed1a09155819eabfa87f276f973f40c12c92b703d7b7848ef8b4466d40823aad3943a312b57432b91ff68be10000000000000000000000000000000015ff9a232d9b5a8020a85d5fe08a1dcfb73ece434258fe0e2fddf10ddef0906c42dcb5f5d62fc97f934ba900f17beb330000000000000000000000000000000009cfe4ee2241d9413c616462d7bac035a6766aeaab69c81e094d75b840df45d7e0dfac0265608b93efefb9a8728b98e44c51f97bcdda93904ae26991b471e9ea942e2b5b8ed26055da11c58bc7b5002a0000000000000000000000000000000017a17b82e3bfadf3250210d8ef572c02c3610d65ab4d7366e0b748768a28ee6a1b51f77ed686a64f087f36f641e7dca900000000000000000000000000000000077ea73d233ccea51dc4d5acecf6d9332bf17ae51598f4b394a5f62fb387e9c9aa1d6823b64a074f5873422ca57545d38964d5867927bc3e35a0b4c457482373969bff5edff8a781d65573e07fd87b89000000000000000000000000000000000c1243478f4fbdc21ea9b241655947a28accd058d0cdb4f9f0576d32f09dddaf0850464550ff07cab5927b3e4c863ce90000000000000000000000000000000015fb54db10ffac0b6cd374eb7168a8cb3df0a7d5f872d8e98c1f623deb66df5dd08ff4c3658f2905ec8bd02598bd4f90787c38b944eadbd03fd3187f450571740f6cd00e5b2e560165846eb800e5c944000000000000000000000000000000000328f09584b6d6c98a709fc22e184123994613aca95a28ac53df8523b92273eb6f4e2d9b2a7dcebb474604d54a210719000000000000000000000000000000001220ebde579911fe2e707446aaad8d3789fae96ae2e23670a4fd856ed82daaab704779eb4224027c1ed9460f39951a1baaee7ae2a237e8e53560c79e7baa9adf9c00a0ea4d6f514e7a6832eb15cef1e10000000000000000000000000000000002ebfa98aa92c32a29ebe17fcb1819ba82e686abd9371fcee8ea793b4c72b6464085044f818f1f5902396df0122830cb00000000000000000000000000000000001184715b8432ed190b459113977289a890f68f6085ea111466af15103c9c02467da33e01d6bff87fd57db6ccba442adac6ed3ef45c1d7d3028f0f89e5458797996d3294b95bebe049b76c7d0db317c0000000000000000000000000000000009d6424e002439998e91cd509f85751ad25e574830c564e7568347d19e3f38add0cab067c0b4b0801785a78bcbeaf246000000000000000000000000000000000ef6d7db03ee654503b46ff0dbc3297536a422e963bda9871a8da8f4eeb98dedebd6071c4880b4636198f4c2375dc795bb30985756c3ca075114c92f231575d6befafe4084517f1166a47376867bd1080000000000000000000000000000000002d1cdb93191d1f9f0308c2c55d0208a071f5520faca7c52ab0311dbc9ba563bd33b5dd6baa77bf45ac2c3269e945f4800000000000000000000000000000000072a52106e6d7b92c594c4dacd20ef5fab7141e45c231457cd7e71463b2254ee6e72689e516fa6a8f29f2a173ce0a190fb730105809f64ea522983d6bbb62f7e2e8cbf702685e9be10e2ef71f81876720000000000000000000000000000000000641642f6801d39a09a536f506056f72a619c50d043673d6d39aa4af11d8e3ded38b9c3bbc970dbc1bd55d68f94b50d0000000000000000000000000000000009ab050de356a24aea90007c6b319614ba2f2ed67223b972767117769e3c8e31ee4056494628fb2892d3d37afb6ac943b6a9408625b0ca8fcbfb21d34eec2d8e24e9a30d2d3b32d7a37d110b13afbfea000000000000000000000000000000000fd4893addbd58fb1bf30b8e62bef068da386edbab9541d198e8719b2de5beb9223d87387af82e8b55bd521ff3e47e2d000000000000000000000000000000000f3a923b76473d5b5a53501790cb02597bb778bdacb3805a9002b152d22241ad131d0f0d6a260739cbab2c2fe602870e3b77283d0a7bb9e17a27e66851792fdd605cc0a339028b8985390fd024374c760000000000000000000000000000000002cb4b24c8aa799fd7cb1e4ab1aab1372113200343d8526ea7bc64dfaf926baf5d90756a40e35617854a2079cd07fba40000000000000000000000000000000003327ca22bd64ebd673cc6d5b02b2a8804d5353c9d251637c4273ad08d581cc0d58da9bea27c37a0b3f4961dbafd276bdd994eae929aee7428fdda2e44f8cb12b10b91c83b22abc8bbb561310b62257c00000000000000000000000000000000024ad70f2b2105ca37112858e84c6f5e3ffd4a8b064522faae1ecba38fabd52a6274cb46b00075deb87472f11f2e67d90000000000000000000000000000000010a502c8b2a68aa30d2cb719273550b9a3c283c35b2e18a01b0b765344ffaaa5cb30a1e3e6ecd3a53ab67658a57876817010b134989c8368c7f831f9dd9f9a890e2c1435681107414f2e8637153bbf6a0000000000000000000000000000000000704cc57c8e0944326ddc7c747d9e7347a7f6918977132eea269f161461eb64066f773352f293a3ac458dc3ccd5026a000000000000000000000000000000001099d3c2bb2d082f2fdcbed013f7ac69e8624f4fcf6dfab3ee9dcf7fbbdb8c49ee79de40e887c0b6828d2496e3a6f76894c68bc8d91ac8c489ee87dbfc4b94c93c8bbd5fc04c27db8b02303f3a65905400000000000000000000000000000000130535a29392c77f045ac90e47f2e7b3cffff94494fe605aad345b41043f6663ada8e2e7ecd3d06f3b8854ef92212f42000000000000000000000000000000001699a3cc1f10cd2ed0dc68eb916b4402e4f12bf4746893bf70e26e209e605ea89e3d53e7ac52bd07713d3c8fc671931db3682accc3939283b870357cf83683350baf73aa0d3d68bda82a0f6ae7e51746,,,invalid input parameters, invalid input length for G1 multiplication -,,,invalid input parameters, Invalid number of pairs -0000000000000000000000000000000012196c5a43d69224d8713389285f26b98f86ee910ab3dd668e413738282003cc5b7357af9a7af54bb713d62255e80f570000000000000000000000000000000006ba8102bfbeea4416b710c73e8cce3032c31c6269c44906f8ac4f7874ce99fb17559992486528963884ce429a992feeb3c940fe79b6966489b527955de7599194a9ac69a6ff58b8d99e7b1084f0464e00000000000000000000000000000000117dbe419018f67844f6a5e1b78a1e597283ad7b8ee7ac5e58846f5a5fd68d0da99ce235a91db3ec1cf340fe6b7afcdb0000000000000000000000000000000013316f23de032d25e912ae8dc9b54c8dba1be7cecdbb9d2228d7e8f652011d46be79089dd0a6080a73c82256ce5e4ed24d0e25bf3f6fc9f4da25d21fdc71773f1947b7a8a775b8177f7eca990b05b71d0000000000000000000000000000000008ab7b556c672db7883ec47efa6d98bb08cec7902ebb421aac1c31506b177ac444ffa2d9b400a6f1cbdc6240c607ee110000000000000000000000000000000016b7fa9adf4addc2192271ce7ad3c8d8f902d061c43b7d2e8e26922009b777855bffabe7ed1a09155819eabfa87f276f973f40c12c92b703d7b7848ef8b4466d40823aad3943a312b57432b91ff68be10000000000000000000000000000000015ff9a232d9b5a8020a85d5fe08a1dcfb73ece434258fe0e2fddf10ddef0906c42dcb5f5d62fc97f934ba900f17beb330000000000000000000000000000000009cfe4ee2241d9413c616462d7bac035a6766aeaab69c81e094d75b840df45d7e0dfac0265608b93efefb9a8728b98e44c51f97bcdda93904ae26991b471e9ea942e2b5b8ed26055da11c58bc7b5002a0000000000000000000000000000000017a17b82e3bfadf3250210d8ef572c02c3610d65ab4d7366e0b748768a28ee6a1b51f77ed686a64f087f36f641e7dca900000000000000000000000000000000077ea73d233ccea51dc4d5acecf6d9332bf17ae51598f4b394a5f62fb387e9c9aa1d6823b64a074f5873422ca57545d38964d5867927bc3e35a0b4c457482373969bff5edff8a781d65573e07fd87b89000000000000000000000000000000000c1243478f4fbdc21ea9b241655947a28accd058d0cdb4f9f0576d32f09dddaf0850464550ff07cab5927b3e4c863ce90000000000000000000000000000000015fb54db10ffac0b6cd374eb7168a8cb3df0a7d5f872d8e98c1f623deb66df5dd08ff4c3658f2905ec8bd02598bd4f90787c38b944eadbd03fd3187f450571740f6cd00e5b2e560165846eb800e5c944000000000000000000000000000000000328f09584b6d6c98a709fc22e184123994613aca95a28ac53df8523b92273eb6f4e2d9b2a7dcebb474604d54a210719000000000000000000000000000000001220ebde579911fe2e707446aaad8d3789fae96ae2e23670a4fd856ed82daaab704779eb4224027c1ed9460f39951a1baaee7ae2a237e8e53560c79e7baa9adf9c00a0ea4d6f514e7a6832eb15cef1e10000000000000000000000000000000002ebfa98aa92c32a29ebe17fcb1819ba82e686abd9371fcee8ea793b4c72b6464085044f818f1f5902396df0122830cb00000000000000000000000000000000001184715b8432ed190b459113977289a890f68f6085ea111466af15103c9c02467da33e01d6bff87fd57db6ccba442adac6ed3ef45c1d7d3028f0f89e5458797996d3294b95bebe049b76c7d0db317c0000000000000000000000000000000009d6424e002439998e91cd509f85751ad25e574830c564e7568347d19e3f38add0cab067c0b4b0801785a78bcbeaf246000000000000000000000000000000000ef6d7db03ee654503b46ff0dbc3297536a422e963bda9871a8da8f4eeb98dedebd6071c4880b4636198f4c2375dc795bb30985756c3ca075114c92f231575d6befafe4084517f1166a47376867bd1080000000000000000000000000000000002d1cdb93191d1f9f0308c2c55d0208a071f5520faca7c52ab0311dbc9ba563bd33b5dd6baa77bf45ac2c3269e945f4800000000000000000000000000000000072a52106e6d7b92c594c4dacd20ef5fab7141e45c231457cd7e71463b2254ee6e72689e516fa6a8f29f2a173ce0a190fb730105809f64ea522983d6bbb62f7e2e8cbf702685e9be10e2ef71f81876720000000000000000000000000000000000641642f6801d39a09a536f506056f72a619c50d043673d6d39aa4af11d8e3ded38b9c3bbc970dbc1bd55d68f94b50d0000000000000000000000000000000009ab050de356a24aea90007c6b319614ba2f2ed67223b972767117769e3c8e31ee4056494628fb2892d3d37afb6ac943b6a9408625b0ca8fcbfb21d34eec2d8e24e9a30d2d3b32d7a37d110b13afbfea000000000000000000000000000000000fd4893addbd58fb1bf30b8e62bef068da386edbab9541d198e8719b2de5beb9223d87387af82e8b55bd521ff3e47e2d000000000000000000000000000000000f3a923b76473d5b5a53501790cb02597bb778bdacb3805a9002b152d22241ad131d0f0d6a260739cbab2c2fe602870e3b77283d0a7bb9e17a27e66851792fdd605cc0a339028b8985390fd024374c760000000000000000000000000000000002cb4b24c8aa799fd7cb1e4ab1aab1372113200343d8526ea7bc64dfaf926baf5d90756a40e35617854a2079cd07fba40000000000000000000000000000000003327ca22bd64ebd673cc6d5b02b2a8804d5353c9d251637c4273ad08d581cc0d58da9bea27c37a0b3f4961dbafd276bdd994eae929aee7428fdda2e44f8cb12b10b91c83b22abc8bbb561310b62257c00000000000000000000000000000000024ad70f2b2105ca37112858e84c6f5e3ffd4a8b064522faae1ecba38fabd52a6274cb46b00075deb87472f11f2e67d90000000000000000000000000000000010a502c8b2a68aa30d2cb719273550b9a3c283c35b2e18a01b0b765344ffaaa5cb30a1e3e6ecd3a53ab67658a57876817010b134989c8368c7f831f9dd9f9a890e2c1435681107414f2e8637153bbf6a0000000000000000000000000000000000704cc57c8e0944326ddc7c747d9e7347a7f6918977132eea269f161461eb64066f773352f293a3ac458dc3ccd5026a000000000000000000000000000000001099d3c2bb2d082f2fdcbed013f7ac69e8624f4fcf6dfab3ee9dcf7fbbdb8c49ee79de40e887c0b6828d2496e3a6f76894c68bc8d91ac8c489ee87dbfc4b94c93c8bbd5fc04c27db8b02303f3a65905400000000000000000000000000000000130535a29392c77f045ac90e47f2e7b3cffff94494fe605aad345b41043f6663ada8e2e7ecd3d06f3b8854ef92212f42000000000000000000000000000000001699a3cc1f10cd2ed0dc68eb916b4402e4f12bf4746893bf70e26e209e605ea89e3d53e7ac52bd07713d3c8fc671931db3682accc3939283b870357cf83683350baf73aa0d3d68bda82a0f6ae7e51746,,,invalid input parameters, Point is not on curve -0000000000000000000000000000000012196c5a43d69224d8713389285f26b98f86ee910ab3dd668e413738282003cc5b7357af9a7af54bb713d62255e80f560000000000000000000000000000000006ba8102bfbeea4416b710c73e8cce3032c31c6269c44906f8ac4f7874ce99fb17559992486528963884ce429a992feeb3c940fe79b6966489b527955de7599194a9ac69a6ff58b8d99e7b1084f0464e00000000000000000000000000000000117dbe419018f67844f6a5e1b78a1e597283ad7b8ee7ac5e58846f5a5fd68d0da99ce235a91db3ec1cf340fe6b7afcdb0000000000000000000000000000000013316f23de032d25e912ae8dc9b54c8dba1be7cecdbb9d2228d7e8f652011d46be79089dd0a6080a73c82256ce5e4ed24d0e25bf3f6fc9f4da25d21fdc71773f1947b7a8a775b8177f7eca990b05b71d0000000000000000000000000000000008ab7b556c672db7883ec47efa6d98bb08cec7902ebb421aac1c31506b177ac444ffa2d9b400a6f1cbdc6240c607ee110000000000000000000000000000000016b7fa9adf4addc2192271ce7ad3c8d8f902d061c43b7d2e8e26922009b777855bffabe7ed1a09155819eabfa87f276f973f40c12c92b703d7b7848ef8b4466d40823aad3943a312b57432b91ff68be10000000000000000000000000000000015ff9a232d9b5a8020a85d5fe08a1dcfb73ece434258fe0e2fddf10ddef0906c42dcb5f5d62fc97f934ba900f17beb330000000000000000000000000000000009cfe4ee2241d9413c616462d7bac035a6766aeaab69c81e094d75b840df45d7e0dfac0265608b93efefb9a8728b98e44c51f97bcdda93904ae26991b471e9ea942e2b5b8ed26055da11c58bc7b5002a0000000000000000000000000000000017a17b82e3bfadf3250210d8ef572c02c3610d65ab4d7366e0b748768a28ee6a1b51f77ed686a64f087f36f641e7dca900000000000000000000000000000000077ea73d233ccea51dc4d5acecf6d9332bf17ae51598f4b394a5f62fb387e9c9aa1d6823b64a074f5873422ca57545d38964d5867927bc3e35a0b4c457482373969bff5edff8a781d65573e07fd87b89000000000000000000000000000000000c1243478f4fbdc21ea9b241655947a28accd058d0cdb4f9f0576d32f09dddaf0850464550ff07cab5927b3e4c863ce90000000000000000000000000000000015fb54db10ffac0b6cd374eb7168a8cb3df0a7d5f872d8e98c1f623deb66df5dd08ff4c3658f2905ec8bd02598bd4f90787c38b944eadbd03fd3187f450571740f6cd00e5b2e560165846eb800e5c944000000000000000000000000000000000328f09584b6d6c98a709fc22e184123994613aca95a28ac53df8523b92273eb6f4e2d9b2a7dcebb474604d54a210719000000000000000000000000000000001220ebde579911fe2e707446aaad8d3789fae96ae2e23670a4fd856ed82daaab704779eb4224027c1ed9460f39951a1baaee7ae2a237e8e53560c79e7baa9adf9c00a0ea4d6f514e7a6832eb15cef1e10000000000000000000000000000000002ebfa98aa92c32a29ebe17fcb1819ba82e686abd9371fcee8ea793b4c72b6464085044f818f1f5902396df0122830cb00000000000000000000000000000000001184715b8432ed190b459113977289a890f68f6085ea111466af15103c9c02467da33e01d6bff87fd57db6ccba442adac6ed3ef45c1d7d3028f0f89e5458797996d3294b95bebe049b76c7d0db317c0000000000000000000000000000000009d6424e002439998e91cd509f85751ad25e574830c564e7568347d19e3f38add0cab067c0b4b0801785a78bcbeaf246000000000000000000000000000000000ef6d7db03ee654503b46ff0dbc3297536a422e963bda9871a8da8f4eeb98dedebd6071c4880b4636198f4c2375dc795bb30985756c3ca075114c92f231575d6befafe4084517f1166a47376867bd1080000000000000000000000000000000002d1cdb93191d1f9f0308c2c55d0208a071f5520faca7c52ab0311dbc9ba563bd33b5dd6baa77bf45ac2c3269e945f4800000000000000000000000000000000072a52106e6d7b92c594c4dacd20ef5fab7141e45c231457cd7e71463b2254ee6e72689e516fa6a8f29f2a173ce0a190fb730105809f64ea522983d6bbb62f7e2e8cbf702685e9be10e2ef71f81876720000000000000000000000000000000000641642f6801d39a09a536f506056f72a619c50d043673d6d39aa4af11d8e3ded38b9c3bbc970dbc1bd55d68f94b50d0000000000000000000000000000000009ab050de356a24aea90007c6b319614ba2f2ed67223b972767117769e3c8e31ee4056494628fb2892d3d37afb6ac943b6a9408625b0ca8fcbfb21d34eec2d8e24e9a30d2d3b32d7a37d110b13afbfea000000000000000000000000000000000fd4893addbd58fb1bf30b8e62bef068da386edbab9541d198e8719b2de5beb9223d87387af82e8b55bd521ff3e47e2d000000000000000000000000000000000f3a923b76473d5b5a53501790cb02597bb778bdacb3805a9002b152d22241ad131d0f0d6a260739cbab2c2fe602870e3b77283d0a7bb9e17a27e66851792fdd605cc0a339028b8985390fd024374c760000000000000000000000000000000002cb4b24c8aa799fd7cb1e4ab1aab1372113200343d8526ea7bc64dfaf926baf5d90756a40e35617854a2079cd07fba40000000000000000000000000000000003327ca22bd64ebd673cc6d5b02b2a8804d5353c9d251637c4273ad08d581cc0d58da9bea27c37a0b3f4961dbafd276bdd994eae929aee7428fdda2e44f8cb12b10b91c83b22abc8bbb561310b62257c00000000000000000000000000000000024ad70f2b2105ca37112858e84c6f5e3ffd4a8b064522faae1ecba38fabd52a6274cb46b00075deb87472f11f2e67d90000000000000000000000000000000010a502c8b2a68aa30d2cb719273550b9a3c283c35b2e18a01b0b765344ffaaa5cb30a1e3e6ecd3a53ab67658a57876817010b134989c8368c7f831f9dd9f9a890e2c1435681107414f2e8637153bbf6a0000000000000000000000000000000000704cc57c8e0944326ddc7c747d9e7347a7f6918977132eea269f161461eb64066f773352f293a3ac458dc3ccd5026a000000000000000000000000000000001099d3c2bb2d082f2fdcbed013f7ac69e8624f4fcf6dfab3ee9dcf7fbbdb8c49ee79de40e887c0b6828d2496e3a6f76894c68bc8d91ac8c489ee87dbfc4b94c93c8bbd5fc04c27db8b02303f3a65905400000000000000000000000000000000130535a29392c77f045ac90e47f2e7b3cffff94494fe605aad345b41043f6663ada8e2e7ecd3d06f3b8854ef92212f43000000000000000000000000000000001699a3cc1f10cd2ed0dc68eb916b4402e4f12bf4746893bf70e26e209e605ea89e3d53e7ac52bd07713d3c8fc671931db3682accc3939283b870357cf83683350baf73aa0d3d68bda82a0f6ae7e51746,,,invalid input parameters, Point is not on curve +,,,invalid input parameters, invalid number of pairs +0000000000000000000000000000000012196c5a43d69224d8713389285f26b98f86ee910ab3dd668e413738282003cc5b7357af9a7af54bb713d62255e80f570000000000000000000000000000000006ba8102bfbeea4416b710c73e8cce3032c31c6269c44906f8ac4f7874ce99fb17559992486528963884ce429a992feeb3c940fe79b6966489b527955de7599194a9ac69a6ff58b8d99e7b1084f0464e00000000000000000000000000000000117dbe419018f67844f6a5e1b78a1e597283ad7b8ee7ac5e58846f5a5fd68d0da99ce235a91db3ec1cf340fe6b7afcdb0000000000000000000000000000000013316f23de032d25e912ae8dc9b54c8dba1be7cecdbb9d2228d7e8f652011d46be79089dd0a6080a73c82256ce5e4ed24d0e25bf3f6fc9f4da25d21fdc71773f1947b7a8a775b8177f7eca990b05b71d0000000000000000000000000000000008ab7b556c672db7883ec47efa6d98bb08cec7902ebb421aac1c31506b177ac444ffa2d9b400a6f1cbdc6240c607ee110000000000000000000000000000000016b7fa9adf4addc2192271ce7ad3c8d8f902d061c43b7d2e8e26922009b777855bffabe7ed1a09155819eabfa87f276f973f40c12c92b703d7b7848ef8b4466d40823aad3943a312b57432b91ff68be10000000000000000000000000000000015ff9a232d9b5a8020a85d5fe08a1dcfb73ece434258fe0e2fddf10ddef0906c42dcb5f5d62fc97f934ba900f17beb330000000000000000000000000000000009cfe4ee2241d9413c616462d7bac035a6766aeaab69c81e094d75b840df45d7e0dfac0265608b93efefb9a8728b98e44c51f97bcdda93904ae26991b471e9ea942e2b5b8ed26055da11c58bc7b5002a0000000000000000000000000000000017a17b82e3bfadf3250210d8ef572c02c3610d65ab4d7366e0b748768a28ee6a1b51f77ed686a64f087f36f641e7dca900000000000000000000000000000000077ea73d233ccea51dc4d5acecf6d9332bf17ae51598f4b394a5f62fb387e9c9aa1d6823b64a074f5873422ca57545d38964d5867927bc3e35a0b4c457482373969bff5edff8a781d65573e07fd87b89000000000000000000000000000000000c1243478f4fbdc21ea9b241655947a28accd058d0cdb4f9f0576d32f09dddaf0850464550ff07cab5927b3e4c863ce90000000000000000000000000000000015fb54db10ffac0b6cd374eb7168a8cb3df0a7d5f872d8e98c1f623deb66df5dd08ff4c3658f2905ec8bd02598bd4f90787c38b944eadbd03fd3187f450571740f6cd00e5b2e560165846eb800e5c944000000000000000000000000000000000328f09584b6d6c98a709fc22e184123994613aca95a28ac53df8523b92273eb6f4e2d9b2a7dcebb474604d54a210719000000000000000000000000000000001220ebde579911fe2e707446aaad8d3789fae96ae2e23670a4fd856ed82daaab704779eb4224027c1ed9460f39951a1baaee7ae2a237e8e53560c79e7baa9adf9c00a0ea4d6f514e7a6832eb15cef1e10000000000000000000000000000000002ebfa98aa92c32a29ebe17fcb1819ba82e686abd9371fcee8ea793b4c72b6464085044f818f1f5902396df0122830cb00000000000000000000000000000000001184715b8432ed190b459113977289a890f68f6085ea111466af15103c9c02467da33e01d6bff87fd57db6ccba442adac6ed3ef45c1d7d3028f0f89e5458797996d3294b95bebe049b76c7d0db317c0000000000000000000000000000000009d6424e002439998e91cd509f85751ad25e574830c564e7568347d19e3f38add0cab067c0b4b0801785a78bcbeaf246000000000000000000000000000000000ef6d7db03ee654503b46ff0dbc3297536a422e963bda9871a8da8f4eeb98dedebd6071c4880b4636198f4c2375dc795bb30985756c3ca075114c92f231575d6befafe4084517f1166a47376867bd1080000000000000000000000000000000002d1cdb93191d1f9f0308c2c55d0208a071f5520faca7c52ab0311dbc9ba563bd33b5dd6baa77bf45ac2c3269e945f4800000000000000000000000000000000072a52106e6d7b92c594c4dacd20ef5fab7141e45c231457cd7e71463b2254ee6e72689e516fa6a8f29f2a173ce0a190fb730105809f64ea522983d6bbb62f7e2e8cbf702685e9be10e2ef71f81876720000000000000000000000000000000000641642f6801d39a09a536f506056f72a619c50d043673d6d39aa4af11d8e3ded38b9c3bbc970dbc1bd55d68f94b50d0000000000000000000000000000000009ab050de356a24aea90007c6b319614ba2f2ed67223b972767117769e3c8e31ee4056494628fb2892d3d37afb6ac943b6a9408625b0ca8fcbfb21d34eec2d8e24e9a30d2d3b32d7a37d110b13afbfea000000000000000000000000000000000fd4893addbd58fb1bf30b8e62bef068da386edbab9541d198e8719b2de5beb9223d87387af82e8b55bd521ff3e47e2d000000000000000000000000000000000f3a923b76473d5b5a53501790cb02597bb778bdacb3805a9002b152d22241ad131d0f0d6a260739cbab2c2fe602870e3b77283d0a7bb9e17a27e66851792fdd605cc0a339028b8985390fd024374c760000000000000000000000000000000002cb4b24c8aa799fd7cb1e4ab1aab1372113200343d8526ea7bc64dfaf926baf5d90756a40e35617854a2079cd07fba40000000000000000000000000000000003327ca22bd64ebd673cc6d5b02b2a8804d5353c9d251637c4273ad08d581cc0d58da9bea27c37a0b3f4961dbafd276bdd994eae929aee7428fdda2e44f8cb12b10b91c83b22abc8bbb561310b62257c00000000000000000000000000000000024ad70f2b2105ca37112858e84c6f5e3ffd4a8b064522faae1ecba38fabd52a6274cb46b00075deb87472f11f2e67d90000000000000000000000000000000010a502c8b2a68aa30d2cb719273550b9a3c283c35b2e18a01b0b765344ffaaa5cb30a1e3e6ecd3a53ab67658a57876817010b134989c8368c7f831f9dd9f9a890e2c1435681107414f2e8637153bbf6a0000000000000000000000000000000000704cc57c8e0944326ddc7c747d9e7347a7f6918977132eea269f161461eb64066f773352f293a3ac458dc3ccd5026a000000000000000000000000000000001099d3c2bb2d082f2fdcbed013f7ac69e8624f4fcf6dfab3ee9dcf7fbbdb8c49ee79de40e887c0b6828d2496e3a6f76894c68bc8d91ac8c489ee87dbfc4b94c93c8bbd5fc04c27db8b02303f3a65905400000000000000000000000000000000130535a29392c77f045ac90e47f2e7b3cffff94494fe605aad345b41043f6663ada8e2e7ecd3d06f3b8854ef92212f42000000000000000000000000000000001699a3cc1f10cd2ed0dc68eb916b4402e4f12bf4746893bf70e26e209e605ea89e3d53e7ac52bd07713d3c8fc671931db3682accc3939283b870357cf83683350baf73aa0d3d68bda82a0f6ae7e51746,,,invalid point: point is not on curve +0000000000000000000000000000000012196c5a43d69224d8713389285f26b98f86ee910ab3dd668e413738282003cc5b7357af9a7af54bb713d62255e80f560000000000000000000000000000000006ba8102bfbeea4416b710c73e8cce3032c31c6269c44906f8ac4f7874ce99fb17559992486528963884ce429a992feeb3c940fe79b6966489b527955de7599194a9ac69a6ff58b8d99e7b1084f0464e00000000000000000000000000000000117dbe419018f67844f6a5e1b78a1e597283ad7b8ee7ac5e58846f5a5fd68d0da99ce235a91db3ec1cf340fe6b7afcdb0000000000000000000000000000000013316f23de032d25e912ae8dc9b54c8dba1be7cecdbb9d2228d7e8f652011d46be79089dd0a6080a73c82256ce5e4ed24d0e25bf3f6fc9f4da25d21fdc71773f1947b7a8a775b8177f7eca990b05b71d0000000000000000000000000000000008ab7b556c672db7883ec47efa6d98bb08cec7902ebb421aac1c31506b177ac444ffa2d9b400a6f1cbdc6240c607ee110000000000000000000000000000000016b7fa9adf4addc2192271ce7ad3c8d8f902d061c43b7d2e8e26922009b777855bffabe7ed1a09155819eabfa87f276f973f40c12c92b703d7b7848ef8b4466d40823aad3943a312b57432b91ff68be10000000000000000000000000000000015ff9a232d9b5a8020a85d5fe08a1dcfb73ece434258fe0e2fddf10ddef0906c42dcb5f5d62fc97f934ba900f17beb330000000000000000000000000000000009cfe4ee2241d9413c616462d7bac035a6766aeaab69c81e094d75b840df45d7e0dfac0265608b93efefb9a8728b98e44c51f97bcdda93904ae26991b471e9ea942e2b5b8ed26055da11c58bc7b5002a0000000000000000000000000000000017a17b82e3bfadf3250210d8ef572c02c3610d65ab4d7366e0b748768a28ee6a1b51f77ed686a64f087f36f641e7dca900000000000000000000000000000000077ea73d233ccea51dc4d5acecf6d9332bf17ae51598f4b394a5f62fb387e9c9aa1d6823b64a074f5873422ca57545d38964d5867927bc3e35a0b4c457482373969bff5edff8a781d65573e07fd87b89000000000000000000000000000000000c1243478f4fbdc21ea9b241655947a28accd058d0cdb4f9f0576d32f09dddaf0850464550ff07cab5927b3e4c863ce90000000000000000000000000000000015fb54db10ffac0b6cd374eb7168a8cb3df0a7d5f872d8e98c1f623deb66df5dd08ff4c3658f2905ec8bd02598bd4f90787c38b944eadbd03fd3187f450571740f6cd00e5b2e560165846eb800e5c944000000000000000000000000000000000328f09584b6d6c98a709fc22e184123994613aca95a28ac53df8523b92273eb6f4e2d9b2a7dcebb474604d54a210719000000000000000000000000000000001220ebde579911fe2e707446aaad8d3789fae96ae2e23670a4fd856ed82daaab704779eb4224027c1ed9460f39951a1baaee7ae2a237e8e53560c79e7baa9adf9c00a0ea4d6f514e7a6832eb15cef1e10000000000000000000000000000000002ebfa98aa92c32a29ebe17fcb1819ba82e686abd9371fcee8ea793b4c72b6464085044f818f1f5902396df0122830cb00000000000000000000000000000000001184715b8432ed190b459113977289a890f68f6085ea111466af15103c9c02467da33e01d6bff87fd57db6ccba442adac6ed3ef45c1d7d3028f0f89e5458797996d3294b95bebe049b76c7d0db317c0000000000000000000000000000000009d6424e002439998e91cd509f85751ad25e574830c564e7568347d19e3f38add0cab067c0b4b0801785a78bcbeaf246000000000000000000000000000000000ef6d7db03ee654503b46ff0dbc3297536a422e963bda9871a8da8f4eeb98dedebd6071c4880b4636198f4c2375dc795bb30985756c3ca075114c92f231575d6befafe4084517f1166a47376867bd1080000000000000000000000000000000002d1cdb93191d1f9f0308c2c55d0208a071f5520faca7c52ab0311dbc9ba563bd33b5dd6baa77bf45ac2c3269e945f4800000000000000000000000000000000072a52106e6d7b92c594c4dacd20ef5fab7141e45c231457cd7e71463b2254ee6e72689e516fa6a8f29f2a173ce0a190fb730105809f64ea522983d6bbb62f7e2e8cbf702685e9be10e2ef71f81876720000000000000000000000000000000000641642f6801d39a09a536f506056f72a619c50d043673d6d39aa4af11d8e3ded38b9c3bbc970dbc1bd55d68f94b50d0000000000000000000000000000000009ab050de356a24aea90007c6b319614ba2f2ed67223b972767117769e3c8e31ee4056494628fb2892d3d37afb6ac943b6a9408625b0ca8fcbfb21d34eec2d8e24e9a30d2d3b32d7a37d110b13afbfea000000000000000000000000000000000fd4893addbd58fb1bf30b8e62bef068da386edbab9541d198e8719b2de5beb9223d87387af82e8b55bd521ff3e47e2d000000000000000000000000000000000f3a923b76473d5b5a53501790cb02597bb778bdacb3805a9002b152d22241ad131d0f0d6a260739cbab2c2fe602870e3b77283d0a7bb9e17a27e66851792fdd605cc0a339028b8985390fd024374c760000000000000000000000000000000002cb4b24c8aa799fd7cb1e4ab1aab1372113200343d8526ea7bc64dfaf926baf5d90756a40e35617854a2079cd07fba40000000000000000000000000000000003327ca22bd64ebd673cc6d5b02b2a8804d5353c9d251637c4273ad08d581cc0d58da9bea27c37a0b3f4961dbafd276bdd994eae929aee7428fdda2e44f8cb12b10b91c83b22abc8bbb561310b62257c00000000000000000000000000000000024ad70f2b2105ca37112858e84c6f5e3ffd4a8b064522faae1ecba38fabd52a6274cb46b00075deb87472f11f2e67d90000000000000000000000000000000010a502c8b2a68aa30d2cb719273550b9a3c283c35b2e18a01b0b765344ffaaa5cb30a1e3e6ecd3a53ab67658a57876817010b134989c8368c7f831f9dd9f9a890e2c1435681107414f2e8637153bbf6a0000000000000000000000000000000000704cc57c8e0944326ddc7c747d9e7347a7f6918977132eea269f161461eb64066f773352f293a3ac458dc3ccd5026a000000000000000000000000000000001099d3c2bb2d082f2fdcbed013f7ac69e8624f4fcf6dfab3ee9dcf7fbbdb8c49ee79de40e887c0b6828d2496e3a6f76894c68bc8d91ac8c489ee87dbfc4b94c93c8bbd5fc04c27db8b02303f3a65905400000000000000000000000000000000130535a29392c77f045ac90e47f2e7b3cffff94494fe605aad345b41043f6663ada8e2e7ecd3d06f3b8854ef92212f43000000000000000000000000000000001699a3cc1f10cd2ed0dc68eb916b4402e4f12bf4746893bf70e26e209e605ea89e3d53e7ac52bd07713d3c8fc671931db3682accc3939283b870357cf83683350baf73aa0d3d68bda82a0f6ae7e51746,,,invalid point: point is not on curve 00000000000000000000000000000000075321084f4251d524581318d27b73a8de0b156f502d8f410b3b4529435bf9a14f609da9f63ac8f338fbbdf65ebf270e000000000000000000000000000000001925396f4b5c00ac49765e17c601bd392a8a96d8d5a65e2693093e6d5699610ad699d04e083f8b248c808619d01c33bce9478f1e5d80ad0ed31dc0bd5234bc41957cb74b63ce59654181c13344a5a3ae00000000000000000000000000000000153753f25d38c68a3b92a486bb896a1b6ca9d4b81620a7a0040386838be7187e8ca73987bb260ee099793009b5cce1f500000000000000000000000000000000063f22c3bedc7ca5ce16db22f44a68a8fa529b2c6aab59c97e4b2353ed1b81da0586dbc0fa49605402da10c5ff7cad7d7d0832bc939e73d01bbb419c98abf35cfd0224f72f6d215de379bad89aedfd65000000000000000000000000000000000d3423a536fe9de27b8da74c6f82fa3fae76945d0c8e50b8de889aa0d533ed1d5b757e918d0eca5b6a8a3b34f9f1de1a000000000000000000000000000000000ae42b8bac10e922cb19169f5d91d50c249e3d81dce761cffb7cd652bde04ca17dcd0ad185fa03b722079b69ad4f4cbc3c2130dfc2b39a0e20abc3f883b4e329496dbb8bc79ea7f30c909140c4b3cd0a000000000000000000000000000000000fdb0c5e83ecf0344a69900d1a59a21bd32f4210bbb0194be6355d18433a5449a81fd2c195e353d844070ed47c88bb500000000000000000000000000000000004c27bb460768252e5d07a952ab5d204e479ff74489933ba64f80ea18799fb937dd6956112872024795eba15f48e60073590f744e04374b92ddc43d0ca3068973b5b48c48a70939fd7d047ede75fb8430000000000000000000000000000000017ff6f3ca925d18ab2afe8c39ac69975769fe0fb6980c3c1c4c678deb01ec4b6e1f5b212a1fd5983e06a372be394c52e00000000000000000000000000000000131e1351e7a7f5fcfb87dffe794934356b36ba49c7d35b99281577ac078c990576a4db6d2be8a45c562a8fc1ec0620e37fd535426244e27c586fe8e87eaae37dfd851601e0a2b001d86f094a63c234f5000000000000000000000000000000000ee908a40185717063897efe710f3f1e929dcd53db503c5e3f0d08bf0c0edf2d68a5958fefd6c0099e9c755dc9407e78000000000000000000000000000000000aa3806ad71189cc119e6d88284d476033386ea4be2f7885d5587e0d991ad88590de58c782ca0bebade6b4b111f3c4ed54e3b4eb4126abb9629e0e5144fdf73716c8654ac8ce827a18f432b5f340e53400000000000000000000000000000000153753f25d38c68a3b92a486bb896a1b6ca9d4b81620a7a0040386838be7187e8ca73987bb260ee099793009b5cce1f500000000000000000000000000000000063f22c3bedc7ca5ce16db22f44a68a8fa529b2c6aab59c97e4b2353ed1b81da0586dbc0fa49605402da10c5ff7cad7d9c5fb237ac8e79e271008eab06ddc9ab45ebaba255fae6912577d0cf1428545f00000000000000000000000000000000153753f25d38c68a3b92a486bb896a1b6ca9d4b81620a7a0040386838be7187e8ca73987bb260ee099793009b5cce1f500000000000000000000000000000000063f22c3bedc7ca5ce16db22f44a68a8fa529b2c6aab59c97e4b2353ed1b81da0586dbc0fa49605402da10c5ff7cad7d0fcca884c7c01ba517c241e44478b35196d441ab3a76b7f023e08100b45d77ff00000000000000000000000000000000153753f25d38c68a3b92a486bb896a1b6ca9d4b81620a7a0040386838be7187e8ca73987bb260ee099793009b5cce1f500000000000000000000000000000000063f22c3bedc7ca5ce16db22f44a68a8fa529b2c6aab59c97e4b2353ed1b81da0586dbc0fa49605402da10c5ff7cad7dd7f494e1b8378362ed31b0287c1b5f6912a677abc0fc392234818d4242e0239e00000000000000000000000000000000153753f25d38c68a3b92a486bb896a1b6ca9d4b81620a7a0040386838be7187e8ca73987bb260ee099793009b5cce1f500000000000000000000000000000000063f22c3bedc7ca5ce16db22f44a68a8fa529b2c6aab59c97e4b2353ed1b81da0586dbc0fa49605402da10c5ff7cad7dba8eae358d75a3dbff9e62624ef6b1c641a1fc6a31c662f13a39d2fab938b519000000000000000000000000000000000f299ebde6e6c7b4d403b10b04832dfbf65b8ef9bcfebfa5352ee3df4f18e43798a0633845822a44a4fc7ec2ba1d13770000000000000000000000000000000003c886084611cb8c95fdb4473bc00d4877dd3ca10ba40765110400c1200d0b1f4cb9b1433e26d358f78d93da63ede6eea44e84f65a823eda9c7903fd4178c9e734996be8f291949341ff2e3b09ce7605000000000000000000000000000000001812e8d91771d93bef2f087058dd26f0c1ae487de050dcab1510e6ec444473f6815d8dd9565c18e777cfce1c836a4a0b00000000000000000000000000000000041fac4c713ba9727b0d5d539ecd45524285a2c179e7620dab88bad649f1b9b40dd422ab2d40c4945bc27dcb6e0a7a96129a1ee5c960052ac3051e4e663ff4f3c83b039dac18f25d4412a07dd9b164f900000000000000000000000000000000153753f25d38c68a3b92a486bb896a1b6ca9d4b81620a7a0040386838be7187e8ca73987bb260ee099793009b5cce1f500000000000000000000000000000000063f22c3bedc7ca5ce16db22f44a68a8fa529b2c6aab59c97e4b2353ed1b81da0586dbc0fa49605402da10c5ff7cad7d5ec8616e3f6fab8a437053de12816f4ca18c1b4d42131c4800904f0c551d8d3a00000000000000000000000000000000153753f25d38c68a3b92a486bb896a1b6ca9d4b81620a7a0040386838be7187e8ca73987bb260ee099793009b5cce1f500000000000000000000000000000000063f22c3bedc7ca5ce16db22f44a68a8fa529b2c6aab59c97e4b2353ed1b81da0586dbc0fa49605402da10c5ff7cad7d0dc25e17fb0ea75c07be8123108c626000191fb5106f3e1921401acb96dcd710000000000000000000000000000000000f59f9d995d77fa65c22d5d84f277f3ccba50eabb8c404f1f9d70a39cd289b37978bfaceea2b987712507d88fae2a8f3000000000000000000000000000000000a4d6759c576fd8f54a8182a8d1191e5c010e38e33c013603b480cece6dec5cd6892972be8ee1c13500c8a601eee5dd352c4962db75fb059c2fe525270edbe9374add7df7b53f79977c9e51fa5e8952b00000000000000000000000000000000153753f25d38c68a3b92a486bb896a1b6ca9d4b81620a7a0040386838be7187e8ca73987bb260ee099793009b5cce1f500000000000000000000000000000000063f22c3bedc7ca5ce16db22f44a68a8fa529b2c6aab59c97e4b2353ed1b81da0586dbc0fa49605402da10c5ff7cad7d7cbed522a1daafa00bc82138e08f1318b629d6409bade3d0dbd1431dfa6d60f4000000000000000000000000000000000809adeabe91b3d8173fcfb1ccb80dfb5a5ce48160d915652ff193e6c79eca0b6d9bdcc484a37723db4fcd3c4463ea9f00000000000000000000000000000000130e0fe4001d5995012202bbfa42584ed476ee0decb95122a9ed61364059d5021f8ef232df6276f93ac38cce8d70ffba145ab6abb85976ae17d459441500228e246aa214cd015460aaef6d8e5e02373200000000000000000000000000000000083908343f7329e4e738aa6de69b4f1e275d41243cfb30a6b9e00f032c0459fd005c43efe5a358ef6c0118b1528f3848000000000000000000000000000000000d39c55cf915d530de551ba3bf9aa147fa24f83d51656aeb63866c38b4f206079ac4f89c7f91ae3c37de09d37713f75dd98cf9f26a404e252383a4402c17de293857da5b7b8fabd9f4c59e5bcef4c0eb00000000000000000000000000000000153753f25d38c68a3b92a486bb896a1b6ca9d4b81620a7a0040386838be7187e8ca73987bb260ee099793009b5cce1f500000000000000000000000000000000063f22c3bedc7ca5ce16db22f44a68a8fa529b2c6aab59c97e4b2353ed1b81da0586dbc0fa49605402da10c5ff7cad7d5a526d3ecc90ba9a2fe62b0673397d4af02440f44551a333fdbca4e2ea6ac0d300000000000000000000000000000000153753f25d38c68a3b92a486bb896a1b6ca9d4b81620a7a0040386838be7187e8ca73987bb260ee099793009b5cce1f500000000000000000000000000000000063f22c3bedc7ca5ce16db22f44a68a8fa529b2c6aab59c97e4b2353ed1b81da0586dbc0fa49605402da10c5ff7cad7de9f0448dd229d025e58f7afb4912ac9878029b29002fb92d4259f815a32916400000000000000000000000000000000005bab5aaedd0f007d0c3e29870e29c93d34f43c26ad57281c03bf273a5e3264fb898059addba45c54a7fbfcecf83e95600000000000000000000000000000000150fb89103ccbd4976372929d3069a0cff886103b8e942e9911f12fd3809003dd5b1aead983c0a3f705b327c73a7aace8e0fc676aeb9d7bb302be47a4efc9e5a6217eb557d6c0d8f37ebe15cd80c170b00000000000000000000000000000000153753f25d38c68a3b92a486bb896a1b6ca9d4b81620a7a0040386838be7187e8ca73987bb260ee099793009b5cce1f500000000000000000000000000000000063f22c3bedc7ca5ce16db22f44a68a8fa529b2c6aab59c97e4b2353ed1b81da0586dbc0fa49605402da10c5ff7cad7d66539fea2e9ea8285538029a644c759190f21bab23f0e98effbe59b6b4af2c5100000000000000000000000000000000153753f25d38c68a3b92a486bb896a1b6ca9d4b81620a7a0040386838be7187e8ca73987bb260ee099793009b5cce1f500000000000000000000000000000000063f22c3bedc7ca5ce16db22f44a68a8fa529b2c6aab59c97e4b2353ed1b81da0586dbc0fa49605402da10c5ff7cad7dd6683f094390667fff0a92fef389fd9ef0a77280f90f41660bbeda517219e3ef000000000000000000000000000000000a7c61050509b59909bf23a56952fded8adfa4acd2f58b5bbbc0253872dd4d542d27ee23a511de762f21f81c5593ba75000000000000000000000000000000001264e5a654cb3d9ec931f9db10cdd851360958c360e53eea634d6eae8d9922e04e7f87b4cfe99932feff5b3926f6e1efafcce5a813bc622c601c3b4cb300cd413b8b0564793556adf1189e42722ff810000000000000000000000000000000000fa6770b293f6b74109947469ac2becdd55879467c8cbbcd0451805c3202e0b6978e43c421ae07cffba10dc37cafdb3f00000000000000000000000000000000060dfe71eac6b8772bcaa2520d343d56754a7e10368637a506decee4ad549ec43d8c4966b436e0bd2c1e270fc466d3a63ee43425efb56b18114a8fc59a63da39e30b7610d02ec5075cc391db59b875e600000000000000000000000000000000000f6e95654c7f61ba0dd368000312c5ba02feb2074c84bb7790daafb3b6c2a3aab5620d43fe3818d7ad92905992b644000000000000000000000000000000000afe6028eb4c49a8bc331ef714f1e0677d7623e3e36b4b3c451e7253ea6ebe065749e6f2e2bf03718ccb067411e2c7fefc3649d0fd8f7fbdd48ab6f6fd11d5fc593426464c32f09f3515948519d99d7300000000000000000000000000000000153753f25d38c68a3b92a486bb896a1b6ca9d4b81620a7a0040386838be7187e8ca73987bb260ee099793009b5cce1f500000000000000000000000000000000063f22c3bedc7ca5ce16db22f44a68a8fa529b2c6aab59c97e4b2353ed1b81da0586dbc0fa49605402da10c5ff7cad7dd824e57eb10a192bacde897180beb87c5559e6df2512be8df9cf043ad24b1e8c00000000000000000000000000000000119ca5f3fde1801e2cef526cd4e06b1230bb4b7dbeb43d34ba059d9bc394e95fc94d9be60ea972375d66b31c4f0482140000000000000000000000000000000007f10bfcb3ced451329af6fde9e153845fca20c6f5abb30a8ae2543880baf3efe6b31b3e7001700332bfc3e1616738b7a8a514daaaf533057c54b86200a1f8d5cbdacf8e3c2d9eaa921250b6387f45a100000000000000000000000000000000180ea28fad486a20615b934640aa883e70ee60c47c6148796691c58c64d03cb80b3802256756ef9217473837bd7bccc0000000000000000000000000000000000977ddcea657c79715e6d4ae801ab6e63a7c2688c0852e229b503dc951bc9611f36a858450614204ec44472914435643604cad22d4e29aab314523cdc14b691e509f260423d28e6f176eee3b659a164100000000000000000000000000000000195c0894c937d13b865ebbd935e4c609eafd492d57115df5f14df86b3381f7f9a111a2122d79d80980ad201c138464f5000000000000000000000000000000000471746c7c57fa94c23cd5978db9c638cca6617d27c445cda89f8298c4cb998317b8bca49f4de36e1e0ce24947021dbf7b1893649115755749a9f858ffd8484d7dbcb04bd2a3ff91a3fba86fb44ab69c00000000000000000000000000000000153753f25d38c68a3b92a486bb896a1b6ca9d4b81620a7a0040386838be7187e8ca73987bb260ee099793009b5cce1f500000000000000000000000000000000063f22c3bedc7ca5ce16db22f44a68a8fa529b2c6aab59c97e4b2353ed1b81da0586dbc0fa49605402da10c5ff7cad7db7930da64294e5949772522fa980479cd419f5014412f53a082e2b35f537ac0800000000000000000000000000000000153753f25d38c68a3b92a486bb896a1b6ca9d4b81620a7a0040386838be7187e8ca73987bb260ee099793009b5cce1f500000000000000000000000000000000063f22c3bedc7ca5ce16db22f44a68a8fa529b2c6aab59c97e4b2353ed1b81da0586dbc0fa49605402da10c5ff7cad7d61abf3d5e8d8df951747925b485dfd8cbdbba2fac2ef5f72a6311f79e89d406e00000000000000000000000000000000056f92baa9ef5e1e434fb70193f924706489968123ed61b8c9938c695852ef681709553c56d979f0925bdf1a8390a8d6000000000000000000000000000000000841faa9c8e27b1e94f2a5c14988806d62d7f35de74ba9a7db0062dd444a19b1a893ef6ee2d1ebefe3631d0ee0fcbca35be3179cb22c10450325b3609d9c3366c5200c1936280b3df162c48a213dce68000000000000000000000000000000000a2398e644fb52d53f02a583e67b11e5c7ac5b8e18e96498b9bbe572c3afd4dba8cd978db48501f5cc525e6c13ce92000000000000000000000000000000000017122a21cc3b7551a787fe260c1ed80ea34bec22d3ebb67b86dd0f2f95f50db7f577732c0d0e020e1ebb4295ba9a9d2a17ca658cbd9f48739b0076f97e4b943276f558760ac051f5c67159ad83bc94410000000000000000000000000000000018b172391adc5b6c44edc54c2bd874a01554be69d848b317fe845e62282d82440ad48c4bb645553bc75a701929aa9de0000000000000000000000000000000000753f19cae676565e45b13141d12fbefdebf6ea7bff7da94ace2af135e1aa38a7d63736de76bbea093251eed8755d6e3c3c4edae42b946fe140e511563d1ffb612a0d4fff66941f66007d0ac33c547840000000000000000000000000000000015916c0f96897e0e2b43bd76a98608d0afc276c1764f458f83db94fcf13adb05f440df55f3773bb12a3c25549e57d09d0000000000000000000000000000000016c6bdf76469f51e0b5dc0f9f2b22fe552e0fd0bd7084cf92946fc4d05692ab32690196a408a87681e32237cf172f5eecd8945187d434ffede5a94aeb3fe3442aba582787eca04c0e17d640820a30399000000000000000000000000000000000ca63266caaa56c1ceb84c922afd869885a1f33512fe59e1b367fe3526d1cf47f96df769d2f7708e1b693b528a28c94100000000000000000000000000000000027dcd246ff92089013faa40b4211e0bd0fa5777457668e57c0142561847542308a51d192ac5bf603ad8aa5119c6a5bc0ccbb0d0ed90f9bf2b75879861eb24b1170c9a83f5cc479beb4cb1e8835e77f2000000000000000000000000000000000d91133d005482f27cadbf8eb2d4a90952cee2d8b4b5a49dcd79a8141bd3cc04d4721fb3e62da217a08bee294a879ef50000000000000000000000000000000003bbd0c8be4f936ce1fa7b48f9158405e52a819cc1d4bb1fbd9f309698f8cdc1b2e1a5554eba3ab8d2e92f191274ac8cfe435dd14091302d34191d6c5028c3e62ad016f5a5b6256f3aaf82e9606f21cd00000000000000000000000000000000153753f25d38c68a3b92a486bb896a1b6ca9d4b81620a7a0040386838be7187e8ca73987bb260ee099793009b5cce1f500000000000000000000000000000000063f22c3bedc7ca5ce16db22f44a68a8fa529b2c6aab59c97e4b2353ed1b81da0586dbc0fa49605402da10c5ff7cad7dabd30cf71788f338622c21204603041353f1ca6885660be7ea826e00321c262000000000000000000000000000000000153753f25d38c68a3b92a486bb896a1b6ca9d4b81620a7a0040386838be7187e8ca73987bb260ee099793009b5cce1f500000000000000000000000000000000063f22c3bedc7ca5ce16db22f44a68a8fa529b2c6aab59c97e4b2353ed1b81da0586dbc0fa49605402da10c5ff7cad7ddebd81c66b87038940c72fac5d33aaa039525bfd21c79af3e4ef46ac5e1b274500000000000000000000000000000000153753f25d38c68a3b92a486bb896a1b6ca9d4b81620a7a0040386838be7187e8ca73987bb260ee099793009b5cce1f500000000000000000000000000000000063f22c3bedc7ca5ce16db22f44a68a8fa529b2c6aab59c97e4b2353ed1b81da0586dbc0fa49605402da10c5ff7cad7d6b382e8936d65c5c6ec4a52a5e22d923ba82072682220a6a30426319584fad480000000000000000000000000000000009edfbf4cad38d597d63663abd67d6a84b5c54dad7b7b147d791c41f9316923859e6daed7e384d9049b0a2203f08607600000000000000000000000000000000168806179a9bcb0bebd363fed37a5b9cc1e8b66d270982c31ea5573b78236f75d36b04efcd2092d7684a18c13de83c512bb927549b1b512c6e6cbe1038bed00f074deda5c63a2367ffc60c5ce7b8afc500000000000000000000000000000000153753f25d38c68a3b92a486bb896a1b6ca9d4b81620a7a0040386838be7187e8ca73987bb260ee099793009b5cce1f500000000000000000000000000000000063f22c3bedc7ca5ce16db22f44a68a8fa529b2c6aab59c97e4b2353ed1b81da0586dbc0fa49605402da10c5ff7cad7dfcfb7d1fdd47912832e10e1f30ec146c120fc68ade3f3ac10604ce548847a83300000000000000000000000000000000153753f25d38c68a3b92a486bb896a1b6ca9d4b81620a7a0040386838be7187e8ca73987bb260ee099793009b5cce1f500000000000000000000000000000000063f22c3bedc7ca5ce16db22f44a68a8fa529b2c6aab59c97e4b2353ed1b81da0586dbc0fa49605402da10c5ff7cad7d1fc561e062ab6a6b015fda81de63bdcff89698bd2a7445d0c21c1b8284d8ebdd00000000000000000000000000000000153753f25d38c68a3b92a486bb896a1b6ca9d4b81620a7a0040386838be7187e8ca73987bb260ee099793009b5cce1f500000000000000000000000000000000063f22c3bedc7ca5ce16db22f44a68a8fa529b2c6aab59c97e4b2353ed1b81da0586dbc0fa49605402da10c5ff7cad7d385829683b3cce18867d07afe8c02723f906a216c7d6d59d5b42518f5999158d00000000000000000000000000000000032d01e694621f0d2821bd2a575424d11cb623e65c1bc2438392ea57f08936e9b98eceedf917f4e51afbdd30dc8c24ef0000000000000000000000000000000010d8d9f87a3c2689ea9ac9afea38a0b1b31d90f0afa71957b596cb89a9bdd414dc2954f1cc747fac377d318769467dedc7839d6bb24f8d23caddf1b6f0895a5a6432fa0843cb313c5ac57e81ff816c6f0000000000000000000000000000000015ccd632042331ff5ea5fd21697810f7c3cfe5eb1d6e7afd9f850e3fd8e5914bce3d548cea90a60ab0ed27e24e72464f0000000000000000000000000000000001d027a23c9de769d155f06b81469ad9d3ea59a93d40388215c2b5c7438fa10e77da03e26f1010dc7a225d179b9298f9852544eb6963fd0dfbede6d8cad90517c2c3dad1ee2f6c49d24d8dd155ac977000000000000000000000000000000000153753f25d38c68a3b92a486bb896a1b6ca9d4b81620a7a0040386838be7187e8ca73987bb260ee099793009b5cce1f500000000000000000000000000000000063f22c3bedc7ca5ce16db22f44a68a8fa529b2c6aab59c97e4b2353ed1b81da0586dbc0fa49605402da10c5ff7cad7d5f94eaaa4947d5d054b54792044ca1450f25da28df35db7e61b7d9efe55debac0000000000000000000000000000000015163cbe70b4f6a2d7d90a8e48ac6f8812dfc7c997add0528f17a6f0cf42faaee56b13e1e95d5b8f306696a41f426c49000000000000000000000000000000000f55f240ced8ad609c288edc4b2a888b84b101aa39473c3353163b501cd888e07d42138e5e450f16d4e1ec0414b5d28f3bdf0bb67b4d2551ea7144121412d258383ed6cb4abb93b7b56b127dd384296c0000000000000000000000000000000011db7b6d983443206e5a7962bf7e2113ae463531cc958e84296c96d0c31f4f2264c8392bfb85f164500d6b872e7890340000000000000000000000000000000008d396e251da387cea196f5b7486788b3c03240451ad437b2d306f3b6ecc6cabd7e2f4111f7321b64022d2aad51fda460aef6a4bfefd1af38ae88ca70324b583e2aaebf559301d7505db962ebae2311400000000000000000000000000000000002b319cf695dec2b8da3475991a774e1c1b01421b0ebfd11297673e0eb218448c4271e67d23bd0ee5be867126091a440000000000000000000000000000000008549085ae48aedb3c8a4bcd271a9da39fb74f528af94e588c8a0a6a2e76026f2711aac32601e944d9547876ed23de7e1a85351cd8c1e3175722cbd8f6aa3806e0d9361f09e70dd03771b6b26d2f93de00000000000000000000000000000000153753f25d38c68a3b92a486bb896a1b6ca9d4b81620a7a0040386838be7187e8ca73987bb260ee099793009b5cce1f500000000000000000000000000000000063f22c3bedc7ca5ce16db22f44a68a8fa529b2c6aab59c97e4b2353ed1b81da0586dbc0fa49605402da10c5ff7cad7d6fcd55de20c3131edb3e85f6aa82f17c5fe5b93f92fa3fd596c833549824ede500000000000000000000000000000000142095eaf85b1017dc314db46100baeb29170a35f429d1563cd7aa6714f6b1dd269ba00be1a82294b0a508f7f038e0d4000000000000000000000000000000001558399b27afcccfa6a89cfd4635a4bd8c87d7ebbb25c28649f24f90897d7fa54c207986dd854f156be69a6eda586aab431309767397001e1e32bd73f685b5f54076732c953974b446a3088f54c9e3240000000000000000000000000000000019ea6e73637995387e7c2cc1a0de3d34953242a8dd3139d8a5886863cf21249e8716a8394f4883a2af632abdd15998a60000000000000000000000000000000010c0c216f747d186300934461ed363744aa30be9e0dbb390d362cd3c71b59728b124a396c6e186ea63aaaeb4d2a454d7d92679e9ce2106708d5206d408ac3650d2046a51eb79eca4dba9416ef0f3527200000000000000000000000000000000153753f25d38c68a3b92a486bb896a1b6ca9d4b81620a7a0040386838be7187e8ca73987bb260ee099793009b5cce1f500000000000000000000000000000000063f22c3bedc7ca5ce16db22f44a68a8fa529b2c6aab59c97e4b2353ed1b81da0586dbc0fa49605402da10c5ff7cad7dfa01f7cf41925a6bbe60b14586586fe0d4ba146c5aa6f02c14d41cd791878554000000000000000000000000000000000e7a795c2e6d4ac210d0fb92e94cd76ff97193ef7bd79446afafa7185df8959389801ac16f846360c8509bd407d28da40000000000000000000000000000000013e260782a41a63ce7c4048109fae191aeb7448fceb79e06c37223de72ded540931ba81ecdcb46423bdc7d564d27ee0aa5138547028a8868888087c4abb44f421757cb5583a6eba82b58504655162463000000000000000000000000000000000ca32c6c4b8746170ef22461dca8893855af15fdabb27a293d2620a20088f3892018e3c10dcf80f67f5227b14a808fb90000000000000000000000000000000001e88d80946624429dfb26f20236fe03680a359f1522a9075d48f27c84de9008bb558a645192bded688197e55b29c1cb5444536040fd8d54b8497d86600a5ed467a4207dead453c71781ce03552fc18500000000000000000000000000000000153753f25d38c68a3b92a486bb896a1b6ca9d4b81620a7a0040386838be7187e8ca73987bb260ee099793009b5cce1f500000000000000000000000000000000063f22c3bedc7ca5ce16db22f44a68a8fa529b2c6aab59c97e4b2353ed1b81da0586dbc0fa49605402da10c5ff7cad7d49e2561d0364b0069838bf24bd021d1e4a95cb0bd5aa7a94a506189f4f5ce5b000000000000000000000000000000000153753f25d38c68a3b92a486bb896a1b6ca9d4b81620a7a0040386838be7187e8ca73987bb260ee099793009b5cce1f500000000000000000000000000000000063f22c3bedc7ca5ce16db22f44a68a8fa529b2c6aab59c97e4b2353ed1b81da0586dbc0fa49605402da10c5ff7cad7dcd2d6f115ac393d6d5733cd0f6e6d3f0231cd825bf899902c50c917d0a56aff000000000000000000000000000000000153753f25d38c68a3b92a486bb896a1b6ca9d4b81620a7a0040386838be7187e8ca73987bb260ee099793009b5cce1f500000000000000000000000000000000063f22c3bedc7ca5ce16db22f44a68a8fa529b2c6aab59c97e4b2353ed1b81da0586dbc0fa49605402da10c5ff7cad7d59d2bd9bc3e12e5d50c9e4c768c2f8c65ce771a11cfbe46da73d80786e027b58000000000000000000000000000000000fdbd45fd634a2f233ff8ef90d5947977023d9ddfa69f3ce6b1dc6abb17bcdcbe97bc4be5059bfd2ab1aa91d17821024000000000000000000000000000000001435c723d4563d17a9c12090347929487409efb3d29119ccc967a6c5e9cc00e20e537a3e05e385cd8efa555dd3f2b722ff0a56d2dcabac5932c5d959f2f036d9ba5c71cffb7e686d319bdc8d1e83093f000000000000000000000000000000000be1163dbc97bc79f8434c744dc0e2c638c9d524903738ebea3cb86b79438ea2fb0238451da6e962b412be9a0e7611f800000000000000000000000000000000022a59b0eb1ca7d35ae94bcdc64f50b443260f8cf7c8003d99c3ae198a7c2fcbee4653566b485f33357d8eb1a6db1511f7adbee3c265263c30e3662a1bd35fdb466bb3677d6d09efe99cd1a7a468548300000000000000000000000000000000153753f25d38c68a3b92a486bb896a1b6ca9d4b81620a7a0040386838be7187e8ca73987bb260ee099793009b5cce1f500000000000000000000000000000000063f22c3bedc7ca5ce16db22f44a68a8fa529b2c6aab59c97e4b2353ed1b81da0586dbc0fa49605402da10c5ff7cad7d6448a9f68973305afe0622c12998037252fc8183296ebd0f29456159b8275e03000000000000000000000000000000001947d6e595915bd7ae4e538306d208a2d312de5de42f0d3bb735916aa741f47ba44834b3965f2aa9b5405c10c2b6b992000000000000000000000000000000000eabf37c5ebf82bf038d3eb58b72a5a584d69ce3e7de1d9668ab5df2abda5797e567321ee43d1aaa15f057048567f7c6f94018c9aa0307288e5126c736b8bc6f270836028ff850de60261bff338b7d7d00000000000000000000000000000000153753f25d38c68a3b92a486bb896a1b6ca9d4b81620a7a0040386838be7187e8ca73987bb260ee099793009b5cce1f500000000000000000000000000000000063f22c3bedc7ca5ce16db22f44a68a8fa529b2c6aab59c97e4b2353ed1b81da0586dbc0fa49605402da10c5ff7cad7d7037d0654ed51af22b5b324e23ca1065dd8cd3408a675ec204cecdfe687bcd8a0000000000000000000000000000000005d727a52fe6676e8508bd7d3a27c79cc4836d412cd5720063ea0ce5ca245cdc6dbd6fdaa26ff502d3ccc6e27701395e000000000000000000000000000000000ffa9dc48cbbf1ba32bf5de2ad98e8f4f1842f1e219660c00ef9702a72aa1166d46b9731b8c80581a795c0a09693cbeea5616463a00009079c228b8a92059926e3e26170c7bf1514823eaa8bc0e6ffa5000000000000000000000000000000001220a1e08ceb679bb165a3c9be882b6429c36ab83a7324ddc07ef7f2d0a4408d741e84791a33775ad4565cf816a4e9b70000000000000000000000000000000001496ad90c53c27392ee8849601aaa5b2c89700112a324864472c1a8d49804fde78e761adfd9c7755ac2d8d7d215c0b53c1cd4a2a7ab5eca1ddcda8887fb2aef01cb454a97bd39f2e0680915be270b970000000000000000000000000000000012b40bf0cbdc9e374ac4162b638403109a79803a726509f9326b85d3f2b20dd2a09015c30a2bcb1156bf7bb888f010c0000000000000000000000000000000000f3bb973815c39b95fb1398d80ebf1530060e31495a96c736b0235c78c5e041ff69e2564746b07d7a270bd45258e4aa7627af6cb2e8a90102e79d2cb19aaf0b6c18dedfdc736894732c7403036f0324600000000000000000000000000000000153753f25d38c68a3b92a486bb896a1b6ca9d4b81620a7a0040386838be7187e8ca73987bb260ee099793009b5cce1f500000000000000000000000000000000063f22c3bedc7ca5ce16db22f44a68a8fa529b2c6aab59c97e4b2353ed1b81da0586dbc0fa49605402da10c5ff7cad7db4371b02a3681f7f8f53acf22cbf8307d6e5276a5a23ec74fe02cc7aad62e98200000000000000000000000000000000007c2f86b037c3a7b67995d96bf4313ab6c20f472994372b40b78a3dfdba4c7616ead79026738d0ec398364806a57189000000000000000000000000000000000e752c8490fa323e0c74f9ffdffcc9ada27016388144bc95445341a6eaa82fa9a10d59c11bd8dce3b9cb0489ab1a5447ddb739a79265fb03de61859590978af384fd44243aa33806a1c7a3e20f37365500000000000000000000000000000000048afef5dd0565942320a985cf8d555408cae3edc40b7a5456ec86308d5f11db5592fe37e058dc6bed42346b42fc4abe0000000000000000000000000000000005e36fcbaf73026442a94ffeb56f4d05df46b90e3e02c3fbcbe3a32b1878edc7f6a5e57dd9f6ba64097c41e8e7ddaefe24584b142d6180187bc728ed22bf802d01db715ff85b51872991e92ff1d70f500000000000000000000000000000000008e3fe3d42e724fafb0501e4d8f2c55ec35bf60c71f6bd31f3d4b890a0b418e00509b8666af4207c8db44b30dc3828b900000000000000000000000000000000122a0dd7a24cf1e42ac8b8795ba785efd1f03f4753985f4071f17c4b8be7706fda8f900364c1676bef4e20e5797583b129566ac3f767fdce83ea91a295d06984d48763136f977f5e7e4f013ce274923400000000000000000000000000000000153753f25d38c68a3b92a486bb896a1b6ca9d4b81620a7a0040386838be7187e8ca73987bb260ee099793009b5cce1f500000000000000000000000000000000063f22c3bedc7ca5ce16db22f44a68a8fa529b2c6aab59c97e4b2353ed1b81da0586dbc0fa49605402da10c5ff7cad7d92af1ecbc9eccb56b3a220398ad3a3885cdfd3f02c9d302add64359bd121cc3e000000000000000000000000000000000e7775462ebb7f1ed737ab730e39ef8bd089222d3d7b4ab904e3583f898739d6a53c1d359d11017892eebe6ed9917253000000000000000000000000000000000d239831ce4acc58fa97e4d4cf56c3961ef313b681ebb9a1e221900e55832989efd1b022d9ec807019dddf73b1a6fdb2a407193f74d08ba9ed5d971f0516e7bbc7f89309dec24a4ea5d2a1f3eccfa5c6000000000000000000000000000000000c5be42126df5197c04f49e618a3fb6b8ff17f90b5ff26db7fd508a0723c4f479645beee629e02c9da60313b19bbfcec000000000000000000000000000000000e7fb0e4699dbc768d51247f5d7030fc698c5875cc9c5b326f3f7a4315c6fdc8e5095e91413dbd2c9b40316645275b3cd8fde96110b12c91bb5a9df196e4ca3c169710a6951e4dafcc2803fea31a43d00000000000000000000000000000000004760b7d9e28a23216b7ad3ac6b95c094e823df1bb05559e1871d9598287ef2f48f2858a1929fabb7ed3d7372a8bc7e6000000000000000000000000000000000f766efb67b69b273f9e1ee0c1f934231072719039e642892623f869b05c3b7af0b18397e76a25cd9f3eefb4f04935a54d02b624a8c2cca31a05cdeda3e09ad819140fec582a88f266291ee6aa1f1ce6000000000000000000000000000000000f734e6b273c6b05e911a4441c3740d13228917fd0916dfcc696930ed1c2e70268ab98d764507e68fd52826bdddd64e2000000000000000000000000000000000c20234fa85fd9eed8b148e79aa833443d47384590788f0700ccdc163b5d50dfaf5fbb901e7802d27a3db86f6aac06e91977c7a5be2688c808528d63a275fa8d18af14d7e90aba7edabfc821f4ea37be0000000000000000000000000000000016f5c2679ac1a70cfeddf38068bb85b6d35de903105a14b3c4b3d00e6f57c8b6c6de7d55f2b697617a4aeb73cbcffc090000000000000000000000000000000014ebec9ccb8e6052a009255080f2e0bc34eff9214e911bd6c4eedb53022a6defd5f0e78c9713c6a2e1f110152ad65b941a5267d9766e7d84ed4693f15ead057ef7396903e8a5f3a55bae74f044368a6300000000000000000000000000000000189b31702e6d365104d661c9c524b2c8d42dff369366d125453496e434f1b9c4f46cf3923afd14b50a4e06e4f73b5f8e0000000000000000000000000000000009eadd06f6cf208c4c70fe079cec8191553cc8a55321ff0a70f818d1cf7b5838292ba5eae5298f9b842577a7cb0ddb4e89246920765fec2a411849831114d529aa308111efdc119e85186b960ea5456600000000000000000000000000000000153753f25d38c68a3b92a486bb896a1b6ca9d4b81620a7a0040386838be7187e8ca73987bb260ee099793009b5cce1f500000000000000000000000000000000063f22c3bedc7ca5ce16db22f44a68a8fa529b2c6aab59c97e4b2353ed1b81da0586dbc0fa49605402da10c5ff7cad7dc088cc74c109957af3548bea8f72505c8ece5c1b690c14dfe958b8faea470aa1000000000000000000000000000000000334aab374f69a9760f58431c6dfa783f71908bb3249f03d05272fcc6b5548dead4791e86d630231133c121ffc10795d0000000000000000000000000000000013b4f68ca1144b9b2723930cf63c5b75fbe7a09997ad6916b933c5713e5c52e918e4a0876e5a3fa282a87335d9c1cf4d6e33049a1bb4429d216991c6aaec7a6601723e52aaeb4fe9dae31b5d3816e93300000000000000000000000000000000153753f25d38c68a3b92a486bb896a1b6ca9d4b81620a7a0040386838be7187e8ca73987bb260ee099793009b5cce1f500000000000000000000000000000000063f22c3bedc7ca5ce16db22f44a68a8fa529b2c6aab59c97e4b2353ed1b81da0586dbc0fa49605402da10c5ff7cad7d44f89ffaa24457b265e18cd544a4107dcb6f3d7f3fd39842a3a6f40cb80ef8b800000000000000000000000000000000153753f25d38c68a3b92a486bb896a1b6ca9d4b81620a7a0040386838be7187e8ca73987bb260ee099793009b5cce1f500000000000000000000000000000000063f22c3bedc7ca5ce16db22f44a68a8fa529b2c6aab59c97e4b2353ed1b81da0586dbc0fa49605402da10c5ff7cad7d39a1a26daf737fedd3f00aa08e7c55933b70060321ff2d862df8d3f2216433be00000000000000000000000000000000153753f25d38c68a3b92a486bb896a1b6ca9d4b81620a7a0040386838be7187e8ca73987bb260ee099793009b5cce1f500000000000000000000000000000000063f22c3bedc7ca5ce16db22f44a68a8fa529b2c6aab59c97e4b2353ed1b81da0586dbc0fa49605402da10c5ff7cad7d792f9741bbc394770f02b271ac249e66e056b225118afb58e804ba6a64d69fab00000000000000000000000000000000026ef7ed98b77106cc9e97e418086f844f2fa5db62484336750db6b140101657350dd20a29036f31b3b61a0a6292f1720000000000000000000000000000000007253b6377638195eaf42daaaabc451ac78e0707f14b12523ba5cfbf5ecb146b8fe1361cfdaf76b7b7395fb4b2ec7733fa4e4476364dad37551ac06e221cfb959094aae57733ae80c00d2213a68a841c0000000000000000000000000000000010213a60637cee478d92dc83b85937f51be6878189ec58c491959206024a726045906c47f39c89c68e8109ac8a09124c000000000000000000000000000000000a915b174003ba76da253296fad341af125a7b0d30e541c92cd25c970fb5d45993c516124b8535024c74d970f12fd7c1ced1ad2563403e274800e80f48fecac97498e58356f33ef6fb3ab123ce15f5d700000000000000000000000000000000149451bc330ffe029b198feb8d796fde5341b0691d0ea058d9a29ae1de78740e3906fd8cbcfc135caed16c03ec8b0fb500000000000000000000000000000000147a09c04d930602218988f7a101cb0572e8a41f83c49bfa6b92217d62a7b817146876b8de99f984cdff2f1509762580bb49d60ebba706d3556aa7ada87267ee3220b7f0b8d333aab79d690feba308710000000000000000000000000000000010d8cd8f975822ed51b18ed332fa6b695e0ab0c884413da5a1f77f0a472e06a257323aae9a3a8233dde0f3e1a797dd6a000000000000000000000000000000000f2b776ac6bbb05bd2d18148df50f3cf9ba3bddbc6ea410a537a65e0bf12ced5dfb8fd9a1586289bf9ae79889102d1f9a8d81a8d537651685cad896598a65479445bcab815793de88f399a7e2989c2e400000000000000000000000000000000153753f25d38c68a3b92a486bb896a1b6ca9d4b81620a7a0040386838be7187e8ca73987bb260ee099793009b5cce1f500000000000000000000000000000000063f22c3bedc7ca5ce16db22f44a68a8fa529b2c6aab59c97e4b2353ed1b81da0586dbc0fa49605402da10c5ff7cad7ddd130785a081c481879877abfa85e66b3b39cf81451696e7fe7524755d5bb0ca0000000000000000000000000000000019fc82c97989866d4e50f03c018dda0c6b356851d014355862a243ac1e2201ae248407ea895ea051a87249518eeeef66000000000000000000000000000000000d7c34b2070466e3107979f43191c09bc5e70ae6523fcefaa5227d04eb6e51de5d9025df74e2056e5e976a60a8b8b612f96d861e2c9a2b8b47f7c6f6f6c63ca93eb83bf5d1995006a7c5f03c2fc25d2b000000000000000000000000000000000928e3c3be2939c1da0a388eb4b55a436a698827c7979d34ec6a0ad3ffb9e23f112350c0b8174f1e52b2c53a8de4649100000000000000000000000000000000123a719f66a3f2dcc8ec1b3f130dcaf9b4e1e9124ae6807c744417ee04dc7464bbf1bd7f6076257753061334332e7192eb64c8c2bdbcc472ed8079a295888c1ee902c948ae48d2149d37815537aa538e000000000000000000000000000000000ebc060619caa0db6ea4c47bad6610802128d2be619173223a9d0f84d901f147db4fdeb250249759487bc727ac061c66000000000000000000000000000000000c44ce1e0c8b3f4e2098aaf2efe85cbfb689fe5478641ae53cd5805924ded81d586644c3bc49a389b15d837e2d4fe44a39f9d35b3f3b4037baa3bb79f7d5e522b9c1acd434fdaac61c3f616016b3bd5d00000000000000000000000000000000153753f25d38c68a3b92a486bb896a1b6ca9d4b81620a7a0040386838be7187e8ca73987bb260ee099793009b5cce1f500000000000000000000000000000000063f22c3bedc7ca5ce16db22f44a68a8fa529b2c6aab59c97e4b2353ed1b81da0586dbc0fa49605402da10c5ff7cad7d91b623b6ee1adbe3728463c29c39379a29809cfd7cd0027835a271a7436f470300000000000000000000000000000000153753f25d38c68a3b92a486bb896a1b6ca9d4b81620a7a0040386838be7187e8ca73987bb260ee099793009b5cce1f500000000000000000000000000000000063f22c3bedc7ca5ce16db22f44a68a8fa529b2c6aab59c97e4b2353ed1b81da0586dbc0fa49605402da10c5ff7cad7d4e2e68c5c52d84b713d3f681fe6d06fff398c110215895ebf9deef50b2a338d3000000000000000000000000000000000cd89c9fe1298920067f1b37be297c5567137a07a95c56dadb2c04f3993608ea498e89b684b8262172a1081505d5c60600000000000000000000000000000000073204f3cbeb83a5189fe1df5f501241e2453afa3220c38776590862681a771cd5d6cef2946228c1416eb3c1d840bcca8e2be1afacb2acc764b129c6c62c2c35801b548f424c4bd3717f6302a44b15b000000000000000000000000000000000177d5d25fddee9f1923b4ae21ae91ddbc4e55a22af46eb61b35e0634f7ec15a7d8bd6ca12be9fde52561d207d26406330000000000000000000000000000000011e9fc830a8865caf50c1c20853f38039c3b0aa956a75140ed699cd0e69730c6f7bdd00fe05529cedde1785a39f67d3f60cb52da68c43935c22b6d1b13b3c32b79f8939ffaacfb4938bb1747e3d31f4900000000000000000000000000000000153753f25d38c68a3b92a486bb896a1b6ca9d4b81620a7a0040386838be7187e8ca73987bb260ee099793009b5cce1f500000000000000000000000000000000063f22c3bedc7ca5ce16db22f44a68a8fa529b2c6aab59c97e4b2353ed1b81da0586dbc0fa49605402da10c5ff7cad7d91181d5d2444d162419133835091288d910bdc603f405c6120679fae82b6e842000000000000000000000000000000001689b5ec4737d58921a131707b92fb7c5b16e084a0415bc5c1bdb5b9a6260327526da2801932b5775f27cad390e6a6980000000000000000000000000000000004b610f2c453e9cc73f04425487f65660f478eed19ed3f3e60aab068f53f2dfdb5a73b02e525a14afe7423f8850ee9fabd637ad431366f08e955799c79f6ea5aaf9c22faf5400e7dc6c249c0e6494c1f000000000000000000000000000000000c37eec1f1033b86368b0fe1e42d9feaf174a77c4a455aeccda479d8fc937faa3a521afc7a2143285e7496f192670242000000000000000000000000000000000ede805910da61cc6daf7b4d465ee83ddf1ab5097634933a70003112a20361cd9c59bfa77b1bc026e93ba6bcfedded5b6ac13b151ae86bfc484c2bc91d4df9a75ef4a2523b968fd31391f9dd0af789f400000000000000000000000000000000153753f25d38c68a3b92a486bb896a1b6ca9d4b81620a7a0040386838be7187e8ca73987bb260ee099793009b5cce1f500000000000000000000000000000000063f22c3bedc7ca5ce16db22f44a68a8fa529b2c6aab59c97e4b2353ed1b81da0586dbc0fa49605402da10c5ff7cad7d6fb50ae4f785f5b5cfdd9aa004f08215d1bb6c1214d5cc5f027c3bc28a812414000000000000000000000000000000001259021c75f2fa3278b16ffaf375146d0ffac5477347ed1641886f703005940cede0bfab44fe49ba20914d580161326f000000000000000000000000000000001029ca636af85218a2a23d4e0b799dfeb713718a258c13df2731c4f352c5629a4d2b996d9b2b3c7adb73ef0a28217ae0042c2d53c35f3fd0005a977237d71ec6da2723a7c9187f1b9f9c86a5d77dc773000000000000000000000000000000000f719b8ee0f2d3c845323b1d4b5df26a6c118f705f62b5cc535ad3a9dfcda6ecee37a0a9cabc52dfcbdee23ee4fa76d3000000000000000000000000000000001550b4ca2ce312e81b6050f7cbb6934f05830c739d3ec8b84cf1f349fd740b13cdcea3f2939bac45bbc71317ee0a3c11cff78aca784067502defb619fce8c8ca407761d3fa78d635b21afed38aefa13000000000000000000000000000000000153753f25d38c68a3b92a486bb896a1b6ca9d4b81620a7a0040386838be7187e8ca73987bb260ee099793009b5cce1f500000000000000000000000000000000063f22c3bedc7ca5ce16db22f44a68a8fa529b2c6aab59c97e4b2353ed1b81da0586dbc0fa49605402da10c5ff7cad7d8bd0c10194e4c8a032574824ab15979cd7fd2014dd7fda706b86d37a24a38990000000000000000000000000000000000d72f3900402e43a50414d8aba5dabe6a4ed9a2ce4df7f18018ed3292da6ce11f32d336cafe428a867dc3f75af7e625e0000000000000000000000000000000015c68638b97c79004b2bcabbbc309884bb4429fb7a947db7c0aa54a941574475b164151619c9bf5046a644391842cfd183158c0345a5f28d1577e3d9dc463b8a355602d25577e328ea82f987983e805100000000000000000000000000000000004eb67438c54c72fc064a92653c60b36d93dc4578b251dfd9fef885fbb71e7e17ce48cc286d364a9403125a285714ba000000000000000000000000000000001711f593ed6016095a9d01a7bf1081a2e279e837a35d250153ffc6a12bf2dce0c9819e5d0cedd8b20bae73414538b61aa03169e13ad2198817b924f5bc1df0f1db63f14df64d1ae24b1c43f18eb78e010000000000000000000000000000000016b3e588f20cb6b4fcfc37a53f57b4b446abc8d56314031db09996769e79ea63cf54549f0bd367545e4d17d5b55a300a0000000000000000000000000000000016feb1a66fbc5cbe44fc73e43735063100d1d5b28cb56a46c5c932111c08c4769fdea4a0a76caac26347148f50355aa0aa98c3852a24f571693d36ba7db3ffd984010e4084738f0b8b60fc7b6ac4b9de000000000000000000000000000000000ed8b7e1b18a4da705a76d23df1623052f99741485af9ddc9f501d6bb09d04356dcdd02e78bbfd8384c51b4156d0709200000000000000000000000000000000116ed2039d4a23fd7bdc56506bd4109509c6c189251ec9014cf9f9023ee810e254539c83f18bb7642a1dc6b41bf809c7f93ec9381604290d5311aa3fb14d124f0ba65df55f6ef3ec4a269edd870ff84900000000000000000000000000000000153753f25d38c68a3b92a486bb896a1b6ca9d4b81620a7a0040386838be7187e8ca73987bb260ee099793009b5cce1f500000000000000000000000000000000063f22c3bedc7ca5ce16db22f44a68a8fa529b2c6aab59c97e4b2353ed1b81da0586dbc0fa49605402da10c5ff7cad7d3f6f400d9cc7bc131fe4e5549b6ab7d82436bf68b504b970ff712ca4c9c2c97d0000000000000000000000000000000006e236535f811c96ff3f9c072eb9cf5f87c45cba5c7574359fdc6000c40693080e7f61867cd5a3c4a65ee9c3d54a6e03000000000000000000000000000000000738e9c888e7bb7d997c4f981c492fd3a4766e4d4c585b7a03779b249331ac014697c89bc21be212ac499fd6ce0b35969e06051cedf33e1f3ad21f763979ffa200c056792ffc8da1b6f44af6eb227248000000000000000000000000000000000af956bfa4d9b6608adf999c46c2c992f8a3eb697692ea3ee630764b855ff44b350ea6de10a3e5e1f271cac23b235fe800000000000000000000000000000000140bd10fc8fd2e934494c9f7b00fe56028ce31d97345ef9b8b31ce6d297cec92c7d4507b3a6fee0ca39dbc9d451143c61e44b07f50d5e8d1a05c82ac2a481ac5e8aa7822db692a1a3fdea6a0506ad93d0000000000000000000000000000000014f9f27a2cf656c4ed0f94d7c3aee20dc0bc821921bfb045f5b68ed83bf0c7d00a986ea7c45d8d705ecbde13597b0e63000000000000000000000000000000000db7075ecc834f4959cdb7e188fafb405960dbee697a82746f478db752751f450d2ff3bba389104e5b285ae61bdc0c8aad55c357b7f2e245173617f50e12c9e28cabd7b5d4698083b5494bb06ee6b94f000000000000000000000000000000000f3d8fa3abc111f80330ce55ae9318b6fec02b352e6d1d255449eaadd7cb073e98c3c0d8eb927c123e1291e4fe3fd21a0000000000000000000000000000000007444b25c17970b80480504eec11391f135bf9a817c39a17490474401bae058b276da0a3e40524aaa202d20ad9371923f67af135d05146e92f729e3176fdd93e17f5c94fcabc5ea6d93ec2872ba9202200000000000000000000000000000000153753f25d38c68a3b92a486bb896a1b6ca9d4b81620a7a0040386838be7187e8ca73987bb260ee099793009b5cce1f500000000000000000000000000000000063f22c3bedc7ca5ce16db22f44a68a8fa529b2c6aab59c97e4b2353ed1b81da0586dbc0fa49605402da10c5ff7cad7dc430190b829e32a784e3024f0a8724f62d4184898b422e1eaa6a6682a8ffa5ed000000000000000000000000000000000933768ebdc9e9a441da03b7b9a256ad6feb63944389641df09c6a17b73032329246f1d0d6bda314fd240c5edcf763f4000000000000000000000000000000000e27fb7f7d159ec8a2936877c69de1018ef076da27682bf900b67ef6fe042bc4f89d8c209d93f49cf8261350f8e3fa5368baff019bf1f9b24e32cce1bb680db6983d6f2b2e60addfa31d5ad9475238aa00000000000000000000000000000000153753f25d38c68a3b92a486bb896a1b6ca9d4b81620a7a0040386838be7187e8ca73987bb260ee099793009b5cce1f500000000000000000000000000000000063f22c3bedc7ca5ce16db22f44a68a8fa529b2c6aab59c97e4b2353ed1b81da0586dbc0fa49605402da10c5ff7cad7d494507004a8ae79912a11252b4b2db7e498b534e338450981ced313193d9687c000000000000000000000000000000001197c02653a12f6af36025306b69c89df784bb7894d505621f05d7f1f6a69e852508df91e3d8a370f4e8cc48ab02d1740000000000000000000000000000000004dc5b0344470d1d4f41aa663b33cbbc1c679ff7a30dfe96f99514e9d99b94d7119ec7e93aef68bee8ff883401e7191036da67891846eab25aaa711c5d03b89f0a5377bcf5470bc4ecb1434e6d7fdad400000000000000000000000000000000153753f25d38c68a3b92a486bb896a1b6ca9d4b81620a7a0040386838be7187e8ca73987bb260ee099793009b5cce1f500000000000000000000000000000000063f22c3bedc7ca5ce16db22f44a68a8fa529b2c6aab59c97e4b2353ed1b81da0586dbc0fa49605402da10c5ff7cad7dedace0762debb30741de59f071e6ee17f2d7ab3d390b1c9eb2128326204c6ac3000000000000000000000000000000001579c41346af232eb0717e393790cabff843cd6c50fbb378900009506ea2aa44c9bda06ac22508fd90dd4b1812c5791100000000000000000000000000000000034c6e25a58fbac1a5e023a5f8a820eef2539c8ef3f0dc9b3d9e05044f72eed9cce1957257364dbe961a2368f6f4a2fba1d68cffa664b8a4fc6612f5088c2206666218627b5a3d8cdab267ba61b6e94a000000000000000000000000000000000f6d092d1eafb6707da09d754ebe75c036b634ab71d45c05b02d087eaf9a4653c44cebfea4b6077a7d27c136861745fa00000000000000000000000000000000073be5a3badb56736b4fc10f1da61a512cb01b9938f613c24c3d3f3bf92311fc96b112c729e4c15edcf5929c88d459a61375f570e38bcaaee664681e407e7f987c82053420837154cb5a6728e0ef94b800000000000000000000000000000000153753f25d38c68a3b92a486bb896a1b6ca9d4b81620a7a0040386838be7187e8ca73987bb260ee099793009b5cce1f500000000000000000000000000000000063f22c3bedc7ca5ce16db22f44a68a8fa529b2c6aab59c97e4b2353ed1b81da0586dbc0fa49605402da10c5ff7cad7dcbd879144a71eb72e27370ccfe3a7838e7ccd0d1a3736363d4db8bc93b8823b60000000000000000000000000000000008b35839caed21e951fe50de3cb5a2c1b1666facfc98416258f142b3b60ceacb20bb0d08e3ef36f9d4f5de717412a2bb00000000000000000000000000000000199763b4f8dd148df64a832e2f23565a715a4587c5cf43fc4a9275952ca7d4a7697e395f130424e97f1f86cbfa961be5e666b68b60b59b28fc886334ee9dd129522d30b920bab308529666cf8ff0d76d00000000000000000000000000000000182c820bcb67b1498243b455e29c1334e4a3a59eb6abf2933d8ec05df470bd8e7ee8d332a209f1202290739623aa26f6000000000000000000000000000000000384ad81bda50856eed135161899d096fbebacf59a0d02e7a87366ed0f096e3bbd1eb4fa3281fb8413259a7d2deb162ff6b2722416947db59e49f3b1b7160356e36ebb1963b41ccbda7ea93b62ca483b00000000000000000000000000000000001b26cc520f5c5d0ebac51d8a24106c2da9131df1c53c6b36b81b2cccacf3ee81b55292c06cde3008225d0f8a69d8db00000000000000000000000000000000126cd4e992718f3b1b366b1ee4459a16bac8ed2a814ae9445c30640efefbc7cc01c3d1fa1dcfe2a7c727fb869f46e1b99c567427455c4304a89fbd4fbdeec02d5b1cbfe0404bedd35114252f94b82a6d00000000000000000000000000000000153753f25d38c68a3b92a486bb896a1b6ca9d4b81620a7a0040386838be7187e8ca73987bb260ee099793009b5cce1f500000000000000000000000000000000063f22c3bedc7ca5ce16db22f44a68a8fa529b2c6aab59c97e4b2353ed1b81da0586dbc0fa49605402da10c5ff7cad7ddf33607ac4386eda9cbe7a68908739c910922eba2b1cd119e794da621196d3aa00000000000000000000000000000000115c394d97c1aa29dfc3c5c42700dddfd435d30d753ebeb8db7e59c9ee129f8fbd87486f476940c958f127ecb166c7f90000000000000000000000000000000018aa9556e962f8af9d5c4db3e10a1f6c9603345a5e155944702904faf70d972553c0ce6b58df3886ad4de85069fc559b317185cfb9f04c5566bca6bc7dc2043ae8744971331180df35320710e25b404d00000000000000000000000000000000153753f25d38c68a3b92a486bb896a1b6ca9d4b81620a7a0040386838be7187e8ca73987bb260ee099793009b5cce1f500000000000000000000000000000000063f22c3bedc7ca5ce16db22f44a68a8fa529b2c6aab59c97e4b2353ed1b81da0586dbc0fa49605402da10c5ff7cad7d4e2e31f85a0c9145eae006fb7a37c31d8455ab1819d22ed08633b61826a110f2000000000000000000000000000000000b3c0cdb73a3f823d61c88327100dca8f06dcc5b275178a9fb4c7833adbdf5a6b531e8a20bae515a27542f4c8327832100000000000000000000000000000000110efd582f71bffc5866731c388ee69d793060d254a2b35dd35a1a5894511aa1c5fd58b20335921f4756e192f78fd24d618405deb577678c50402b1ab3054f9d74079022abe527279f459da7e464815700000000000000000000000000000000153753f25d38c68a3b92a486bb896a1b6ca9d4b81620a7a0040386838be7187e8ca73987bb260ee099793009b5cce1f500000000000000000000000000000000063f22c3bedc7ca5ce16db22f44a68a8fa529b2c6aab59c97e4b2353ed1b81da0586dbc0fa49605402da10c5ff7cad7d67d8a868ae890084858f063477cf8f8e2463415841530281cb2ee435042ff86400000000000000000000000000000000153753f25d38c68a3b92a486bb896a1b6ca9d4b81620a7a0040386838be7187e8ca73987bb260ee099793009b5cce1f500000000000000000000000000000000063f22c3bedc7ca5ce16db22f44a68a8fa529b2c6aab59c97e4b2353ed1b81da0586dbc0fa49605402da10c5ff7cad7d362802543485898cfa1f4e16eec307f6f0d2a0a49755573abefc8805ebf05d61,0x00000000000000000000000000000000198b43bd45d1858e93b542d86515454ac355d15448f3686d53346a73125bc3f356bc458fb1a2039f79bd27802bcfac1100000000000000000000000000000000180dd0333f06df2ca759049c18dee700ffac00c28006813df050d775219fd2ceaeaf971f57268c8d400e55a975723311,269352, -000000000000000000000000000000000123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef00000000000000000000000000000000193fb7cedb32b2c3adc06ec11a96bc0d661869316f5e4a577a9f7c179593987beb4fb2ee424dbb2f5dd891e228b46c4a000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a210000000000000000000000000000000000000000000000000000000000000002,,,Point is not in the expected subgroup \ No newline at end of file +000000000000000000000000000000000123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef00000000000000000000000000000000193fb7cedb32b2c3adc06ec11a96bc0d661869316f5e4a577a9f7c179593987beb4fb2ee424dbb2f5dd891e228b46c4a000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a210000000000000000000000000000000000000000000000000000000000000002,,,invalid point: subgroup check failed diff --git a/evm/src/test/resources/org/hyperledger/besu/evm/precompile/g2_add.csv b/evm/src/test/resources/org/hyperledger/besu/evm/precompile/g2_add.csv index f65c176905..3eb4492684 100644 --- a/evm/src/test/resources/org/hyperledger/besu/evm/precompile/g2_add.csv +++ b/evm/src/test/resources/org/hyperledger/besu/evm/precompile/g2_add.csv @@ -101,5 +101,5 @@ input,result,gas,notes 0000000000000000000000000000000010d001a09cf5dc3276482185f26ef3f75d28cd6d2667eb08a7fe06c03b99f3b6c4d82390739b6867a314291cc642a8b2000000000000000000000000000000000587846a460b1f37c2e7f491f9a097b4e86e1943d9cd0999313f65627b3907f09b5d5ac1be376a313a959dd136f7e9b3000000000000000000000000000000000af439695556e86b102926d3b40e3e54cc84464e120de3b4e3c5541a6a5bca44151fb0594009663764c1824518b13f020000000000000000000000000000000003bfd9418c1e57269e222152d321b83ae090f216cb422956dd1fcc464f68526cb4a05cdaefc7bbe6e81d4ffe27d64db400000000000000000000000000000000085dd8bfc00ba517dc8d7ddb49d711d35bd36f9fe3843689019e779624a032d2f023533b8184b73042d1a1953d2885e50000000000000000000000000000000009ba8d5d36e6efe02097a3206bbed68529f0cb9875ab81deafd886d9243bfec8b403d2abe713a2ec929b93305dd2da220000000000000000000000000000000007f8f90ebb2771136a92023901ca85e87fb7c8b1a40f88ae564a124bdd0ff0bc27ea98612a817e2c871fb4bcea3bb06600000000000000000000000000000000152de417d02f1d14e5899201db8fd5db8ecb40ea8d415dcdedce8ac70c28d851db68e9aef94506a50ec28145547a2d68,0000000000000000000000000000000017555399f979745302f08210de5311a6401b6b181100b3bc6b6d450f0f62079d2f02d7badcb164f50dfc46a975cbd6720000000000000000000000000000000014aea86c06e4c1fbf0711a8cfced2544c7624abc7ae7906cd992bdf575a702540c45c2117e221446ba09960cbc9048ac0000000000000000000000000000000002fac56960c4989a84e02ce36e8970c2e847ee45579d31ca77f042bf96505af574af822da084ae64b22ff876610ba9a5000000000000000000000000000000000a481cfea2aef8975c80a297ce5a185dacd25649d41f8466d3c63d786e3c264a8e4ccab5ef6b80ab1260e86ab6d5b3f3,800, 000000000000000000000000000000039b10ccd664da6f273ea134bb55ee48f09ba585a7e2bb95b5aec610631ac49810d5d616f67ba0147e6d1be476ea220e0000000000000000000000000000000000fbcdff4e48e07d1f73ec42fe7eb026f5c30407cfd2f22bbbfe5b2a09e8a7bb4884178cb6afd1c95f80e646929d30040000000000000000000000000000000001ed3b0e71acb0adbf44643374edbf4405af87cfc0507db7e8978889c6c3afbe9754d1182e98ac3060d64994d31ef576000000000000000000000000000000001681a2bf65b83be5a2ca50430949b6e2a099977482e9405b593f34d2ed877a3f0d1bddc37d0cec4d59d7df74b2b8f2df0000000000000000000000000000000017c9fcf0504e62d3553b2f089b64574150aa5117bd3d2e89a8c1ed59bb7f70fb83215975ef31976e757abf60a75a1d9f0000000000000000000000000000000008f5a53d704298fe0cfc955e020442874fe87d5c729c7126abbdcbed355eef6c8f07277bee6d49d56c4ebaf334848624000000000000000000000000000000001302dcc50c6ce4c28086f8e1b43f9f65543cf598be440123816765ab6bc93f62bceda80045fbcad8598d4f32d03ee8fa000000000000000000000000000000000bbb4eb37628d60b035a3e0c45c0ea8c4abef5a6ddc5625e0560097ef9caab208221062e81cd77ef72162923a1906a40,,,invalid input parameters, invalid input length for G2 addition 0000000000000000000000000000000000039b10ccd664da6f273ea134bb55ee48f09ba585a7e2bb95b5aec610631ac49810d5d616f67ba0147e6d1be476ea220e0000000000000000000000000000000000fbcdff4e48e07d1f73ec42fe7eb026f5c30407cfd2f22bbbfe5b2a09e8a7bb4884178cb6afd1c95f80e646929d30040000000000000000000000000000000001ed3b0e71acb0adbf44643374edbf4405af87cfc0507db7e8978889c6c3afbe9754d1182e98ac3060d64994d31ef576000000000000000000000000000000001681a2bf65b83be5a2ca50430949b6e2a099977482e9405b593f34d2ed877a3f0d1bddc37d0cec4d59d7df74b2b8f2df0000000000000000000000000000000017c9fcf0504e62d3553b2f089b64574150aa5117bd3d2e89a8c1ed59bb7f70fb83215975ef31976e757abf60a75a1d9f0000000000000000000000000000000008f5a53d704298fe0cfc955e020442874fe87d5c729c7126abbdcbed355eef6c8f07277bee6d49d56c4ebaf334848624000000000000000000000000000000001302dcc50c6ce4c28086f8e1b43f9f65543cf598be440123816765ab6bc93f62bceda80045fbcad8598d4f32d03ee8fa000000000000000000000000000000000bbb4eb37628d60b035a3e0c45c0ea8c4abef5a6ddc5625e0560097ef9caab208221062e81cd77ef72162923a1906a40,,,invalid input parameters, invalid input length for G2 addition -00000000000000000000000000000000039b10ccd664da6f273ea134bb55ee48f09ba585a7e2bb95b5aec610631ac49810d5d616f67ba0147e6d1be476ea220f0000000000000000000000000000000000fbcdff4e48e07d1f73ec42fe7eb026f5c30407cfd2f22bbbfe5b2a09e8a7bb4884178cb6afd1c95f80e646929d30040000000000000000000000000000000001ed3b0e71acb0adbf44643374edbf4405af87cfc0507db7e8978889c6c3afbe9754d1182e98ac3060d64994d31ef576000000000000000000000000000000001681a2bf65b83be5a2ca50430949b6e2a099977482e9405b593f34d2ed877a3f0d1bddc37d0cec4d59d7df74b2b8f2df0000000000000000000000000000000017c9fcf0504e62d3553b2f089b64574150aa5117bd3d2e89a8c1ed59bb7f70fb83215975ef31976e757abf60a75a1d9f0000000000000000000000000000000008f5a53d704298fe0cfc955e020442874fe87d5c729c7126abbdcbed355eef6c8f07277bee6d49d56c4ebaf334848624000000000000000000000000000000001302dcc50c6ce4c28086f8e1b43f9f65543cf598be440123816765ab6bc93f62bceda80045fbcad8598d4f32d03ee8fa000000000000000000000000000000000bbb4eb37628d60b035a3e0c45c0ea8c4abef5a6ddc5625e0560097ef9caab208221062e81cd77ef72162923a1906a40,,,invalid input parameters, Point 0 is not on curve -00000000000000000000000000000000039b10ccd664da6f273ea134bb55ee48f09ba585a7e2bb95b5aec610631ac49810d5d616f67ba0147e6d1be476ea220e0000000000000000000000000000000000fbcdff4e48e07d1f73ec42fe7eb026f5c30407cfd2f22bbbfe5b2a09e8a7bb4884178cb6afd1c95f80e646929d30040000000000000000000000000000000001ed3b0e71acb0adbf44643374edbf4405af87cfc0507db7e8978889c6c3afbe9754d1182e98ac3060d64994d31ef576000000000000000000000000000000001681a2bf65b83be5a2ca50430949b6e2a099977482e9405b593f34d2ed877a3f0d1bddc37d0cec4d59d7df74b2b8f2df0000000000000000000000000000000017c9fcf0504e62d3553b2f089b64574150aa5117bd3d2e89a8c1ed59bb7f70fb83215975ef31976e757abf60a75a1da00000000000000000000000000000000008f5a53d704298fe0cfc955e020442874fe87d5c729c7126abbdcbed355eef6c8f07277bee6d49d56c4ebaf334848624000000000000000000000000000000001302dcc50c6ce4c28086f8e1b43f9f65543cf598be440123816765ab6bc93f62bceda80045fbcad8598d4f32d03ee8fa000000000000000000000000000000000bbb4eb37628d60b035a3e0c45c0ea8c4abef5a6ddc5625e0560097ef9caab208221062e81cd77ef72162923a1906a40,,,invalid input parameters, Point 1 is not on curve +00000000000000000000000000000000039b10ccd664da6f273ea134bb55ee48f09ba585a7e2bb95b5aec610631ac49810d5d616f67ba0147e6d1be476ea220f0000000000000000000000000000000000fbcdff4e48e07d1f73ec42fe7eb026f5c30407cfd2f22bbbfe5b2a09e8a7bb4884178cb6afd1c95f80e646929d30040000000000000000000000000000000001ed3b0e71acb0adbf44643374edbf4405af87cfc0507db7e8978889c6c3afbe9754d1182e98ac3060d64994d31ef576000000000000000000000000000000001681a2bf65b83be5a2ca50430949b6e2a099977482e9405b593f34d2ed877a3f0d1bddc37d0cec4d59d7df74b2b8f2df0000000000000000000000000000000017c9fcf0504e62d3553b2f089b64574150aa5117bd3d2e89a8c1ed59bb7f70fb83215975ef31976e757abf60a75a1d9f0000000000000000000000000000000008f5a53d704298fe0cfc955e020442874fe87d5c729c7126abbdcbed355eef6c8f07277bee6d49d56c4ebaf334848624000000000000000000000000000000001302dcc50c6ce4c28086f8e1b43f9f65543cf598be440123816765ab6bc93f62bceda80045fbcad8598d4f32d03ee8fa000000000000000000000000000000000bbb4eb37628d60b035a3e0c45c0ea8c4abef5a6ddc5625e0560097ef9caab208221062e81cd77ef72162923a1906a40,,,invalid point: point is not on curve +00000000000000000000000000000000039b10ccd664da6f273ea134bb55ee48f09ba585a7e2bb95b5aec610631ac49810d5d616f67ba0147e6d1be476ea220e0000000000000000000000000000000000fbcdff4e48e07d1f73ec42fe7eb026f5c30407cfd2f22bbbfe5b2a09e8a7bb4884178cb6afd1c95f80e646929d30040000000000000000000000000000000001ed3b0e71acb0adbf44643374edbf4405af87cfc0507db7e8978889c6c3afbe9754d1182e98ac3060d64994d31ef576000000000000000000000000000000001681a2bf65b83be5a2ca50430949b6e2a099977482e9405b593f34d2ed877a3f0d1bddc37d0cec4d59d7df74b2b8f2df0000000000000000000000000000000017c9fcf0504e62d3553b2f089b64574150aa5117bd3d2e89a8c1ed59bb7f70fb83215975ef31976e757abf60a75a1da00000000000000000000000000000000008f5a53d704298fe0cfc955e020442874fe87d5c729c7126abbdcbed355eef6c8f07277bee6d49d56c4ebaf334848624000000000000000000000000000000001302dcc50c6ce4c28086f8e1b43f9f65543cf598be440123816765ab6bc93f62bceda80045fbcad8598d4f32d03ee8fa000000000000000000000000000000000bbb4eb37628d60b035a3e0c45c0ea8c4abef5a6ddc5625e0560097ef9caab208221062e81cd77ef72162923a1906a40,,,invalid point: point is not on curve diff --git a/evm/src/test/resources/org/hyperledger/besu/evm/precompile/g2_mul.csv b/evm/src/test/resources/org/hyperledger/besu/evm/precompile/g2_mul.csv index e8863e7ee4..7f9ee261bd 100644 --- a/evm/src/test/resources/org/hyperledger/besu/evm/precompile/g2_mul.csv +++ b/evm/src/test/resources/org/hyperledger/besu/evm/precompile/g2_mul.csv @@ -99,7 +99,7 @@ input,result,gas,notes 00000000000000000000000000000000156ca5e80be8c8c03a5506ce9abd22a9d4958c372678c0caf6f1329898507dfcb1f06a9464cf080bc6881fa5b7df1ebe00000000000000000000000000000000088174d486b4086b931010da298a399e15b60a113e08f571e096d3a4e94b57b3a684711318796eeca9319119b201abb30000000000000000000000000000000000b96ff68505c088cc03a1c2dc363b05bc8544728a12b29569bed137780523123eb17e68f4632383c252d81bca0c5ca9000000000000000000000000000000000486fc6e5224c5fad56234c41856e60bee4a6c1046f673bf7d5c1bbb603b141fc91074da5f9d3d41b796a2ebcebd9e74d16aa883a20307f5436354bab32b4633e83178f33626af3edb14f82724b8e125,0000000000000000000000000000000000ea29b1e059560fec21c3692d4e632a45c88a807c953fa23dbedb271b049d7fc717333b498ed12573a896f872e795dc000000000000000000000000000000000de0d10c47df92010a6635e3403dd6e91a1bf35bfcae82c1008998e86aa2d18a6cfd3f2f1207fde3bb39b723ec4d3ca60000000000000000000000000000000005e2aef9cd37430b15e5e76b2c7870630d255f630c12e865caefe308a39833e00319406746dbb2af3ed32135e91eed49000000000000000000000000000000000c229fad41b0d27ad7b5db33188fa70b97f22e323e429ef65fcf98f5339e908c31df8859b863356e0fc90538c5c49cf2,45000, 00000000000000000000000000000000121fe97c62e068988ebff21d8129d52aa903afdbb62862c7fd99564d9ad72182ab1f3a1100223ae486cd76f6938e123f000000000000000000000000000000000968ddedb04f52140160061828b5f88dfd09aaf37df625ee6f66b9500d6608df31c7edf86296eccf8f9918b051a5e4df000000000000000000000000000000000b7491cb8f6252e3861d7160feb0afdd736d27886863ec0909a7cc711a9b71aace18b17a00a2999dd57ca1a74f148516000000000000000000000000000000000fdb280093ef45b12b694ca3390a865ee18e4c04b231e2c98cc28706d4cefaf4e654582ee03f34ecf1dfa9674489d553041390a2209b80f7c64d14965cc2f515d5fbdf37953f75c4a0203bf0d9fb674b,000000000000000000000000000000000444a00cfd258bd46f659b09eef17be9929008d3d1c65e46cdc762eeaa2f0b52abfd636e6094e21983fad8171194c71a00000000000000000000000000000000090833e68614be5bf298e04e44527480cb35128bbdecae15eb95d6931a718f66869ddb68352130b4dd8a921ab3f26d080000000000000000000000000000000000994015b1b55340c3839d48320d178b2ffaa0bbff038f7aa63d4dff41a217582fae9613bc537fdeac8d0670c0cf479a000000000000000000000000000000000fc486e2a1680c10ca28d4c3bb22dbccc9572036512645bf868e7693ae4591569c973f9ea26342a573e23a06c2fb4b70,45000, 0000000000000000000000000000000010d001a09cf5dc3276482185f26ef3f75d28cd6d2667eb08a7fe06c03b99f3b6c4d82390739b6867a314291cc642a8b2000000000000000000000000000000000587846a460b1f37c2e7f491f9a097b4e86e1943d9cd0999313f65627b3907f09b5d5ac1be376a313a959dd136f7e9b3000000000000000000000000000000000af439695556e86b102926d3b40e3e54cc84464e120de3b4e3c5541a6a5bca44151fb0594009663764c1824518b13f020000000000000000000000000000000003bfd9418c1e57269e222152d321b83ae090f216cb422956dd1fcc464f68526cb4a05cdaefc7bbe6e81d4ffe27d64db47cf23dee8d95d94046678f3bdb4b0ea3d4e3a1a2f07f582e2a98ad6eb7562cbf,000000000000000000000000000000001375bd5ee66c330796bd8381a26cefa3f40f8cc8de42d4d59a7adbcd3852e6d632422e6ad9a06a6e497b23b17b1df87500000000000000000000000000000000165d8e7be17ecae9bf51a773da705aea42536d0fa3a2206267da50451f5104ee241811dd0e6710a80c38df77b126c009000000000000000000000000000000001559572407aff34969f83c394d2b095a7ae9f53a8e6c923910f256bb87b6ec076fa6acb85465102fd24d34031f88f7510000000000000000000000000000000015ff9ba89b55ef75f63732dec1e64106d7a912a6657fcc970dd011a03b5364117cca46d6cbafbc0c5049db10fa83fe6d,45000, -000000000000000000000000000000039b10ccd664da6f273ea134bb55ee48f09ba585a7e2bb95b5aec610631ac49810d5d616f67ba0147e6d1be476ea220e0000000000000000000000000000000000fbcdff4e48e07d1f73ec42fe7eb026f5c30407cfd2f22bbbfe5b2a09e8a7bb4884178cb6afd1c95f80e646929d30040000000000000000000000000000000001ed3b0e71acb0adbf44643374edbf4405af87cfc0507db7e8978889c6c3afbe9754d1182e98ac3060d64994d31ef576000000000000000000000000000000001681a2bf65b83be5a2ca50430949b6e2a099977482e9405b593f34d2ed877a3f0d1bddc37d0cec4d59d7df74b2b8f2dfb3c940fe79b6966489b527955de7599194a9ac69a6ff58b8d99e7b1084f0464e,,,invalid input parameters, invalid input length for G1 multiplication -0000000000000000000000000000000000039b10ccd664da6f273ea134bb55ee48f09ba585a7e2bb95b5aec610631ac49810d5d616f67ba0147e6d1be476ea220e0000000000000000000000000000000000fbcdff4e48e07d1f73ec42fe7eb026f5c30407cfd2f22bbbfe5b2a09e8a7bb4884178cb6afd1c95f80e646929d30040000000000000000000000000000000001ed3b0e71acb0adbf44643374edbf4405af87cfc0507db7e8978889c6c3afbe9754d1182e98ac3060d64994d31ef576000000000000000000000000000000001681a2bf65b83be5a2ca50430949b6e2a099977482e9405b593f34d2ed877a3f0d1bddc37d0cec4d59d7df74b2b8f2dfb3c940fe79b6966489b527955de7599194a9ac69a6ff58b8d99e7b1084f0464e,,,invalid input parameters, invalid input length for G1 multiplication -00000000000000000000000000000000039b10ccd664da6f273ea134bb55ee48f09ba585a7e2bb95b5aec610631ac49810d5d616f67ba0147e6d1be476ea220f0000000000000000000000000000000000fbcdff4e48e07d1f73ec42fe7eb026f5c30407cfd2f22bbbfe5b2a09e8a7bb4884178cb6afd1c95f80e646929d30040000000000000000000000000000000001ed3b0e71acb0adbf44643374edbf4405af87cfc0507db7e8978889c6c3afbe9754d1182e98ac3060d64994d31ef576000000000000000000000000000000001681a2bf65b83be5a2ca50430949b6e2a099977482e9405b593f34d2ed877a3f0d1bddc37d0cec4d59d7df74b2b8f2dfb3c940fe79b6966489b527955de7599194a9ac69a6ff58b8d99e7b1084f0464e,,,invalid input parameters, Point is not on curve -00000000000000000000000000000000197bfd0342bbc8bee2beced2f173e1a87be576379b343e93232d6cef98d84b1d696e5612ff283ce2cfdccb2cfb65fa0c00000000000000000000000000000000184e811f55e6f9d84d77d2f79102fd7ea7422f4759df5bf7f6331d550245e3f1bcf6a30e3b29110d85e0ca16f9f6ae7a000000000000000000000000000000000f10e1eb3c1e53d2ad9cf2d398b2dc22c5842fab0a74b174f691a7e914975da3564d835cd7d2982815b8ac57f507348f000000000000000000000000000000000767d1c453890f1b9110fda82f5815c27281aba3f026ee868e4176a0654feea41a96575e0c4d58a14dbfbcc05b5010b10000000000000000000000000000000000000000000000000000000000000002,,,Point is not in the expected subgroup +000000000000000000000000000000039b10ccd664da6f273ea134bb55ee48f09ba585a7e2bb95b5aec610631ac49810d5d616f67ba0147e6d1be476ea220e0000000000000000000000000000000000fbcdff4e48e07d1f73ec42fe7eb026f5c30407cfd2f22bbbfe5b2a09e8a7bb4884178cb6afd1c95f80e646929d30040000000000000000000000000000000001ed3b0e71acb0adbf44643374edbf4405af87cfc0507db7e8978889c6c3afbe9754d1182e98ac3060d64994d31ef576000000000000000000000000000000001681a2bf65b83be5a2ca50430949b6e2a099977482e9405b593f34d2ed877a3f0d1bddc37d0cec4d59d7df74b2b8f2dfb3c940fe79b6966489b527955de7599194a9ac69a6ff58b8d99e7b1084f0464e,,,invalid input parameters, invalid input length for G2 multiplication +0000000000000000000000000000000000039b10ccd664da6f273ea134bb55ee48f09ba585a7e2bb95b5aec610631ac49810d5d616f67ba0147e6d1be476ea220e0000000000000000000000000000000000fbcdff4e48e07d1f73ec42fe7eb026f5c30407cfd2f22bbbfe5b2a09e8a7bb4884178cb6afd1c95f80e646929d30040000000000000000000000000000000001ed3b0e71acb0adbf44643374edbf4405af87cfc0507db7e8978889c6c3afbe9754d1182e98ac3060d64994d31ef576000000000000000000000000000000001681a2bf65b83be5a2ca50430949b6e2a099977482e9405b593f34d2ed877a3f0d1bddc37d0cec4d59d7df74b2b8f2dfb3c940fe79b6966489b527955de7599194a9ac69a6ff58b8d99e7b1084f0464e,,,invalid input parameters, invalid input length for G2 multiplication +00000000000000000000000000000000039b10ccd664da6f273ea134bb55ee48f09ba585a7e2bb95b5aec610631ac49810d5d616f67ba0147e6d1be476ea220f0000000000000000000000000000000000fbcdff4e48e07d1f73ec42fe7eb026f5c30407cfd2f22bbbfe5b2a09e8a7bb4884178cb6afd1c95f80e646929d30040000000000000000000000000000000001ed3b0e71acb0adbf44643374edbf4405af87cfc0507db7e8978889c6c3afbe9754d1182e98ac3060d64994d31ef576000000000000000000000000000000001681a2bf65b83be5a2ca50430949b6e2a099977482e9405b593f34d2ed877a3f0d1bddc37d0cec4d59d7df74b2b8f2dfb3c940fe79b6966489b527955de7599194a9ac69a6ff58b8d99e7b1084f0464e,,,invalid point: point is not on curve +00000000000000000000000000000000197bfd0342bbc8bee2beced2f173e1a87be576379b343e93232d6cef98d84b1d696e5612ff283ce2cfdccb2cfb65fa0c00000000000000000000000000000000184e811f55e6f9d84d77d2f79102fd7ea7422f4759df5bf7f6331d550245e3f1bcf6a30e3b29110d85e0ca16f9f6ae7a000000000000000000000000000000000f10e1eb3c1e53d2ad9cf2d398b2dc22c5842fab0a74b174f691a7e914975da3564d835cd7d2982815b8ac57f507348f000000000000000000000000000000000767d1c453890f1b9110fda82f5815c27281aba3f026ee868e4176a0654feea41a96575e0c4d58a14dbfbcc05b5010b10000000000000000000000000000000000000000000000000000000000000002,,,invalid point: subgroup check failed diff --git a/evm/src/test/resources/org/hyperledger/besu/evm/precompile/g2_multiexp.csv b/evm/src/test/resources/org/hyperledger/besu/evm/precompile/g2_multiexp.csv index 460fd7fa3b..dfeab857b7 100644 --- a/evm/src/test/resources/org/hyperledger/besu/evm/precompile/g2_multiexp.csv +++ b/evm/src/test/resources/org/hyperledger/besu/evm/precompile/g2_multiexp.csv @@ -99,9 +99,9 @@ input,result,gas,notes 000000000000000000000000000000000cd1d25f285c2073175ecad5bba4987cc52012eadc7b19dbaa20fa82d7a6cfb8a52f33469b6308d921eb4b3b23f7022d000000000000000000000000000000001707b67a23d9212d30c06f26f0040c38389b185057e80236d2c828a8d9ade4f72eee1d6eccd78e4f4d71e2c28ee9539e0000000000000000000000000000000008e5c04effd14d915b9afc2083afa2b6d4008cfa0e47144a41982d8b5a8e77922a2609384e2c5d18c871ae24a7d505b7000000000000000000000000000000000f414acb056fff2cd6d9b408adb6eb7f34c8f66a66ee93945a3381d46c2d181613047ca6d4067614c190da444223cab685431a1df7678e49ee049b75ea968ca255ef456dd58cce57b64edffac1ac223c0000000000000000000000000000000008ea841aced2d0b8dd688947648a8ff18d0f6f03f63ee1c331f126dd4fc0da3d386535156b80902bdc1f65add7769cd70000000000000000000000000000000017a32ad2763d99c38c954f62466e78c0332e48875e15afbbe9c78376f1bab12346c73a573738353e2162d3928091dede0000000000000000000000000000000010ea738884dbfe5bc35d031bde9aa4109b1fca529502e236aebb5ad0bf71dd2f3db250d924415b0bfca56519f8ca5d290000000000000000000000000000000013699e29cc1871f51a469898be8b3c732b5cf7860286e655e65bd8176832804d17b48d0ff85eb023360db78162581297b6ccbc0b600f11f1b89061d94c6fbdc9b1d389244fb29a5d140dab8842d44eaa00000000000000000000000000000000004d504e62b2825651381ae862fd33407309851d5291591cd0f541fd092800d709ede00a9134e65ee752eaceb0a344b50000000000000000000000000000000016481efba290c37aa4ecbf940c76ee5df199b0c1f90fddebd2db28120bb5a14dd9f4a067b6d4889aeb683cca0f6ab337000000000000000000000000000000001400c89942cc63417ca4cb05c9d81dda3251e5611c27fc7727c3e803170672f103bff26f7216a0b646533aac3171488d0000000000000000000000000000000019889641be9db08880543ff476b9d4c72167092548ba49a3f3ace4518d3874f4f7993ae7b8cec90f092f144ec9d66c1a54dfe31190469897c30ac3736ab166220dd3702df5bc897835347713d03a8d04000000000000000000000000000000001927fe80adc6dbb581349c603103ad8831e645d9275af8669939b83829182cc6e2a30df2fdeda6d3aa2e2a6126e00ba3000000000000000000000000000000000b6d7934d5ca1098a85a0c60acca075220105e221b802b1be97c2967820bffc2937fc3278ed0f26905c60d44d5fd8dc000000000000000000000000000000000057acc1379f23c0d1d37427d400eb1b0a89f3736c83d3ffd797ae279e01e2acddd84082f13f3c8b8f1bf7c275702a9c700000000000000000000000000000000038dbcd7e08d34c553850a52336991a7d48968e98057e930790d78b5c6368eb2fe01571b60c4aefb653ec04122953d56eff1ceff9e5184dd9fea44da4f07529823dc9b100f776cef6f6881120f7de11a00000000000000000000000000000000014052031b88af979b7edb06c99c2e46bd9df2c862c7e1b71321754841fad67fc3242b51141e49ad86b61344aec913f40000000000000000000000000000000014806a86d078ee9bdde99257b67f50dc2ddf9bbf01dde931742ee6f739aa986cfdca06cd32d23d86f2c14c3b09033d29000000000000000000000000000000000e0561e795d35ceb8bd9e3b276406ec1f697a38ada25d1dbe08715a28bdd3d6ce6e0aac01f7dfc7c2b403850ab213b4700000000000000000000000000000000146a65209b09487e00e356e3b29952280ebc6a06343c4ce14efa0c6281bc2482698bd02295bc35125275ff5f5bb867dfb273e4c6266c1f5cf022902fe1310d2191af91c47995486342bc61cd361eab8500000000000000000000000000000000021592cd7f4cf9cab3be53561c889c9ee865961aad51339f6393dd6a0b7dcc8a7c48b753c947b15cd3add01abd3d76d8000000000000000000000000000000000f9e1a80bad58055a8577700c177889c4d702de04343c1202eaed9485a76493158547b20bcb552b66c42a0c86df809ed0000000000000000000000000000000013908dcff1945cf06f038e3caac9a7fbb3a6466ca18627e93468a875759a2b5599a96834ff21fcd6bfbba82b79536b9a0000000000000000000000000000000001b6354665109c5a64613c3bd7d805b3a34098708f3d41c7b77db031ac6fa0b2d4e2f2f70c84ac78687b0c0f9bf334771342b5cd4ad3179f406941ef6ea15d0aecdf9f6d96dc334c39b7dca89d256d4f0000000000000000000000000000000019394063202186e141dcebce7b8f0f267ba6057a0f993bb1cbe22a5bc528323823bfd1597a87017d478186a18f09a47800000000000000000000000000000000148437bcc43d432d70b47dadac8e738616c97d38d0f84dc132599626612f7bba74988bb23ae47ac15e6f70c059d607ed00000000000000000000000000000000180851594710f4bb5be7ae0104a383081c50f59e4e048614660ab5a4e2661e171510f5b112d8cf97a6af27d56d137c860000000000000000000000000000000000599f3f82f29b493ffe9ee3a8363b9a599a5ef3c9c5c680d4e003f4ac5a7de0562cba8e2a4c6da7d07cbe86c3f7bfb85b36620f65ed84fc0bb344b4b73f4eba4b1680a47b28b47f6d10f9ee82398125000000000000000000000000000000000cfdce7997601afbe484901893a1b5fc0b83e8d238d41d2f889a58fd4d884df1c667a000b53b587df2c42ad46aa2c3e0000000000000000000000000000000000c50bf3e06400cb10494cd09bd89f3c96ff49c9f74dd5325f9489ed6be13b59bd7b0b2351411ac854d430405b8a2a3de0000000000000000000000000000000001db313a34ca4073e4fa2287e234ac32bc579742de22e5218f7873b922f5804894826e6054925a394f125fce850f33ef000000000000000000000000000000000e0627a66d286e8d4d3654b32fc5f552a7ca12f0bd47eb6dee0dde22ee48165247c067a0f4c3d422bf3562d38a3c0cf1249ca9bcf879a770b0a054422a6ea97ae795118ae45532c1523c842696de6d170000000000000000000000000000000005285ba39f5bd981fce2fdf853706d70992acab2dc6d4c4198144fab397392a60d631056b580d0d98f3f350414ce554e0000000000000000000000000000000013bddbc1180f155872376fcdfaff2fb12d3d9645b81bd1475a5323ea855cea820ed7eb693791caa9bd3fa5c66036439700000000000000000000000000000000125644d32df397def58dff875d7e3f14166e765ed49a3991f45b38d74db3985fc7f5052058d85594c8b97afcf850e11b000000000000000000000000000000000fca4662eb1b39f576ee820385fba88ddd2fc01fcfb9d9f874453ad725cd5defb357be028fae97ce71bc5ac26d11c1bac014a0aa616e809b674390b4553bf2d9bf325e73d3a935eba94488dddee4e8950000000000000000000000000000000015b97d7c74c8ec102083b41d7ce5490466e1c0e261b5ea5c756d3f9ae79dd2d8ec6eb5075cfb76dfcf7bfdd80442f7d10000000000000000000000000000000016812f845faf96b8b69ac7a6af3c8947aa25877199e3c12552527706a17b768bbea259ea61ea82c4624a96cbcdf4040d00000000000000000000000000000000123ad55e5cb5ac5bdd3ca0a5afa7c3f8e4b98ad91a205f073fb546fe799ffc57b3c1c3a6209547ffc6ef05fd24be6f5d00000000000000000000000000000000017719f31946aedabe0e9d88ef3f90eb6ceda884f5e3d2ece368373785b2d8bf0f9677731803b25accfcb6cb716e0aa4ab722a1c20f068b6955a44073914c418a082345796912ca634e79983a24ec4bb0000000000000000000000000000000000497e3480d58027c780f47cc35a121ee0cd76c4e84d9a2f9002c04a1c286be990167a0138049ad70467132818f48ec9000000000000000000000000000000000ec0ddf938553105400f70989140ca322d996f48ffb1b35641ca36a6ba9ac1daac1603c100822f80cf62ec3bfb442158000000000000000000000000000000000a0b6ebee28a792df46d2f727af812c15fc91a471e0d8e34b25b26048f3b9606d8375b5b268c40fb04ef8f098e1d03340000000000000000000000000000000017843dd19bfabbd0cfa41fb58e70a8900397d17ccea783087ece90962560f5cf090e8d9eaa873a6a6ebac45219ea97a68b314f83cc3ad501caa44b4c3ca8cf68c70ff6920f445d3a7ada212b6a19ba3e000000000000000000000000000000000b27c82d71f7e4aab9a68596669596df3f62071e921e131ba4d9e59d8d81d370e077e93a4a6a43e059661227f40b38c800000000000000000000000000000000093004917ceb2fb4a1b33960ff74943d520f86e83aa02b9a6c85e4b9a489e9331863cd30cb6ad6f099d03289b4ada5520000000000000000000000000000000016f04e35186c7deaf730708e1678089bf3e73c1164bca24bf8f70c4f6cccd5bbb34bbb5dc313ee428aec4ac9c638a01a00000000000000000000000000000000011052348cec9dc3e85e01abcca5a652461f08a9f5d72b3fc27140a6a571137f0065ed7ccf9ec8cebe314ad9a214d5ed94ffab83099c69845cc87727d459ae300a5725ec53176424ab0ec8bd3f80eaff0000000000000000000000000000000007083dfb0738d58ba8933a1f60283e5da8bf90af5aae4053ca573ee7223d3b80e4bdc30b4a831ce6af9f52f393e9742600000000000000000000000000000000130c627b7d3a527c94cfeba9f514e75eac047e1b6088c082229a8c95d0765a0898ce1e45694ca2c7935bb8e41e44e8b10000000000000000000000000000000009610645b074e652a08f2b89dbe594afa3009d795ef211f7c036a56274b1e1bd69a035c4f356b6b21f69b9cec2bf7c32000000000000000000000000000000001020f3cdef468af700269aa1e9d928e71b8c521f23586c9b0155314f0073da7de04ca41ececd5edcc052af72c05f0e4bb1d80be637e2abd98d0433150e14b629d98fc0918c7dfc179204669ab465e90300000000000000000000000000000000123540047f0768b0af841aa4aeceaf3dac31ea832daed86c8cbd1d33ed0282c6f697d5881f9022af032e90ff82efb6bc000000000000000000000000000000000113daffbe413075f5f4f6fb42f37b6e9d5e5822aa24d6f865792f63e6078584246bcf8b17117385db1d6233974f6ed9000000000000000000000000000000001067b46fd221b6995d25d4bf0adb088e0554d858d4e5d9d6b59e1ae2a7d57188d559b0208918a8944aedd62b1ebd4f4700000000000000000000000000000000087dae77e483d5c0baa37b9b96dad5ca92b5869fa253bffad24dd8747446f7ce60858b52438e58233210d86f470f765fe670a57ce4dcfa680e60ef33ba99c437e4fdb160ea1012de36f4b59613a6af8500000000000000000000000000000000039d09a094d655c139cb9714aa258d9548473162548048b0f07c9317a41a7e5dbaa5aca156992c8a509d4071d9ae4394000000000000000000000000000000000f0273a38b1b9d006efa43c15a53f026587a676912d0275968608519e97994ea9c6a147e377f68b1738ebeaa178f9c1000000000000000000000000000000000132cd92417578d2e46884f1c1a1080b1916c8c8404d2533a4de02bf8575c80ce7e8097c2ddd1f95737355521c0ec21ce0000000000000000000000000000000019adbf09a268a3ed8eff936d25fbe8af2874e44d2580c7941dc14fb89c5da963b468a7088c4a763eac89f4d15deaaf5e54a999fdf391d3944318c54680e69b58ce3778683b6f2c607d64450ed32c6d89000000000000000000000000000000000756dced467ea32c3c425590b7690a45e250e464ac6927ad3f5d2d8d2826961b8dd7572db609375c8d06cc3b9bc3a157000000000000000000000000000000000b79b4eecbaf1d0f8a89f9ef8fc144b3aff38148ae260da7c20e9dd3866d946585df7ed12c8b7005e7b0e1387c9db41d000000000000000000000000000000000afc403b008b70e19f17b1ef37c9c396577a585b6c34b23d09621b891efc00ef9460c3f4b5f3e851ef63620dc06c824300000000000000000000000000000000024e06f3f3b18c026a166c41f75d7bcf699480f5b6811463c27606c9ec1232fd249a46235b7f5b5a2ed3b53231b333150563ae7b444cca7ebaba36b8d59aaa5c0e6c1454a4a2907866247e752e640a7d,0000000000000000000000000000000004f2480d0b7e84a996965b76055f6879aab5bab26656e4e5ca7220adc17f14b5946047484327bbc5952d9f2ffa5f92af0000000000000000000000000000000002f7260c55c500b54df4391a55eb4adefa7d19bcbec82a107fc0d222c898b97360a679a02ab3023ce2ebdcffd125ddf30000000000000000000000000000000002cddfa94c8f6b3f29c2fe018b1f8679d0e98c8c2656f86f327b9cbcba574cc52643ab423b458994a03347460deef6570000000000000000000000000000000014eb4c84f71ef5935e707a11a92ba34780677ac7eb198e160585ad92aa5c1ea21e3a77be940fe344e7e170680e2a8d53,240480, 000000000000000000000000000000000c2c4c039047d297049afd0e8f0375bd4294d628d3a22078d93b684b737e8c4b6ad3ee544ecbeaad6b3c75d8d217f3a20000000000000000000000000000000004c77a2c0943c6f997ce2e785461f8ec253c47273ded4e1af43ae882766ef8c168e66d831abc2b3b3a0849bbc210cbd40000000000000000000000000000000004456a6c267a5cc6b7d9a9f573270855186a1b621cfdc465fe71ddb4d614565d9d36b13985b31396587919226843c6230000000000000000000000000000000009487cdd8a0cf7f40e9087fd3121cb480730f4302339d25fa12128033239662ed65579a59b837bf1bc5fa87db15b15335b59d128b5ac47106b4114cf225dceb621d177141ef5783943f40a54ad94e990000000000000000000000000000000000ba43205e8392168824f77bac344d60c1a9a0b14ab55538c3bfea4a64984cf381a2f61c64f1ba1bcfd8a7973e43f6e80000000000000000000000000000000000e95e5ac415c3e3e7c9feb6e7a2af3e8189afca06ae1fe54bbeb31783810860921ab3c76a475fb227b3c8299e3f1caf00000000000000000000000000000000001e3cb2106a23e77a126013087751c4d2a419a51beedc3a33faa6c933bedb3d34ee9c6450c583642426edb352e04da98000000000000000000000000000000000ab5af4c98aca1fc3fa55355351d12f3bc639662bf8b5b772152988d676b00ef39f767237a2fa3be936e83d1dd77da86a057c0405e24b7373f67197b2109b633a02589711b6a92ff49ca024f893d7ecc0000000000000000000000000000000012f3d927316ba638bd6294f7dd2f3f166d20285ee1662ae4dc145835704a17127078343d26042a5c397bfef31754186200000000000000000000000000000000162893d6252361c340057bcac31986458b8b55a8a4283f5a06ce1730098f9838dad1bca264374e7261bb9d08c177c1820000000000000000000000000000000017264aead0ec41a079827296f3d32c12adfca7cb6c674070d54087438d57b6ccca4822b2337263e60075d469b4ce0ccc000000000000000000000000000000000480cae035bd3bf1b4a4a766bcd5f188833e9587e1aff0e1f10e36ebbf2f3ae76bc0946e7c336efc3ee00bf42e7efbb9677b05905180182427efeb848b2ba2eafbabc7519ab33db14de0746afb607191000000000000000000000000000000000d13375356b1518e37a13b43b7d192eb74bd69636f91c570c41a741a8763c03caf8d13c7364f57c867a4a3983e88060f000000000000000000000000000000000f6f78dffb404faab88ac7373e0c765209c0af80514d438e18393bfcfeb60d9a5e13158d399f43162033571ee4a75dbc0000000000000000000000000000000010c379860638ccf3b6cb8479aa38881b0004197e3e367a1d5ef7c7fcf075689d283b87022e2825b5c789ac6a448467320000000000000000000000000000000002dc392872cf2fcd8e196f10c1ded175300070e4e38aa58c89c81e1aa5faa08d770a5ad90a8295a890551f9329a13cee53e7f69582f4c106ee5bfccba1d5f557736c1b75b6e3777cfde47d552e6bdcac0000000000000000000000000000000010383a21acda7c8f3f3be980bff2d57fa0a5b2dc424164dd2ce53c0b20ca399d6227913b7b550462180b01c231e4813200000000000000000000000000000000078aec90354721f0a31e1377b3652bcb1f388ab36f1866c955f3ea8dfe6ac2c25bc4cea14f54aee71595c2c1bd2dc4910000000000000000000000000000000007dfeec77213d952c183452b98ad936e8854608d950c0c1451262cdc7d6de5aed0db07a8d74b3e8f674967cb4839c4d00000000000000000000000000000000015c09e4ed2ea76d10d196f7a733ccc272b94dc436d6bb5fafad2fae4a96372c2c6f1325d1554746814ae292d8e6b1e3634c87bfb629b817e7ab97def7400b0a83e47af8d628787ff814733fdf34ba8d500000000000000000000000000000000138656fa091cc6613b1fcff04a3efb4f9c393985b2c78fa838eecbbbb8b6dafd88d9c72441f9bc735649480b5187acac000000000000000000000000000000000a35cec4819ca3321917cea5aa589db8cf61882fd1135031dc41a8207a8e71d326312799291b160a646148c382ed086b0000000000000000000000000000000005b6e4c02c9c54630c96271073513cac3a42d47a7272f62a21c7ad4c85c19b60b70d04719626cf4273f6c5691719931700000000000000000000000000000000166a20da734a47d7e28cce8f0c2d679fa6c738a7a1ca9089dc67ba2b1c92a83b024b8991f131e7e8802a617153de4554bebb60069acf431e1671e3d00e4da0d70fa11ed4099b21d45a2b811f99dd9cca000000000000000000000000000000000a4432a544deda931b1f62759320ada2963062e722bc1b748c9bd0d026ffae10f228be36ea0ab076358924f4c06b6feb0000000000000000000000000000000000e955b1b1b28d2044b6be371c58bc85097c77145b239e913bb0729757518c465d9e69338066f7496aa6a2038ea604f900000000000000000000000000000000017ca2a7d52c3a82ab8abf9fc1bc187389b6e4904e161541008e5b3ba0981870e01060d1272a6d59bfcfb294c942403f000000000000000000000000000000001870649a50e0978185551f213eefd9305d33e92b3f8c39752b6ebe18ae86ad97f92acef05971dceee3b3729becea18168b1ee2765e762f1b8c2451270cd5a755758fd733d7922a537aa9f1fd7d0c95960000000000000000000000000000000013713effa20d5039ced751ebafe1516f062f11ee05ffad37281cfee9d7a49ab14c065709832f6674bfbf2c9f379bc9c9000000000000000000000000000000000295f7ef148430209b48c292b024474f05036edfdee082c56aea05a62f1fba3ee7a540955423f78614c8385da8ef60040000000000000000000000000000000007408c97321b6d7c27e5e442a9e35b054e743c34d845874aeb1ccf4e903ca7803ed7fb1288327865f9e0ff0a388e92b400000000000000000000000000000000081808d03722a2d48846a693059c2662dee614f181dc406825544d30a6adc0f9d84a712eff80bddd4a27a036e4bf7359d5009fd559714d5692de5500ec8cae9c04ae1ab1c7c6e08c8738ef22da19ceca000000000000000000000000000000000880b646a674723c15b240ff56d2031e5db724251b1402a68df8b26261ffc9fb60a81abf165c6832137dc7a7293142d200000000000000000000000000000000172354b62bfb8d388b5a984411414738302725a508e8abeacdcb46454371d5e9cf762028fb65921d5c3dd8c67d42a981000000000000000000000000000000000a1af459bc3122dcef78359e468f4094d609ae3da09ca5aa6efb71a7494dafa2373a3906bac1f324d98b3eaa982a27d500000000000000000000000000000000092ac3b47253c7f090df076914cdc08a715faf153e8e365392b4859fca1db14d3f7fb998c97de9ad99b7d0b357252f086330c755ef708d8eb129475785f24be9e7836385ac918c60ad36e80e2f3281b80000000000000000000000000000000003b23eff722c078a781771d8b75d519e7a062ca3e4252ecca877845920158fb20d79a9ce449d9087426b113da0091826000000000000000000000000000000000c9026e8d3fee6282492393db504a2c41db19d8fbb83260624b05ba4107d6cb2c90d645a3c16862b27cc3fcce9bf89840000000000000000000000000000000018b8648d0a42285d474f809519696df9e1ad5c35d8e848ad74fbee37425aee8844a8be8cb4d3331670ee294ddb9a290200000000000000000000000000000000068cad37ee8578f4b502ac2ef4371a10e5432e57fe20d0cb074dc427831872113d3514a0b199d813b796b8357fa2a3dbc2431888d05cae840dde4c26911db1893659fdc345d5433556d9bf75e51fe3740000000000000000000000000000000013200f0aea4c60937be47213b6149b0ae76767f3559e0519f774af4a5d9431e2dd7ea74b42cc3ceb28ccf0d2f01116f30000000000000000000000000000000001c5bff08fd16ecb68f21289a3e7b9a2ec5da1357d604710a18e78ab780f8ef0343d5d9ee7f7988a009329b17e498beb00000000000000000000000000000000125453772eb9d1335ce4dbcc8f2ab8426fe89a0e49fec51d4e96718a38570aa82dbef452368141be2df260fb131c50b2000000000000000000000000000000000432cdd445519775b9914a986a0941cc829b4a15cd361df9ae7129547b24f7a6a15cd8fe9393fa1551db2d761a208b8ec9a72369cda74e5c86c6559cbc4f4db1b3ab24c5150c7decea862ede3c02c505000000000000000000000000000000000396cb6d7b44f92b716ed02985d351b4e8cd1bbb95f239e4f29d7379428470be395e2faeb8e3a910007aaa490d3c336d0000000000000000000000000000000000ad0c0623fdf50c2b504777554dbab3cde1b9705e976561873d7c22b81f49c7654a7c76e558fad1518ed73a0d3c3570000000000000000000000000000000001241d5bed68e02a2ddeb3ccbe109a161abe81edd7affb72182c5163851211c4763e6aecf766053b61ce575de893985f800000000000000000000000000000000183696d2a48feef6088f4e9f75a5055e8c54b3813658b593958490ddd4245ac495a8ff966861b20f26047f07fa8609a0c2f50989b04fc29c4c4a0090fb11e860c15f89a66f3bb8281e4678ba63ff3f9a000000000000000000000000000000000fe0ce41aa9e7cb2bcb4e01721b7b1d99fca4e9b7c4df09bec00bd346fc57c25118ba70d5333b7f3eef2659c64520a470000000000000000000000000000000005c932e09c62b7ddaf3f5c420c60740befa7cdff5bb812e0f089c45098d71b57004b7a207f0cdd34daaa3282cf6e9f7e000000000000000000000000000000001874200ead9776c1ecd6a54a57e5d0f9577910a4b3afb9b051622f658fe3ef6cc5070af60e7ef910562720e9716158d6000000000000000000000000000000000c2c657e58e400a67e59deee8c28234ff4688e781a2f6f2f0d0b186a5e4012695a522dfa0770cfd543f55939a05e20b09fc9abf1c76ff11ab538f46ce768ba597eb5f2f63073ec67e8de10aa1d666720000000000000000000000000000000000f0b561e5860321249b9ff434c604d26c3275824fc4ab9c1ce5c5858605ddaafae83ae27e523bf6006932f6c7f33d0a7000000000000000000000000000000000b47aab85bbd909599aa85c5eda363b67790ac6729fd8b1f4f53f66dd796cf2fa3496407b1bfaea4dc8eae53519054e70000000000000000000000000000000000cab1ebd23bc05c53bc9e8481c469eac3ee1b140af545bebed10a8fe50698d2ed883219881929207c0addf2f687198d0000000000000000000000000000000007742de55b799950e6f786f4eef45d0fb67e0475272ad68a183135b70047abab6c2ed51ede16c39be7b986df334e9e75d4167723682bc0e7476797b3be5e14b8de3e4e23b4ca33c50a2096cda8766dd7000000000000000000000000000000000923861332988bc843a65ec5dd4637f9dca8a15e71b82c780fe60d768213d118d8948ab554e30bb9253e900a9b7d87f200000000000000000000000000000000132b1faef49e7966a05783ba526e71134bfb577b13116548352da37e91e617d7c72ed2645e672ebbc517e079247dfb0e00000000000000000000000000000000000a46a8893a194ebfe077afd05fb25d4680f1e4991a3ec29475fa5651d086d20b38136155a65a4c70af31de5a78af59000000000000000000000000000000001344eb957594028b4228cbdb8efb03cc7cf49ec43b2ca5481eae1df6f2df3d5be9a7c4e4e78f8c39be546e29a83c92f49644c3727f78dd12811092190d5d10adcd5b9fc581dd783c97d4e7b5130f309a0000000000000000000000000000000012d7111303563a6358e5ce9155d7a153b5781062c2f6b919efc67ddfb4c61ef03be8828ca6339397b84763a5f8a7e8330000000000000000000000000000000010a2a0ea9973728d3fb1b5906ee84b2635c687c11398ebf605cad30216df3b7b4e3ee1653d4b323a690e6ba614ebec30000000000000000000000000000000000b93d5de37b892d4de9407a820c73ecfd6cd9fa565db82e7e8c14c8406823f705ff0adf6bd6add5ddc5f72c91e52e840000000000000000000000000000000000dcb320ceba5436df8f099c5a77f34376c96d830f5e8ab80667d156d89f6bf8998c148ef9a53847ed395871ab86f6d280df9846c84354ab7f947caca7800e12e38d8e6651527e6831f4d8b1bd66c4f3d,000000000000000000000000000000000ff3e299e6b9fc488d6db991cf9d226d330846e87c4a5cd3e5d4ac955bc2c3c2d1ee5ff230098b48f594d256495f489800000000000000000000000000000000097fdb8fc95d64c7070d8c71e0fd2a933d1e1ad3fefa230f079bc5743828317cd1b0c6d4253ba9c3c6ec6b12d53afa700000000000000000000000000000000002448bbb179d82eaa453cd5452752b9a083b52694cc65c5d9b47f72eff118d7aa06b0fba18eafe93d2937d7399c001af0000000000000000000000000000000009dec4c0aff2a46b07855c87e08832811633709ddfbbc30dbb7e78b3de43bd95e383baa6ff4c58188f0c7643e0ea5a40,240480, 0000000000000000000000000000000008afabec8a9985cbbc6246825785654c1d2eb7da5a01f76c4af4d0096b9baed3c33dbe492d14a6f9e762f06eb3d198f800000000000000000000000000000000027c592315dee4bcc892acc6f41a6eff5219c308253f7cd715d0e4a32c03c6d0d0e8568e146e9e799ac3025486c77fc30000000000000000000000000000000015b4ee27a3aa518a1ec1b447bb8f9128301c85b7176296d68dad3339b1dee78715b2f031a7fb6ba376145c97ceafeef60000000000000000000000000000000004b7e30ec7cc024ced863ce511cef3cabe954a4e5843dd636d776645a44225a36ed7e153ab5bf5d18f23c6444751875c8a71abe11a893fce872f6b8a020b6d84241df03eb934b50cbf3571df4800a83300000000000000000000000000000000119949d36d8d8e2bc1c26ded5f5fb01225a980a28b934ed3862480dc9297a3758e0f08ccaab3a09b5e5c0e4215e3246c0000000000000000000000000000000004a82dc22316ee6af39d937b662d1f1f2dc855c2ca8f33ec3274d833e87d594633fc7fab247911e0f46564397910d6ce00000000000000000000000000000000196900a09d8504ed960d41f4a8a2cde2e5dac61b008d3f6eb47e86d7b2ce6fcdc0f85157e3ab1571094d9fdaa75d0d500000000000000000000000000000000010c52ef9407eb4ec57844aebbcc3ea5000b1940d035dcc2a873327affaaabdd79e3560cbd29c63ce04f6279056d6eed1bbf28e5bca314391550d3a0fce50b1220965860e72c8c3865a2d4c599d31d3f1000000000000000000000000000000000e43655ae05dc6cfa93113dc26cea895d1c5bc73f20454c7b441dbc5ac80035b290514b13b31b41931ea5336d8d9a6a7000000000000000000000000000000001199a873958c63147e6b82625dfea15ce90dd41ceb4e315f67221eb874ef32c6a2953412e7e981659c72239a7a72bfe6000000000000000000000000000000001845af5936b4d7487ffe59137ba2f86daea3770cf37fd560969ee48243389941a1072205e049ddaa06c0ac56b7edc8930000000000000000000000000000000003cc831177f24614f93a118b896434105f05a277051a852fb9973a775fc54f779c2a1f3d64c457e5231dc22d6aef606b58b208a6845aeb2bf31999042c59b7b130a7ce5297e88023953b1aef63616fe400000000000000000000000000000000005e63584bc85ba58615985f6a466afe05268e545e0062cd7214e0b6fc8b87537c745b754cd9a1144948bc88b3c43acd000000000000000000000000000000000635b6a49090ccede3ed2ef203f0ed164783e3df4d9a7d93319515cb9230bd841b61a097f39e30175793b3e934d8e426000000000000000000000000000000001861e65f47a9da1584c45bc79a66045d86bc1709c2d1cf6cd2930a9fcc8c4efaa6536b5015be8d54789e8f574f93f9f70000000000000000000000000000000009290ce63d55eb436794acf11be9d896f03e7608a1bc8528f61ec9473f054bc9fbbda1072440e58e2f6ba080a01180173b53b6cf9e0ce1661c4960283be790abf956c2d6433529b8f3a32b92b227aebe0000000000000000000000000000000018feed9500bff884d2bb58554da2180c68267b6d3a45c2c7cee4c3f8524252d3faaa5eff971bf40123587e669fe66bbb000000000000000000000000000000001441bd3b58b4a4a87c2459f873c0692f5977b775af984bab46dd76cb9f775d2faebcb77b2854c9f1faa33f6c5de61c6a00000000000000000000000000000000123a890c3362c77e5b5cf9846d9c9e43fb3242d5a831e640ad080993fa0547854c8d11cc22f7f7b426528bf1154d2300000000000000000000000000000000000ff4a59ea98d13cfd353ae61e18d3c7018688f755561e6a1da5f09acc4277e8d49645087115acc64f992ea778a11f39bb049228435ade4c4c565e65f39f13a84c747c312afcdaff352560b9fb3cfebcc0000000000000000000000000000000006b019d005141e82393a2ca04469d1f6fd7b9456001ffef4c34eff6b2e91df58e99fd07944f52b108bd41ab6c4d6bbf200000000000000000000000000000000109ae87042029856befff0c916db5437e1e058a96f2970d8816b3becc93a1a50d6d336d5451303715f3e272147a36caa0000000000000000000000000000000000fc381b8dc9dc02d34db13e34732a10d0dfcf676c224a05a3bffd888b0af7c415b38af0b6afe6b464ffca42947c6ee5000000000000000000000000000000000087040d09c39ccd06c9ecc360fa02147a32e8036ad6e4b6bdf5b3883722a4e5a887dd022d53706d2585fe558696be6656197f5ad17062d2ecbdc8887bcdd32e5ed4c48cefd9e14d622a0b800d970330000000000000000000000000000000000e35c27b29df0fa9298bb9ab6a38b3450782223e2115d79152f9baa924d762d583b3ebe88e42f33028814ec78e5b319d00000000000000000000000000000000190c65667627a16f0af0ac7f23af0803bca810f3986b906b7b4f126d98473d52badf45e90e2e45bb390242fa8c40135100000000000000000000000000000000103f0283a5673c16bcc0f74f259c2eb077061947da04e467dfebf62aa005491e32b85cb73418b624a30dbaa01672921e000000000000000000000000000000000465466955c908607191faf15f0768dce42488c488eb4a065977f21ac7484766bc0abf23961ea2ba46dcc04956abf6c7721d9d7fe10104cafcad71307e785321ab87b2b69593535caecbf0e166cfda5b00000000000000000000000000000000082346e352e845a54cd4267f93b85b2c8623d4650e00c1c56082b73ee31f63588d2c117d3cdecc0378fbbf8956b082040000000000000000000000000000000001a7f43c2bb19cb32345c43c950536f8e85815b86364f278f6ec8169eca80917c2b8fc08d59b20cf55f25dc468e7bd7f00000000000000000000000000000000085a5cb020df10f9b4c7afc01b1d11700579dec1e85e766507def2e6cf5b714174f7be9cce3b18533a5ebfeec2b4e481000000000000000000000000000000001836d7506d1cc984fb777b8ee935d6f5b110644f59e96ff44d8329336d59a3e1d2b53a05d35e97f634baa4fdc11a6cd8461531ecb61365908019c1e8074a4c322df2b356eea3f3eea9aa1e0e1fc5525e000000000000000000000000000000000c1c59828ec6257a02679cff0bee0d665d449d2a158bc6d877e84cc0fe2161c297dde09b778d5e1249c515833e483004000000000000000000000000000000000f5e82589bfb7781e4110f1486752b00cbdf96cdf4191d75053c6d6d646e1c989add011361031a11559e156d64139fbf0000000000000000000000000000000015053afa7fb2b4e4b70f3c8a570fef8288fdc22dd951b6ba8a40b6087b9ab04ede21f0ddfa84d6d18914041bcf244c110000000000000000000000000000000003f399800cba51ab35624d866831ab6506392cb3acf549787153ffaf08cc451acea46c7a612821dd96c45f8b75133d88569c1c1ae2d18bbe36ed50db1bf30957802b09a982fbed49d4968815552e010d000000000000000000000000000000000e26242c8f73116079369ef4265f624abd4377e4e3485c28197663de9de9f5618c3b6ee602ff6bebd1c242aef7295b2200000000000000000000000000000000066ceb3ea6067220bd28fa1164237782859d27c1d3087a42b4d09bcc343611e4ed2be014a27f5b394c67643dc00f57cf00000000000000000000000000000000157f9d30de52110ea7a2a35ddfe67d9fad7223c5e3307e797dd0df3621520a421958a2835205e3c4777923f47d47e5310000000000000000000000000000000016ebb41beb85b9489a6d5482f8a3330a5c5c5e5718e8efb8b67362f9d8e9c313e9e563275ba38c207c5bf3d89c406ea62061d33b2f7e786effbd2e93101a56ba1bb62c1a773a08b72ca82f5183bea35b0000000000000000000000000000000005d1c9109b5b7409f94ae3f7dd9e8ae4908a9b378fea4ea284cbd33d1e59b605577b63892aaa8ec14d415f34e22fec520000000000000000000000000000000005afed05e62599f20f7eca019f41d770c630cf6359cb5601464be821691fba5205c16e7b580e6881047214f938e5104b00000000000000000000000000000000105637a2aa4725d8e080dec3b731a111ea4c94b79f898dfd51f645501ef0c8d68ea8e80fde28ff96e927e44306ebbb1d00000000000000000000000000000000080cfeea754474ceb37973234d5dc3269f8ca99bd862d4d2d1a602321fc709945a3209e5ff2cc962cfa6d03017c9a1354129b150752d2d5551a622231ab067931678454aaeb23f76168219406f0d50ee00000000000000000000000000000000137762ea5c80033aaf17570451b15a062feedde810f11ebdbe9a79a3275dc12613e0505835c122bd5f9afea7dba84203000000000000000000000000000000000d89c04e45e60769a63fcd73df2a138c457bb549195f2c4eebb3be1ea46149f286756795be8328b5b886f497d8167b34000000000000000000000000000000000be43d515083c8c10f467618685a43d4d5f6457204bacd278445943a9f44f7189b561a0e1bc59d2757fcfab2e3f93a4a0000000000000000000000000000000011a52583227c6dcdc1784d3633fd584612a9f3bbc1922477396dcd5af84413e5e9382a34a71b3a72491ea09fab2fc6bf366c32d5d3c132f32a6ac3cfe1dabb649c59ae224338f747ad98b193e8346729000000000000000000000000000000000073acefe33525dd2d5204cce72371ed82c7e4b58d1b4e7f4b4994f9c58b02d9d6206fefb3552446b6b355e860ace43c0000000000000000000000000000000007344eaeaae71e17930e769e02bcb4f44ddf3d040ffa0b081f25901cc125a37a58a6a5d13e7b0ba493802ccdaa054e29000000000000000000000000000000000a65fec6ad29ec3eee9ddc7ded2297f49d03ff18a255f1e6d29d2a67c20713f319d79d513af0c58ae3cddfd1f6240ff50000000000000000000000000000000019d5f00d9e2b271f4e9ac779a096386f08ae124f77fb8183405d48ea7f16e685805442dc67a392aefc643ea95b4f1fcfd997516cac28a3968ac6946b5bffaace0856a52e38fdcca11ddfa16cf5a568f50000000000000000000000000000000018230bf1a873aa04855af1426da30f1b3ef4b64eec613b9f660222e3827b325c318baea031b463c7e9f775165d22ec8f00000000000000000000000000000000017faafa1294fac53e1de8cae9601acc62d76a5f01a39ce49d65f3f5d2cd5cca33eb90bb4116b3ea36f912ae2b81b6cf000000000000000000000000000000000fc3ef5ea59849a87fcd45500989f1744cb5570ee88e34a952cec32cea2eb5900b64d8d0d04ef5c51e8fdcccd46412490000000000000000000000000000000001c53aa8aaae8422fa4fddc86cacdefa89c37592c8e67e472a23627514623a90901a619af79e93561a0dc65215837274e881ec65fdc2f58e46d3ee45a06d0c5ac844ee5b62872c7ba21f6b48621a3371000000000000000000000000000000000e3db6885c2db9244548e11b8c49b73f85e4104b413f54308497262fdff1957495859830114528a22c45d39a554ba82700000000000000000000000000000000181b1bfe2d9a1c563e73356d73f4ed3e7061a79c610bc97c911ab1a0213d123c9f83ed6706e862087a796ce14c5cf53d0000000000000000000000000000000013f5fdceddce771588869b945bd6025e5ce485fe78a362356720b474b83998f27e535cfd8d33ee51cfc68e5d514f915c0000000000000000000000000000000007e8fd7ba457a3cefd50c641847425cf2262deb1d6945a0bd740eadf38dcaa616edc48c3912508d663349f089b8b56fadcd9b95e49473277a665ca0f9a8309df9ed6ee4f25d803aa967fb8f688273e650000000000000000000000000000000004b20b0408da7b704694b47607928a655077015f2174fe01bac9a0b3a61dae087b0b593f58d2947d8d84f75bbfb327c900000000000000000000000000000000106d623b2007c5d7128e03e540325ba763e992a651e2e5c78936f82ee2ff72d89a1a914345486cd0a04440c75beb190b000000000000000000000000000000001847348e5ef429cfdf1ba4d265d8c5ebcbec3d5dd4611ba36e2754fbd3d327273bf2eb7b7ba4b3888d059dc87f034739000000000000000000000000000000000bcb0a9dfe5189bc965e9721407b4cb3ed4171510aa4d4e5d5f0823a1c2827643e1278f9c0ee960c54ef8f6c208eee7b334582482a9038ab906880e43a4a9d39e73b6c63604eba0c8f6399eb5c288638,000000000000000000000000000000001205b70b29ee04212589f8a70a71e004f517d3354e714c1b4fe42cf93faf1a8ed40dbc1b5089ddb53bb052c9cb74c0e8000000000000000000000000000000000f619082734dd9de653b61cf2fb927199f228637db70797bd2a21fdd48b6ecd4c4f712097037534024880a436fdd63680000000000000000000000000000000000592eca560be6ae256abe1796f7ec394a8085c127437f6590c8d41501a482c61456392cb320b9e801044dcba7802df9000000000000000000000000000000000a6d20b8009708ca01a274aed6dece732c5eed5aae5e4c2f3793b5fa1f8cb8c95037ce387bda2e7476e9c493507c7fbc,240480, -000000000000000000000000000000039b10ccd664da6f273ea134bb55ee48f09ba585a7e2bb95b5aec610631ac49810d5d616f67ba0147e6d1be476ea220e0000000000000000000000000000000000fbcdff4e48e07d1f73ec42fe7eb026f5c30407cfd2f22bbbfe5b2a09e8a7bb4884178cb6afd1c95f80e646929d30040000000000000000000000000000000001ed3b0e71acb0adbf44643374edbf4405af87cfc0507db7e8978889c6c3afbe9754d1182e98ac3060d64994d31ef576000000000000000000000000000000001681a2bf65b83be5a2ca50430949b6e2a099977482e9405b593f34d2ed877a3f0d1bddc37d0cec4d59d7df74b2b8f2dfb3c940fe79b6966489b527955de7599194a9ac69a6ff58b8d99e7b1084f0464e0000000000000000000000000000000018c0ada6351b70661f053365deae56910798bd2ace6e2bf6ba4192d1a229967f6af6ca1c9a8a11ebc0a232344ee0f6d6000000000000000000000000000000000cc70a587f4652039d8117b6103858adcd9728f6aebe230578389a62da0042b7623b1c0436734f463cfdd187d20903240000000000000000000000000000000009f50bd7beedb23328818f9ffdafdb6da6a4dd80c5a9048ab8b154df3cad938ccede829f1156f769d9e149791e8e0cd900000000000000000000000000000000079ba50d2511631b20b6d6f3841e616e9d11b68ec3368cd60129d9d4787ab56c4e9145a38927e51c9cd6271d493d93884d0e25bf3f6fc9f4da25d21fdc71773f1947b7a8a775b8177f7eca990b05b71d0000000000000000000000000000000003632695b09dbf86163909d2bb25995b36ad1d137cf252860fd4bb6c95749e19eb0c1383e9d2f93f2791cb0cf6c8ed9d000000000000000000000000000000001688a855609b0bbff4452d146396558ff18777f329fd4f76a96859dabfc6a6f6977c2496280dbe3b1f8923990c1d6407000000000000000000000000000000000c8567fee05d05af279adc67179468a29d7520b067dbb348ee315a99504f70a206538b81a457cce855f4851ad48b7e80000000000000000000000000000000001238dcdfa80ea46e1500026ea5feadb421de4409f4992ffbf5ae59fa67fd82f38452642a50261b849e74b4a33eed70cc973f40c12c92b703d7b7848ef8b4466d40823aad3943a312b57432b91ff68be1000000000000000000000000000000000149704960cccf9d5ea414c73871e896b1d4cf0a946b0db72f5f2c5df98d2ec4f3adbbc14c78047961bc9620cb6cfb5900000000000000000000000000000000140c5d25e534fb1bfdc19ba4cecaabe619f6e0cd3d60b0f17dafd7bcd27b286d4f4477d00c5e1af22ee1a0c67fbf177c00000000000000000000000000000000029a1727041590b8459890de736df15c00d80ab007c3aee692ddcdf75790c9806d198e9f4502bec2f0a623491c3f877d0000000000000000000000000000000008a94c98baa9409151030d4fae2bd4a64c6f11ea3c99b9661fdaed226b9a7c2a7d609be34afda5d18b8911b6e015bf494c51f97bcdda93904ae26991b471e9ea942e2b5b8ed26055da11c58bc7b5002a000000000000000000000000000000001156d478661337478ab0cbc877a99d9e4d9824a2b3f605d41404d6b557b3ffabbf42635b0bbcb854cf9ed8b8637561a8000000000000000000000000000000001147ed317d5642e699787a7b47e6795c9a8943a34a694007e44f8654ba96390cf19f010dcf695e22c21874022c6ce291000000000000000000000000000000000c6dccdf920fd5e7fae284115511952633744c6ad94120d9cae6acda8a7c23c48bd912cba6c38de5159587e1e6cad519000000000000000000000000000000001944227d462bc2e5dcc6f6db0f83dad411ba8895262836f975b2b91e06fd0e2138862162acc04e9e65050b34ccbd1a4e8964d5867927bc3e35a0b4c457482373969bff5edff8a781d65573e07fd87b890000000000000000000000000000000019c31e3ab8cc9c920aa8f56371f133b6cb8d7b0b74b23c0c7201aca79e5ae69dc01f1f74d2492dcb081895b17d106b4e000000000000000000000000000000001789b0d371bd63077ccde3dbbebf3531368feb775bced187fb31cc6821481664600978e323ff21085b8c08e0f21daf72000000000000000000000000000000000009eacfe8f4a2a9bae6573424d07f42bd6af8a9d55f71476a7e3c7a4b2b898550c1e72ec13afd4eff22421a03af1d31000000000000000000000000000000000410bd4ea74dcfa33f2976aa1b571c67cbb596ab10f76a8aaf4548f1097e55b3373bff02683f806cb84e1e0e877819e2787c38b944eadbd03fd3187f450571740f6cd00e5b2e560165846eb800e5c94400000000000000000000000000000000147f09986691f2e57073378e8bfd58804241eed7934f6adfe6d0a6bac4da0b738495778a303e52113e1c80e698476d50000000000000000000000000000000000762348b84c92a8ca6de319cf1f8f11db296a71b90fe13e1e4bcd25903829c00a5d2ad4b1c8d98c37eaad7e042ab023d0000000000000000000000000000000011d1d94530d4a2daf0e902a5c3382cd135938557f94b04bccea5e16ea089c5e020e13524c854a316662bd68784fe31f300000000000000000000000000000000070828522bec75b6a492fd9bca7b54dac6fbbf4f0bc3179d312bb65c647439e3868e4d5b21af5a64c93aeee8a9b7e46eaaee7ae2a237e8e53560c79e7baa9adf9c00a0ea4d6f514e7a6832eb15cef1e1000000000000000000000000000000000690a0869204c8dced5ba0ce13554b2703a3f18afb8fa8fa1c457d79c58fdc25471ae85bafad52e506fc1917fc3becff0000000000000000000000000000000010f7dbb16f8571ede1cec79e3f9ea03ae6468d7285984713f19607f5cab902b9a6b7cbcfd900be5c2e407cc093ea0e6700000000000000000000000000000000151caf87968433cb1f85fc1854c57049be22c26497a86bfbd66a2b3af121d894dba8004a17c6ff96a5843c2719fa32d10000000000000000000000000000000011f0270f2b039409f70392879bcc2c67c836c100cf9883d3dc48d7adbcd52037d270539e863a951acd47ecaa1ca4db12dac6ed3ef45c1d7d3028f0f89e5458797996d3294b95bebe049b76c7d0db317c0000000000000000000000000000000017fae043c8fd4c520a90d4a6bd95f5b0484acc279b899e7b1d8f7f7831cc6ba37cd5965c4dc674768f5805842d433af30000000000000000000000000000000008ddd7b41b8fa4d29fb931830f29b46f4015ec202d51cb969d7c832aafc0995c875cd45eff4a083e2d5ecb5ad185b64f0000000000000000000000000000000015d384ab7e52420b83a69827257cb52b00f0199ed2240a142812b46cf67e92b99942ac59fb9f9efd7dd822f5a36c799f00000000000000000000000000000000074b3a16a9cc4be9da0ac8e2e7003d9c1ec89244d2c33441b31af76716cce439f805843a9a44701203231efdca551d5bbb30985756c3ca075114c92f231575d6befafe4084517f1166a47376867bd108000000000000000000000000000000000e25365988664e8b6ade2e5a40da49c11ff1e084cc0f8dca51f0d0578555d39e3617c8cadb2abc2633b28c5895ab0a9e00000000000000000000000000000000169f5fd768152169c403475dee475576fd2cc3788179453b0039ff3cb1b7a5a0fff8f82d03f56e65cad579218486c3b600000000000000000000000000000000087ccd7f92032febc1f75c7115111ede4acbb2e429cbccf3959524d0b79c449d431ff65485e1aecb442b53fec80ecb4000000000000000000000000000000000135d63f264360003b2eb28f126c6621a40088c6eb15acc4aea89d6068e9d5a47f842aa4b4300f5cda5cc5831edb81596fb730105809f64ea522983d6bbb62f7e2e8cbf702685e9be10e2ef71f818767200000000000000000000000000000000159da74f15e4c614b418997f81a1b8a3d9eb8dd80d94b5bad664bff271bb0f2d8f3c4ceb947dc6300d5003a2f7d7a829000000000000000000000000000000000cdd4d1d4666f385dd54052cf5c1966328403251bebb29f0d553a9a96b5ade350c8493270e9b5282d8a06f9fa8d7b1d900000000000000000000000000000000189f8d3c94fdaa72cc67a7f93d35f91e22206ff9e97eed9601196c28d45b69c802ae92bcbf582754717b0355e08d37c000000000000000000000000000000000054b0a282610f108fc7f6736b8c22c8778d082bf4b0d0abca5a228198eba6a868910dd5c5c440036968e977955054196b6a9408625b0ca8fcbfb21d34eec2d8e24e9a30d2d3b32d7a37d110b13afbfea000000000000000000000000000000000f29b0d2b6e3466668e1328048e8dbc782c1111ab8cbe718c85d58ded992d97ca8ba20b9d048feb6ed0aa1b4139d02d3000000000000000000000000000000000d1f0dae940b99fbfc6e4a58480cac8c4e6b2fe33ce6f39c7ac1671046ce94d9e16cba2bb62c6749ef73d45bea21501a000000000000000000000000000000001902ccece1c0c763fd06934a76d1f2f056563ae6d8592bafd589cfebd6f057726fd908614ccd6518a21c66ecc2f78b660000000000000000000000000000000017f6b113f8872c3187d20b0c765d73b850b54244a719cf461fb318796c0b8f310b5490959f9d9187f99c8ed3e25e42a93b77283d0a7bb9e17a27e66851792fdd605cc0a339028b8985390fd024374c76000000000000000000000000000000000576b8cf1e69efdc277465c344cadf7f8cceffacbeca83821f3ff81717308b97f4ac046f1926e7c2eb42677d7afc257c000000000000000000000000000000000cc1524531e96f3c00e4250dd351aedb5a4c3184aff52ec8c13d470068f5967f3674fe173ee239933e67501a9decc6680000000000000000000000000000000001610cfcaea414c241b44cf6f3cc319dcb51d6b8de29c8a6869ff7c1ebb7b747d881e922b42e8fab96bde7cf23e8e4cd0000000000000000000000000000000017d4444dc8b6893b681cf10dac8169054f9d2f61d3dd5fd785ae7afa49d18ebbde9ce8dde5641adc6b38173173459836dd994eae929aee7428fdda2e44f8cb12b10b91c83b22abc8bbb561310b62257c000000000000000000000000000000000ca8f961f86ee6c46fc88fbbf721ba760186f13cd4cce743f19dc60a89fd985cb3feee34dcc4656735a326f515a729e400000000000000000000000000000000174baf466b809b1155d524050f7ee58c7c5cf728c674e0ce549f5551047a4479ca15bdf69b403b03fa74eb1b26bbff6c0000000000000000000000000000000000e8c8b587c171b1b292779abfef57202ed29e7fe94ade9634ec5a2b3b4692a4f3c15468e3f6418b144674be70780d5b000000000000000000000000000000001865e99cf97d88bdf56dae32314eb32295c39a1e755cd7d1478bea8520b9ff21c39b683b92ae15568420c390c42b123b7010b134989c8368c7f831f9dd9f9a890e2c1435681107414f2e8637153bbf6a0000000000000000000000000000000017eccd446f10018219a1bd111b8786cf9febd49f9e7e754e82dd155ead59b819f0f20e42f4635d5044ec5d550d847623000000000000000000000000000000000403969d2b8f914ff2ea3bf902782642e2c6157bd2a343acf60ff9125b48b558d990a74c6d4d6398e7a3cc2a16037346000000000000000000000000000000000bd45f61f142bd78619fb520715320eb5e6ebafa8b078ce796ba62fe1a549d5fb9df57e92d8d2795988eb6ae18cf9d9300000000000000000000000000000000097db1314e064b8e670ec286958f17065bce644cf240ab1b1b220504560d36a0b43fc18453ff3a2bb315e219965f5bd394c68bc8d91ac8c489ee87dbfc4b94c93c8bbd5fc04c27db8b02303f3a65905400000000000000000000000000000000018244ab39a716e252cbfb986c7958b371e29ea9190010d1f5e1cfdb6ce4822d4055c37cd411fc9a0c46d728f2c13ecf0000000000000000000000000000000001985d3c667c8d68c9adb92bdc7a8af959c17146544997d97116120a0f55366bd7ad7ffa28d93ee51222ff9222779675000000000000000000000000000000000c70fd4e3c8f2a451f83fb6c046431b38251b7bae44cf8d36df69a03e2d3ce6137498523fcf0bcf29b5d69e8f265e24d00000000000000000000000000000000047b9163a218f7654a72e0d7c651a2cf7fd95e9784a59e0bf119d081de6c0465d374a55fbc1eff9828c9fd29abf4c4bdb3682accc3939283b870357cf83683350baf73aa0d3d68bda82a0f6ae7e51746,,,invalid input parameters, invalid input length for G1 multiplication -0000000000000000000000000000000000039b10ccd664da6f273ea134bb55ee48f09ba585a7e2bb95b5aec610631ac49810d5d616f67ba0147e6d1be476ea220e0000000000000000000000000000000000fbcdff4e48e07d1f73ec42fe7eb026f5c30407cfd2f22bbbfe5b2a09e8a7bb4884178cb6afd1c95f80e646929d30040000000000000000000000000000000001ed3b0e71acb0adbf44643374edbf4405af87cfc0507db7e8978889c6c3afbe9754d1182e98ac3060d64994d31ef576000000000000000000000000000000001681a2bf65b83be5a2ca50430949b6e2a099977482e9405b593f34d2ed877a3f0d1bddc37d0cec4d59d7df74b2b8f2dfb3c940fe79b6966489b527955de7599194a9ac69a6ff58b8d99e7b1084f0464e0000000000000000000000000000000018c0ada6351b70661f053365deae56910798bd2ace6e2bf6ba4192d1a229967f6af6ca1c9a8a11ebc0a232344ee0f6d6000000000000000000000000000000000cc70a587f4652039d8117b6103858adcd9728f6aebe230578389a62da0042b7623b1c0436734f463cfdd187d20903240000000000000000000000000000000009f50bd7beedb23328818f9ffdafdb6da6a4dd80c5a9048ab8b154df3cad938ccede829f1156f769d9e149791e8e0cd900000000000000000000000000000000079ba50d2511631b20b6d6f3841e616e9d11b68ec3368cd60129d9d4787ab56c4e9145a38927e51c9cd6271d493d93884d0e25bf3f6fc9f4da25d21fdc71773f1947b7a8a775b8177f7eca990b05b71d0000000000000000000000000000000003632695b09dbf86163909d2bb25995b36ad1d137cf252860fd4bb6c95749e19eb0c1383e9d2f93f2791cb0cf6c8ed9d000000000000000000000000000000001688a855609b0bbff4452d146396558ff18777f329fd4f76a96859dabfc6a6f6977c2496280dbe3b1f8923990c1d6407000000000000000000000000000000000c8567fee05d05af279adc67179468a29d7520b067dbb348ee315a99504f70a206538b81a457cce855f4851ad48b7e80000000000000000000000000000000001238dcdfa80ea46e1500026ea5feadb421de4409f4992ffbf5ae59fa67fd82f38452642a50261b849e74b4a33eed70cc973f40c12c92b703d7b7848ef8b4466d40823aad3943a312b57432b91ff68be1000000000000000000000000000000000149704960cccf9d5ea414c73871e896b1d4cf0a946b0db72f5f2c5df98d2ec4f3adbbc14c78047961bc9620cb6cfb5900000000000000000000000000000000140c5d25e534fb1bfdc19ba4cecaabe619f6e0cd3d60b0f17dafd7bcd27b286d4f4477d00c5e1af22ee1a0c67fbf177c00000000000000000000000000000000029a1727041590b8459890de736df15c00d80ab007c3aee692ddcdf75790c9806d198e9f4502bec2f0a623491c3f877d0000000000000000000000000000000008a94c98baa9409151030d4fae2bd4a64c6f11ea3c99b9661fdaed226b9a7c2a7d609be34afda5d18b8911b6e015bf494c51f97bcdda93904ae26991b471e9ea942e2b5b8ed26055da11c58bc7b5002a000000000000000000000000000000001156d478661337478ab0cbc877a99d9e4d9824a2b3f605d41404d6b557b3ffabbf42635b0bbcb854cf9ed8b8637561a8000000000000000000000000000000001147ed317d5642e699787a7b47e6795c9a8943a34a694007e44f8654ba96390cf19f010dcf695e22c21874022c6ce291000000000000000000000000000000000c6dccdf920fd5e7fae284115511952633744c6ad94120d9cae6acda8a7c23c48bd912cba6c38de5159587e1e6cad519000000000000000000000000000000001944227d462bc2e5dcc6f6db0f83dad411ba8895262836f975b2b91e06fd0e2138862162acc04e9e65050b34ccbd1a4e8964d5867927bc3e35a0b4c457482373969bff5edff8a781d65573e07fd87b890000000000000000000000000000000019c31e3ab8cc9c920aa8f56371f133b6cb8d7b0b74b23c0c7201aca79e5ae69dc01f1f74d2492dcb081895b17d106b4e000000000000000000000000000000001789b0d371bd63077ccde3dbbebf3531368feb775bced187fb31cc6821481664600978e323ff21085b8c08e0f21daf72000000000000000000000000000000000009eacfe8f4a2a9bae6573424d07f42bd6af8a9d55f71476a7e3c7a4b2b898550c1e72ec13afd4eff22421a03af1d31000000000000000000000000000000000410bd4ea74dcfa33f2976aa1b571c67cbb596ab10f76a8aaf4548f1097e55b3373bff02683f806cb84e1e0e877819e2787c38b944eadbd03fd3187f450571740f6cd00e5b2e560165846eb800e5c94400000000000000000000000000000000147f09986691f2e57073378e8bfd58804241eed7934f6adfe6d0a6bac4da0b738495778a303e52113e1c80e698476d50000000000000000000000000000000000762348b84c92a8ca6de319cf1f8f11db296a71b90fe13e1e4bcd25903829c00a5d2ad4b1c8d98c37eaad7e042ab023d0000000000000000000000000000000011d1d94530d4a2daf0e902a5c3382cd135938557f94b04bccea5e16ea089c5e020e13524c854a316662bd68784fe31f300000000000000000000000000000000070828522bec75b6a492fd9bca7b54dac6fbbf4f0bc3179d312bb65c647439e3868e4d5b21af5a64c93aeee8a9b7e46eaaee7ae2a237e8e53560c79e7baa9adf9c00a0ea4d6f514e7a6832eb15cef1e1000000000000000000000000000000000690a0869204c8dced5ba0ce13554b2703a3f18afb8fa8fa1c457d79c58fdc25471ae85bafad52e506fc1917fc3becff0000000000000000000000000000000010f7dbb16f8571ede1cec79e3f9ea03ae6468d7285984713f19607f5cab902b9a6b7cbcfd900be5c2e407cc093ea0e6700000000000000000000000000000000151caf87968433cb1f85fc1854c57049be22c26497a86bfbd66a2b3af121d894dba8004a17c6ff96a5843c2719fa32d10000000000000000000000000000000011f0270f2b039409f70392879bcc2c67c836c100cf9883d3dc48d7adbcd52037d270539e863a951acd47ecaa1ca4db12dac6ed3ef45c1d7d3028f0f89e5458797996d3294b95bebe049b76c7d0db317c0000000000000000000000000000000017fae043c8fd4c520a90d4a6bd95f5b0484acc279b899e7b1d8f7f7831cc6ba37cd5965c4dc674768f5805842d433af30000000000000000000000000000000008ddd7b41b8fa4d29fb931830f29b46f4015ec202d51cb969d7c832aafc0995c875cd45eff4a083e2d5ecb5ad185b64f0000000000000000000000000000000015d384ab7e52420b83a69827257cb52b00f0199ed2240a142812b46cf67e92b99942ac59fb9f9efd7dd822f5a36c799f00000000000000000000000000000000074b3a16a9cc4be9da0ac8e2e7003d9c1ec89244d2c33441b31af76716cce439f805843a9a44701203231efdca551d5bbb30985756c3ca075114c92f231575d6befafe4084517f1166a47376867bd108000000000000000000000000000000000e25365988664e8b6ade2e5a40da49c11ff1e084cc0f8dca51f0d0578555d39e3617c8cadb2abc2633b28c5895ab0a9e00000000000000000000000000000000169f5fd768152169c403475dee475576fd2cc3788179453b0039ff3cb1b7a5a0fff8f82d03f56e65cad579218486c3b600000000000000000000000000000000087ccd7f92032febc1f75c7115111ede4acbb2e429cbccf3959524d0b79c449d431ff65485e1aecb442b53fec80ecb4000000000000000000000000000000000135d63f264360003b2eb28f126c6621a40088c6eb15acc4aea89d6068e9d5a47f842aa4b4300f5cda5cc5831edb81596fb730105809f64ea522983d6bbb62f7e2e8cbf702685e9be10e2ef71f818767200000000000000000000000000000000159da74f15e4c614b418997f81a1b8a3d9eb8dd80d94b5bad664bff271bb0f2d8f3c4ceb947dc6300d5003a2f7d7a829000000000000000000000000000000000cdd4d1d4666f385dd54052cf5c1966328403251bebb29f0d553a9a96b5ade350c8493270e9b5282d8a06f9fa8d7b1d900000000000000000000000000000000189f8d3c94fdaa72cc67a7f93d35f91e22206ff9e97eed9601196c28d45b69c802ae92bcbf582754717b0355e08d37c000000000000000000000000000000000054b0a282610f108fc7f6736b8c22c8778d082bf4b0d0abca5a228198eba6a868910dd5c5c440036968e977955054196b6a9408625b0ca8fcbfb21d34eec2d8e24e9a30d2d3b32d7a37d110b13afbfea000000000000000000000000000000000f29b0d2b6e3466668e1328048e8dbc782c1111ab8cbe718c85d58ded992d97ca8ba20b9d048feb6ed0aa1b4139d02d3000000000000000000000000000000000d1f0dae940b99fbfc6e4a58480cac8c4e6b2fe33ce6f39c7ac1671046ce94d9e16cba2bb62c6749ef73d45bea21501a000000000000000000000000000000001902ccece1c0c763fd06934a76d1f2f056563ae6d8592bafd589cfebd6f057726fd908614ccd6518a21c66ecc2f78b660000000000000000000000000000000017f6b113f8872c3187d20b0c765d73b850b54244a719cf461fb318796c0b8f310b5490959f9d9187f99c8ed3e25e42a93b77283d0a7bb9e17a27e66851792fdd605cc0a339028b8985390fd024374c76000000000000000000000000000000000576b8cf1e69efdc277465c344cadf7f8cceffacbeca83821f3ff81717308b97f4ac046f1926e7c2eb42677d7afc257c000000000000000000000000000000000cc1524531e96f3c00e4250dd351aedb5a4c3184aff52ec8c13d470068f5967f3674fe173ee239933e67501a9decc6680000000000000000000000000000000001610cfcaea414c241b44cf6f3cc319dcb51d6b8de29c8a6869ff7c1ebb7b747d881e922b42e8fab96bde7cf23e8e4cd0000000000000000000000000000000017d4444dc8b6893b681cf10dac8169054f9d2f61d3dd5fd785ae7afa49d18ebbde9ce8dde5641adc6b38173173459836dd994eae929aee7428fdda2e44f8cb12b10b91c83b22abc8bbb561310b62257c000000000000000000000000000000000ca8f961f86ee6c46fc88fbbf721ba760186f13cd4cce743f19dc60a89fd985cb3feee34dcc4656735a326f515a729e400000000000000000000000000000000174baf466b809b1155d524050f7ee58c7c5cf728c674e0ce549f5551047a4479ca15bdf69b403b03fa74eb1b26bbff6c0000000000000000000000000000000000e8c8b587c171b1b292779abfef57202ed29e7fe94ade9634ec5a2b3b4692a4f3c15468e3f6418b144674be70780d5b000000000000000000000000000000001865e99cf97d88bdf56dae32314eb32295c39a1e755cd7d1478bea8520b9ff21c39b683b92ae15568420c390c42b123b7010b134989c8368c7f831f9dd9f9a890e2c1435681107414f2e8637153bbf6a0000000000000000000000000000000017eccd446f10018219a1bd111b8786cf9febd49f9e7e754e82dd155ead59b819f0f20e42f4635d5044ec5d550d847623000000000000000000000000000000000403969d2b8f914ff2ea3bf902782642e2c6157bd2a343acf60ff9125b48b558d990a74c6d4d6398e7a3cc2a16037346000000000000000000000000000000000bd45f61f142bd78619fb520715320eb5e6ebafa8b078ce796ba62fe1a549d5fb9df57e92d8d2795988eb6ae18cf9d9300000000000000000000000000000000097db1314e064b8e670ec286958f17065bce644cf240ab1b1b220504560d36a0b43fc18453ff3a2bb315e219965f5bd394c68bc8d91ac8c489ee87dbfc4b94c93c8bbd5fc04c27db8b02303f3a65905400000000000000000000000000000000018244ab39a716e252cbfb986c7958b371e29ea9190010d1f5e1cfdb6ce4822d4055c37cd411fc9a0c46d728f2c13ecf0000000000000000000000000000000001985d3c667c8d68c9adb92bdc7a8af959c17146544997d97116120a0f55366bd7ad7ffa28d93ee51222ff9222779675000000000000000000000000000000000c70fd4e3c8f2a451f83fb6c046431b38251b7bae44cf8d36df69a03e2d3ce6137498523fcf0bcf29b5d69e8f265e24d00000000000000000000000000000000047b9163a218f7654a72e0d7c651a2cf7fd95e9784a59e0bf119d081de6c0465d374a55fbc1eff9828c9fd29abf4c4bdb3682accc3939283b870357cf83683350baf73aa0d3d68bda82a0f6ae7e51746,,,invalid input parameters, invalid input length for G1 multiplication -,,,invalid input parameters, Invalid number of pairs -00000000000000000000000000000000039b10ccd664da6f273ea134bb55ee48f09ba585a7e2bb95b5aec610631ac49810d5d616f67ba0147e6d1be476ea220f0000000000000000000000000000000000fbcdff4e48e07d1f73ec42fe7eb026f5c30407cfd2f22bbbfe5b2a09e8a7bb4884178cb6afd1c95f80e646929d30040000000000000000000000000000000001ed3b0e71acb0adbf44643374edbf4405af87cfc0507db7e8978889c6c3afbe9754d1182e98ac3060d64994d31ef576000000000000000000000000000000001681a2bf65b83be5a2ca50430949b6e2a099977482e9405b593f34d2ed877a3f0d1bddc37d0cec4d59d7df74b2b8f2dfb3c940fe79b6966489b527955de7599194a9ac69a6ff58b8d99e7b1084f0464e0000000000000000000000000000000018c0ada6351b70661f053365deae56910798bd2ace6e2bf6ba4192d1a229967f6af6ca1c9a8a11ebc0a232344ee0f6d6000000000000000000000000000000000cc70a587f4652039d8117b6103858adcd9728f6aebe230578389a62da0042b7623b1c0436734f463cfdd187d20903240000000000000000000000000000000009f50bd7beedb23328818f9ffdafdb6da6a4dd80c5a9048ab8b154df3cad938ccede829f1156f769d9e149791e8e0cd900000000000000000000000000000000079ba50d2511631b20b6d6f3841e616e9d11b68ec3368cd60129d9d4787ab56c4e9145a38927e51c9cd6271d493d93884d0e25bf3f6fc9f4da25d21fdc71773f1947b7a8a775b8177f7eca990b05b71d0000000000000000000000000000000003632695b09dbf86163909d2bb25995b36ad1d137cf252860fd4bb6c95749e19eb0c1383e9d2f93f2791cb0cf6c8ed9d000000000000000000000000000000001688a855609b0bbff4452d146396558ff18777f329fd4f76a96859dabfc6a6f6977c2496280dbe3b1f8923990c1d6407000000000000000000000000000000000c8567fee05d05af279adc67179468a29d7520b067dbb348ee315a99504f70a206538b81a457cce855f4851ad48b7e80000000000000000000000000000000001238dcdfa80ea46e1500026ea5feadb421de4409f4992ffbf5ae59fa67fd82f38452642a50261b849e74b4a33eed70cc973f40c12c92b703d7b7848ef8b4466d40823aad3943a312b57432b91ff68be1000000000000000000000000000000000149704960cccf9d5ea414c73871e896b1d4cf0a946b0db72f5f2c5df98d2ec4f3adbbc14c78047961bc9620cb6cfb5900000000000000000000000000000000140c5d25e534fb1bfdc19ba4cecaabe619f6e0cd3d60b0f17dafd7bcd27b286d4f4477d00c5e1af22ee1a0c67fbf177c00000000000000000000000000000000029a1727041590b8459890de736df15c00d80ab007c3aee692ddcdf75790c9806d198e9f4502bec2f0a623491c3f877d0000000000000000000000000000000008a94c98baa9409151030d4fae2bd4a64c6f11ea3c99b9661fdaed226b9a7c2a7d609be34afda5d18b8911b6e015bf494c51f97bcdda93904ae26991b471e9ea942e2b5b8ed26055da11c58bc7b5002a000000000000000000000000000000001156d478661337478ab0cbc877a99d9e4d9824a2b3f605d41404d6b557b3ffabbf42635b0bbcb854cf9ed8b8637561a8000000000000000000000000000000001147ed317d5642e699787a7b47e6795c9a8943a34a694007e44f8654ba96390cf19f010dcf695e22c21874022c6ce291000000000000000000000000000000000c6dccdf920fd5e7fae284115511952633744c6ad94120d9cae6acda8a7c23c48bd912cba6c38de5159587e1e6cad519000000000000000000000000000000001944227d462bc2e5dcc6f6db0f83dad411ba8895262836f975b2b91e06fd0e2138862162acc04e9e65050b34ccbd1a4e8964d5867927bc3e35a0b4c457482373969bff5edff8a781d65573e07fd87b890000000000000000000000000000000019c31e3ab8cc9c920aa8f56371f133b6cb8d7b0b74b23c0c7201aca79e5ae69dc01f1f74d2492dcb081895b17d106b4e000000000000000000000000000000001789b0d371bd63077ccde3dbbebf3531368feb775bced187fb31cc6821481664600978e323ff21085b8c08e0f21daf72000000000000000000000000000000000009eacfe8f4a2a9bae6573424d07f42bd6af8a9d55f71476a7e3c7a4b2b898550c1e72ec13afd4eff22421a03af1d31000000000000000000000000000000000410bd4ea74dcfa33f2976aa1b571c67cbb596ab10f76a8aaf4548f1097e55b3373bff02683f806cb84e1e0e877819e2787c38b944eadbd03fd3187f450571740f6cd00e5b2e560165846eb800e5c94400000000000000000000000000000000147f09986691f2e57073378e8bfd58804241eed7934f6adfe6d0a6bac4da0b738495778a303e52113e1c80e698476d50000000000000000000000000000000000762348b84c92a8ca6de319cf1f8f11db296a71b90fe13e1e4bcd25903829c00a5d2ad4b1c8d98c37eaad7e042ab023d0000000000000000000000000000000011d1d94530d4a2daf0e902a5c3382cd135938557f94b04bccea5e16ea089c5e020e13524c854a316662bd68784fe31f300000000000000000000000000000000070828522bec75b6a492fd9bca7b54dac6fbbf4f0bc3179d312bb65c647439e3868e4d5b21af5a64c93aeee8a9b7e46eaaee7ae2a237e8e53560c79e7baa9adf9c00a0ea4d6f514e7a6832eb15cef1e1000000000000000000000000000000000690a0869204c8dced5ba0ce13554b2703a3f18afb8fa8fa1c457d79c58fdc25471ae85bafad52e506fc1917fc3becff0000000000000000000000000000000010f7dbb16f8571ede1cec79e3f9ea03ae6468d7285984713f19607f5cab902b9a6b7cbcfd900be5c2e407cc093ea0e6700000000000000000000000000000000151caf87968433cb1f85fc1854c57049be22c26497a86bfbd66a2b3af121d894dba8004a17c6ff96a5843c2719fa32d10000000000000000000000000000000011f0270f2b039409f70392879bcc2c67c836c100cf9883d3dc48d7adbcd52037d270539e863a951acd47ecaa1ca4db12dac6ed3ef45c1d7d3028f0f89e5458797996d3294b95bebe049b76c7d0db317c0000000000000000000000000000000017fae043c8fd4c520a90d4a6bd95f5b0484acc279b899e7b1d8f7f7831cc6ba37cd5965c4dc674768f5805842d433af30000000000000000000000000000000008ddd7b41b8fa4d29fb931830f29b46f4015ec202d51cb969d7c832aafc0995c875cd45eff4a083e2d5ecb5ad185b64f0000000000000000000000000000000015d384ab7e52420b83a69827257cb52b00f0199ed2240a142812b46cf67e92b99942ac59fb9f9efd7dd822f5a36c799f00000000000000000000000000000000074b3a16a9cc4be9da0ac8e2e7003d9c1ec89244d2c33441b31af76716cce439f805843a9a44701203231efdca551d5bbb30985756c3ca075114c92f231575d6befafe4084517f1166a47376867bd108000000000000000000000000000000000e25365988664e8b6ade2e5a40da49c11ff1e084cc0f8dca51f0d0578555d39e3617c8cadb2abc2633b28c5895ab0a9e00000000000000000000000000000000169f5fd768152169c403475dee475576fd2cc3788179453b0039ff3cb1b7a5a0fff8f82d03f56e65cad579218486c3b600000000000000000000000000000000087ccd7f92032febc1f75c7115111ede4acbb2e429cbccf3959524d0b79c449d431ff65485e1aecb442b53fec80ecb4000000000000000000000000000000000135d63f264360003b2eb28f126c6621a40088c6eb15acc4aea89d6068e9d5a47f842aa4b4300f5cda5cc5831edb81596fb730105809f64ea522983d6bbb62f7e2e8cbf702685e9be10e2ef71f818767200000000000000000000000000000000159da74f15e4c614b418997f81a1b8a3d9eb8dd80d94b5bad664bff271bb0f2d8f3c4ceb947dc6300d5003a2f7d7a829000000000000000000000000000000000cdd4d1d4666f385dd54052cf5c1966328403251bebb29f0d553a9a96b5ade350c8493270e9b5282d8a06f9fa8d7b1d900000000000000000000000000000000189f8d3c94fdaa72cc67a7f93d35f91e22206ff9e97eed9601196c28d45b69c802ae92bcbf582754717b0355e08d37c000000000000000000000000000000000054b0a282610f108fc7f6736b8c22c8778d082bf4b0d0abca5a228198eba6a868910dd5c5c440036968e977955054196b6a9408625b0ca8fcbfb21d34eec2d8e24e9a30d2d3b32d7a37d110b13afbfea000000000000000000000000000000000f29b0d2b6e3466668e1328048e8dbc782c1111ab8cbe718c85d58ded992d97ca8ba20b9d048feb6ed0aa1b4139d02d3000000000000000000000000000000000d1f0dae940b99fbfc6e4a58480cac8c4e6b2fe33ce6f39c7ac1671046ce94d9e16cba2bb62c6749ef73d45bea21501a000000000000000000000000000000001902ccece1c0c763fd06934a76d1f2f056563ae6d8592bafd589cfebd6f057726fd908614ccd6518a21c66ecc2f78b660000000000000000000000000000000017f6b113f8872c3187d20b0c765d73b850b54244a719cf461fb318796c0b8f310b5490959f9d9187f99c8ed3e25e42a93b77283d0a7bb9e17a27e66851792fdd605cc0a339028b8985390fd024374c76000000000000000000000000000000000576b8cf1e69efdc277465c344cadf7f8cceffacbeca83821f3ff81717308b97f4ac046f1926e7c2eb42677d7afc257c000000000000000000000000000000000cc1524531e96f3c00e4250dd351aedb5a4c3184aff52ec8c13d470068f5967f3674fe173ee239933e67501a9decc6680000000000000000000000000000000001610cfcaea414c241b44cf6f3cc319dcb51d6b8de29c8a6869ff7c1ebb7b747d881e922b42e8fab96bde7cf23e8e4cd0000000000000000000000000000000017d4444dc8b6893b681cf10dac8169054f9d2f61d3dd5fd785ae7afa49d18ebbde9ce8dde5641adc6b38173173459836dd994eae929aee7428fdda2e44f8cb12b10b91c83b22abc8bbb561310b62257c000000000000000000000000000000000ca8f961f86ee6c46fc88fbbf721ba760186f13cd4cce743f19dc60a89fd985cb3feee34dcc4656735a326f515a729e400000000000000000000000000000000174baf466b809b1155d524050f7ee58c7c5cf728c674e0ce549f5551047a4479ca15bdf69b403b03fa74eb1b26bbff6c0000000000000000000000000000000000e8c8b587c171b1b292779abfef57202ed29e7fe94ade9634ec5a2b3b4692a4f3c15468e3f6418b144674be70780d5b000000000000000000000000000000001865e99cf97d88bdf56dae32314eb32295c39a1e755cd7d1478bea8520b9ff21c39b683b92ae15568420c390c42b123b7010b134989c8368c7f831f9dd9f9a890e2c1435681107414f2e8637153bbf6a0000000000000000000000000000000017eccd446f10018219a1bd111b8786cf9febd49f9e7e754e82dd155ead59b819f0f20e42f4635d5044ec5d550d847623000000000000000000000000000000000403969d2b8f914ff2ea3bf902782642e2c6157bd2a343acf60ff9125b48b558d990a74c6d4d6398e7a3cc2a16037346000000000000000000000000000000000bd45f61f142bd78619fb520715320eb5e6ebafa8b078ce796ba62fe1a549d5fb9df57e92d8d2795988eb6ae18cf9d9300000000000000000000000000000000097db1314e064b8e670ec286958f17065bce644cf240ab1b1b220504560d36a0b43fc18453ff3a2bb315e219965f5bd394c68bc8d91ac8c489ee87dbfc4b94c93c8bbd5fc04c27db8b02303f3a65905400000000000000000000000000000000018244ab39a716e252cbfb986c7958b371e29ea9190010d1f5e1cfdb6ce4822d4055c37cd411fc9a0c46d728f2c13ecf0000000000000000000000000000000001985d3c667c8d68c9adb92bdc7a8af959c17146544997d97116120a0f55366bd7ad7ffa28d93ee51222ff9222779675000000000000000000000000000000000c70fd4e3c8f2a451f83fb6c046431b38251b7bae44cf8d36df69a03e2d3ce6137498523fcf0bcf29b5d69e8f265e24d00000000000000000000000000000000047b9163a218f7654a72e0d7c651a2cf7fd95e9784a59e0bf119d081de6c0465d374a55fbc1eff9828c9fd29abf4c4bdb3682accc3939283b870357cf83683350baf73aa0d3d68bda82a0f6ae7e51746,,,invalid input parameters, Point is not on curve -00000000000000000000000000000000039b10ccd664da6f273ea134bb55ee48f09ba585a7e2bb95b5aec610631ac49810d5d616f67ba0147e6d1be476ea220e0000000000000000000000000000000000fbcdff4e48e07d1f73ec42fe7eb026f5c30407cfd2f22bbbfe5b2a09e8a7bb4884178cb6afd1c95f80e646929d30040000000000000000000000000000000001ed3b0e71acb0adbf44643374edbf4405af87cfc0507db7e8978889c6c3afbe9754d1182e98ac3060d64994d31ef576000000000000000000000000000000001681a2bf65b83be5a2ca50430949b6e2a099977482e9405b593f34d2ed877a3f0d1bddc37d0cec4d59d7df74b2b8f2dfb3c940fe79b6966489b527955de7599194a9ac69a6ff58b8d99e7b1084f0464e0000000000000000000000000000000018c0ada6351b70661f053365deae56910798bd2ace6e2bf6ba4192d1a229967f6af6ca1c9a8a11ebc0a232344ee0f6d6000000000000000000000000000000000cc70a587f4652039d8117b6103858adcd9728f6aebe230578389a62da0042b7623b1c0436734f463cfdd187d20903240000000000000000000000000000000009f50bd7beedb23328818f9ffdafdb6da6a4dd80c5a9048ab8b154df3cad938ccede829f1156f769d9e149791e8e0cd900000000000000000000000000000000079ba50d2511631b20b6d6f3841e616e9d11b68ec3368cd60129d9d4787ab56c4e9145a38927e51c9cd6271d493d93884d0e25bf3f6fc9f4da25d21fdc71773f1947b7a8a775b8177f7eca990b05b71d0000000000000000000000000000000003632695b09dbf86163909d2bb25995b36ad1d137cf252860fd4bb6c95749e19eb0c1383e9d2f93f2791cb0cf6c8ed9d000000000000000000000000000000001688a855609b0bbff4452d146396558ff18777f329fd4f76a96859dabfc6a6f6977c2496280dbe3b1f8923990c1d6407000000000000000000000000000000000c8567fee05d05af279adc67179468a29d7520b067dbb348ee315a99504f70a206538b81a457cce855f4851ad48b7e80000000000000000000000000000000001238dcdfa80ea46e1500026ea5feadb421de4409f4992ffbf5ae59fa67fd82f38452642a50261b849e74b4a33eed70cc973f40c12c92b703d7b7848ef8b4466d40823aad3943a312b57432b91ff68be1000000000000000000000000000000000149704960cccf9d5ea414c73871e896b1d4cf0a946b0db72f5f2c5df98d2ec4f3adbbc14c78047961bc9620cb6cfb5900000000000000000000000000000000140c5d25e534fb1bfdc19ba4cecaabe619f6e0cd3d60b0f17dafd7bcd27b286d4f4477d00c5e1af22ee1a0c67fbf177c00000000000000000000000000000000029a1727041590b8459890de736df15c00d80ab007c3aee692ddcdf75790c9806d198e9f4502bec2f0a623491c3f877d0000000000000000000000000000000008a94c98baa9409151030d4fae2bd4a64c6f11ea3c99b9661fdaed226b9a7c2a7d609be34afda5d18b8911b6e015bf494c51f97bcdda93904ae26991b471e9ea942e2b5b8ed26055da11c58bc7b5002a000000000000000000000000000000001156d478661337478ab0cbc877a99d9e4d9824a2b3f605d41404d6b557b3ffabbf42635b0bbcb854cf9ed8b8637561a8000000000000000000000000000000001147ed317d5642e699787a7b47e6795c9a8943a34a694007e44f8654ba96390cf19f010dcf695e22c21874022c6ce291000000000000000000000000000000000c6dccdf920fd5e7fae284115511952633744c6ad94120d9cae6acda8a7c23c48bd912cba6c38de5159587e1e6cad519000000000000000000000000000000001944227d462bc2e5dcc6f6db0f83dad411ba8895262836f975b2b91e06fd0e2138862162acc04e9e65050b34ccbd1a4e8964d5867927bc3e35a0b4c457482373969bff5edff8a781d65573e07fd87b890000000000000000000000000000000019c31e3ab8cc9c920aa8f56371f133b6cb8d7b0b74b23c0c7201aca79e5ae69dc01f1f74d2492dcb081895b17d106b4e000000000000000000000000000000001789b0d371bd63077ccde3dbbebf3531368feb775bced187fb31cc6821481664600978e323ff21085b8c08e0f21daf72000000000000000000000000000000000009eacfe8f4a2a9bae6573424d07f42bd6af8a9d55f71476a7e3c7a4b2b898550c1e72ec13afd4eff22421a03af1d31000000000000000000000000000000000410bd4ea74dcfa33f2976aa1b571c67cbb596ab10f76a8aaf4548f1097e55b3373bff02683f806cb84e1e0e877819e2787c38b944eadbd03fd3187f450571740f6cd00e5b2e560165846eb800e5c94400000000000000000000000000000000147f09986691f2e57073378e8bfd58804241eed7934f6adfe6d0a6bac4da0b738495778a303e52113e1c80e698476d50000000000000000000000000000000000762348b84c92a8ca6de319cf1f8f11db296a71b90fe13e1e4bcd25903829c00a5d2ad4b1c8d98c37eaad7e042ab023d0000000000000000000000000000000011d1d94530d4a2daf0e902a5c3382cd135938557f94b04bccea5e16ea089c5e020e13524c854a316662bd68784fe31f300000000000000000000000000000000070828522bec75b6a492fd9bca7b54dac6fbbf4f0bc3179d312bb65c647439e3868e4d5b21af5a64c93aeee8a9b7e46eaaee7ae2a237e8e53560c79e7baa9adf9c00a0ea4d6f514e7a6832eb15cef1e1000000000000000000000000000000000690a0869204c8dced5ba0ce13554b2703a3f18afb8fa8fa1c457d79c58fdc25471ae85bafad52e506fc1917fc3becff0000000000000000000000000000000010f7dbb16f8571ede1cec79e3f9ea03ae6468d7285984713f19607f5cab902b9a6b7cbcfd900be5c2e407cc093ea0e6700000000000000000000000000000000151caf87968433cb1f85fc1854c57049be22c26497a86bfbd66a2b3af121d894dba8004a17c6ff96a5843c2719fa32d10000000000000000000000000000000011f0270f2b039409f70392879bcc2c67c836c100cf9883d3dc48d7adbcd52037d270539e863a951acd47ecaa1ca4db12dac6ed3ef45c1d7d3028f0f89e5458797996d3294b95bebe049b76c7d0db317c0000000000000000000000000000000017fae043c8fd4c520a90d4a6bd95f5b0484acc279b899e7b1d8f7f7831cc6ba37cd5965c4dc674768f5805842d433af30000000000000000000000000000000008ddd7b41b8fa4d29fb931830f29b46f4015ec202d51cb969d7c832aafc0995c875cd45eff4a083e2d5ecb5ad185b64f0000000000000000000000000000000015d384ab7e52420b83a69827257cb52b00f0199ed2240a142812b46cf67e92b99942ac59fb9f9efd7dd822f5a36c799f00000000000000000000000000000000074b3a16a9cc4be9da0ac8e2e7003d9c1ec89244d2c33441b31af76716cce439f805843a9a44701203231efdca551d5bbb30985756c3ca075114c92f231575d6befafe4084517f1166a47376867bd108000000000000000000000000000000000e25365988664e8b6ade2e5a40da49c11ff1e084cc0f8dca51f0d0578555d39e3617c8cadb2abc2633b28c5895ab0a9e00000000000000000000000000000000169f5fd768152169c403475dee475576fd2cc3788179453b0039ff3cb1b7a5a0fff8f82d03f56e65cad579218486c3b600000000000000000000000000000000087ccd7f92032febc1f75c7115111ede4acbb2e429cbccf3959524d0b79c449d431ff65485e1aecb442b53fec80ecb4000000000000000000000000000000000135d63f264360003b2eb28f126c6621a40088c6eb15acc4aea89d6068e9d5a47f842aa4b4300f5cda5cc5831edb81596fb730105809f64ea522983d6bbb62f7e2e8cbf702685e9be10e2ef71f818767200000000000000000000000000000000159da74f15e4c614b418997f81a1b8a3d9eb8dd80d94b5bad664bff271bb0f2d8f3c4ceb947dc6300d5003a2f7d7a829000000000000000000000000000000000cdd4d1d4666f385dd54052cf5c1966328403251bebb29f0d553a9a96b5ade350c8493270e9b5282d8a06f9fa8d7b1d900000000000000000000000000000000189f8d3c94fdaa72cc67a7f93d35f91e22206ff9e97eed9601196c28d45b69c802ae92bcbf582754717b0355e08d37c000000000000000000000000000000000054b0a282610f108fc7f6736b8c22c8778d082bf4b0d0abca5a228198eba6a868910dd5c5c440036968e977955054196b6a9408625b0ca8fcbfb21d34eec2d8e24e9a30d2d3b32d7a37d110b13afbfea000000000000000000000000000000000f29b0d2b6e3466668e1328048e8dbc782c1111ab8cbe718c85d58ded992d97ca8ba20b9d048feb6ed0aa1b4139d02d3000000000000000000000000000000000d1f0dae940b99fbfc6e4a58480cac8c4e6b2fe33ce6f39c7ac1671046ce94d9e16cba2bb62c6749ef73d45bea21501a000000000000000000000000000000001902ccece1c0c763fd06934a76d1f2f056563ae6d8592bafd589cfebd6f057726fd908614ccd6518a21c66ecc2f78b660000000000000000000000000000000017f6b113f8872c3187d20b0c765d73b850b54244a719cf461fb318796c0b8f310b5490959f9d9187f99c8ed3e25e42a93b77283d0a7bb9e17a27e66851792fdd605cc0a339028b8985390fd024374c76000000000000000000000000000000000576b8cf1e69efdc277465c344cadf7f8cceffacbeca83821f3ff81717308b97f4ac046f1926e7c2eb42677d7afc257c000000000000000000000000000000000cc1524531e96f3c00e4250dd351aedb5a4c3184aff52ec8c13d470068f5967f3674fe173ee239933e67501a9decc6680000000000000000000000000000000001610cfcaea414c241b44cf6f3cc319dcb51d6b8de29c8a6869ff7c1ebb7b747d881e922b42e8fab96bde7cf23e8e4cd0000000000000000000000000000000017d4444dc8b6893b681cf10dac8169054f9d2f61d3dd5fd785ae7afa49d18ebbde9ce8dde5641adc6b38173173459836dd994eae929aee7428fdda2e44f8cb12b10b91c83b22abc8bbb561310b62257c000000000000000000000000000000000ca8f961f86ee6c46fc88fbbf721ba760186f13cd4cce743f19dc60a89fd985cb3feee34dcc4656735a326f515a729e400000000000000000000000000000000174baf466b809b1155d524050f7ee58c7c5cf728c674e0ce549f5551047a4479ca15bdf69b403b03fa74eb1b26bbff6c0000000000000000000000000000000000e8c8b587c171b1b292779abfef57202ed29e7fe94ade9634ec5a2b3b4692a4f3c15468e3f6418b144674be70780d5b000000000000000000000000000000001865e99cf97d88bdf56dae32314eb32295c39a1e755cd7d1478bea8520b9ff21c39b683b92ae15568420c390c42b123b7010b134989c8368c7f831f9dd9f9a890e2c1435681107414f2e8637153bbf6a0000000000000000000000000000000017eccd446f10018219a1bd111b8786cf9febd49f9e7e754e82dd155ead59b819f0f20e42f4635d5044ec5d550d847623000000000000000000000000000000000403969d2b8f914ff2ea3bf902782642e2c6157bd2a343acf60ff9125b48b558d990a74c6d4d6398e7a3cc2a16037346000000000000000000000000000000000bd45f61f142bd78619fb520715320eb5e6ebafa8b078ce796ba62fe1a549d5fb9df57e92d8d2795988eb6ae18cf9d9300000000000000000000000000000000097db1314e064b8e670ec286958f17065bce644cf240ab1b1b220504560d36a0b43fc18453ff3a2bb315e219965f5bd394c68bc8d91ac8c489ee87dbfc4b94c93c8bbd5fc04c27db8b02303f3a65905400000000000000000000000000000000018244ab39a716e252cbfb986c7958b371e29ea9190010d1f5e1cfdb6ce4822d4055c37cd411fc9a0c46d728f2c13ed00000000000000000000000000000000001985d3c667c8d68c9adb92bdc7a8af959c17146544997d97116120a0f55366bd7ad7ffa28d93ee51222ff9222779675000000000000000000000000000000000c70fd4e3c8f2a451f83fb6c046431b38251b7bae44cf8d36df69a03e2d3ce6137498523fcf0bcf29b5d69e8f265e24d00000000000000000000000000000000047b9163a218f7654a72e0d7c651a2cf7fd95e9784a59e0bf119d081de6c0465d374a55fbc1eff9828c9fd29abf4c4bdb3682accc3939283b870357cf83683350baf73aa0d3d68bda82a0f6ae7e51746,,,invalid input parameters, Point is not on curve -00000000000000000000000000000000197bfd0342bbc8bee2beced2f173e1a87be576379b343e93232d6cef98d84b1d696e5612ff283ce2cfdccb2cfb65fa0c00000000000000000000000000000000184e811f55e6f9d84d77d2f79102fd7ea7422f4759df5bf7f6331d550245e3f1bcf6a30e3b29110d85e0ca16f9f6ae7a000000000000000000000000000000000f10e1eb3c1e53d2ad9cf2d398b2dc22c5842fab0a74b174f691a7e914975da3564d835cd7d2982815b8ac57f507348f000000000000000000000000000000000767d1c453890f1b9110fda82f5815c27281aba3f026ee868e4176a0654feea41a96575e0c4d58a14dbfbcc05b5010b1000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d8784510000000000000000000000000000000000000000000000000000000000000002,,,Point is not in the expected subgroup +000000000000000000000000000000039b10ccd664da6f273ea134bb55ee48f09ba585a7e2bb95b5aec610631ac49810d5d616f67ba0147e6d1be476ea220e0000000000000000000000000000000000fbcdff4e48e07d1f73ec42fe7eb026f5c30407cfd2f22bbbfe5b2a09e8a7bb4884178cb6afd1c95f80e646929d30040000000000000000000000000000000001ed3b0e71acb0adbf44643374edbf4405af87cfc0507db7e8978889c6c3afbe9754d1182e98ac3060d64994d31ef576000000000000000000000000000000001681a2bf65b83be5a2ca50430949b6e2a099977482e9405b593f34d2ed877a3f0d1bddc37d0cec4d59d7df74b2b8f2dfb3c940fe79b6966489b527955de7599194a9ac69a6ff58b8d99e7b1084f0464e0000000000000000000000000000000018c0ada6351b70661f053365deae56910798bd2ace6e2bf6ba4192d1a229967f6af6ca1c9a8a11ebc0a232344ee0f6d6000000000000000000000000000000000cc70a587f4652039d8117b6103858adcd9728f6aebe230578389a62da0042b7623b1c0436734f463cfdd187d20903240000000000000000000000000000000009f50bd7beedb23328818f9ffdafdb6da6a4dd80c5a9048ab8b154df3cad938ccede829f1156f769d9e149791e8e0cd900000000000000000000000000000000079ba50d2511631b20b6d6f3841e616e9d11b68ec3368cd60129d9d4787ab56c4e9145a38927e51c9cd6271d493d93884d0e25bf3f6fc9f4da25d21fdc71773f1947b7a8a775b8177f7eca990b05b71d0000000000000000000000000000000003632695b09dbf86163909d2bb25995b36ad1d137cf252860fd4bb6c95749e19eb0c1383e9d2f93f2791cb0cf6c8ed9d000000000000000000000000000000001688a855609b0bbff4452d146396558ff18777f329fd4f76a96859dabfc6a6f6977c2496280dbe3b1f8923990c1d6407000000000000000000000000000000000c8567fee05d05af279adc67179468a29d7520b067dbb348ee315a99504f70a206538b81a457cce855f4851ad48b7e80000000000000000000000000000000001238dcdfa80ea46e1500026ea5feadb421de4409f4992ffbf5ae59fa67fd82f38452642a50261b849e74b4a33eed70cc973f40c12c92b703d7b7848ef8b4466d40823aad3943a312b57432b91ff68be1000000000000000000000000000000000149704960cccf9d5ea414c73871e896b1d4cf0a946b0db72f5f2c5df98d2ec4f3adbbc14c78047961bc9620cb6cfb5900000000000000000000000000000000140c5d25e534fb1bfdc19ba4cecaabe619f6e0cd3d60b0f17dafd7bcd27b286d4f4477d00c5e1af22ee1a0c67fbf177c00000000000000000000000000000000029a1727041590b8459890de736df15c00d80ab007c3aee692ddcdf75790c9806d198e9f4502bec2f0a623491c3f877d0000000000000000000000000000000008a94c98baa9409151030d4fae2bd4a64c6f11ea3c99b9661fdaed226b9a7c2a7d609be34afda5d18b8911b6e015bf494c51f97bcdda93904ae26991b471e9ea942e2b5b8ed26055da11c58bc7b5002a000000000000000000000000000000001156d478661337478ab0cbc877a99d9e4d9824a2b3f605d41404d6b557b3ffabbf42635b0bbcb854cf9ed8b8637561a8000000000000000000000000000000001147ed317d5642e699787a7b47e6795c9a8943a34a694007e44f8654ba96390cf19f010dcf695e22c21874022c6ce291000000000000000000000000000000000c6dccdf920fd5e7fae284115511952633744c6ad94120d9cae6acda8a7c23c48bd912cba6c38de5159587e1e6cad519000000000000000000000000000000001944227d462bc2e5dcc6f6db0f83dad411ba8895262836f975b2b91e06fd0e2138862162acc04e9e65050b34ccbd1a4e8964d5867927bc3e35a0b4c457482373969bff5edff8a781d65573e07fd87b890000000000000000000000000000000019c31e3ab8cc9c920aa8f56371f133b6cb8d7b0b74b23c0c7201aca79e5ae69dc01f1f74d2492dcb081895b17d106b4e000000000000000000000000000000001789b0d371bd63077ccde3dbbebf3531368feb775bced187fb31cc6821481664600978e323ff21085b8c08e0f21daf72000000000000000000000000000000000009eacfe8f4a2a9bae6573424d07f42bd6af8a9d55f71476a7e3c7a4b2b898550c1e72ec13afd4eff22421a03af1d31000000000000000000000000000000000410bd4ea74dcfa33f2976aa1b571c67cbb596ab10f76a8aaf4548f1097e55b3373bff02683f806cb84e1e0e877819e2787c38b944eadbd03fd3187f450571740f6cd00e5b2e560165846eb800e5c94400000000000000000000000000000000147f09986691f2e57073378e8bfd58804241eed7934f6adfe6d0a6bac4da0b738495778a303e52113e1c80e698476d50000000000000000000000000000000000762348b84c92a8ca6de319cf1f8f11db296a71b90fe13e1e4bcd25903829c00a5d2ad4b1c8d98c37eaad7e042ab023d0000000000000000000000000000000011d1d94530d4a2daf0e902a5c3382cd135938557f94b04bccea5e16ea089c5e020e13524c854a316662bd68784fe31f300000000000000000000000000000000070828522bec75b6a492fd9bca7b54dac6fbbf4f0bc3179d312bb65c647439e3868e4d5b21af5a64c93aeee8a9b7e46eaaee7ae2a237e8e53560c79e7baa9adf9c00a0ea4d6f514e7a6832eb15cef1e1000000000000000000000000000000000690a0869204c8dced5ba0ce13554b2703a3f18afb8fa8fa1c457d79c58fdc25471ae85bafad52e506fc1917fc3becff0000000000000000000000000000000010f7dbb16f8571ede1cec79e3f9ea03ae6468d7285984713f19607f5cab902b9a6b7cbcfd900be5c2e407cc093ea0e6700000000000000000000000000000000151caf87968433cb1f85fc1854c57049be22c26497a86bfbd66a2b3af121d894dba8004a17c6ff96a5843c2719fa32d10000000000000000000000000000000011f0270f2b039409f70392879bcc2c67c836c100cf9883d3dc48d7adbcd52037d270539e863a951acd47ecaa1ca4db12dac6ed3ef45c1d7d3028f0f89e5458797996d3294b95bebe049b76c7d0db317c0000000000000000000000000000000017fae043c8fd4c520a90d4a6bd95f5b0484acc279b899e7b1d8f7f7831cc6ba37cd5965c4dc674768f5805842d433af30000000000000000000000000000000008ddd7b41b8fa4d29fb931830f29b46f4015ec202d51cb969d7c832aafc0995c875cd45eff4a083e2d5ecb5ad185b64f0000000000000000000000000000000015d384ab7e52420b83a69827257cb52b00f0199ed2240a142812b46cf67e92b99942ac59fb9f9efd7dd822f5a36c799f00000000000000000000000000000000074b3a16a9cc4be9da0ac8e2e7003d9c1ec89244d2c33441b31af76716cce439f805843a9a44701203231efdca551d5bbb30985756c3ca075114c92f231575d6befafe4084517f1166a47376867bd108000000000000000000000000000000000e25365988664e8b6ade2e5a40da49c11ff1e084cc0f8dca51f0d0578555d39e3617c8cadb2abc2633b28c5895ab0a9e00000000000000000000000000000000169f5fd768152169c403475dee475576fd2cc3788179453b0039ff3cb1b7a5a0fff8f82d03f56e65cad579218486c3b600000000000000000000000000000000087ccd7f92032febc1f75c7115111ede4acbb2e429cbccf3959524d0b79c449d431ff65485e1aecb442b53fec80ecb4000000000000000000000000000000000135d63f264360003b2eb28f126c6621a40088c6eb15acc4aea89d6068e9d5a47f842aa4b4300f5cda5cc5831edb81596fb730105809f64ea522983d6bbb62f7e2e8cbf702685e9be10e2ef71f818767200000000000000000000000000000000159da74f15e4c614b418997f81a1b8a3d9eb8dd80d94b5bad664bff271bb0f2d8f3c4ceb947dc6300d5003a2f7d7a829000000000000000000000000000000000cdd4d1d4666f385dd54052cf5c1966328403251bebb29f0d553a9a96b5ade350c8493270e9b5282d8a06f9fa8d7b1d900000000000000000000000000000000189f8d3c94fdaa72cc67a7f93d35f91e22206ff9e97eed9601196c28d45b69c802ae92bcbf582754717b0355e08d37c000000000000000000000000000000000054b0a282610f108fc7f6736b8c22c8778d082bf4b0d0abca5a228198eba6a868910dd5c5c440036968e977955054196b6a9408625b0ca8fcbfb21d34eec2d8e24e9a30d2d3b32d7a37d110b13afbfea000000000000000000000000000000000f29b0d2b6e3466668e1328048e8dbc782c1111ab8cbe718c85d58ded992d97ca8ba20b9d048feb6ed0aa1b4139d02d3000000000000000000000000000000000d1f0dae940b99fbfc6e4a58480cac8c4e6b2fe33ce6f39c7ac1671046ce94d9e16cba2bb62c6749ef73d45bea21501a000000000000000000000000000000001902ccece1c0c763fd06934a76d1f2f056563ae6d8592bafd589cfebd6f057726fd908614ccd6518a21c66ecc2f78b660000000000000000000000000000000017f6b113f8872c3187d20b0c765d73b850b54244a719cf461fb318796c0b8f310b5490959f9d9187f99c8ed3e25e42a93b77283d0a7bb9e17a27e66851792fdd605cc0a339028b8985390fd024374c76000000000000000000000000000000000576b8cf1e69efdc277465c344cadf7f8cceffacbeca83821f3ff81717308b97f4ac046f1926e7c2eb42677d7afc257c000000000000000000000000000000000cc1524531e96f3c00e4250dd351aedb5a4c3184aff52ec8c13d470068f5967f3674fe173ee239933e67501a9decc6680000000000000000000000000000000001610cfcaea414c241b44cf6f3cc319dcb51d6b8de29c8a6869ff7c1ebb7b747d881e922b42e8fab96bde7cf23e8e4cd0000000000000000000000000000000017d4444dc8b6893b681cf10dac8169054f9d2f61d3dd5fd785ae7afa49d18ebbde9ce8dde5641adc6b38173173459836dd994eae929aee7428fdda2e44f8cb12b10b91c83b22abc8bbb561310b62257c000000000000000000000000000000000ca8f961f86ee6c46fc88fbbf721ba760186f13cd4cce743f19dc60a89fd985cb3feee34dcc4656735a326f515a729e400000000000000000000000000000000174baf466b809b1155d524050f7ee58c7c5cf728c674e0ce549f5551047a4479ca15bdf69b403b03fa74eb1b26bbff6c0000000000000000000000000000000000e8c8b587c171b1b292779abfef57202ed29e7fe94ade9634ec5a2b3b4692a4f3c15468e3f6418b144674be70780d5b000000000000000000000000000000001865e99cf97d88bdf56dae32314eb32295c39a1e755cd7d1478bea8520b9ff21c39b683b92ae15568420c390c42b123b7010b134989c8368c7f831f9dd9f9a890e2c1435681107414f2e8637153bbf6a0000000000000000000000000000000017eccd446f10018219a1bd111b8786cf9febd49f9e7e754e82dd155ead59b819f0f20e42f4635d5044ec5d550d847623000000000000000000000000000000000403969d2b8f914ff2ea3bf902782642e2c6157bd2a343acf60ff9125b48b558d990a74c6d4d6398e7a3cc2a16037346000000000000000000000000000000000bd45f61f142bd78619fb520715320eb5e6ebafa8b078ce796ba62fe1a549d5fb9df57e92d8d2795988eb6ae18cf9d9300000000000000000000000000000000097db1314e064b8e670ec286958f17065bce644cf240ab1b1b220504560d36a0b43fc18453ff3a2bb315e219965f5bd394c68bc8d91ac8c489ee87dbfc4b94c93c8bbd5fc04c27db8b02303f3a65905400000000000000000000000000000000018244ab39a716e252cbfb986c7958b371e29ea9190010d1f5e1cfdb6ce4822d4055c37cd411fc9a0c46d728f2c13ecf0000000000000000000000000000000001985d3c667c8d68c9adb92bdc7a8af959c17146544997d97116120a0f55366bd7ad7ffa28d93ee51222ff9222779675000000000000000000000000000000000c70fd4e3c8f2a451f83fb6c046431b38251b7bae44cf8d36df69a03e2d3ce6137498523fcf0bcf29b5d69e8f265e24d00000000000000000000000000000000047b9163a218f7654a72e0d7c651a2cf7fd95e9784a59e0bf119d081de6c0465d374a55fbc1eff9828c9fd29abf4c4bdb3682accc3939283b870357cf83683350baf73aa0d3d68bda82a0f6ae7e51746,,,invalid input parameters, invalid input length for G2 multiplication +0000000000000000000000000000000000039b10ccd664da6f273ea134bb55ee48f09ba585a7e2bb95b5aec610631ac49810d5d616f67ba0147e6d1be476ea220e0000000000000000000000000000000000fbcdff4e48e07d1f73ec42fe7eb026f5c30407cfd2f22bbbfe5b2a09e8a7bb4884178cb6afd1c95f80e646929d30040000000000000000000000000000000001ed3b0e71acb0adbf44643374edbf4405af87cfc0507db7e8978889c6c3afbe9754d1182e98ac3060d64994d31ef576000000000000000000000000000000001681a2bf65b83be5a2ca50430949b6e2a099977482e9405b593f34d2ed877a3f0d1bddc37d0cec4d59d7df74b2b8f2dfb3c940fe79b6966489b527955de7599194a9ac69a6ff58b8d99e7b1084f0464e0000000000000000000000000000000018c0ada6351b70661f053365deae56910798bd2ace6e2bf6ba4192d1a229967f6af6ca1c9a8a11ebc0a232344ee0f6d6000000000000000000000000000000000cc70a587f4652039d8117b6103858adcd9728f6aebe230578389a62da0042b7623b1c0436734f463cfdd187d20903240000000000000000000000000000000009f50bd7beedb23328818f9ffdafdb6da6a4dd80c5a9048ab8b154df3cad938ccede829f1156f769d9e149791e8e0cd900000000000000000000000000000000079ba50d2511631b20b6d6f3841e616e9d11b68ec3368cd60129d9d4787ab56c4e9145a38927e51c9cd6271d493d93884d0e25bf3f6fc9f4da25d21fdc71773f1947b7a8a775b8177f7eca990b05b71d0000000000000000000000000000000003632695b09dbf86163909d2bb25995b36ad1d137cf252860fd4bb6c95749e19eb0c1383e9d2f93f2791cb0cf6c8ed9d000000000000000000000000000000001688a855609b0bbff4452d146396558ff18777f329fd4f76a96859dabfc6a6f6977c2496280dbe3b1f8923990c1d6407000000000000000000000000000000000c8567fee05d05af279adc67179468a29d7520b067dbb348ee315a99504f70a206538b81a457cce855f4851ad48b7e80000000000000000000000000000000001238dcdfa80ea46e1500026ea5feadb421de4409f4992ffbf5ae59fa67fd82f38452642a50261b849e74b4a33eed70cc973f40c12c92b703d7b7848ef8b4466d40823aad3943a312b57432b91ff68be1000000000000000000000000000000000149704960cccf9d5ea414c73871e896b1d4cf0a946b0db72f5f2c5df98d2ec4f3adbbc14c78047961bc9620cb6cfb5900000000000000000000000000000000140c5d25e534fb1bfdc19ba4cecaabe619f6e0cd3d60b0f17dafd7bcd27b286d4f4477d00c5e1af22ee1a0c67fbf177c00000000000000000000000000000000029a1727041590b8459890de736df15c00d80ab007c3aee692ddcdf75790c9806d198e9f4502bec2f0a623491c3f877d0000000000000000000000000000000008a94c98baa9409151030d4fae2bd4a64c6f11ea3c99b9661fdaed226b9a7c2a7d609be34afda5d18b8911b6e015bf494c51f97bcdda93904ae26991b471e9ea942e2b5b8ed26055da11c58bc7b5002a000000000000000000000000000000001156d478661337478ab0cbc877a99d9e4d9824a2b3f605d41404d6b557b3ffabbf42635b0bbcb854cf9ed8b8637561a8000000000000000000000000000000001147ed317d5642e699787a7b47e6795c9a8943a34a694007e44f8654ba96390cf19f010dcf695e22c21874022c6ce291000000000000000000000000000000000c6dccdf920fd5e7fae284115511952633744c6ad94120d9cae6acda8a7c23c48bd912cba6c38de5159587e1e6cad519000000000000000000000000000000001944227d462bc2e5dcc6f6db0f83dad411ba8895262836f975b2b91e06fd0e2138862162acc04e9e65050b34ccbd1a4e8964d5867927bc3e35a0b4c457482373969bff5edff8a781d65573e07fd87b890000000000000000000000000000000019c31e3ab8cc9c920aa8f56371f133b6cb8d7b0b74b23c0c7201aca79e5ae69dc01f1f74d2492dcb081895b17d106b4e000000000000000000000000000000001789b0d371bd63077ccde3dbbebf3531368feb775bced187fb31cc6821481664600978e323ff21085b8c08e0f21daf72000000000000000000000000000000000009eacfe8f4a2a9bae6573424d07f42bd6af8a9d55f71476a7e3c7a4b2b898550c1e72ec13afd4eff22421a03af1d31000000000000000000000000000000000410bd4ea74dcfa33f2976aa1b571c67cbb596ab10f76a8aaf4548f1097e55b3373bff02683f806cb84e1e0e877819e2787c38b944eadbd03fd3187f450571740f6cd00e5b2e560165846eb800e5c94400000000000000000000000000000000147f09986691f2e57073378e8bfd58804241eed7934f6adfe6d0a6bac4da0b738495778a303e52113e1c80e698476d50000000000000000000000000000000000762348b84c92a8ca6de319cf1f8f11db296a71b90fe13e1e4bcd25903829c00a5d2ad4b1c8d98c37eaad7e042ab023d0000000000000000000000000000000011d1d94530d4a2daf0e902a5c3382cd135938557f94b04bccea5e16ea089c5e020e13524c854a316662bd68784fe31f300000000000000000000000000000000070828522bec75b6a492fd9bca7b54dac6fbbf4f0bc3179d312bb65c647439e3868e4d5b21af5a64c93aeee8a9b7e46eaaee7ae2a237e8e53560c79e7baa9adf9c00a0ea4d6f514e7a6832eb15cef1e1000000000000000000000000000000000690a0869204c8dced5ba0ce13554b2703a3f18afb8fa8fa1c457d79c58fdc25471ae85bafad52e506fc1917fc3becff0000000000000000000000000000000010f7dbb16f8571ede1cec79e3f9ea03ae6468d7285984713f19607f5cab902b9a6b7cbcfd900be5c2e407cc093ea0e6700000000000000000000000000000000151caf87968433cb1f85fc1854c57049be22c26497a86bfbd66a2b3af121d894dba8004a17c6ff96a5843c2719fa32d10000000000000000000000000000000011f0270f2b039409f70392879bcc2c67c836c100cf9883d3dc48d7adbcd52037d270539e863a951acd47ecaa1ca4db12dac6ed3ef45c1d7d3028f0f89e5458797996d3294b95bebe049b76c7d0db317c0000000000000000000000000000000017fae043c8fd4c520a90d4a6bd95f5b0484acc279b899e7b1d8f7f7831cc6ba37cd5965c4dc674768f5805842d433af30000000000000000000000000000000008ddd7b41b8fa4d29fb931830f29b46f4015ec202d51cb969d7c832aafc0995c875cd45eff4a083e2d5ecb5ad185b64f0000000000000000000000000000000015d384ab7e52420b83a69827257cb52b00f0199ed2240a142812b46cf67e92b99942ac59fb9f9efd7dd822f5a36c799f00000000000000000000000000000000074b3a16a9cc4be9da0ac8e2e7003d9c1ec89244d2c33441b31af76716cce439f805843a9a44701203231efdca551d5bbb30985756c3ca075114c92f231575d6befafe4084517f1166a47376867bd108000000000000000000000000000000000e25365988664e8b6ade2e5a40da49c11ff1e084cc0f8dca51f0d0578555d39e3617c8cadb2abc2633b28c5895ab0a9e00000000000000000000000000000000169f5fd768152169c403475dee475576fd2cc3788179453b0039ff3cb1b7a5a0fff8f82d03f56e65cad579218486c3b600000000000000000000000000000000087ccd7f92032febc1f75c7115111ede4acbb2e429cbccf3959524d0b79c449d431ff65485e1aecb442b53fec80ecb4000000000000000000000000000000000135d63f264360003b2eb28f126c6621a40088c6eb15acc4aea89d6068e9d5a47f842aa4b4300f5cda5cc5831edb81596fb730105809f64ea522983d6bbb62f7e2e8cbf702685e9be10e2ef71f818767200000000000000000000000000000000159da74f15e4c614b418997f81a1b8a3d9eb8dd80d94b5bad664bff271bb0f2d8f3c4ceb947dc6300d5003a2f7d7a829000000000000000000000000000000000cdd4d1d4666f385dd54052cf5c1966328403251bebb29f0d553a9a96b5ade350c8493270e9b5282d8a06f9fa8d7b1d900000000000000000000000000000000189f8d3c94fdaa72cc67a7f93d35f91e22206ff9e97eed9601196c28d45b69c802ae92bcbf582754717b0355e08d37c000000000000000000000000000000000054b0a282610f108fc7f6736b8c22c8778d082bf4b0d0abca5a228198eba6a868910dd5c5c440036968e977955054196b6a9408625b0ca8fcbfb21d34eec2d8e24e9a30d2d3b32d7a37d110b13afbfea000000000000000000000000000000000f29b0d2b6e3466668e1328048e8dbc782c1111ab8cbe718c85d58ded992d97ca8ba20b9d048feb6ed0aa1b4139d02d3000000000000000000000000000000000d1f0dae940b99fbfc6e4a58480cac8c4e6b2fe33ce6f39c7ac1671046ce94d9e16cba2bb62c6749ef73d45bea21501a000000000000000000000000000000001902ccece1c0c763fd06934a76d1f2f056563ae6d8592bafd589cfebd6f057726fd908614ccd6518a21c66ecc2f78b660000000000000000000000000000000017f6b113f8872c3187d20b0c765d73b850b54244a719cf461fb318796c0b8f310b5490959f9d9187f99c8ed3e25e42a93b77283d0a7bb9e17a27e66851792fdd605cc0a339028b8985390fd024374c76000000000000000000000000000000000576b8cf1e69efdc277465c344cadf7f8cceffacbeca83821f3ff81717308b97f4ac046f1926e7c2eb42677d7afc257c000000000000000000000000000000000cc1524531e96f3c00e4250dd351aedb5a4c3184aff52ec8c13d470068f5967f3674fe173ee239933e67501a9decc6680000000000000000000000000000000001610cfcaea414c241b44cf6f3cc319dcb51d6b8de29c8a6869ff7c1ebb7b747d881e922b42e8fab96bde7cf23e8e4cd0000000000000000000000000000000017d4444dc8b6893b681cf10dac8169054f9d2f61d3dd5fd785ae7afa49d18ebbde9ce8dde5641adc6b38173173459836dd994eae929aee7428fdda2e44f8cb12b10b91c83b22abc8bbb561310b62257c000000000000000000000000000000000ca8f961f86ee6c46fc88fbbf721ba760186f13cd4cce743f19dc60a89fd985cb3feee34dcc4656735a326f515a729e400000000000000000000000000000000174baf466b809b1155d524050f7ee58c7c5cf728c674e0ce549f5551047a4479ca15bdf69b403b03fa74eb1b26bbff6c0000000000000000000000000000000000e8c8b587c171b1b292779abfef57202ed29e7fe94ade9634ec5a2b3b4692a4f3c15468e3f6418b144674be70780d5b000000000000000000000000000000001865e99cf97d88bdf56dae32314eb32295c39a1e755cd7d1478bea8520b9ff21c39b683b92ae15568420c390c42b123b7010b134989c8368c7f831f9dd9f9a890e2c1435681107414f2e8637153bbf6a0000000000000000000000000000000017eccd446f10018219a1bd111b8786cf9febd49f9e7e754e82dd155ead59b819f0f20e42f4635d5044ec5d550d847623000000000000000000000000000000000403969d2b8f914ff2ea3bf902782642e2c6157bd2a343acf60ff9125b48b558d990a74c6d4d6398e7a3cc2a16037346000000000000000000000000000000000bd45f61f142bd78619fb520715320eb5e6ebafa8b078ce796ba62fe1a549d5fb9df57e92d8d2795988eb6ae18cf9d9300000000000000000000000000000000097db1314e064b8e670ec286958f17065bce644cf240ab1b1b220504560d36a0b43fc18453ff3a2bb315e219965f5bd394c68bc8d91ac8c489ee87dbfc4b94c93c8bbd5fc04c27db8b02303f3a65905400000000000000000000000000000000018244ab39a716e252cbfb986c7958b371e29ea9190010d1f5e1cfdb6ce4822d4055c37cd411fc9a0c46d728f2c13ecf0000000000000000000000000000000001985d3c667c8d68c9adb92bdc7a8af959c17146544997d97116120a0f55366bd7ad7ffa28d93ee51222ff9222779675000000000000000000000000000000000c70fd4e3c8f2a451f83fb6c046431b38251b7bae44cf8d36df69a03e2d3ce6137498523fcf0bcf29b5d69e8f265e24d00000000000000000000000000000000047b9163a218f7654a72e0d7c651a2cf7fd95e9784a59e0bf119d081de6c0465d374a55fbc1eff9828c9fd29abf4c4bdb3682accc3939283b870357cf83683350baf73aa0d3d68bda82a0f6ae7e51746,,,invalid input parameters, invalid input length for G2 multiplication +,,,invalid input parameters, invalid number of pairs +00000000000000000000000000000000039b10ccd664da6f273ea134bb55ee48f09ba585a7e2bb95b5aec610631ac49810d5d616f67ba0147e6d1be476ea220f0000000000000000000000000000000000fbcdff4e48e07d1f73ec42fe7eb026f5c30407cfd2f22bbbfe5b2a09e8a7bb4884178cb6afd1c95f80e646929d30040000000000000000000000000000000001ed3b0e71acb0adbf44643374edbf4405af87cfc0507db7e8978889c6c3afbe9754d1182e98ac3060d64994d31ef576000000000000000000000000000000001681a2bf65b83be5a2ca50430949b6e2a099977482e9405b593f34d2ed877a3f0d1bddc37d0cec4d59d7df74b2b8f2dfb3c940fe79b6966489b527955de7599194a9ac69a6ff58b8d99e7b1084f0464e0000000000000000000000000000000018c0ada6351b70661f053365deae56910798bd2ace6e2bf6ba4192d1a229967f6af6ca1c9a8a11ebc0a232344ee0f6d6000000000000000000000000000000000cc70a587f4652039d8117b6103858adcd9728f6aebe230578389a62da0042b7623b1c0436734f463cfdd187d20903240000000000000000000000000000000009f50bd7beedb23328818f9ffdafdb6da6a4dd80c5a9048ab8b154df3cad938ccede829f1156f769d9e149791e8e0cd900000000000000000000000000000000079ba50d2511631b20b6d6f3841e616e9d11b68ec3368cd60129d9d4787ab56c4e9145a38927e51c9cd6271d493d93884d0e25bf3f6fc9f4da25d21fdc71773f1947b7a8a775b8177f7eca990b05b71d0000000000000000000000000000000003632695b09dbf86163909d2bb25995b36ad1d137cf252860fd4bb6c95749e19eb0c1383e9d2f93f2791cb0cf6c8ed9d000000000000000000000000000000001688a855609b0bbff4452d146396558ff18777f329fd4f76a96859dabfc6a6f6977c2496280dbe3b1f8923990c1d6407000000000000000000000000000000000c8567fee05d05af279adc67179468a29d7520b067dbb348ee315a99504f70a206538b81a457cce855f4851ad48b7e80000000000000000000000000000000001238dcdfa80ea46e1500026ea5feadb421de4409f4992ffbf5ae59fa67fd82f38452642a50261b849e74b4a33eed70cc973f40c12c92b703d7b7848ef8b4466d40823aad3943a312b57432b91ff68be1000000000000000000000000000000000149704960cccf9d5ea414c73871e896b1d4cf0a946b0db72f5f2c5df98d2ec4f3adbbc14c78047961bc9620cb6cfb5900000000000000000000000000000000140c5d25e534fb1bfdc19ba4cecaabe619f6e0cd3d60b0f17dafd7bcd27b286d4f4477d00c5e1af22ee1a0c67fbf177c00000000000000000000000000000000029a1727041590b8459890de736df15c00d80ab007c3aee692ddcdf75790c9806d198e9f4502bec2f0a623491c3f877d0000000000000000000000000000000008a94c98baa9409151030d4fae2bd4a64c6f11ea3c99b9661fdaed226b9a7c2a7d609be34afda5d18b8911b6e015bf494c51f97bcdda93904ae26991b471e9ea942e2b5b8ed26055da11c58bc7b5002a000000000000000000000000000000001156d478661337478ab0cbc877a99d9e4d9824a2b3f605d41404d6b557b3ffabbf42635b0bbcb854cf9ed8b8637561a8000000000000000000000000000000001147ed317d5642e699787a7b47e6795c9a8943a34a694007e44f8654ba96390cf19f010dcf695e22c21874022c6ce291000000000000000000000000000000000c6dccdf920fd5e7fae284115511952633744c6ad94120d9cae6acda8a7c23c48bd912cba6c38de5159587e1e6cad519000000000000000000000000000000001944227d462bc2e5dcc6f6db0f83dad411ba8895262836f975b2b91e06fd0e2138862162acc04e9e65050b34ccbd1a4e8964d5867927bc3e35a0b4c457482373969bff5edff8a781d65573e07fd87b890000000000000000000000000000000019c31e3ab8cc9c920aa8f56371f133b6cb8d7b0b74b23c0c7201aca79e5ae69dc01f1f74d2492dcb081895b17d106b4e000000000000000000000000000000001789b0d371bd63077ccde3dbbebf3531368feb775bced187fb31cc6821481664600978e323ff21085b8c08e0f21daf72000000000000000000000000000000000009eacfe8f4a2a9bae6573424d07f42bd6af8a9d55f71476a7e3c7a4b2b898550c1e72ec13afd4eff22421a03af1d31000000000000000000000000000000000410bd4ea74dcfa33f2976aa1b571c67cbb596ab10f76a8aaf4548f1097e55b3373bff02683f806cb84e1e0e877819e2787c38b944eadbd03fd3187f450571740f6cd00e5b2e560165846eb800e5c94400000000000000000000000000000000147f09986691f2e57073378e8bfd58804241eed7934f6adfe6d0a6bac4da0b738495778a303e52113e1c80e698476d50000000000000000000000000000000000762348b84c92a8ca6de319cf1f8f11db296a71b90fe13e1e4bcd25903829c00a5d2ad4b1c8d98c37eaad7e042ab023d0000000000000000000000000000000011d1d94530d4a2daf0e902a5c3382cd135938557f94b04bccea5e16ea089c5e020e13524c854a316662bd68784fe31f300000000000000000000000000000000070828522bec75b6a492fd9bca7b54dac6fbbf4f0bc3179d312bb65c647439e3868e4d5b21af5a64c93aeee8a9b7e46eaaee7ae2a237e8e53560c79e7baa9adf9c00a0ea4d6f514e7a6832eb15cef1e1000000000000000000000000000000000690a0869204c8dced5ba0ce13554b2703a3f18afb8fa8fa1c457d79c58fdc25471ae85bafad52e506fc1917fc3becff0000000000000000000000000000000010f7dbb16f8571ede1cec79e3f9ea03ae6468d7285984713f19607f5cab902b9a6b7cbcfd900be5c2e407cc093ea0e6700000000000000000000000000000000151caf87968433cb1f85fc1854c57049be22c26497a86bfbd66a2b3af121d894dba8004a17c6ff96a5843c2719fa32d10000000000000000000000000000000011f0270f2b039409f70392879bcc2c67c836c100cf9883d3dc48d7adbcd52037d270539e863a951acd47ecaa1ca4db12dac6ed3ef45c1d7d3028f0f89e5458797996d3294b95bebe049b76c7d0db317c0000000000000000000000000000000017fae043c8fd4c520a90d4a6bd95f5b0484acc279b899e7b1d8f7f7831cc6ba37cd5965c4dc674768f5805842d433af30000000000000000000000000000000008ddd7b41b8fa4d29fb931830f29b46f4015ec202d51cb969d7c832aafc0995c875cd45eff4a083e2d5ecb5ad185b64f0000000000000000000000000000000015d384ab7e52420b83a69827257cb52b00f0199ed2240a142812b46cf67e92b99942ac59fb9f9efd7dd822f5a36c799f00000000000000000000000000000000074b3a16a9cc4be9da0ac8e2e7003d9c1ec89244d2c33441b31af76716cce439f805843a9a44701203231efdca551d5bbb30985756c3ca075114c92f231575d6befafe4084517f1166a47376867bd108000000000000000000000000000000000e25365988664e8b6ade2e5a40da49c11ff1e084cc0f8dca51f0d0578555d39e3617c8cadb2abc2633b28c5895ab0a9e00000000000000000000000000000000169f5fd768152169c403475dee475576fd2cc3788179453b0039ff3cb1b7a5a0fff8f82d03f56e65cad579218486c3b600000000000000000000000000000000087ccd7f92032febc1f75c7115111ede4acbb2e429cbccf3959524d0b79c449d431ff65485e1aecb442b53fec80ecb4000000000000000000000000000000000135d63f264360003b2eb28f126c6621a40088c6eb15acc4aea89d6068e9d5a47f842aa4b4300f5cda5cc5831edb81596fb730105809f64ea522983d6bbb62f7e2e8cbf702685e9be10e2ef71f818767200000000000000000000000000000000159da74f15e4c614b418997f81a1b8a3d9eb8dd80d94b5bad664bff271bb0f2d8f3c4ceb947dc6300d5003a2f7d7a829000000000000000000000000000000000cdd4d1d4666f385dd54052cf5c1966328403251bebb29f0d553a9a96b5ade350c8493270e9b5282d8a06f9fa8d7b1d900000000000000000000000000000000189f8d3c94fdaa72cc67a7f93d35f91e22206ff9e97eed9601196c28d45b69c802ae92bcbf582754717b0355e08d37c000000000000000000000000000000000054b0a282610f108fc7f6736b8c22c8778d082bf4b0d0abca5a228198eba6a868910dd5c5c440036968e977955054196b6a9408625b0ca8fcbfb21d34eec2d8e24e9a30d2d3b32d7a37d110b13afbfea000000000000000000000000000000000f29b0d2b6e3466668e1328048e8dbc782c1111ab8cbe718c85d58ded992d97ca8ba20b9d048feb6ed0aa1b4139d02d3000000000000000000000000000000000d1f0dae940b99fbfc6e4a58480cac8c4e6b2fe33ce6f39c7ac1671046ce94d9e16cba2bb62c6749ef73d45bea21501a000000000000000000000000000000001902ccece1c0c763fd06934a76d1f2f056563ae6d8592bafd589cfebd6f057726fd908614ccd6518a21c66ecc2f78b660000000000000000000000000000000017f6b113f8872c3187d20b0c765d73b850b54244a719cf461fb318796c0b8f310b5490959f9d9187f99c8ed3e25e42a93b77283d0a7bb9e17a27e66851792fdd605cc0a339028b8985390fd024374c76000000000000000000000000000000000576b8cf1e69efdc277465c344cadf7f8cceffacbeca83821f3ff81717308b97f4ac046f1926e7c2eb42677d7afc257c000000000000000000000000000000000cc1524531e96f3c00e4250dd351aedb5a4c3184aff52ec8c13d470068f5967f3674fe173ee239933e67501a9decc6680000000000000000000000000000000001610cfcaea414c241b44cf6f3cc319dcb51d6b8de29c8a6869ff7c1ebb7b747d881e922b42e8fab96bde7cf23e8e4cd0000000000000000000000000000000017d4444dc8b6893b681cf10dac8169054f9d2f61d3dd5fd785ae7afa49d18ebbde9ce8dde5641adc6b38173173459836dd994eae929aee7428fdda2e44f8cb12b10b91c83b22abc8bbb561310b62257c000000000000000000000000000000000ca8f961f86ee6c46fc88fbbf721ba760186f13cd4cce743f19dc60a89fd985cb3feee34dcc4656735a326f515a729e400000000000000000000000000000000174baf466b809b1155d524050f7ee58c7c5cf728c674e0ce549f5551047a4479ca15bdf69b403b03fa74eb1b26bbff6c0000000000000000000000000000000000e8c8b587c171b1b292779abfef57202ed29e7fe94ade9634ec5a2b3b4692a4f3c15468e3f6418b144674be70780d5b000000000000000000000000000000001865e99cf97d88bdf56dae32314eb32295c39a1e755cd7d1478bea8520b9ff21c39b683b92ae15568420c390c42b123b7010b134989c8368c7f831f9dd9f9a890e2c1435681107414f2e8637153bbf6a0000000000000000000000000000000017eccd446f10018219a1bd111b8786cf9febd49f9e7e754e82dd155ead59b819f0f20e42f4635d5044ec5d550d847623000000000000000000000000000000000403969d2b8f914ff2ea3bf902782642e2c6157bd2a343acf60ff9125b48b558d990a74c6d4d6398e7a3cc2a16037346000000000000000000000000000000000bd45f61f142bd78619fb520715320eb5e6ebafa8b078ce796ba62fe1a549d5fb9df57e92d8d2795988eb6ae18cf9d9300000000000000000000000000000000097db1314e064b8e670ec286958f17065bce644cf240ab1b1b220504560d36a0b43fc18453ff3a2bb315e219965f5bd394c68bc8d91ac8c489ee87dbfc4b94c93c8bbd5fc04c27db8b02303f3a65905400000000000000000000000000000000018244ab39a716e252cbfb986c7958b371e29ea9190010d1f5e1cfdb6ce4822d4055c37cd411fc9a0c46d728f2c13ecf0000000000000000000000000000000001985d3c667c8d68c9adb92bdc7a8af959c17146544997d97116120a0f55366bd7ad7ffa28d93ee51222ff9222779675000000000000000000000000000000000c70fd4e3c8f2a451f83fb6c046431b38251b7bae44cf8d36df69a03e2d3ce6137498523fcf0bcf29b5d69e8f265e24d00000000000000000000000000000000047b9163a218f7654a72e0d7c651a2cf7fd95e9784a59e0bf119d081de6c0465d374a55fbc1eff9828c9fd29abf4c4bdb3682accc3939283b870357cf83683350baf73aa0d3d68bda82a0f6ae7e51746,,,invalid point: point is not on curve +00000000000000000000000000000000039b10ccd664da6f273ea134bb55ee48f09ba585a7e2bb95b5aec610631ac49810d5d616f67ba0147e6d1be476ea220e0000000000000000000000000000000000fbcdff4e48e07d1f73ec42fe7eb026f5c30407cfd2f22bbbfe5b2a09e8a7bb4884178cb6afd1c95f80e646929d30040000000000000000000000000000000001ed3b0e71acb0adbf44643374edbf4405af87cfc0507db7e8978889c6c3afbe9754d1182e98ac3060d64994d31ef576000000000000000000000000000000001681a2bf65b83be5a2ca50430949b6e2a099977482e9405b593f34d2ed877a3f0d1bddc37d0cec4d59d7df74b2b8f2dfb3c940fe79b6966489b527955de7599194a9ac69a6ff58b8d99e7b1084f0464e0000000000000000000000000000000018c0ada6351b70661f053365deae56910798bd2ace6e2bf6ba4192d1a229967f6af6ca1c9a8a11ebc0a232344ee0f6d6000000000000000000000000000000000cc70a587f4652039d8117b6103858adcd9728f6aebe230578389a62da0042b7623b1c0436734f463cfdd187d20903240000000000000000000000000000000009f50bd7beedb23328818f9ffdafdb6da6a4dd80c5a9048ab8b154df3cad938ccede829f1156f769d9e149791e8e0cd900000000000000000000000000000000079ba50d2511631b20b6d6f3841e616e9d11b68ec3368cd60129d9d4787ab56c4e9145a38927e51c9cd6271d493d93884d0e25bf3f6fc9f4da25d21fdc71773f1947b7a8a775b8177f7eca990b05b71d0000000000000000000000000000000003632695b09dbf86163909d2bb25995b36ad1d137cf252860fd4bb6c95749e19eb0c1383e9d2f93f2791cb0cf6c8ed9d000000000000000000000000000000001688a855609b0bbff4452d146396558ff18777f329fd4f76a96859dabfc6a6f6977c2496280dbe3b1f8923990c1d6407000000000000000000000000000000000c8567fee05d05af279adc67179468a29d7520b067dbb348ee315a99504f70a206538b81a457cce855f4851ad48b7e80000000000000000000000000000000001238dcdfa80ea46e1500026ea5feadb421de4409f4992ffbf5ae59fa67fd82f38452642a50261b849e74b4a33eed70cc973f40c12c92b703d7b7848ef8b4466d40823aad3943a312b57432b91ff68be1000000000000000000000000000000000149704960cccf9d5ea414c73871e896b1d4cf0a946b0db72f5f2c5df98d2ec4f3adbbc14c78047961bc9620cb6cfb5900000000000000000000000000000000140c5d25e534fb1bfdc19ba4cecaabe619f6e0cd3d60b0f17dafd7bcd27b286d4f4477d00c5e1af22ee1a0c67fbf177c00000000000000000000000000000000029a1727041590b8459890de736df15c00d80ab007c3aee692ddcdf75790c9806d198e9f4502bec2f0a623491c3f877d0000000000000000000000000000000008a94c98baa9409151030d4fae2bd4a64c6f11ea3c99b9661fdaed226b9a7c2a7d609be34afda5d18b8911b6e015bf494c51f97bcdda93904ae26991b471e9ea942e2b5b8ed26055da11c58bc7b5002a000000000000000000000000000000001156d478661337478ab0cbc877a99d9e4d9824a2b3f605d41404d6b557b3ffabbf42635b0bbcb854cf9ed8b8637561a8000000000000000000000000000000001147ed317d5642e699787a7b47e6795c9a8943a34a694007e44f8654ba96390cf19f010dcf695e22c21874022c6ce291000000000000000000000000000000000c6dccdf920fd5e7fae284115511952633744c6ad94120d9cae6acda8a7c23c48bd912cba6c38de5159587e1e6cad519000000000000000000000000000000001944227d462bc2e5dcc6f6db0f83dad411ba8895262836f975b2b91e06fd0e2138862162acc04e9e65050b34ccbd1a4e8964d5867927bc3e35a0b4c457482373969bff5edff8a781d65573e07fd87b890000000000000000000000000000000019c31e3ab8cc9c920aa8f56371f133b6cb8d7b0b74b23c0c7201aca79e5ae69dc01f1f74d2492dcb081895b17d106b4e000000000000000000000000000000001789b0d371bd63077ccde3dbbebf3531368feb775bced187fb31cc6821481664600978e323ff21085b8c08e0f21daf72000000000000000000000000000000000009eacfe8f4a2a9bae6573424d07f42bd6af8a9d55f71476a7e3c7a4b2b898550c1e72ec13afd4eff22421a03af1d31000000000000000000000000000000000410bd4ea74dcfa33f2976aa1b571c67cbb596ab10f76a8aaf4548f1097e55b3373bff02683f806cb84e1e0e877819e2787c38b944eadbd03fd3187f450571740f6cd00e5b2e560165846eb800e5c94400000000000000000000000000000000147f09986691f2e57073378e8bfd58804241eed7934f6adfe6d0a6bac4da0b738495778a303e52113e1c80e698476d50000000000000000000000000000000000762348b84c92a8ca6de319cf1f8f11db296a71b90fe13e1e4bcd25903829c00a5d2ad4b1c8d98c37eaad7e042ab023d0000000000000000000000000000000011d1d94530d4a2daf0e902a5c3382cd135938557f94b04bccea5e16ea089c5e020e13524c854a316662bd68784fe31f300000000000000000000000000000000070828522bec75b6a492fd9bca7b54dac6fbbf4f0bc3179d312bb65c647439e3868e4d5b21af5a64c93aeee8a9b7e46eaaee7ae2a237e8e53560c79e7baa9adf9c00a0ea4d6f514e7a6832eb15cef1e1000000000000000000000000000000000690a0869204c8dced5ba0ce13554b2703a3f18afb8fa8fa1c457d79c58fdc25471ae85bafad52e506fc1917fc3becff0000000000000000000000000000000010f7dbb16f8571ede1cec79e3f9ea03ae6468d7285984713f19607f5cab902b9a6b7cbcfd900be5c2e407cc093ea0e6700000000000000000000000000000000151caf87968433cb1f85fc1854c57049be22c26497a86bfbd66a2b3af121d894dba8004a17c6ff96a5843c2719fa32d10000000000000000000000000000000011f0270f2b039409f70392879bcc2c67c836c100cf9883d3dc48d7adbcd52037d270539e863a951acd47ecaa1ca4db12dac6ed3ef45c1d7d3028f0f89e5458797996d3294b95bebe049b76c7d0db317c0000000000000000000000000000000017fae043c8fd4c520a90d4a6bd95f5b0484acc279b899e7b1d8f7f7831cc6ba37cd5965c4dc674768f5805842d433af30000000000000000000000000000000008ddd7b41b8fa4d29fb931830f29b46f4015ec202d51cb969d7c832aafc0995c875cd45eff4a083e2d5ecb5ad185b64f0000000000000000000000000000000015d384ab7e52420b83a69827257cb52b00f0199ed2240a142812b46cf67e92b99942ac59fb9f9efd7dd822f5a36c799f00000000000000000000000000000000074b3a16a9cc4be9da0ac8e2e7003d9c1ec89244d2c33441b31af76716cce439f805843a9a44701203231efdca551d5bbb30985756c3ca075114c92f231575d6befafe4084517f1166a47376867bd108000000000000000000000000000000000e25365988664e8b6ade2e5a40da49c11ff1e084cc0f8dca51f0d0578555d39e3617c8cadb2abc2633b28c5895ab0a9e00000000000000000000000000000000169f5fd768152169c403475dee475576fd2cc3788179453b0039ff3cb1b7a5a0fff8f82d03f56e65cad579218486c3b600000000000000000000000000000000087ccd7f92032febc1f75c7115111ede4acbb2e429cbccf3959524d0b79c449d431ff65485e1aecb442b53fec80ecb4000000000000000000000000000000000135d63f264360003b2eb28f126c6621a40088c6eb15acc4aea89d6068e9d5a47f842aa4b4300f5cda5cc5831edb81596fb730105809f64ea522983d6bbb62f7e2e8cbf702685e9be10e2ef71f818767200000000000000000000000000000000159da74f15e4c614b418997f81a1b8a3d9eb8dd80d94b5bad664bff271bb0f2d8f3c4ceb947dc6300d5003a2f7d7a829000000000000000000000000000000000cdd4d1d4666f385dd54052cf5c1966328403251bebb29f0d553a9a96b5ade350c8493270e9b5282d8a06f9fa8d7b1d900000000000000000000000000000000189f8d3c94fdaa72cc67a7f93d35f91e22206ff9e97eed9601196c28d45b69c802ae92bcbf582754717b0355e08d37c000000000000000000000000000000000054b0a282610f108fc7f6736b8c22c8778d082bf4b0d0abca5a228198eba6a868910dd5c5c440036968e977955054196b6a9408625b0ca8fcbfb21d34eec2d8e24e9a30d2d3b32d7a37d110b13afbfea000000000000000000000000000000000f29b0d2b6e3466668e1328048e8dbc782c1111ab8cbe718c85d58ded992d97ca8ba20b9d048feb6ed0aa1b4139d02d3000000000000000000000000000000000d1f0dae940b99fbfc6e4a58480cac8c4e6b2fe33ce6f39c7ac1671046ce94d9e16cba2bb62c6749ef73d45bea21501a000000000000000000000000000000001902ccece1c0c763fd06934a76d1f2f056563ae6d8592bafd589cfebd6f057726fd908614ccd6518a21c66ecc2f78b660000000000000000000000000000000017f6b113f8872c3187d20b0c765d73b850b54244a719cf461fb318796c0b8f310b5490959f9d9187f99c8ed3e25e42a93b77283d0a7bb9e17a27e66851792fdd605cc0a339028b8985390fd024374c76000000000000000000000000000000000576b8cf1e69efdc277465c344cadf7f8cceffacbeca83821f3ff81717308b97f4ac046f1926e7c2eb42677d7afc257c000000000000000000000000000000000cc1524531e96f3c00e4250dd351aedb5a4c3184aff52ec8c13d470068f5967f3674fe173ee239933e67501a9decc6680000000000000000000000000000000001610cfcaea414c241b44cf6f3cc319dcb51d6b8de29c8a6869ff7c1ebb7b747d881e922b42e8fab96bde7cf23e8e4cd0000000000000000000000000000000017d4444dc8b6893b681cf10dac8169054f9d2f61d3dd5fd785ae7afa49d18ebbde9ce8dde5641adc6b38173173459836dd994eae929aee7428fdda2e44f8cb12b10b91c83b22abc8bbb561310b62257c000000000000000000000000000000000ca8f961f86ee6c46fc88fbbf721ba760186f13cd4cce743f19dc60a89fd985cb3feee34dcc4656735a326f515a729e400000000000000000000000000000000174baf466b809b1155d524050f7ee58c7c5cf728c674e0ce549f5551047a4479ca15bdf69b403b03fa74eb1b26bbff6c0000000000000000000000000000000000e8c8b587c171b1b292779abfef57202ed29e7fe94ade9634ec5a2b3b4692a4f3c15468e3f6418b144674be70780d5b000000000000000000000000000000001865e99cf97d88bdf56dae32314eb32295c39a1e755cd7d1478bea8520b9ff21c39b683b92ae15568420c390c42b123b7010b134989c8368c7f831f9dd9f9a890e2c1435681107414f2e8637153bbf6a0000000000000000000000000000000017eccd446f10018219a1bd111b8786cf9febd49f9e7e754e82dd155ead59b819f0f20e42f4635d5044ec5d550d847623000000000000000000000000000000000403969d2b8f914ff2ea3bf902782642e2c6157bd2a343acf60ff9125b48b558d990a74c6d4d6398e7a3cc2a16037346000000000000000000000000000000000bd45f61f142bd78619fb520715320eb5e6ebafa8b078ce796ba62fe1a549d5fb9df57e92d8d2795988eb6ae18cf9d9300000000000000000000000000000000097db1314e064b8e670ec286958f17065bce644cf240ab1b1b220504560d36a0b43fc18453ff3a2bb315e219965f5bd394c68bc8d91ac8c489ee87dbfc4b94c93c8bbd5fc04c27db8b02303f3a65905400000000000000000000000000000000018244ab39a716e252cbfb986c7958b371e29ea9190010d1f5e1cfdb6ce4822d4055c37cd411fc9a0c46d728f2c13ed00000000000000000000000000000000001985d3c667c8d68c9adb92bdc7a8af959c17146544997d97116120a0f55366bd7ad7ffa28d93ee51222ff9222779675000000000000000000000000000000000c70fd4e3c8f2a451f83fb6c046431b38251b7bae44cf8d36df69a03e2d3ce6137498523fcf0bcf29b5d69e8f265e24d00000000000000000000000000000000047b9163a218f7654a72e0d7c651a2cf7fd95e9784a59e0bf119d081de6c0465d374a55fbc1eff9828c9fd29abf4c4bdb3682accc3939283b870357cf83683350baf73aa0d3d68bda82a0f6ae7e51746,,,invalid point: point is not on curve +00000000000000000000000000000000197bfd0342bbc8bee2beced2f173e1a87be576379b343e93232d6cef98d84b1d696e5612ff283ce2cfdccb2cfb65fa0c00000000000000000000000000000000184e811f55e6f9d84d77d2f79102fd7ea7422f4759df5bf7f6331d550245e3f1bcf6a30e3b29110d85e0ca16f9f6ae7a000000000000000000000000000000000f10e1eb3c1e53d2ad9cf2d398b2dc22c5842fab0a74b174f691a7e914975da3564d835cd7d2982815b8ac57f507348f000000000000000000000000000000000767d1c453890f1b9110fda82f5815c27281aba3f026ee868e4176a0654feea41a96575e0c4d58a14dbfbcc05b5010b1000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d8784510000000000000000000000000000000000000000000000000000000000000002,,,invalid point: subgroup check failed diff --git a/evm/src/test/resources/org/hyperledger/besu/evm/precompile/invalid_subgroup_for_pairing.csv b/evm/src/test/resources/org/hyperledger/besu/evm/precompile/invalid_subgroup_for_pairing.csv index b0c4d6de21..acc3197d1b 100644 --- a/evm/src/test/resources/org/hyperledger/besu/evm/precompile/invalid_subgroup_for_pairing.csv +++ b/evm/src/test/resources/org/hyperledger/besu/evm/precompile/invalid_subgroup_for_pairing.csv @@ -1,101 +1,101 @@ input,result,gas,notes -000000000000000000000000000000000ded5634c6bab9610e70f3a9be2bb39c51f2ddd762d22d6c3f0961af19350c4ca4bae333bf4cf586d8cd1e0a0a6c674e0000000000000000000000000000000012309fe1d843245e2cb58d419ff06ed8e93ec901c01d0c5be453e11d10f930afa0c35428ef0c8dc13ce99c990af166630000000000000000000000000000000017c9fcf0504e62d3553b2f089b64574150aa5117bd3d2e89a8c1ed59bb7f70fb83215975ef31976e757abf60a75a1d9f0000000000000000000000000000000008f5a53d704298fe0cfc955e020442874fe87d5c729c7126abbdcbed355eef6c8f07277bee6d49d56c4ebaf334848624000000000000000000000000000000001302dcc50c6ce4c28086f8e1b43f9f65543cf598be440123816765ab6bc93f62bceda80045fbcad8598d4f32d03ee8fa000000000000000000000000000000000bbb4eb37628d60b035a3e0c45c0ea8c4abef5a6ddc5625e0560097ef9caab208221062e81cd77ef72162923a1906a400000000000000000000000000000000012196c5a43d69224d8713389285f26b98f86ee910ab3dd668e413738282003cc5b7357af9a7af54bb713d62255e80f560000000000000000000000000000000006ba8102bfbeea4416b710c73e8cce3032c31c6269c44906f8ac4f7874ce99fb17559992486528963884ce429a992fee0000000000000000000000000000000017c9fcf0504e62d3553b2f089b64574150aa5117bd3d2e89a8c1ed59bb7f70fb83215975ef31976e757abf60a75a1d9f0000000000000000000000000000000008f5a53d704298fe0cfc955e020442874fe87d5c729c7126abbdcbed355eef6c8f07277bee6d49d56c4ebaf334848624000000000000000000000000000000001302dcc50c6ce4c28086f8e1b43f9f65543cf598be440123816765ab6bc93f62bceda80045fbcad8598d4f32d03ee8fa000000000000000000000000000000000bbb4eb37628d60b035a3e0c45c0ea8c4abef5a6ddc5625e0560097ef9caab208221062e81cd77ef72162923a1906a40,,,invalid input parameters, G1 point is not in the expected subgroup -0000000000000000000000000000000014881e90a100e5c1e07588d68c69b9b217d2c57b2bd8782ea7579abfac3a38275677a8dee7e689c1b185712ea38bf0ba00000000000000000000000000000000061e48ceb68db1cb84ed39f9772f937922198b47082d7517c8258e46a490fc20e4e01971711853ab653d064f8adc79e200000000000000000000000000000000173518c27d76414f3027ed3e4936ad1b6aaebf0a98462df3e3a55aa38e19fb121acc6eeadb7689c84fec18580b63784c0000000000000000000000000000000007c116829ccc1d5505dcce029f5c8b7c8a9cbc9dd562a874766a5654483aec977a0fb9e611f9471d2f0c91fd6534892f000000000000000000000000000000001560b267e66200e69d6298250456d88500a0d79ea69870358a6cb39609fb6596e539b28bfea9d1c7054b5b51a4c0f3950000000000000000000000000000000000cc196f93e5a2dd3a41a1ba23fd2e53bf376c910117e9216663e30091b96c897080bca189ce3107720dac1c54dc4fc70000000000000000000000000000000014881e90a100e5c1e07588d68c69b9b217d2c57b2bd8782ea7579abfac3a38275677a8dee7e689c1b185712ea38bf0ba00000000000000000000000000000000061e48ceb68db1cb84ed39f9772f937922198b47082d7517c8258e46a490fc20e4e01971711853ab653d064f8adc79e20000000000000000000000000000000015237996817e97b29ef5b4ee49e6aea7129bdc4a46707f99df3ab8af36eb4123e93496d94846f7807b3bd2c87d3ca039000000000000000000000000000000000df666f7728483689a746e5b39f4848a9f2d831cb17d4e5f7fb67de5d497f6399de5f37ba9e6ab76937e26450000d600000000000000000000000000000000000e4ffecf86b371ddc9ee6a72b5ada74790b590acc51c6c5c479c43c532a9507b4b4909bdc901b00932371a109fd38b7e000000000000000000000000000000000354f92ccabccc9390072671ccc8d3ea0a0c44f85816f20bd6e8b485e648e8ba0d5b845a8835395ce65b8101015ea83f,,,invalid input parameters, G2 point is not in the expected subgroup -00000000000000000000000000000000199fa649608972d295befae38d36940663d2b67bb286a3d549c75deef39ef8068728bbba2cafac44c102499601e4bd860000000000000000000000000000000002dac960f96822774a4956fc0ba97a235d0a2c10d81d9adf7b88215250c934b68c3de07a97adcaee2aaad0d3d84ecf6800000000000000000000000000000000000eb3c91515d4a41209a73564741a8ccf901a624df9db22e195a5d02d24b7bc0a12756b15b8d006cb991a7e088eaef1000000000000000000000000000000000704ce8afc808b0161f6f61b22d990d713ae398779e6e74e9b5771daf006ce0bba3a8088edf75156f0e48b92ee8409b00000000000000000000000000000000018fe81e05aff0620f4bdbe4a715e015650497afab62921eba0ab86b649e5a2fd3d54041868928519f537e36448688a0d00000000000000000000000000000000162bd97161201ea3c26f8dd1204a9c6b61b762bdf573cb5d20b6b255f30208ca7d96aa47b46fb8c6bf0922075f1c1ca8000000000000000000000000000000000d5bb4fa8b494c0adf4b695477d4a05f0ce48f7f971ef53952f685e9fb69dc8db1603e4a58292ddab7129bb5911d6cea0000000000000000000000000000000004a568c556641f0e0a2f44124b77ba70e4e560d7e030f1a21eff41eeec0d3c437b43488c535cdabf19a70acc777bacca00000000000000000000000000000000000eb3c91515d4a41209a73564741a8ccf901a624df9db22e195a5d02d24b7bc0a12756b15b8d006cb991a7e088eaef1000000000000000000000000000000000704ce8afc808b0161f6f61b22d990d713ae398779e6e74e9b5771daf006ce0bba3a8088edf75156f0e48b92ee8409b00000000000000000000000000000000018fe81e05aff0620f4bdbe4a715e015650497afab62921eba0ab86b649e5a2fd3d54041868928519f537e36448688a0d00000000000000000000000000000000162bd97161201ea3c26f8dd1204a9c6b61b762bdf573cb5d20b6b255f30208ca7d96aa47b46fb8c6bf0922075f1c1ca8,,,invalid input parameters, G1 point is not in the expected subgroup -0000000000000000000000000000000009d928f478fea86b1e3c1ebf59b230af42e4a539dd43ff17b9ca250605401273edc42806bf2cb887c6093729238fc0560000000000000000000000000000000005b6040ce6d0802719af5b9c0fe48366c5a97bcad2c6ec25f64cd73f39dc73a22d0084c69f2e86637c584d2de55d6064000000000000000000000000000000000aaeceb367eaf2ab8afb5070b5f5611f19fed17e16f6b01cd20f5f1a7e550d4689c89d6490878877c46492e8fbc9db600000000000000000000000000000000019dc59fbefa7abf12f1aa92e420f52595a06e819e974c07b62a3ae459c62545922016abd8e91301aca8f48ed793b91af0000000000000000000000000000000012f5352825a95ff0a0f0948b150e5eb1ab53d6591dc54ca8b37941fa94a0fa68af8c35aaa26c73951d2dd52e9c7a55bf000000000000000000000000000000000531e610f3706a1c67b31909a97232acef0e23c35c657dc82d9508fcf33bfff777386dc8265accb52d0da207957d25160000000000000000000000000000000009d928f478fea86b1e3c1ebf59b230af42e4a539dd43ff17b9ca250605401273edc42806bf2cb887c6093729238fc0560000000000000000000000000000000005b6040ce6d0802719af5b9c0fe48366c5a97bcad2c6ec25f64cd73f39dc73a22d0084c69f2e86637c584d2de55d6064000000000000000000000000000000000cf95f6bc3f14cc8a657da35f212d55d3633ca0d224794ac1e49cbf1e1db7757dac2bb08880f7b13f2ac0c2b95ff483c00000000000000000000000000000000115bf27014a31726503f0665301f9e183de41e002db568916aaaeaa4c8046475860db3b993b2ac2af58b12614f0b9f2d000000000000000000000000000000000983ee62076e9c5f8e6ac3ba8e5f98823a37ff20432f0b4e7d9e008660965f551bb5538e6ba28541ad514e87d128da1b0000000000000000000000000000000019c9930e3e009986608463c80aa0049fcac5e897474e519b52c80960f1dada5a48332d810f1f9a34ee479383b5b556b3,,,invalid input parameters, G2 point is not in the expected subgroup -000000000000000000000000000000000f240a4daf7acbe8f4c5a9cb40ccc6d99dd712b8dae4c13e9d3839b0c88c5eef6f050144a4b731267e2132a81b1a635c000000000000000000000000000000001931c93a957ba9005fa69004c7e984b9dc86f45ec03eeed77addb3e1bee3c2424105df8e8faacae2b07623cd3cc7261e000000000000000000000000000000000805892f21889cab3cfe62226eaff6a8d3586d4396692b379efc7e90b0eaad4c9afbdf0f56b30f0c07ae0bc4013343b30000000000000000000000000000000007853f0e75c8dee034c2444299da58c98f22de367a90550dbc635fb52c9a8f61ccc100f70f10208944e48d09507fdce100000000000000000000000000000000064afd6b3ef7ff7ec34f1fa330877b42958a46a7698c6d21adf73bfdfcab7793b312e21e5988652e655f2d42edb8a673000000000000000000000000000000000ea8a2217c3dbcc0f6e562de9cb2f334c896577d0b3a7108d96b1aba2d705dbf531e870d4023cec2c0533455013242330000000000000000000000000000000019c822a4d44ac22f6fbaef356c37ceff93c1d6933e8c8f3b55784cfe62e5705930be48607c3f7a4a2ca146945cad6242000000000000000000000000000000000353d6521a17474856ad69582ce225f27d60f5a8319bea8cefded2c3f6b862d76fe633c77ed8ccdf99d2b10430253fc8000000000000000000000000000000000805892f21889cab3cfe62226eaff6a8d3586d4396692b379efc7e90b0eaad4c9afbdf0f56b30f0c07ae0bc4013343b30000000000000000000000000000000007853f0e75c8dee034c2444299da58c98f22de367a90550dbc635fb52c9a8f61ccc100f70f10208944e48d09507fdce100000000000000000000000000000000064afd6b3ef7ff7ec34f1fa330877b42958a46a7698c6d21adf73bfdfcab7793b312e21e5988652e655f2d42edb8a673000000000000000000000000000000000ea8a2217c3dbcc0f6e562de9cb2f334c896577d0b3a7108d96b1aba2d705dbf531e870d4023cec2c053345501324233,,,invalid input parameters, G1 point is not in the expected subgroup -0000000000000000000000000000000012d75b62dd32798ea12b99f51a496bbf61bca93cd233dd288e00259893dbe7c73b6342860d41fd86878a6de608dba0ed00000000000000000000000000000000018e963e1cdb31ce3f636091952c17ab4c03c0f55940196b5772002850c6c86a3da13a9a5fbfaa8256fb0a9c4139bfc60000000000000000000000000000000018330d288ddc1786744f95c4b3bacbdfd10ab560fc283c1ecde1bcbdc53cb284198f340241242763c77b4cd3b8c729200000000000000000000000000000000019a3d86d9b3ff0b03da1686c3234bb2b8109ab12ffd7599ef9e3489fcee40e50036dd952f7a4129473340fb725458cc50000000000000000000000000000000010f70de44c7e0510c8ff8327dd83ea4087f9f8b5a53fbe18615fa31a3b57862b52a7726b3e9403afe93dcafc5606dfe500000000000000000000000000000000199e6da569d0eb7938d52b396c9bc6d8b563dd6e64edd60e2e25c493475a0cbd953e7ff54309d189eba2b3827ad614180000000000000000000000000000000012d75b62dd32798ea12b99f51a496bbf61bca93cd233dd288e00259893dbe7c73b6342860d41fd86878a6de608dba0ed00000000000000000000000000000000018e963e1cdb31ce3f636091952c17ab4c03c0f55940196b5772002850c6c86a3da13a9a5fbfaa8256fb0a9c4139bfc600000000000000000000000000000000192b17cf1539a57ee64701bcd07ed0b067a6ab12ef17408ad3ba1db0d94889cc481c877588fd70270287aa8f279659af000000000000000000000000000000001779c74b7e83c8d931510b555de206dee2d9edbb49b473c586c5b7046d1389e6f612cf96ee76446a21b02f135492fa1c0000000000000000000000000000000007165050fd4407a69143a98001c290f8b1aef02d64d28ee046744009f4afa376da95b4f6a3dd36427a297ed25e6bb3320000000000000000000000000000000005a9238272385614f6df896801f7f9af9cda1ac0ce3c816174693bd52b1799386c4f6355fc36f9ecd566a3a4b20e612b,,,invalid input parameters, G2 point is not in the expected subgroup -000000000000000000000000000000000d612430d9b8956188fefa4cd839ec8dffee18678f83d4984b08e227880ec127e63860bf5d7a27c309fb425b90c0afa500000000000000000000000000000000100556e6391ac2a05b15e552e67d6509e21c4770cfe2f8126fd1d9663995839420a4915656d6292d0767892833369bbc000000000000000000000000000000000aeb5c087644595d0912879f61959d2731ff55260c682ed2bc5fc55c13964ef7c1f70aeb55876d2264d558c31371ca69000000000000000000000000000000000e173848f4570525b03a2b2c86f4dcdb8b28dd6d18c1354cad31028eb1b8b44432c2346edaace093e3954c7fa6d338a4000000000000000000000000000000001949b0902506d111ef6318edcd7a58ca4d69f5804a028aee73c3786cb2db168c6a73b77194f7a021ae6ae43ac78ade340000000000000000000000000000000017c5e28ba6103d97e2f3d3611c0c78f06406e0da8a49ae29c7d460b52f75136920784cd500aa3593858b877697eb84240000000000000000000000000000000007dc719ae9e3f1e11d3ed4747a546a7b973ccb1967adb1b3066645a8bde9632bcfa3530e768f088ddbc022b169e67cbf000000000000000000000000000000000bbf9cf884b19c84045da1cead7dcd9fdbf39d764ff1ad60d83ed1e4fd0ce0554f0fb618203952cf02a7c4ba466c66b8000000000000000000000000000000000aeb5c087644595d0912879f61959d2731ff55260c682ed2bc5fc55c13964ef7c1f70aeb55876d2264d558c31371ca69000000000000000000000000000000000e173848f4570525b03a2b2c86f4dcdb8b28dd6d18c1354cad31028eb1b8b44432c2346edaace093e3954c7fa6d338a4000000000000000000000000000000001949b0902506d111ef6318edcd7a58ca4d69f5804a028aee73c3786cb2db168c6a73b77194f7a021ae6ae43ac78ade340000000000000000000000000000000017c5e28ba6103d97e2f3d3611c0c78f06406e0da8a49ae29c7d460b52f75136920784cd500aa3593858b877697eb8424,,,invalid input parameters, G1 point is not in the expected subgroup -0000000000000000000000000000000013b23b5a61ad3ed0ed74a57023285338c77c01dd93e17fd93d4225d27a7168dbdae3fff0c8ebcfc30887df348deea7ae000000000000000000000000000000001245282782135d41eee4dbd9b69a586e1ae2e17426643494427eabec93ba3c056089ce9c8a667727c3464178f7c87655000000000000000000000000000000000d35887ecdfce840b79f60f77af0e7cc01289ff20e1558a14b57a73f3fdd8e66ca496a73ce888d1c8cd0888d8219412b000000000000000000000000000000000cca9ce1b3c5bb6d02d5c36549438a4854dacacab7b173b434d09e496256edc2372a08edb2de26e5369af03dd0e2d73e00000000000000000000000000000000152d022429b54ac4bb70dacc888a2a3409cd7d2db0614ba0afe236c7bff311967718a70eb7943f93a6dbc88d3c008e8b00000000000000000000000000000000191e99ff1e02809121098597de4d176dfc85586d3e13609b3399c08da7c9cd6fa006e8b95551878a74e140cf166625c30000000000000000000000000000000013b23b5a61ad3ed0ed74a57023285338c77c01dd93e17fd93d4225d27a7168dbdae3fff0c8ebcfc30887df348deea7ae000000000000000000000000000000001245282782135d41eee4dbd9b69a586e1ae2e17426643494427eabec93ba3c056089ce9c8a667727c3464178f7c8765500000000000000000000000000000000179657b434fbb3ecb4857b4559c8cdaa1448b2a4bf4314349341a45bd3a2cdeb2aa6be75ee1aaaef0f90d086df55ccc40000000000000000000000000000000011ec9abd1a497dc7cc4b4b9e2cef8a7abc767969703d79ff51d7a4f1ab93ae9fc7e8bd4852da22ec067d326fffa54757000000000000000000000000000000000a45435d1f78ad93aeef8a88dad39aebc0cf38cc16fbb02c571a269bbec773e71b5ee9d09a505afc9a7fe11b06f040cd0000000000000000000000000000000000b6ee9d2b0fbd996455169ef07afa3be3c6535d65545c8503c3d77dd0576eecd2f81b50dabbb62328edfe236981d5c1,,,invalid input parameters, G2 point is not in the expected subgroup -000000000000000000000000000000000b14b12ecaa94f9656be54772be9b22a2495d4ff873b0bb971c27ab1d8b940c84cabcf921f6f75e93942c38cddeb8751000000000000000000000000000000000c9ad793ae80ad0e1c39670876d679bc7f930c1df1f9202593d1901079687b77f18e4b1536bd7c4152ec197321dc945a0000000000000000000000000000000006a90568fa25b401756e3f86b5300c4d3b626dc6274f4685e8a9f56ec5ca2afce36a1fdc6d3414edc8780c4e650f10dc0000000000000000000000000000000012e41e8e0dd10b3ee31fa866753aa5d9db7669153b141114cdb2ef7fa6df5db27aef0cc70e76a741eae504b038ecf2300000000000000000000000000000000005c35f3372f1ec9845bd04ea722fbed2be1388abf59e622dd3dafb4b3af49bc5fba9e20235e7e58973fedf4b8b720691000000000000000000000000000000001111d18d621070509805d306a31c109701288fd55d4c0644349deb080c6591b6e852b4f7e009b80019513de7f2fce17d00000000000000000000000000000000000707c711f77bb425cddc71ecf96a18b6eb0bed7f012c4f6cc9431003f2e1ac17f7c1f68c4965a4fcc273a3db93451d000000000000000000000000000000001211464c91c7e78b00fe156da874407e4eeb7f422dbd698effb9a83357bf226d3f189f2db541eb17db3ed555084e91ec0000000000000000000000000000000006a90568fa25b401756e3f86b5300c4d3b626dc6274f4685e8a9f56ec5ca2afce36a1fdc6d3414edc8780c4e650f10dc0000000000000000000000000000000012e41e8e0dd10b3ee31fa866753aa5d9db7669153b141114cdb2ef7fa6df5db27aef0cc70e76a741eae504b038ecf2300000000000000000000000000000000005c35f3372f1ec9845bd04ea722fbed2be1388abf59e622dd3dafb4b3af49bc5fba9e20235e7e58973fedf4b8b720691000000000000000000000000000000001111d18d621070509805d306a31c109701288fd55d4c0644349deb080c6591b6e852b4f7e009b80019513de7f2fce17d,,,invalid input parameters, G1 point is not in the expected subgroup -000000000000000000000000000000000e96f4879493d577aa02e9793aba3c680de9296dadef569d70484297398cca1e3d8acadc6c188345d98d5208f5b2d7800000000000000000000000000000000003bee60fe5a42f31ae4218a6c6fff2ffb51329c86f8d3c381fb090bba0274eef8cf0d351fb4bbe2d51e25d9f7b2094ee000000000000000000000000000000001664847d2bfb8939cccda0bc7b7ef02fcc1188fcade83341db7c4dfdd4a1a3bdd627379544dd405bcdb58caf4be39cb40000000000000000000000000000000001a293caf801299370cd133fd54d2086c6d1aa96ec32a1c9c57679f45785c9e6fa91018720c2d0515b38790914ab61d20000000000000000000000000000000017efcbccb71f6bbfa515e89d59b5fcdda4bf37c90fc6dafe9c6b0fe3d42a372ad9c66e5d60e04eff30ea7c1952f3fed30000000000000000000000000000000018893c6a3c621ba6c1119529a07d6c2f9c1d4bee5e0090c4c0204d8d4f3e200ab3300dcdf1cfe61370d68849806ddd8e000000000000000000000000000000000e96f4879493d577aa02e9793aba3c680de9296dadef569d70484297398cca1e3d8acadc6c188345d98d5208f5b2d7800000000000000000000000000000000003bee60fe5a42f31ae4218a6c6fff2ffb51329c86f8d3c381fb090bba0274eef8cf0d351fb4bbe2d51e25d9f7b2094ee00000000000000000000000000000000060a0cdf9ea84b21c7399b21e337dab42f357c30f50b076b4f95bf8623b88e557cc8b346e41a996adbfbaf0a3697ae8e00000000000000000000000000000000003746a481d5760263d43ee3c2ed6493caddcc59754fb8534ff57ff9bf167f356d901277b9935210ddac4dfff8f21161000000000000000000000000000000000d80e40583153e6e0adf9f95ebc4fd501f5aa426ff77038b69f0fe8259268f9224628ead1a63b7ecb4218ba825ee45b60000000000000000000000000000000005d0421b213f88469887d67c68316a98c18d2035a601dec994f6a4b91fb6c3b7e5ac7741cd07c956908869e1023dd32d,,,invalid input parameters, G2 point is not in the expected subgroup -000000000000000000000000000000001576c6f620bbe36a7df78985dbffd355c032bb667f4757501bb27a426c99e1949a1bc65afebaeac0668ff3d375b7837d000000000000000000000000000000001651783a82f2a8e1e389923bfb53836492c00e447b288873071bd8682a0ef30864f4d0fc9a626bf701bdfe1a48f4479f000000000000000000000000000000001335276775545fbb4c701beb57cb34312108c9f1d46b4aa4b09a16faf0e648b4e80848bf5e75ed8730715f0107afc9820000000000000000000000000000000006ffff8736bab41b4ee5681b741a81fc870e648001027161144254d04c678e4f954e9f191bd8b26201aec681cbf0654b00000000000000000000000000000000026ede90d14fa0885baad21f9631bae058573251cbef5757bb8cfad061f3bdc78834fa5862dea19a2236c014b0f1652e0000000000000000000000000000000009844d0cf7f6f3401145d8d720defa577ca46b49e04e39c4c139ec6811a574e7dd5ce3acd00d1ce9496f10dd15c6d946000000000000000000000000000000000a6ff5f01a97c0f3c89ac0a460861dc9040f00693bfae22d81ea9a46b6c570436f0688ed0deef5cdcc5e2142f195b5c000000000000000000000000000000000193a17880edffe5b2ebedf0dc25e479cac3b136db9b6b24009ea0a9ca526d6dd9714d10d64c999d4334baa081b9f2fbe000000000000000000000000000000001335276775545fbb4c701beb57cb34312108c9f1d46b4aa4b09a16faf0e648b4e80848bf5e75ed8730715f0107afc9820000000000000000000000000000000006ffff8736bab41b4ee5681b741a81fc870e648001027161144254d04c678e4f954e9f191bd8b26201aec681cbf0654b00000000000000000000000000000000026ede90d14fa0885baad21f9631bae058573251cbef5757bb8cfad061f3bdc78834fa5862dea19a2236c014b0f1652e0000000000000000000000000000000009844d0cf7f6f3401145d8d720defa577ca46b49e04e39c4c139ec6811a574e7dd5ce3acd00d1ce9496f10dd15c6d946,,,invalid input parameters, G1 point is not in the expected subgroup -0000000000000000000000000000000016e8fb30c523be94fed64c81cefcbed03d7a2c85ce975601a441a920d70980be8b7c682ebf2aa3cc36ad1bf2d98a711e00000000000000000000000000000000056d7a36324b92ce3bf1644a2a0f6e717b0e9d94e9e5231f0c999c0f6eac936f5c1b1ff4aef04b821454a951882fd45000000000000000000000000000000000069ce7ace071ac2f7034200da8eb9252c55cbb50a591c563684013fa8071d7289a44ce5b100db6af1e8732b8e5b3b7fb0000000000000000000000000000000019535c703e9dec227c92db508c5c0553b986b93e3a90b35f472ad8e5b217bc7658ceb7ea452b76984d3d17859fbd7fc300000000000000000000000000000000008b3677ecfb10faae0478be5be5c72fcd7137042b5972fffbd15ac95d6104687a81fa3db232edbbb8703280412eddd30000000000000000000000000000000012a628e23e5c7f0225eaa75b6c9199d1d3a0316d474d1fa729640c295ec156ce3bd49f193d993165b9a69ad6cb2ed75c0000000000000000000000000000000016e8fb30c523be94fed64c81cefcbed03d7a2c85ce975601a441a920d70980be8b7c682ebf2aa3cc36ad1bf2d98a711e00000000000000000000000000000000056d7a36324b92ce3bf1644a2a0f6e717b0e9d94e9e5231f0c999c0f6eac936f5c1b1ff4aef04b821454a951882fd4500000000000000000000000000000000005b6ff8cf47cdedab38d984013db8401fa4783e7c8e78160c7a420de86636683b8dc292e1f0494dba5865f217e33e7c40000000000000000000000000000000008287d216fc45ee3e210630f0dc4893dfbba90b3bfd34986b64b04a2ec6fea0496cb0f2910cbb99a70896e5afcf809e8000000000000000000000000000000000a1a11f1b52c35b9e061c57b7b7f5f76f4db764607c93c2dddf245170f4c6fcf5915d72130e6f8f0c0c5b29a4970aeb30000000000000000000000000000000009255413a3db5889608069b7a72879b659ee5e1e71165752a9173cf1ef749050fefb86584ce90cbd3c3aa3db023b3322,,,invalid input parameters, G2 point is not in the expected subgroup -00000000000000000000000000000000117e2e3a8753660374fb2b812038bfd8f15d36d26c7b07fb546610405cd4442c79166060c8b8e767ea4084a583bbbcca0000000000000000000000000000000011247def4be1da163e724a175f74afde615df1417cdc2491158fd560442e56ebbcb61f51f9712ac93131024e27a1caa90000000000000000000000000000000001cdfae9234096578b9413f926ef8c6831f2c0f700e25d7553a746aef44238e493f8032e09f67f2fed9676c9611f60e70000000000000000000000000000000019c8bae08d3926997146f7827f00cde863684dd4050ea5da64f6798e7a930d3c1f34046bea0f44232594f5469db566280000000000000000000000000000000013574b997ee8988aa81db0e2ddb98be2e7005603076fac5cb246f65c869aa7bb3f148c8dde970e34e5e5efce023e633c000000000000000000000000000000000998bc9d41c5d527360fc4e68ba067d3778cf5cf00e5959b5ec52c1595aabe6e2e92d40cb34faa84513d150568c8cfc00000000000000000000000000000000009ec00ea2da59d937d3154d86dbed2957667253401bce9de80e0ffe6df32f36b06404b9e3af08e912a0b4ef091f93efb000000000000000000000000000000000dd8d1bd66f4accbc9d0c7dabef7af72f51c67a0d61384647533ad92bba44a312f0be0fa52163176f1aff4e64c00aefb0000000000000000000000000000000001cdfae9234096578b9413f926ef8c6831f2c0f700e25d7553a746aef44238e493f8032e09f67f2fed9676c9611f60e70000000000000000000000000000000019c8bae08d3926997146f7827f00cde863684dd4050ea5da64f6798e7a930d3c1f34046bea0f44232594f5469db566280000000000000000000000000000000013574b997ee8988aa81db0e2ddb98be2e7005603076fac5cb246f65c869aa7bb3f148c8dde970e34e5e5efce023e633c000000000000000000000000000000000998bc9d41c5d527360fc4e68ba067d3778cf5cf00e5959b5ec52c1595aabe6e2e92d40cb34faa84513d150568c8cfc0,,,invalid input parameters, G1 point is not in the expected subgroup -0000000000000000000000000000000018de31d75ba31dc1441bee38f5fb9e9d347e0243e6c3220de664e04a0af17c776fbb483f63ebeac48c7811adc0fff6bc000000000000000000000000000000001053f5c7a65dfb41b7631a22e60337769beabd663fa76eaa1e01f0c0e3c901f40a22b34adfb13b38e298eb83f08d7b1400000000000000000000000000000000079daf601b5fdd1c00552382a819e1924a517226864aa3565d384dc399e6e124c3ad61b236e19321078eab585579572d0000000000000000000000000000000008ff51b4d60d9fb1718c5622b1a3353675ca0144e12e68875481394755107b7f3364d1320283ce34737d5ea0b7d9b40f0000000000000000000000000000000000f430d35de439bf8ef82df4dc61459cf9783d66531e8075f323dbf102035032972a4830ba6bf391b568e6b691723ea600000000000000000000000000000000042df3a5c7b534c48c9af9f48e5cb296e2e514e3322630989c3da9696485797fe2ae036e13484e26cb59b48a479d3f520000000000000000000000000000000018de31d75ba31dc1441bee38f5fb9e9d347e0243e6c3220de664e04a0af17c776fbb483f63ebeac48c7811adc0fff6bc000000000000000000000000000000001053f5c7a65dfb41b7631a22e60337769beabd663fa76eaa1e01f0c0e3c901f40a22b34adfb13b38e298eb83f08d7b1400000000000000000000000000000000180168b2c9a59a9bedcf002336a6ce5d5ff36937948f5d3aa9fc1ef1912d9fed526edcaa00b5ede76906c40994937da00000000000000000000000000000000018d47a4f6e4320a230b8a4e5f5eea7807fb5b0dccc72af182e8bb811f2470dfd485f291b8197899af84332e3674d56950000000000000000000000000000000000dbfed96298ad2f57fe7b1eff4791abdae5fd0ca3573e66270f8c9f6adcbf6e54a746789a496714f5cc06eb2b8190070000000000000000000000000000000002939de2a2f7ec3d44dc5ae679967a5d7efcf80df8a21d9708c036c602a5050487f80a39cc36c7e587f0f2610fed86b2,,,invalid input parameters, G2 point is not in the expected subgroup -0000000000000000000000000000000001ac9e5f4fdccfe8d2979ad5329b07b23b497c2b7f26283f8c79548387610580568bdd9dc040261d6c265aac581b4665000000000000000000000000000000000eaf31d6368bb9d762ea067eed73b008dcb4d84643471dc1d64104eaefaf500858d9a9323b7fa2ba3c22bf15e7db6b9d0000000000000000000000000000000007457f2601621a99050d8993244f026b9a62ff7055b325e6f1edd1cf54065785f003cf7c8a4bb1f7bdf14e220e490ada000000000000000000000000000000000928eb76b428dde37546a27f3d77605c293738f448fbdd6d618747b0de04004aa4419cc5601600419c6e1d470c15982e0000000000000000000000000000000008074e9f5473492dd2e536f7b305be4e5c564cfc9218934d03dde6dc5118064ebaa5c26fdd1123a9c31336c37c1234900000000000000000000000000000000002bba1f9b7da6abd2b322c8f11c749b2a284552eab25a77d21b38b028da477a3ffec1901a015e81fe2893576a41e4c0b00000000000000000000000000000000172447291285a20c3ffcdef805260f00fbd4c5d3a42ee5b17d5ec05a723aadf4c2acc49f839e222155f29d0c6384bb0a000000000000000000000000000000001490dae85f858ed057fdb61c22ebf3d45c3af02afa53f32b2542808bb4db5bb1b9603e377f0b6d214e03050379f8006c0000000000000000000000000000000007457f2601621a99050d8993244f026b9a62ff7055b325e6f1edd1cf54065785f003cf7c8a4bb1f7bdf14e220e490ada000000000000000000000000000000000928eb76b428dde37546a27f3d77605c293738f448fbdd6d618747b0de04004aa4419cc5601600419c6e1d470c15982e0000000000000000000000000000000008074e9f5473492dd2e536f7b305be4e5c564cfc9218934d03dde6dc5118064ebaa5c26fdd1123a9c31336c37c1234900000000000000000000000000000000002bba1f9b7da6abd2b322c8f11c749b2a284552eab25a77d21b38b028da477a3ffec1901a015e81fe2893576a41e4c0b,,,invalid input parameters, G1 point is not in the expected subgroup -000000000000000000000000000000000515390641039576df1debf767b899deed928bba057d8564e7d117b324dd7f45e38939ffa1056fea35e1df8ba38815ad000000000000000000000000000000000013af9258135a09e5710a22dc437a4efdfee1f6c25cc08fb026c7ea2accddb9446333a91a532742c7713f6639e0cc460000000000000000000000000000000017203225f7e7b55e52793698b8a1166de5cb3d130c7df6f74ae428c4f39e7d042d41eb3aed266ca8cd3be1618cfcbdf60000000000000000000000000000000016b8053ab19a08a8c23a166bfe7a89be6eed05f305525146d9ff6e03e47ba125403cb2f000672d08a2b59051242f61ea000000000000000000000000000000001136f9a9369aa3561d65e54869f36ae9d6945654ac16335aaf717e0f848463ad401a99e83b3581c79d4221f65d649e9c000000000000000000000000000000000302ecf71033b917efac49d7a22db2e5c59b656639c4d0aefdb431749718d560b7e5580b4532048a693ccc09fb8a44a6000000000000000000000000000000000515390641039576df1debf767b899deed928bba057d8564e7d117b324dd7f45e38939ffa1056fea35e1df8ba38815ad000000000000000000000000000000000013af9258135a09e5710a22dc437a4efdfee1f6c25cc08fb026c7ea2accddb9446333a91a532742c7713f6639e0cc46000000000000000000000000000000001330e5c71d9b0209c8f8c04b4a28ad70d826b2c781493ac50fe58d0d6b740de3ed08f9829aa9b207ecf623a36dc8de610000000000000000000000000000000019a81ae1c6c08004a75b8fb5426ec899a09becce68dfb63fa7335420f05075bcf42c85dfa688ae75398c3ae5e4d28d12000000000000000000000000000000001597318859306f3814d20faee54926d5e8ec01005fae8aa408989afd5a1d7add8956d8fd3e75f9e446fb8b2a31050b6b00000000000000000000000000000000151e7c5bbcaf1e9581ac48e2b9bc63bf4576ee5d938981550f00fe9e3a42d389d6b56acd0ac9254ceaa71519b5049a4c,,,invalid input parameters, G2 point is not in the expected subgroup -000000000000000000000000000000000a2e9dcb8461de77fffb1281df7360c947108baef671602902c3bfa4afe60e0b4810cd46bd91276cd58e33fbf4973301000000000000000000000000000000000c039ea7e94fca4a32a275691131df8e3d470d6026aa306c8ae855e9e411878247368615094621e6af5486809b467a7d00000000000000000000000000000000138ddc71e9709e595ce2631c9155069818d07f225f80511eac21c5655721df83f83e2abbf56e2d5ebc9698f9128f0579000000000000000000000000000000000080f7ae78277c94833c0f12aa2cd98285621e0d92a89b45cac848f5a75ea652e98cd085150b2d7babaa9a365123d90e000000000000000000000000000000001147cec62010d42cd84651ec61ad8263699786f0f34aa7f9de75ac841861fae2e8ce3795fde8e7038c8506f573cf0e0f00000000000000000000000000000000138ed243889db13546c69583c1aa93ee98366220ad80c590ad112adcb4b7c87fb48a34483e76d4a5c55a30f2adf1a6a6000000000000000000000000000000000077b7a4c4644b21ac3ef56db1163f7b2e07a817cfd9d4c6830a97d0ae0b620e0b235376d590162c378899ba12eadb5900000000000000000000000000000000022beafe4b4ab44434c9dabae45a395b5b8da15da2fc2e723c1b30b5efc95e880846844f27eb47dfae8657fa27ab64ef00000000000000000000000000000000138ddc71e9709e595ce2631c9155069818d07f225f80511eac21c5655721df83f83e2abbf56e2d5ebc9698f9128f0579000000000000000000000000000000000080f7ae78277c94833c0f12aa2cd98285621e0d92a89b45cac848f5a75ea652e98cd085150b2d7babaa9a365123d90e000000000000000000000000000000001147cec62010d42cd84651ec61ad8263699786f0f34aa7f9de75ac841861fae2e8ce3795fde8e7038c8506f573cf0e0f00000000000000000000000000000000138ed243889db13546c69583c1aa93ee98366220ad80c590ad112adcb4b7c87fb48a34483e76d4a5c55a30f2adf1a6a6,,,invalid input parameters, G1 point is not in the expected subgroup -0000000000000000000000000000000004db2336ff5016a6f0f34b2881eb80cfbb35f557ef492f2dc54a654c8c574651fc89f3f211a46510ebffcf5c890e5ee700000000000000000000000000000000103d17d59c26d8c85426b73593843e3863cd672043b7a392cdb05bf5dd69cd11583423a4b146dcd3fbcde4ef4349bd78000000000000000000000000000000000e07265d2762e8e398c83efe1c43452d91b90b7a4271c09ff693c83745a6c01b73561ffe3da9300c8e7e1602dbaab0bc000000000000000000000000000000000375579c16a167fd9f9f61d5177705f157aa0df3451971029a9444432db119fb33b8c07de33fc822eab46ed4ae47cf8200000000000000000000000000000000098cee454129e946d758f95e649a601b6e682467093cf32c76e5cd1328111f9d48cbb2850d4d2faafe429161b090f8ab0000000000000000000000000000000012a3fdf296743b2eb3f389eb6dbea52da21e7dbaad180177184afb7976e06fd4ad488399d39b760ca146278cb3759d7e0000000000000000000000000000000004db2336ff5016a6f0f34b2881eb80cfbb35f557ef492f2dc54a654c8c574651fc89f3f211a46510ebffcf5c890e5ee700000000000000000000000000000000103d17d59c26d8c85426b73593843e3863cd672043b7a392cdb05bf5dd69cd11583423a4b146dcd3fbcde4ef4349bd78000000000000000000000000000000000e87688c9f6f48450528cec78f874d87dcfab499bce391e964a0abd601d675eec8a2b4cc6c44811cbe918913a230975c000000000000000000000000000000000451c1a17567b55123da563e173b2d92ab635c4957d116fdff8eb5a3e00bfbe079abead42b9c990b56db919719d066160000000000000000000000000000000003206eb27b9e53bc451bdbe5059133a51d656d9d80654647163a070741761af3e712e2042acc5ca29fe72cafb3a98ec7000000000000000000000000000000001869b7fd294c230aa5901db9cca31e6d3801069e0795e4c7c63dea8adc1e4a5709ec62670e2abeeb040031b7fcc8521a,,,invalid input parameters, G2 point is not in the expected subgroup -0000000000000000000000000000000007248a496f2cc918cc3cf0240c5c3d0dce36228a199766106999205b5767db09c2ff5cc720691ebc6bb1c316159d1c000000000000000000000000000000000019ab8e34bc4c0ba409c7edf7bbd4d0cf03f7185a2baa3f22ebd6234503d56e9b0d84a5d8d46ef9e3ac6430029be82b2b00000000000000000000000000000000143220e1cd08ffaa6db4795ed4aa35f3b12cce724fcad005367328972f2364f34096e32f1f1cb7a4287ab636d0030322000000000000000000000000000000000f2de47a37a55edbb75ff0bcc446611d690d7f9efdd09ca1ebb6f1d64a330bed420bcc85aed8b95316fcac3aa7d1f2230000000000000000000000000000000016afb044b8b8c64547e000f80b25576aa329a4319dcd4f1bbe15d12e6f3bbdddbb52140e6297c637311ef0c7a31cafab0000000000000000000000000000000019e6803c07fbaa075093f6a69f9dde05ba3d3f58e67389d7f096e56df49f8270008ed422b64fcdadf7cbbc8334037682000000000000000000000000000000000b231eac9869c94f055f22c16ef5efb687a7399da838c9456bb2469b3e394dd21e462bcc9298d5b56173c7b76f79ee9d0000000000000000000000000000000013a1bb963b7fbe1c3f6bb78cce8c3122773428ccbd87cbb2e76f306a8c5369577267e9b4ccb3417a235fc9045e8828f100000000000000000000000000000000143220e1cd08ffaa6db4795ed4aa35f3b12cce724fcad005367328972f2364f34096e32f1f1cb7a4287ab636d0030322000000000000000000000000000000000f2de47a37a55edbb75ff0bcc446611d690d7f9efdd09ca1ebb6f1d64a330bed420bcc85aed8b95316fcac3aa7d1f2230000000000000000000000000000000016afb044b8b8c64547e000f80b25576aa329a4319dcd4f1bbe15d12e6f3bbdddbb52140e6297c637311ef0c7a31cafab0000000000000000000000000000000019e6803c07fbaa075093f6a69f9dde05ba3d3f58e67389d7f096e56df49f8270008ed422b64fcdadf7cbbc8334037682,,,invalid input parameters, G1 point is not in the expected subgroup -000000000000000000000000000000000ee60801e3aaacf27167207a03b42594cdca4cdfe3a1f8e5f87b0e423ad36c56725dc79a26c157f41699e89884d27c1b0000000000000000000000000000000017c92b0beee470e126830843170bf0a89d13856ff6b0209e23bbf2a68e0668bd81db29de726ec7593124bea89771da97000000000000000000000000000000000a1beec4d223edbf1d09c448ea27038327bd8621842d3c7851779286060abd8130e4a641100627057498a421b59e90a600000000000000000000000000000000076a9559f5e33a2d5bdff6a89037c12e58ef920a3d8b9b4ca2a78299dca5dbf07c80d51014ee9288af8725e6c4312225000000000000000000000000000000000755036dd19c7d703343bc29238ae9332823514aeb4779b3378e8f7a3463a4089eef3fe79608db22b703b5d88c65bd80000000000000000000000000000000000ee3d82959dc04b5d59428142411e48e7a2fcfcff91e5554b725868c62d139bfd763720c9e2727c1b1fdc0bfd60f7297000000000000000000000000000000000ee60801e3aaacf27167207a03b42594cdca4cdfe3a1f8e5f87b0e423ad36c56725dc79a26c157f41699e89884d27c1b0000000000000000000000000000000017c92b0beee470e126830843170bf0a89d13856ff6b0209e23bbf2a68e0668bd81db29de726ec7593124bea89771da97000000000000000000000000000000000360e8bf07554b56d6f27de6a4b1f9184adb7980311e8f4128f619d9c8e64e98bcfca8eb3cab93e183882827fce2d06800000000000000000000000000000000010b0b114b55b17531576f782b6bee122cb5fb1e40d5af37ebaa1d4dad55a0f5d130c9a58cf27b1594eebd0b1492c0400000000000000000000000000000000018b70f0c047aaf7e17cb96015642e0d32f3135999de6dd8bded2c600866485ea75ab3a3e37581ae7dcfa1f54381f542300000000000000000000000000000000028cbef4b476a9cfb8daa35b1321a486b8c94f8b8df2352a0c8d509325706eee328b8dc3657122afb81be1fa2e60aafe,,,invalid input parameters, G2 point is not in the expected subgroup -000000000000000000000000000000001573cb3b6f4e841fe97549f42e06db33abeb2bc481cc0bc8c5e7bd81948432dcbd34b64c5766e1e491bc131e77a011aa000000000000000000000000000000000e205be14db0dfb21e58b302d45916de4f4bb48ac95228326cf49c50e6c8588a655a343b90645f73dd03c9aa51c5659a000000000000000000000000000000000a109e3cf72bba0e695bd756478c72884210868c95f0dd6ced22b7254eed0432c2345bbf8addbbd11349fec6e354d2350000000000000000000000000000000018aaf98535812ee760e17ad933acbe6b57bc1310b6fef550210053f06a611ce9df5dfcfdb028497468802c08cc2117320000000000000000000000000000000007590fa8cb07f9dc2ce7b2090685730104ca65a101c8f93965264913bf1deae794b71ff226a805a273248dc641225585000000000000000000000000000000000fbca4e20854a6069c298224eca9a064b7ddc4d834f8671ac45cb5d1d39265fa435ff1750cde5135e170824e516d6d2c000000000000000000000000000000001510f39616d7f576980055d0547c603d882dbe85dd0b634577fae134f210736007345d035d815306db660de4a07fc24300000000000000000000000000000000064d356ad7bd2edcd3622b1fc225fe319f86b5f7da875cd57fe5adc5bdb6443c5b09d676950e2d069bd4303b8f920692000000000000000000000000000000000a109e3cf72bba0e695bd756478c72884210868c95f0dd6ced22b7254eed0432c2345bbf8addbbd11349fec6e354d2350000000000000000000000000000000018aaf98535812ee760e17ad933acbe6b57bc1310b6fef550210053f06a611ce9df5dfcfdb028497468802c08cc2117320000000000000000000000000000000007590fa8cb07f9dc2ce7b2090685730104ca65a101c8f93965264913bf1deae794b71ff226a805a273248dc641225585000000000000000000000000000000000fbca4e20854a6069c298224eca9a064b7ddc4d834f8671ac45cb5d1d39265fa435ff1750cde5135e170824e516d6d2c,,,invalid input parameters, G1 point is not in the expected subgroup -0000000000000000000000000000000002ff87f9bcde30db0919444e2582a5e987fdda67264ed7abf60a93b37288143dd44db75403988cb5b3bcd8d34ebdb4e2000000000000000000000000000000000c672f8bf6e9e747cccb9438be047e56d1cfbd0808864e601de59b0b28b5438cdd10f1194ff5abe8694a598ff3dc1481000000000000000000000000000000000c01823cb218303c7e611f6caf6994615cc3805bb4310bb0bb82b56740c4314ed0a2f9409c8fa6b9f10dead667880fe000000000000000000000000000000000013eb3436ceac3f12dcdd9e71707b85b7cd872ce144c502078d4fd3ec8b4ee579410cbaf2e3db1df9ba6b55f14fbbb0c000000000000000000000000000000000ecb26e5814d5bc66fbbcdff5dd5934a597c4344487e7e63138c31d47a8201433be5ce14205660cae129891f5b7aa8e000000000000000000000000000000000040241f695cc864e99e1dcb04440135c4f3d90a86310441647ab265e9fedf51592b0c11d5e91d2d28ac4ed19245e9cc90000000000000000000000000000000002ff87f9bcde30db0919444e2582a5e987fdda67264ed7abf60a93b37288143dd44db75403988cb5b3bcd8d34ebdb4e2000000000000000000000000000000000c672f8bf6e9e747cccb9438be047e56d1cfbd0808864e601de59b0b28b5438cdd10f1194ff5abe8694a598ff3dc1481000000000000000000000000000000000a2e0129c31f3427340e234df5facbb5d1994a4c8a058fe84f7d5c62c7d00013cc0133d8b0faf497aa8f7c04abc59c3400000000000000000000000000000000160da6086a089fc1a31b89a0f0c95ff2bd85debf5f0d1372f3ca6fc26348d8a8d0b03525b27f7d7db6603f0e55d3a08f000000000000000000000000000000001893edc299faf35510b92c97ef665f458b19e4097299b4f8b0f8a2ea1f31343c9d2f4c35dbdfb36bf7f3e30686e8c3240000000000000000000000000000000009b8731ed8df8ae90ec344c9dea1eeee98f4000b5fe30460e58f30e4ea17821389d613458c7721fd1d759ec4f2bcb325,,,invalid input parameters, G2 point is not in the expected subgroup -000000000000000000000000000000000e42f5097dabc6b0fef4dccbfc659da40b66671d7efbc19dbc14a42a368402156469c818f233ad911574899db01ed86d00000000000000000000000000000000128bbee344b7a19212b549cefaaec31c0644c986ab863005e4d3ecf532be633597ac3906e53ca79b22de916ab92b4ad70000000000000000000000000000000009003b42c08b5c7d3ee9f6abb96e08e6f537da25cd0cf7eb85a49067746c03566e133b54153380286ef5725db5b41058000000000000000000000000000000000f09b7b754c255e0e3b8435ade64d6960285759495659dfdb9b117806397baf8d3c87e30bee02c9e1b22fa3efcc58f300000000000000000000000000000000003582c08a8de4bbd20ebfa833517a75682618fba2702b6c71a4785f70dbdede4e86ad8e04aae1f50a6bb75842ab74aea000000000000000000000000000000000ec013f22e64a4d4fb6f964e8319feb1ddbcfb71329186545d9b9d7f97d1f6a56c8aad03d20e9c30966ca932e1f2bc670000000000000000000000000000000002f78becf8a5717fbfcbe110bd6d4ba683658c1a45afeaeecf7742502d3df54b262de4fe30bd41ed0019cc79b595b5ad000000000000000000000000000000000dbae184899af1ad6221b75fc62cadcd61c623e011672b691a5aa498684f49796220fc5a73ea7170ed2fa44b9f3c39090000000000000000000000000000000009003b42c08b5c7d3ee9f6abb96e08e6f537da25cd0cf7eb85a49067746c03566e133b54153380286ef5725db5b41058000000000000000000000000000000000f09b7b754c255e0e3b8435ade64d6960285759495659dfdb9b117806397baf8d3c87e30bee02c9e1b22fa3efcc58f300000000000000000000000000000000003582c08a8de4bbd20ebfa833517a75682618fba2702b6c71a4785f70dbdede4e86ad8e04aae1f50a6bb75842ab74aea000000000000000000000000000000000ec013f22e64a4d4fb6f964e8319feb1ddbcfb71329186545d9b9d7f97d1f6a56c8aad03d20e9c30966ca932e1f2bc67,,,invalid input parameters, G1 point is not in the expected subgroup -0000000000000000000000000000000002dd02e23d8a9b7aaba94e8ce97a2d988291b6efb1d4d8d1c53b65581b737f992a428cb72ad38d4c6d470d6b50c869f0000000000000000000000000000000000661ddb1f0edbaa208c5e1db143ff41be5a35442da7b3e12d2928310ba5b64847f4909be93f860858f752cffce5e73870000000000000000000000000000000018fc47e1aaeefc1ea653eb42543940ba58044b247eef2627331142988f3a1a4fe72583738c7caa00c562d010089754eb000000000000000000000000000000000b5f8e9d774d99c3b6d224790d5c48367d68167aafc309ad8b351d1de8b601211737235bb0ff1b01e508ecf36a40db5d0000000000000000000000000000000013509c76fe4383e47d8ea35ba6ebcba13579bbf43cee0cbe27291d2601c3d74428bc9d5d1200718c86977abd16cb77a7000000000000000000000000000000000efbeccb9e9f348ba98ce0fd191c2e81de4925d7185f01b39a51aa44b30496f1fa3be4582c539889bef7b5783f730aa70000000000000000000000000000000002dd02e23d8a9b7aaba94e8ce97a2d988291b6efb1d4d8d1c53b65581b737f992a428cb72ad38d4c6d470d6b50c869f0000000000000000000000000000000000661ddb1f0edbaa208c5e1db143ff41be5a35442da7b3e12d2928310ba5b64847f4909be93f860858f752cffce5e7387000000000000000000000000000000000629fc2184297509e1dc0707b707067fa8b9a079d95f271ca230c32705c7e783f91ce1ef0323aedc6aa2febf750392b8000000000000000000000000000000000f29cb4bdb7d53671f9f1b1ee514cc916a657b7c17f298f409ad92ad7b2ca36b0298bd0581db7837994b781b829980c30000000000000000000000000000000014b839ecd27f2d6fdb92a36792c62ef503fb0189d3174447c4b1132e5f66d7970a005e315e6906ecd2ce6c72742d210500000000000000000000000000000000091bbfcfbd929cc8ecd000cf8ccf083c2f8cbd84f19b48b1ad20781e675ca7a77887b962435520e3f707fc0631fdc8f1,,,invalid input parameters, G2 point is not in the expected subgroup -000000000000000000000000000000000f67855b0cf915ab52190c7e69129d40dbeffae28fe110745edefacdca42bf979c5c5da1c6ebd78b43667cbfe360874c0000000000000000000000000000000014c5523f37b011c632e9e8eb08611e5a244ace2746264706b92a5a933b34bb9932c95c493ea7e8fd049d80acddd05e860000000000000000000000000000000012b63d867bbfe5505a83f765b85b0e8f182c796857f11125e691969c8e81eae927a5e1b137c81473e8b99ea0727c873c0000000000000000000000000000000010a8241f3b30c54a5d2fd7adca9be47b001f2268973e955ffa61d57793256a2d82fefa5e449548c64fa5aefda6d933220000000000000000000000000000000008e7d2f2e34a60504a5437275f358d0e742c445080c5e46053ea459893d6865e8d20906b2b58f1d1446a100cb1c9a513000000000000000000000000000000001369bfc5f24e2a7a7ace891444764ca32a32513c8ddf654f418c6eb7690e2cba77a4c4d4b98eb546d4e4046dd3c3267200000000000000000000000000000000153310de30b7a485753dd8443f8638c12b21083f6133a1c093648bcb566b33f73631c6fc558f32abeb0d6df8430e61a900000000000000000000000000000000005be397e9f77556ad952dba0540f46cbc7db910d5203cb976e168a7be3a3b8557c5f08d51cca9379552694a291d67fb0000000000000000000000000000000012b63d867bbfe5505a83f765b85b0e8f182c796857f11125e691969c8e81eae927a5e1b137c81473e8b99ea0727c873c0000000000000000000000000000000010a8241f3b30c54a5d2fd7adca9be47b001f2268973e955ffa61d57793256a2d82fefa5e449548c64fa5aefda6d933220000000000000000000000000000000008e7d2f2e34a60504a5437275f358d0e742c445080c5e46053ea459893d6865e8d20906b2b58f1d1446a100cb1c9a513000000000000000000000000000000001369bfc5f24e2a7a7ace891444764ca32a32513c8ddf654f418c6eb7690e2cba77a4c4d4b98eb546d4e4046dd3c32672,,,invalid input parameters, G1 point is not in the expected subgroup -000000000000000000000000000000000f3300926ec62bbc0a73e4e0404de3a55dc0ad4fdc393b291ccf9f80818b6a69c0a3f9c6edf024db295a353b6aa71a5400000000000000000000000000000000195b21606667c62a181b275184014fcef97218b451c3642e2e4dcf5502d03cbcc88839e827732feb32e77e52f702529c00000000000000000000000000000000198fe6684d3de4ec9c9ed5c59c9e662c4eb1b026995859db3a753ffa96c6cef7a063a607fc54599f706820fb864d7b0500000000000000000000000000000000116af6c03511ba2bcc32ea54c2fe2bedfb0848d2ee3017547cb25acf892400203e3ce4ea1986ecde0cdd383d42b61e180000000000000000000000000000000004a22ed8f30766b6b1dfc7286616066ccc262875e3de42e2c9528f6d23a7fda67ddb371f9ec419ae4dec48a354ffe21300000000000000000000000000000000086651d7ab0a4b1dfb9a56e42443f42d48c1f16866338d997adba078736d32bf4387b95da2da33e714662f800838a077000000000000000000000000000000000f3300926ec62bbc0a73e4e0404de3a55dc0ad4fdc393b291ccf9f80818b6a69c0a3f9c6edf024db295a353b6aa71a5400000000000000000000000000000000195b21606667c62a181b275184014fcef97218b451c3642e2e4dcf5502d03cbcc88839e827732feb32e77e52f702529c000000000000000000000000000000001367e0843d866d010ab03723026aa9ab1f930d3579daeabadc1fdefc06047ade30b36326d79bbae74293d3daf2e6c7a4000000000000000000000000000000000550be918ba9e28ddacb89ec526db63072bc14a62ec7ac06775f951de5b32af93d2d8f95389a6384cde62dffb941fb5a0000000000000000000000000000000014f59aa4f0603d5f166caa5692d9b068ee10a6f45670c6f4d492a4d1fa7a13a5146efcae33a841b5acf75a32b853b2770000000000000000000000000000000010ca0d9ba50c730006c95bc5439e2d39a40a9055ddac935a900bdeafe7141990db20ad0a840d3297c4b9b5f69aada6df,,,invalid input parameters, G2 point is not in the expected subgroup -000000000000000000000000000000000b9590b1d0d292d9967d759060a551f4e8e4c1c0066a9a3c0be515085847fa26b77462e3bae9e2621f28e01f897df0bf000000000000000000000000000000000a00d39c6c14d18dc5888b8a8835c3ef6f83ead2fa380be24ae857677b904b3868ceabdbb3abf3c186c5353a67fad0a60000000000000000000000000000000017d978d60fc89b0429c1a6424231fe9274cedad5d78d9c4ac5aa2dd5e70e8238a0bb1904bb4b6ee5de5cd1ac514c62a8000000000000000000000000000000000d4ce85a95dbc40f405f4e7ebf9121cdcd22766737c39618ad0fb3e10a6e53be1faceaa96073b2a877ab808483ec9b6f0000000000000000000000000000000016c61599ae4da787fa6db233fc28f5c56f7133d403901800ab5fa19d058fb27ecb34ca2e56ffa7628ed004c9e62092700000000000000000000000000000000001e64e4adfdafbb423b1b9f8973738c690713911f68f658d234e57dc35b9554e0f7ba345dd7920b429a12b9c74775222000000000000000000000000000000000c453b5a2f6c721f0303b6b9205e51ccab7829345e0cf13e457491ff35e0f38dc5ac2e5b0d8195e3d322704c38d3280600000000000000000000000000000000092ddd55120b22e2853983dd3dea9bad3e4bf23e46dce297aa3db85856907d1b980185c5a6e02890f24a5463e7895b950000000000000000000000000000000017d978d60fc89b0429c1a6424231fe9274cedad5d78d9c4ac5aa2dd5e70e8238a0bb1904bb4b6ee5de5cd1ac514c62a8000000000000000000000000000000000d4ce85a95dbc40f405f4e7ebf9121cdcd22766737c39618ad0fb3e10a6e53be1faceaa96073b2a877ab808483ec9b6f0000000000000000000000000000000016c61599ae4da787fa6db233fc28f5c56f7133d403901800ab5fa19d058fb27ecb34ca2e56ffa7628ed004c9e62092700000000000000000000000000000000001e64e4adfdafbb423b1b9f8973738c690713911f68f658d234e57dc35b9554e0f7ba345dd7920b429a12b9c74775222,,,invalid input parameters, G1 point is not in the expected subgroup -000000000000000000000000000000000eb7d975030858b57bae3e7a8a7e297f9d7d6b2bcf27fa8bb9b73cf60a1a1a5e6638adc726eb2e7fd5500353de95179e0000000000000000000000000000000015c783845a98d2b12a8cada673e1df4c266b34302cf7d004e00612584d0913283d43150337c36dc3912bbd757e6a370b0000000000000000000000000000000014a0222d6d0a809cb5598db18e35f5b7f5c49ec5574fbb5d801d9f890ede23d20c62a22321394b6efd1a45b9780a4efd0000000000000000000000000000000017c8bc1b8f7ebbbcd6203f6ffcc758a787a96533a77290affc18b76fc6dce7c2ba8f169dd8ecdb8b240c92664852bfc70000000000000000000000000000000001a673ad0af4bdd53027b145472d1e8dfa05029b7ba5bcb7dcc63b5e6369b2e693f27e5665167a8dc8b6d3c9b85eccbb00000000000000000000000000000000085efb596145e58b4eae7aedc8f7aff6949f1edf8fbe0c88e6dcad46423cf7b2d5f8f54bbdcf8f1427438e6a4da71914000000000000000000000000000000000eb7d975030858b57bae3e7a8a7e297f9d7d6b2bcf27fa8bb9b73cf60a1a1a5e6638adc726eb2e7fd5500353de95179e0000000000000000000000000000000015c783845a98d2b12a8cada673e1df4c266b34302cf7d004e00612584d0913283d43150337c36dc3912bbd757e6a370b000000000000000000000000000000001425d6d5cfd04d310d8ef3ff1a3b3d227771f3bb3cb552c64ca1debd3e2e75e7a96b9a0d5768ff041098d743de445e790000000000000000000000000000000008b12959963c17ce7247490d9806e0ab02f9aeed8d8faf4591b955885f5aae509358a19c1eab19dacb72cb67b9c22c46000000000000000000000000000000000a7108fb7442fa6c50b472dda60d6c277bba83aa21ac1630bd3df6f116c8a58e60e8c4a303a041b9825b65301d388e410000000000000000000000000000000000faf3042f00060eff3e5e13e1a964c9dd605677596c49cbeccd6d0374c6a4ab9742cac63d1801631d5fa5e00d399fd7,,,invalid input parameters, G2 point is not in the expected subgroup -000000000000000000000000000000000f6d131c756d031041ba97dd20719cbfc864de16dddf00d282f6c41de683d193a015a781232ea5513321c131505fa4ee0000000000000000000000000000000008d754d62b8f1fb0d0e9dfe4746d9c5f9e4a296c6799d6379a4a1a07583d0959c62b05011b636b72cdb87d3c92d94f3600000000000000000000000000000000061bf88e4c5f6bfacbf1e2e72566d9c44a001237f22d7f6a7240ee0bd3c8d175786f7c2ace267774fa5615d7bd3ec8f800000000000000000000000000000000192c987bed20d707400d3211e480b8760021a33dfbaef829b1e865f92b37cd3962e56a38d4c06c5ad73bea5e7321b176000000000000000000000000000000000dbc62270cf7623e571f6ebcd29f426f214cf1c8f71edf9aeefbeb6037b7e71bfe41a55828cd4353bae2e1e927812aa80000000000000000000000000000000005f6e7064a9708e20bce8e5002c352b13d4531d87be1320bcf3322d5e2b851a54aefaf6f9ae26e277ecad307c448511c00000000000000000000000000000000041fd1625afa48a446454d6613c17cc6a65b3ec8b8f2125c0eb7b8e5d07968397d43969a6579226f496d9b24dbb71b820000000000000000000000000000000006131c506f243b5ac40354f826ac1838839eee9f61301aabd88e499d40e57df3122edc8b36f0a8b16b72f9ac783efd3e00000000000000000000000000000000061bf88e4c5f6bfacbf1e2e72566d9c44a001237f22d7f6a7240ee0bd3c8d175786f7c2ace267774fa5615d7bd3ec8f800000000000000000000000000000000192c987bed20d707400d3211e480b8760021a33dfbaef829b1e865f92b37cd3962e56a38d4c06c5ad73bea5e7321b176000000000000000000000000000000000dbc62270cf7623e571f6ebcd29f426f214cf1c8f71edf9aeefbeb6037b7e71bfe41a55828cd4353bae2e1e927812aa80000000000000000000000000000000005f6e7064a9708e20bce8e5002c352b13d4531d87be1320bcf3322d5e2b851a54aefaf6f9ae26e277ecad307c448511c,,,invalid input parameters, G1 point is not in the expected subgroup -000000000000000000000000000000000c9856c54b638559ce67cffb3e784b9649bbeabe135c89ecb8108341a16ef3c5ac49e9243144792a4f9371f2d6f8f6b6000000000000000000000000000000000e17a67cdee23e13c95e5b951c5f51703660ff614fbba363e5a73ea74b86af6893ae90a929df3d7e2af8852dbad77a01000000000000000000000000000000000c01d2e1592a61cda87dab7fb2a45d7468a8ce56f74fd7c8d401e224b9610d675cbdc0d4719dd2dc10f47547bc641dd90000000000000000000000000000000002d57ac9ac9b4cd7a477e162965c763ec1d0c5752b478449839e0ebd7a1110374fe90aaa2006bd03f08f9242c0419e99000000000000000000000000000000000d50b11e1ea90ef8ef0f7a95ad41ce2cd30cf804e46a96762fadbc275ad513827e6e75b95968a00b42085aa89bb0839e000000000000000000000000000000001250e40358d42dd3a6aa2dc93d89010f2a7b33e5b426ffd7e6eeb9bc02f8f22fd6e91c4fae603f14ed682617dd503eda000000000000000000000000000000000c9856c54b638559ce67cffb3e784b9649bbeabe135c89ecb8108341a16ef3c5ac49e9243144792a4f9371f2d6f8f6b6000000000000000000000000000000000e17a67cdee23e13c95e5b951c5f51703660ff614fbba363e5a73ea74b86af6893ae90a929df3d7e2af8852dbad77a0100000000000000000000000000000000048dfa619f3f77c794d119ff97e04826b5bf49d71591b778b502205875b97b17c9c9d2ae95c8d7035e9d2ade10a511ff0000000000000000000000000000000002fe9b3108c8911b07e4ee52a8d4df17bebc8153f837665513ad5c8af53cd7387100204fafefc2febb2f5e18c9d958b10000000000000000000000000000000016c98a41fac6665657b00bfe9336942e7aa145bea3131224ffa35ec9b9cd4d629b4ceeca98a15ad07e03ffcf898f8a390000000000000000000000000000000011a0d16ccdf98beffdb0953c509261f18567a1656acdd895395b480ebf8843e7d3b965e2151c58e9b610e9e3b5491832,,,invalid input parameters, G2 point is not in the expected subgroup -000000000000000000000000000000000f4eebd0bb8233e020629f72258d3cec7fcd3c181fa913977a405ef7437f6fdc0ee34fe6a7e349730e695f383e4478ad00000000000000000000000000000000080577fec3a6cc706037b43cd39f4bace98191511cb26cc606c11659b63112b519123a00b62158ab7a24dfe086705b470000000000000000000000000000000011e8ecf1e341f0146c59a79a8428bb01d2399d3f87d90d057f63e6cb9837432154d17975f70df175a016735caf85120a0000000000000000000000000000000002a5bd53e4f4c5b9682e1af1f7e09dd305e7342d1688f62885b5e59f173a9fc731cec481559ad693030004a5fbd90a9d000000000000000000000000000000000f9601f95e12bf05c35deb204558d44a60fd630c05f4060b7bd9ff943946e8eab507422afe00a3e7706b8ed013f712c20000000000000000000000000000000003bf6fecc0c7414a69c2b48e2c16e88d988ea8ae9d8b59017ecb89394732a20e4321cb5e4fb071aec7d2736220a455370000000000000000000000000000000018fe22fe0b39f508823e2332712f988efcce291d93c416c544272e88cc0902d79e41b01af005feddaaef6c42a26c824700000000000000000000000000000000164fe8d2934cda6f0b863bb42d13f91c52a49706182f8d337d6a629da65113818d1c177508d6735cc86a6b3837ce49320000000000000000000000000000000011e8ecf1e341f0146c59a79a8428bb01d2399d3f87d90d057f63e6cb9837432154d17975f70df175a016735caf85120a0000000000000000000000000000000002a5bd53e4f4c5b9682e1af1f7e09dd305e7342d1688f62885b5e59f173a9fc731cec481559ad693030004a5fbd90a9d000000000000000000000000000000000f9601f95e12bf05c35deb204558d44a60fd630c05f4060b7bd9ff943946e8eab507422afe00a3e7706b8ed013f712c20000000000000000000000000000000003bf6fecc0c7414a69c2b48e2c16e88d988ea8ae9d8b59017ecb89394732a20e4321cb5e4fb071aec7d2736220a45537,,,invalid input parameters, G1 point is not in the expected subgroup -000000000000000000000000000000000d6e0830ba9839db89621518e1ed86e9d035d7fb03b18d8a615acd58ff5c8c3dbdcf1acfcb8a910e8d3d0da770057cde0000000000000000000000000000000018c38d6e458e22cdd381010568606d26770b9eaaeb38e02a80cd0a0d584577fca7b391bbabe902825a3338682f7d3173000000000000000000000000000000000e5d5bfbe5ab3da8c033663cc457cf69062e1de6bcda6420826301d4e5fb4c47a5c90432f15608aa50678ad083f618c700000000000000000000000000000000146cd56ad5d977fa6471f7c12ee3fd66dfbe4b276b846cf4a74619cfae4a5101e85d01db615e0e6d28a5eca7a92cd05d0000000000000000000000000000000010fa99a243f1de85f40bf6a08e3e9ed3e478562468f0975bb79b1b80c9eef8c433c18ccf6e5149eb99c21f74494eed6e0000000000000000000000000000000018504d4687cf9f055c5cf8360fda2cb2123ea3a3e9c8f58853a68063e60a7ba24f2d1c153090ba2e77156cbb5ded79d7000000000000000000000000000000000d6e0830ba9839db89621518e1ed86e9d035d7fb03b18d8a615acd58ff5c8c3dbdcf1acfcb8a910e8d3d0da770057cde0000000000000000000000000000000018c38d6e458e22cdd381010568606d26770b9eaaeb38e02a80cd0a0d584577fca7b391bbabe902825a3338682f7d31730000000000000000000000000000000016267be431a654019b3f02389fb2f2f307f3bb56590c3ff1924554b2ee6fbbb68381b5ba4a8668fc541dd7e3fe9afc9a000000000000000000000000000000000c41d1daa258be71001babb484d98501c9ea015aad96e398aa6015b9ef618f6a56a45d45383dc34c70ca05242490ae18000000000000000000000000000000000dadc282d8cc0c066f28881cf440fb5a621449dc16488d02e34492fe8af53fd1749886fe6df2e377190e4043d6e3dd290000000000000000000000000000000018a30f1ae8927af27147ee5ea3c7aa848b0e303d16018fc2c3ca4bd088ec5ad3a808e7699ca009a4bf6f5b707edc1fd8,,,invalid input parameters, G2 point is not in the expected subgroup -0000000000000000000000000000000009f71faeb58c4d442272ea0116a03f106008ed68030bce1bc53a3964ec4f9758f508735c8c17017645ccb77124b46cb40000000000000000000000000000000016a2ea9e548342538ccfdae6806ec9ce0b7b892875155f898017929d7105001e8de041bfcab7398cccd060dcee3b6e84000000000000000000000000000000000579462f03502615d26d76e05c758a7f835e4e70f1adfdec8c7ef26580544326d66ba4e23be3c078e1f187ab498ab9dc0000000000000000000000000000000000d386d0af32f630bdf6c13ee82fd35e42961ec4b11ee8fa196d69bed775b8ecfe74409693c531631aa716957e5fe6d7000000000000000000000000000000000ce8a020608c1e7d70d7a03d11b84f48d6b3b77c5836b7c914627f3a84d3d0b3de513029c1379b20ee38a19928e57f44000000000000000000000000000000000dd10882001be7fa52ff21f1a0adab02e688539f098901fe515b61fbdbca02c4146f6c17f7ad7cf59f5e8acd85da60b000000000000000000000000000000000128e019ff92e7171d3c791bd4cf75b0f47c2a9d8722b4a8279f1178db6dddf8a4c00083a935168518a1c26a56b23624f0000000000000000000000000000000008d0c5f3300e73682f4756e6ff1d6722dde576beb587301ded34427d6935e59e76cc8a8cb0ea5f659db9ad5435851e53000000000000000000000000000000000579462f03502615d26d76e05c758a7f835e4e70f1adfdec8c7ef26580544326d66ba4e23be3c078e1f187ab498ab9dc0000000000000000000000000000000000d386d0af32f630bdf6c13ee82fd35e42961ec4b11ee8fa196d69bed775b8ecfe74409693c531631aa716957e5fe6d7000000000000000000000000000000000ce8a020608c1e7d70d7a03d11b84f48d6b3b77c5836b7c914627f3a84d3d0b3de513029c1379b20ee38a19928e57f44000000000000000000000000000000000dd10882001be7fa52ff21f1a0adab02e688539f098901fe515b61fbdbca02c4146f6c17f7ad7cf59f5e8acd85da60b0,,,invalid input parameters, G1 point is not in the expected subgroup -00000000000000000000000000000000167a40d69e2d2e5683ec69af7b226c5456d05241d9c9eb24e988ee2dba845eab361a956cdea64cf971dafea08f0056260000000000000000000000000000000014e5b8ae5032a924da081d3063f31889da110d00330903c6f988684b7d77b7b1bdcbefbf70941d0eb5a34bcb010a3bf200000000000000000000000000000000043a000741027fbd191e2399b7cb5fdb4db3728d81d8b9d25362e8a1d397ec99d1b2339a3a511d0969e7e727f98d4163000000000000000000000000000000000cbda70eab332bf962d123aaf08b8b96680055f1946dd5fdb8818fbb330b816d83062ffaa79e18f1f4f6d53deda53cf200000000000000000000000000000000160a7048e508da288270e8ac5793e9461eaa282b85ce5350b6a661209efa6699874aae71515dc4265125d490a5771ff900000000000000000000000000000000041aa7292f258125d729c1761a3a6f7979a7a92ff179be678ebe301de3ffe12e4a863becbfb2bd0067e42aefc5f5617200000000000000000000000000000000167a40d69e2d2e5683ec69af7b226c5456d05241d9c9eb24e988ee2dba845eab361a956cdea64cf971dafea08f0056260000000000000000000000000000000014e5b8ae5032a924da081d3063f31889da110d00330903c6f988684b7d77b7b1bdcbefbf70941d0eb5a34bcb010a3bf200000000000000000000000000000000158feb06ab69f5da37037c554aa8b4b511e9de7e13a08c2f9a8899f5a504b191195e4de1ab7d937913f60e24a1b3d3f8000000000000000000000000000000000beeea216d85a767af2facfa7fa0399c095a23b7a974ddc3d36b7e79822d7691e53f85c976b8cc948e155f196b7f168c0000000000000000000000000000000009802e94ad5cd6b071a0911cbbc1de29a79a5a4fc145cc79db03119c3c8dac88fa3740bdb35b0b0e6e34127ee1bb081c0000000000000000000000000000000004599d1e0bfe642ff275fbf1dc86bbf83b87c241de09570183faf4e2c1cefc6b8b2354aa2be4aa9f69d6d61546d3a685,,,invalid input parameters, G2 point is not in the expected subgroup -000000000000000000000000000000000130761fb4d4720b8e69b849e1472f15c24cf909920c598aaecd34c5b420a1989a6ea95f89c362a61e4a11f88982f9a6000000000000000000000000000000000d707b24e8720ecd4a14d9f658060303d233253caa63bafd0f475b2985fcebd326924c936a9d66b21b9a75085aaeb54e0000000000000000000000000000000009faa74f66ec0384f0458893c0026f73688c764e8df9ce056a88a2ed0b84ed8f88d1b683443a3269a3db838f8aeb808a000000000000000000000000000000000949c4be2708c1aac86aff39290ab6a8e0f332e7a098bbd64227a175473d9dfe136e07548b282f69a94a15e2c32dada10000000000000000000000000000000014f2c7c7da781e2f50803e3a948381c3c439b127949f79824df1e5722c206efccd6c0ec5dd75ef63d8b1fa301c83356900000000000000000000000000000000176753460d241f38aff41bafdad51688ab0dc9a5fb3643977c7b9d282ad4532fcca1e725715227780ec28bf1c32bbc1d0000000000000000000000000000000010ad2405965f283c845edf92cf34508c0ca625816690d739fec9776d261784a946e083112d11c0776edd04403eaa5b820000000000000000000000000000000007e400896eaaddf797643b05a53f612f73737a2c438762d3f6216d53761f28bc88f402a4f02f36d26bbb431616b1b5690000000000000000000000000000000009faa74f66ec0384f0458893c0026f73688c764e8df9ce056a88a2ed0b84ed8f88d1b683443a3269a3db838f8aeb808a000000000000000000000000000000000949c4be2708c1aac86aff39290ab6a8e0f332e7a098bbd64227a175473d9dfe136e07548b282f69a94a15e2c32dada10000000000000000000000000000000014f2c7c7da781e2f50803e3a948381c3c439b127949f79824df1e5722c206efccd6c0ec5dd75ef63d8b1fa301c83356900000000000000000000000000000000176753460d241f38aff41bafdad51688ab0dc9a5fb3643977c7b9d282ad4532fcca1e725715227780ec28bf1c32bbc1d,,,invalid input parameters, G1 point is not in the expected subgroup -000000000000000000000000000000000220d192e0c635f05870113aac899f996622cd21ad251fb4c300a0ae0051dfd93b0b622f54e149fc4e5bf280ef31b0c6000000000000000000000000000000000dcfd7def563a0937b5173d20f830e6a2350a9d6f1b8a2193e5f755142e850bb7f95519ca187dfe735c197c21688528c0000000000000000000000000000000002479a989dbf27141bd9f467447218dfa6ef60781a7231f089d5f1f1d8dca2ce9606a75c09f63f37f9cc1ee61dceb32500000000000000000000000000000000037c2f1b96170f6847138232bac663e4940bca602717c877f58ff7f5259778246085d499ec6bbeaade18f738df333cc700000000000000000000000000000000115a30e7b71e48efc7166b9a8d2e1ecec6c6e4c058065a18277ca547cf1ebc193e635eb9b65d14c9c94ebde3c83a55dc000000000000000000000000000000000b68916150436f74c61b071a339909f78701d1f3045f7201f076991d7447570fd90887126ca54d96c1310e59ad489190000000000000000000000000000000000220d192e0c635f05870113aac899f996622cd21ad251fb4c300a0ae0051dfd93b0b622f54e149fc4e5bf280ef31b0c6000000000000000000000000000000000dcfd7def563a0937b5173d20f830e6a2350a9d6f1b8a2193e5f755142e850bb7f95519ca187dfe735c197c21688528c00000000000000000000000000000000147610c1075d625dc36388a2bd451ad2c15eae8cbd30393bb9fa30fc233b29a0f5483579752a748bc0f5ca9c90875e0e0000000000000000000000000000000003dff69511f2a53e859b6769ef4c257acf31062eb72f8668f57da60f225ac052badef9df25d43148b4d3baa64c29eccc0000000000000000000000000000000006d2a71dd9c1b302e22c4cecd14dc385e068e63e28e167c060de3ceac8410461d83f961c9292cad30afc0084855ebf1d000000000000000000000000000000000890ce53931aa18e42f00379b40c8e205582f71707a67761acced851fc91755505ae960951dec4ef46353b66e0b928c1,,,invalid input parameters, G2 point is not in the expected subgroup -00000000000000000000000000000000050ae21faa31371d791e3f6163f1c18c577367badb337aa6fa7c8214ec58bacfb24300a81d8226e81d7f47730c734386000000000000000000000000000000000987a0c7abd7c72140bcdba9cf171389ea7971493187c567b0970f05d129b4202124d72bd01038bc77023171de379762000000000000000000000000000000000d4b71595321913e94b9e6ee6ae2391cd5037e8b55e61fd96c745539bcb4bc4fcbab678749f6d47fd2c95001da4715f70000000000000000000000000000000005436e1be9029a2f7cfac51a305fbb7e760a9171c79a5bfce6b161493fb2855df09b3345ddbc8b04318c6b2e0225b74a000000000000000000000000000000000b8f317d36c50c8d039ad137f7d9adbefb3fc147a9cfd6cceb02c75b95fe307c3d6f673a216484f3211f045c2ba9012c000000000000000000000000000000000156bc67e17c8eaa905fb7d9f3f251cc81eeecc86de791c8be30c34aea896755fe2bac28cdb035222afe6237614878c300000000000000000000000000000000065856fe1dcbef934cef47b177ecb7df76cc8796624400d5c0518aa9438bcadf397234808d099bed89ab674560ffbb1800000000000000000000000000000000071b2ff64379ed3e20cda000602c3504616dd673aebbe7690e797d6428ecfbdb29f11138169f3462dffd319cad68b96e000000000000000000000000000000000d4b71595321913e94b9e6ee6ae2391cd5037e8b55e61fd96c745539bcb4bc4fcbab678749f6d47fd2c95001da4715f70000000000000000000000000000000005436e1be9029a2f7cfac51a305fbb7e760a9171c79a5bfce6b161493fb2855df09b3345ddbc8b04318c6b2e0225b74a000000000000000000000000000000000b8f317d36c50c8d039ad137f7d9adbefb3fc147a9cfd6cceb02c75b95fe307c3d6f673a216484f3211f045c2ba9012c000000000000000000000000000000000156bc67e17c8eaa905fb7d9f3f251cc81eeecc86de791c8be30c34aea896755fe2bac28cdb035222afe6237614878c3,,,invalid input parameters, G1 point is not in the expected subgroup -000000000000000000000000000000000e4bfbc392b1de6b17a32387d694f634cb484be4531f425d72833a30ed5aa73a958d5081b30cf98484762ba51542f87b0000000000000000000000000000000010e6acae9df1b5567854f4bbca0ab07c6a0e726bc6ec7a1d2ce8b04e1677776d0ee2642950db040365d581a52a41832300000000000000000000000000000000036a2ac8ecf17fc72ed792c0d8939060117aa0d6c13854fdcf56ed0d1ed3b39da9a67aadfdff484850f9cdf439495712000000000000000000000000000000000a1bd875b74e1ebec19591eb137e68ca7f0db1b3056d341b6bad28c3f45e87688e73fe28e9ef44c7d494442ee0b9472e0000000000000000000000000000000002e26e5a36c008bddc431048d999b7fb44961bb4d931b2dec0cb1d1b0987587f44cd31d429a6cef05d3c060ac828ba7d00000000000000000000000000000000050640087ed6c04ffed759f63e211ff5880c8b06933c1e812954a7a4240a9c644175c4ca3048a4ed68d034f6cbdcf175000000000000000000000000000000000e4bfbc392b1de6b17a32387d694f634cb484be4531f425d72833a30ed5aa73a958d5081b30cf98484762ba51542f87b0000000000000000000000000000000010e6acae9df1b5567854f4bbca0ab07c6a0e726bc6ec7a1d2ce8b04e1677776d0ee2642950db040365d581a52a4183230000000000000000000000000000000003fea73d9ecfb879ea601865d3279ef9b271fdeb14e1094745d5718bf214f1fba99245746716bbf012e2ccff5e22887d0000000000000000000000000000000011b1aa3049157abfa01f3bef33583635873d4bc66801785f41ca51b9a11d95b49a8bbaa543fbe68db86c3560ae258954000000000000000000000000000000001740661de7e1b6e1eff626acc4e37c877d00a0ceb8008d99e76a1dfe826b4dd0ee69b150535caa20386d644394dcf6b800000000000000000000000000000000090c0bc61286187a58f2cf49e2ce6f49d721b4146d973dd7716db271da770450dcba33b7aae37d6842a43063c88704e8,,,invalid input parameters, G2 point is not in the expected subgroup -0000000000000000000000000000000002cd3682c1f87aac1ea91b3f4ac577f0c9531c7702864c444b4163435b4770c9a2ebf94fae2d45a63adecc314d9d536400000000000000000000000000000000103a1eaebc0ee53e21d5bda78bd912f20cc28a13e5e209e062a52ddec3453fa9c364a6b403a68d9db8a40a07755ee1eb00000000000000000000000000000000024494aab30849df790185a4f939954b724c387c9a366fbe833b628577654174f705d05e7d7dbcd29b8873aecd55df0b000000000000000000000000000000000863054fe3e4838d2caec7103e3d0453e86a17fff0dfdb84dd819f31756032e9e97b7be89b636e5e0b642718f6da217b0000000000000000000000000000000015c8bb4fcb6d9cf941b722136d8d76d847fd6d5c643f4c0049c9746e76e49726fd463ce7899f4df66d04e5d48e523e6a000000000000000000000000000000000f101bea4e1bf610d2782ede91da95eb2b0be9ce60485465b9e94cbb9530b416c4394862f0ba7ee8067bb48e94c07c530000000000000000000000000000000001b32ce5c51441e1abbbcc0b6af95380f2de24876ba377ebea44fede8886acbe23aa18681bb08130252bc04193939853000000000000000000000000000000000e5d718c9980140b41fb971fe596070982bf92937df77ef44040ffc27162bb443a60f5c64411ffefc24524ff32fa17ff00000000000000000000000000000000024494aab30849df790185a4f939954b724c387c9a366fbe833b628577654174f705d05e7d7dbcd29b8873aecd55df0b000000000000000000000000000000000863054fe3e4838d2caec7103e3d0453e86a17fff0dfdb84dd819f31756032e9e97b7be89b636e5e0b642718f6da217b0000000000000000000000000000000015c8bb4fcb6d9cf941b722136d8d76d847fd6d5c643f4c0049c9746e76e49726fd463ce7899f4df66d04e5d48e523e6a000000000000000000000000000000000f101bea4e1bf610d2782ede91da95eb2b0be9ce60485465b9e94cbb9530b416c4394862f0ba7ee8067bb48e94c07c53,,,invalid input parameters, G1 point is not in the expected subgroup -0000000000000000000000000000000006e340bc57495a5c01bd44eb6dee60e94feadd69bd0274e7c9755f7b0e7b4e59eb70a2cd7e4da9d1a5f60d93a5df19080000000000000000000000000000000013d7c393a2191ac8d13a0743fecd768a7e15d279be409ccea1d58ba39e91f592b425955ddfc8443861a2899de02cd0fc000000000000000000000000000000000369067d9012509bbc75333fcfa37cd42dc3d6331a55b4720f9efb937916692ed7c7cf4739142ea13fb9130e9dae92fa0000000000000000000000000000000005306d73dd33e26ece5d8cf2ea8d7e25976f7b95dc7091420c2e91b1d0b2ef96db69a364c3cdc3b24a49ec5e307553490000000000000000000000000000000008a9fe15ea4e16e675c42c25b29655683844949b9aff4448f0b79ff08ec2a6526cad973f80123943b863ba9f30b45666000000000000000000000000000000001754caabe499e1ad04ae65d696507096939dc826578db55738e5024601eb052a9fc15f20b601253533847f79a5f6a6ae0000000000000000000000000000000006e340bc57495a5c01bd44eb6dee60e94feadd69bd0274e7c9755f7b0e7b4e59eb70a2cd7e4da9d1a5f60d93a5df19080000000000000000000000000000000013d7c393a2191ac8d13a0743fecd768a7e15d279be409ccea1d58ba39e91f592b425955ddfc8443861a2899de02cd0fc000000000000000000000000000000000ddc7df1bb36d54beb969a244a67c3ae87cab2eddce9397869421999497ab00a3e0ee29e384f3182b52158304790b05c0000000000000000000000000000000006f527de4412dd61845ab1e4536a114c7ac2bee2f3d22c16c660b3189b1666849f70462d6d650846331dc630dfaa075e0000000000000000000000000000000015aae1fad9e6cb3adc8bd93c432c9321a9d2f7cb961671c8e517da7024d1e35b519a2cc662d795173441479fa35f2e830000000000000000000000000000000008485999f40a4a363ddb3da273f7522344f284fb5bcee383a590c7c1287baa10f21312428d6818eebc96ec59d716fae1,,,invalid input parameters, G2 point is not in the expected subgroup -0000000000000000000000000000000015845de9692590d7fbf4187b50f4b2d067983b0a2209ed2bc6d60914be106decc5dfefba112baaf98ba3bf9e4d102b660000000000000000000000000000000004f2ca0858d056f769bc8e6ebf7cca745ca647ba497940b25b31c0541297626cd26ac10f8ae8476b5c868a95226da290000000000000000000000000000000000b1374a47c7c1c833f3856b0fe5ecaefaf2a8f96148eb540482288b56897d9e7e4269ea3a2c3742993b751bd9e484f2d000000000000000000000000000000000bc7fadac70d0a401e61683562cc83ffe107924ba1788bb6e06b0c60f22de0d93b10b63afcca343cad0572209b03b12b000000000000000000000000000000000c22c75d826d2700a8bad4e9c271d8b505ab2911dc257909c69dfdde2bcf332e5f13592eccabf578f48f6078550c1e9c00000000000000000000000000000000057db54159019d1e291131d28a936ac1337f2884f0c4bfc4d8adaa75bc0edf8b0f3030725e33a3d1a2e7e9ea39512fc70000000000000000000000000000000000232940188006769a382a4958383aa6702b2cbfb9c2907a989938ac618f23e241767b021e8ae11c23617ab393d4f85a0000000000000000000000000000000016a672061fe76ed943e36b2d6fa4aadf579db96eba5e4c60cda2884ddcbb0f37668638a3167d8858cd296917eaeff8e0000000000000000000000000000000000b1374a47c7c1c833f3856b0fe5ecaefaf2a8f96148eb540482288b56897d9e7e4269ea3a2c3742993b751bd9e484f2d000000000000000000000000000000000bc7fadac70d0a401e61683562cc83ffe107924ba1788bb6e06b0c60f22de0d93b10b63afcca343cad0572209b03b12b000000000000000000000000000000000c22c75d826d2700a8bad4e9c271d8b505ab2911dc257909c69dfdde2bcf332e5f13592eccabf578f48f6078550c1e9c00000000000000000000000000000000057db54159019d1e291131d28a936ac1337f2884f0c4bfc4d8adaa75bc0edf8b0f3030725e33a3d1a2e7e9ea39512fc7,,,invalid input parameters, G1 point is not in the expected subgroup -0000000000000000000000000000000018611593c7663a36330e0640bc912221a17d0ec9d2a250f1701303249655c7088bdc07b024878a260753d1dde306fd4900000000000000000000000000000000069d26308af5907c15532f31dca8c884b9e54a0da5e428c66fd79d980774cca106e2ccf3f93fe3e01669c594b9770a800000000000000000000000000000000001a38d296c4b7b8351164b935b915c08caf6af9d5233ecfe609e4ed855589bdbc9fb0adc55bb5cc6a2526bd82ab9287f00000000000000000000000000000000184ac28f62c7101bec49879af5da794740f9ba99afab4fcb576fa1149f3b701079915934c624f022b0d3213adc884c2c0000000000000000000000000000000004f64835227f459e76aae3397dfe53eddb1e97c8afd8beaba09382fe79ab378c3f03d6962dfee823c426cab426e51d2d000000000000000000000000000000000577263fd875f6388b723f6abc78aa3b0cc2e6b0ab53beb59286e30d1e982114c161fc0ef490bb1347fd8a3f3cba72710000000000000000000000000000000018611593c7663a36330e0640bc912221a17d0ec9d2a250f1701303249655c7088bdc07b024878a260753d1dde306fd4900000000000000000000000000000000069d26308af5907c15532f31dca8c884b9e54a0da5e428c66fd79d980774cca106e2ccf3f93fe3e01669c594b9770a800000000000000000000000000000000000c072a812b26927b5a672359032e71597002d8c45572db6c575e25c81181a522ca304867b1bcb583c58b2ad6bb1695d0000000000000000000000000000000003c4f5f548f50e835f402105cbd315081e0e8773dd91f3874687ace6fd5ffa66b6ebf6dac4580357b870f8835ed15cdd000000000000000000000000000000000f039e2e73334386b28ed4cc52db09b69c942c0c87f81328a9b7fbe8553eed48a60224ae9d52baf4f62a3fb0d58d451d000000000000000000000000000000001974da8867204f048b81d0c7a90d224dc5b87f3c4f47d1dfb09afc292430bf51d69e3538fdd13ca0749dee76c2ba9b17,,,invalid input parameters, G2 point is not in the expected subgroup -000000000000000000000000000000000754f3a9ea93a01fa244ef6badeac64fbb4dc81d3489c4195a01148e268e2af46011e6c593b4b873fa1470eecc6f79ef0000000000000000000000000000000018043830aa55a8c7efd5dc246622c71bbb4bc6a5d69cf594f46f62d8c3e2a5d4ba1d3990b5445f8b446e404a00259a8a000000000000000000000000000000000e49e94cfa35d8ade2b76865cc8be04737d00b48b195078c8085cbe782232a544cdb548373bd8ad0282674ba5c96fe0700000000000000000000000000000000047d59661f095c41bcc27da5f260f13a3fce334bba216b45df548894bdebc691fe779ccd63d99a9872973ab165a90c01000000000000000000000000000000000772e9a9c22bc7352fdf74915bc464de99ecd96420ef1af6e8bd5a05d73fff89c78e28eb340d4967e906f28afe1320490000000000000000000000000000000018bccff27bf9d7cb2159b9f2d1faabbf8591b53ca8e67e661d9f44f6dba6296e3e46ac32c50128bb5fb076cb8f214e27000000000000000000000000000000000252149178c606d2d6c0311e9f4a66cf348869efc09ec887cf99088ec754c01551796aaf168dc1a09cb741ab3c9d6891000000000000000000000000000000000db7baeeb5acfb22d680e032965a4d417b2f2f6717d3667d786e006327140c1288ff44842142eb1d2730b3be64fcf420000000000000000000000000000000000e49e94cfa35d8ade2b76865cc8be04737d00b48b195078c8085cbe782232a544cdb548373bd8ad0282674ba5c96fe0700000000000000000000000000000000047d59661f095c41bcc27da5f260f13a3fce334bba216b45df548894bdebc691fe779ccd63d99a9872973ab165a90c01000000000000000000000000000000000772e9a9c22bc7352fdf74915bc464de99ecd96420ef1af6e8bd5a05d73fff89c78e28eb340d4967e906f28afe1320490000000000000000000000000000000018bccff27bf9d7cb2159b9f2d1faabbf8591b53ca8e67e661d9f44f6dba6296e3e46ac32c50128bb5fb076cb8f214e27,,,invalid input parameters, G1 point is not in the expected subgroup -0000000000000000000000000000000003455a16c1cf9a408bf17cbb0b8ec2a5f24ba41d5b8a06a10750797f3371bcf361d3b6902d73949df3a24f5a8b9977c10000000000000000000000000000000016480e13653604d05f025b8264fb35a2cf06dc6a90ec7751ed80ee81cd064864655d133ce398e293c289a572dd98605e0000000000000000000000000000000015015aeb1965917cb5b55092d7eeb54915e21fbd5b9a62530b3dd5b8ae07d6f491df46e1987f565223a83cbc90f91735000000000000000000000000000000000658266a6bb01958b791b288ea9f5e138316724398218be522bf816ee5b5b34ef4acc83b82959f52792af6940816bb41000000000000000000000000000000000bf8d18b55a57e67c76882f1a1ad845480196f28556ef569a6a6054426bfa39459ac030b594201be76968cc33c301dd4000000000000000000000000000000000fd8b264f9bd71e00e3987cd221d2e9fbbee34ddcc5c563f02dd150451050bd20b3bd3a6ce1284fb0ebff0c6c1318fa10000000000000000000000000000000003455a16c1cf9a408bf17cbb0b8ec2a5f24ba41d5b8a06a10750797f3371bcf361d3b6902d73949df3a24f5a8b9977c10000000000000000000000000000000016480e13653604d05f025b8264fb35a2cf06dc6a90ec7751ed80ee81cd064864655d133ce398e293c289a572dd98605e000000000000000000000000000000000c5c8e759f71292c8b25dca51bfd40daec58d2d2befe991b27993ae32489b3ef70c0c3f873b3f47ffb013fd31732f763000000000000000000000000000000000a78f4e402668544cada859953182f14421c54446c264312daa5f27cb18a3955a277e5620b0f28f4f9bf233c49f3341f000000000000000000000000000000000e27d9b1bf12c01ab05fa5ed5b2e70444c0582aa5b430d0e10feb69dcddddadeec88c024ec87e23737ec1385461edaad00000000000000000000000000000000065984e81590e368aa6de051129761e94ca218df58ec0132ec22aa7d4128b9ace20e7da35c56a674ed1031d202e9f313,,,invalid input parameters, G2 point is not in the expected subgroup -0000000000000000000000000000000005a54ee5e3dc05c38ade7a42c71baf5a1467938f97c0cdf0742441cd339f22542b1ca6cd215d385b3fd6ba74ec996a520000000000000000000000000000000005f63d18f8bbc1c7b119ee0d58b688477129b2558be0084865297fe119224aec83b3633a646a3d423029cb52f0294aa20000000000000000000000000000000015e2547357626e6160105e5254d8deb80155c42d7b0c13bbe350c3395317913ccea5db61494aa2634857a8c83baa42a0000000000000000000000000000000000629ebc8d1798e2f9280493d2de7c159c558156782487d307ba358fd2bf696c29518d6cf2f975509bdefa89033f1cfa20000000000000000000000000000000011e3f568b9d1793519d5a8cd3bac7cf35091665f981ecb7a9e942f630c5f18fe7cd9747ff539816993b70573410410ac000000000000000000000000000000000889dedf6f29ed9959d8eb7276ae6122fec5a1bfae72c793902e1e3062be444b89a95129dd59f74ea0849b5a2aefd48b000000000000000000000000000000001963e29f92f6f72be2afa4635221b0d2f6afe9ada4582bd7ca4b77eb77fc4503578f38fb49aa1838751db8cf1ca0b0cd0000000000000000000000000000000009856a48f12966554afbcde1971499ee3ae40c9c5c3aef13bc415fddb97545ed84d5f50d2a26b9c16c4403a487dca6140000000000000000000000000000000015e2547357626e6160105e5254d8deb80155c42d7b0c13bbe350c3395317913ccea5db61494aa2634857a8c83baa42a0000000000000000000000000000000000629ebc8d1798e2f9280493d2de7c159c558156782487d307ba358fd2bf696c29518d6cf2f975509bdefa89033f1cfa20000000000000000000000000000000011e3f568b9d1793519d5a8cd3bac7cf35091665f981ecb7a9e942f630c5f18fe7cd9747ff539816993b70573410410ac000000000000000000000000000000000889dedf6f29ed9959d8eb7276ae6122fec5a1bfae72c793902e1e3062be444b89a95129dd59f74ea0849b5a2aefd48b,,,invalid input parameters, G1 point is not in the expected subgroup -0000000000000000000000000000000010df7793a66234599791ae07db9953bba83492389b150a05063105c191c6f32559b9533f1875ed154fa813586e84d0c40000000000000000000000000000000018de32e27e5c97b8b39380dde927e2143bca5d5591d770b2a7a77d7b59bdd533f04c41aef3a5a60df55ed90742869b7400000000000000000000000000000000182f0aa672674c27d8f3fbcc0fc7c1608c01188cf5c28b8ac08d6f99a4e3e214aa3ba61a19607b513b4d01f1d4424a990000000000000000000000000000000000b47be5b5249eab6f67aca9c9349d4a83956550cd21856485132c26e3be3ca133050d79507e2e8cafb67b44a7f4b4da00000000000000000000000000000000060efe7e7a4ca52063b49f6c839666deebe2e8e563de18b210fb477e86420aefa38f89e926cc41334e80f4d47d810d97000000000000000000000000000000000c2243c2a34286b146462a643979a72e75f7ff31f9f043164a5514d3e5da8b0cd891e97af2dd3d6c6f3584b390e5faf60000000000000000000000000000000010df7793a66234599791ae07db9953bba83492389b150a05063105c191c6f32559b9533f1875ed154fa813586e84d0c40000000000000000000000000000000018de32e27e5c97b8b39380dde927e2143bca5d5591d770b2a7a77d7b59bdd533f04c41aef3a5a60df55ed90742869b740000000000000000000000000000000015f7e6dbb904f4f1fbef282667d77c846c0dac6d78f4daaf32123b4326f1c6e42b15cb06ed7b3b46c8877e684ca7f9de00000000000000000000000000000000004a87f0ef3285709a3ded240f529e8e10991a82c7fb40de0bd256a9fafdbc212eabb8121f52c6bf67a45bf36246921c00000000000000000000000000000000156a1d58dd64734149b1e37b1b69fa4ea4452c40d2d041f5cf3de3adadf3bfdf433626fb96c46f9104b1c16114108599000000000000000000000000000000000fc3a0e58ed3fb583e2e1c3b0db5fac2a6d75694aa3d0732243b5a75688fa0ffb5fc9023545b9585df224ee9f6c5d171,,,invalid input parameters, G2 point is not in the expected subgroup -000000000000000000000000000000001639642196e9d6d720e17ace198232d1c0a7c05660c2766b9d28147504308ee48d949755ffcd1c95e024fa299657c8d10000000000000000000000000000000017a5975410b3a80e339b200ec63d7b7d550514653726e3ae6a97a383545118bd4221bba3e27922a826057b244ad025f30000000000000000000000000000000017aa7a3f1ebbdec6abe12abea12ef50a3daabbf96a5f2ebfb517885f0b7aba1e927c682b15521529cb9e1f87c59be99e0000000000000000000000000000000016e23f7effbb9dd34ec1f6974115e7f0d23cc4553d86e6d61a0c98f47d09510e06b3f987c5bcf4bc30e20ae9684da74e000000000000000000000000000000000f3905dd4f99cfcfa6152db53106b4d1f6e24518a822da9388d8ca1dd654a4b8315697328571691f105d1abe9aad3dae0000000000000000000000000000000006bfd10d33df9326a55b35aa6d2bc3e831d4c3b5959aaa35613156e5e19343b74e34ed2670c43ba1a45cd3d91f055c9a000000000000000000000000000000000024c53fb66f77329f70394626073ae298c6aaba115aa6af7bdaf3d2fb74a07441d46eeb398feec036727e86891db2030000000000000000000000000000000016b96c27d4342c47caafa584ec9847c79870eaebcce158535d8da95d7a847ecdc5057425fb3dd862303d1ac03162317e0000000000000000000000000000000017aa7a3f1ebbdec6abe12abea12ef50a3daabbf96a5f2ebfb517885f0b7aba1e927c682b15521529cb9e1f87c59be99e0000000000000000000000000000000016e23f7effbb9dd34ec1f6974115e7f0d23cc4553d86e6d61a0c98f47d09510e06b3f987c5bcf4bc30e20ae9684da74e000000000000000000000000000000000f3905dd4f99cfcfa6152db53106b4d1f6e24518a822da9388d8ca1dd654a4b8315697328571691f105d1abe9aad3dae0000000000000000000000000000000006bfd10d33df9326a55b35aa6d2bc3e831d4c3b5959aaa35613156e5e19343b74e34ed2670c43ba1a45cd3d91f055c9a,,,invalid input parameters, G1 point is not in the expected subgroup -000000000000000000000000000000000680d1062d24bb96b09d9dc9791364b5138e7c36c163589f919354101459de2fa76440616351d1d9bcd961673b106684000000000000000000000000000000000ca650f50b670befbf16d65b486e5c98dea6857862cf23d7bdd2dee2abc0855273495b047431ed03bb1c72b5403c2a4e0000000000000000000000000000000015b2586a23d909e6fd7ef6e58595817bec1389faed80db6d59db219435e7fb1b6492178a849c12bf6418341529d141330000000000000000000000000000000013ee3539c49e0c26e78f46c67b1e3993eed56c72dda43936b419e1340a3aa223ca09a2dca3ca56f2f9578b4a3f885aa00000000000000000000000000000000018e5fd242eca2314b3ade4a1e913177a499d72b539907839c5025b7de69efa24b08b3eb1e85fd05724db82b29edac344000000000000000000000000000000000478706e91d6213e4d4fd9a6c5051c88d86c7271aed7c74ef3b43e904f8ccfe4108f94660807316e8f1eabb85b734d50000000000000000000000000000000000680d1062d24bb96b09d9dc9791364b5138e7c36c163589f919354101459de2fa76440616351d1d9bcd961673b106684000000000000000000000000000000000ca650f50b670befbf16d65b486e5c98dea6857862cf23d7bdd2dee2abc0855273495b047431ed03bb1c72b5403c2a4e000000000000000000000000000000001600e44d53c706898736f5cccab585af5d04f7da91cad6f97b991b51adbc22ce27744f12c0a24804b6fc3dcc53011a59000000000000000000000000000000000751b090922b29f5c299340b12a56a77fd9c32f27995a59cd032cd09ead834d9faf5e151fbf7a0d810738de1beba5b4100000000000000000000000000000000114e35fcef45e87312a90fca21fef50c46b8a0f114df5c67ac9872ccadf858f319977138f03279ddd1edcab4602838eb000000000000000000000000000000000145c6cd707efd8d271dda5b9af26173e337a169c01b28a44f5d4ad06b125a05e867f0b1f873bbc048ea6cec06967c33,,,invalid input parameters, G2 point is not in the expected subgroup -000000000000000000000000000000000d6427dedfdcd624c896ca8e1ef717e212985ae23a4f830ee466c75b37ea2e994e7653b9717928f1be4583aae73f70040000000000000000000000000000000017be03dd7c9c14000aaec774812a8d8bc4aa2f1ecca9a894fd1385864b28a38091d3fb5706ee7c36086c7d50e35eb5b9000000000000000000000000000000000ce359fe7d997e151b94af2f5e167aa4834caf5a07ff056fe049d4b2c2780b35e8ecf9426444da4725a3e66de6691d960000000000000000000000000000000004c7ff987f866ff3919fb4769cc704928af09406c8f5a39e6fdcde5f4ef8a188cff406f853261bd3abd0f67c6cad1f3f000000000000000000000000000000000914584031ca57b9b0bcc35fbe76d967aee164b5eeeaa5e29c02901194fb0f88f5a249040c37ab47a715d34b2329a2b30000000000000000000000000000000007a42352ff521b8e6267a5d0dd1eadcb63db1fec68cff31bee1b2080b451ac731caf0efb86758b26b0c78df5cee8864800000000000000000000000000000000141d878adfaa6a3982cd0de93b4d64ba840a07c026ca443d6d4c2b6c36cf882e109d80df63b1626c112f9a89809788080000000000000000000000000000000005a5888d22a2f654a58d9a03c68d59cde9ab5e5356b2288033ba58fe2dbacf533e59344bdf30eed07698261d6269fc70000000000000000000000000000000000ce359fe7d997e151b94af2f5e167aa4834caf5a07ff056fe049d4b2c2780b35e8ecf9426444da4725a3e66de6691d960000000000000000000000000000000004c7ff987f866ff3919fb4769cc704928af09406c8f5a39e6fdcde5f4ef8a188cff406f853261bd3abd0f67c6cad1f3f000000000000000000000000000000000914584031ca57b9b0bcc35fbe76d967aee164b5eeeaa5e29c02901194fb0f88f5a249040c37ab47a715d34b2329a2b30000000000000000000000000000000007a42352ff521b8e6267a5d0dd1eadcb63db1fec68cff31bee1b2080b451ac731caf0efb86758b26b0c78df5cee88648,,,invalid input parameters, G1 point is not in the expected subgroup -000000000000000000000000000000000da87318eb51b90ca822bff1df4dbc040fb1d74129242d832e1096e813dec5d91f950f44bbb07980dcaaee3366f03a0c00000000000000000000000000000000157d5f5c8ad06af803b9362b22519a23def6dbb700db517c85a663bf1bef9665d6e81e9b02ccaac97f0940d223b83ac400000000000000000000000000000000176835484cf24c47b154b7c35877eaf5194e0e1d8f053842fb5ff8fa833dabebc887f3d34b825fe9cf2c374a2066124a000000000000000000000000000000000d31805157ecafb751536c484fd0c81664de9524a1420c969d54260dd5264bc5454a3234d1e5b090bbb8ee1066b685ee00000000000000000000000000000000196b4f58c12a7d7ac4d720cf9b6c44efdab88e06dad0023a01572cc2ba7bc0a4baf7fa45c06f04ff3d067ba191a84e6000000000000000000000000000000000038cb5d328ac9d1fab9c402b8ed9e72ccd462ca80075132f6be141457ec25a6c84a15e42b78cb64cf05ef18b003e4652000000000000000000000000000000000da87318eb51b90ca822bff1df4dbc040fb1d74129242d832e1096e813dec5d91f950f44bbb07980dcaaee3366f03a0c00000000000000000000000000000000157d5f5c8ad06af803b9362b22519a23def6dbb700db517c85a663bf1bef9665d6e81e9b02ccaac97f0940d223b83ac4000000000000000000000000000000000065c10395b93e8d04f5eb67d8e06e8649139d261ad8fbf5ff2c7d6d364c87837fa8e744834ec9341c714318195896770000000000000000000000000000000009fcc05ee486d42c3b2d480a309e4bb19563f7a27b4a10182ccb2d233ed42943ba472681d1f847249cbd11e4d79ea51f00000000000000000000000000000000053a516998d7c2b2bfa70349bf3f5e3967df827f65044634071450761ae8860e893824b1ae3f204b0ffbf8b091ddd277000000000000000000000000000000000d7cd03cc2cf97a164c7dd65b961df2866e82bf6fa979e56d0ca3f9638319772f56eab2e2134a33515dbcc137da8ec8e,,,invalid input parameters, G2 point is not in the expected subgroup -000000000000000000000000000000000be4cb58fd1dab8fccaa410e1c301be4fd2e7bae95cc1717d2aecaa705d717c67d7f20611dd1403d9350798642fa021d00000000000000000000000000000000075100bfbdb3f6271e5d8bcd4472580e56fd507b73aef3c3c5084d77e11a61b69bea0b85ba62885f7da36d223fca20760000000000000000000000000000000007649efeb3e0bee49b9adb13f8e5d7db1c06d7fde08a3f3082194153bf4b3615aff1450e47fae88ac93f55a389a319da0000000000000000000000000000000008334731582fb1b6125d7ee1da0124fe88f0c70a0a3f6188636976c31ba6a72beed927fe598386f328e4ae534729a57c0000000000000000000000000000000010b57d80fce5cdc90bc93b3bc7a1affadd19fb00aeec2ca9a6287bf4e40fb74616986a44f2f7d945f58501a965f37f3000000000000000000000000000000000180dcae46ee41bccd422b3cc2b34cad26f6816dd08ba51b2f12835e7439ae2d46933de28ac04bbcad68a188e7e90ee8d000000000000000000000000000000000a869358fd3d64849fd62e513db8fce1ab2618d3524acecbd04fef6b8c77703258cc557587f316cbb74bc5af5cb5551100000000000000000000000000000000059eb0e90e0910c24ee2145921ccee83707d8f89a188dcaae7d5c75b7113cacff92a2a030e67927bfec0da39f2bf65ed0000000000000000000000000000000007649efeb3e0bee49b9adb13f8e5d7db1c06d7fde08a3f3082194153bf4b3615aff1450e47fae88ac93f55a389a319da0000000000000000000000000000000008334731582fb1b6125d7ee1da0124fe88f0c70a0a3f6188636976c31ba6a72beed927fe598386f328e4ae534729a57c0000000000000000000000000000000010b57d80fce5cdc90bc93b3bc7a1affadd19fb00aeec2ca9a6287bf4e40fb74616986a44f2f7d945f58501a965f37f3000000000000000000000000000000000180dcae46ee41bccd422b3cc2b34cad26f6816dd08ba51b2f12835e7439ae2d46933de28ac04bbcad68a188e7e90ee8d,,,invalid input parameters, G1 point is not in the expected subgroup -0000000000000000000000000000000010eeac4d171a17d607dc544c559226db50d40193b435ce7528086eee21ec437e986c89dbe05931083768221e4bf06ede00000000000000000000000000000000140ef3af9f3dfe760e8c9dbe8d24abecfe611699ad337a97481a1553e9cabdb2e8a8cb48bc032bd02738cd26cd1388c300000000000000000000000000000000165bb8a97dd4b60ed7fa432f019f7f09a19c8e7a9b70e7370ae668d4597a3cf12c06fe062d880611e34ad9e586c193c00000000000000000000000000000000008c684f30de5c67f675e98400d854397e8cc6a139dca7e9ee179309a9617ce0ae034bfbd0faba7a2f9e7ee39de8770c900000000000000000000000000000000030e524c87a658e44df117fa0a877afcf8a4907979c932921a631a209dd58ddcaf693c7321c537e7e2a5adafe5761fa0000000000000000000000000000000000cd44b77f2d92706b3db5e374f13f6f12e3b030c6341d31e1c55d627e6af06a1b64498e590dbff08ee6354902263ff260000000000000000000000000000000010eeac4d171a17d607dc544c559226db50d40193b435ce7528086eee21ec437e986c89dbe05931083768221e4bf06ede00000000000000000000000000000000140ef3af9f3dfe760e8c9dbe8d24abecfe611699ad337a97481a1553e9cabdb2e8a8cb48bc032bd02738cd26cd1388c300000000000000000000000000000000062e54c21986cff68cd57903594d0e9f2f8348191aea6abc19e8b895e6ca59bf2eb731d10e426ad98726c51adc2d53b4000000000000000000000000000000000594d2a92e0b979c95daf6f78216be8c33ef23f0bebcda479326a1d63ec8234b283ee29fff7fccd441ab4ea6e17371a40000000000000000000000000000000019179f35ebf4ad9f8f9dd577b2db1ed58a988954b4bf4232301b713809be318e746f5b2bd663a21de755125f414bae9700000000000000000000000000000000172d8ad43611623865bff86df2bea58a02b7d6a2c41b85b98d6a2bd4f5e1bef25c978ac0bbb7f4746297c6e0e40b4e23,,,invalid input parameters, G2 point is not in the expected subgroup -00000000000000000000000000000000054dce4bc0b703b8957539c594d8d443fec161c3cb2f806f8eaa8158a665d84cfd551c0b7c0a08bede0cbeb780a6ca5b000000000000000000000000000000000cb3d3f9bbda28f8fe597907a76a8250567f4e481b6e9409e03ead60eab77153cf8f25ffcebb243a310094740cc2e2a9000000000000000000000000000000000a71dc159647864abd64655bf5ef956f21ad55529bdb49ac910ef628cc62a3d43b2b9ee26180232fa29f4b0e8371286b000000000000000000000000000000000c72d0fbe0a7604c9fab394b285ebf1c322c95013651bd21f88865e269eafa65e135ff90f5b249a794cef4e6cfcb56270000000000000000000000000000000019ac0043071372ba077bc8d91a4ac80fb5b8c8131981c4dfc698ba9ae50b506f93149eb73e4bc4f4ded94d6824473817000000000000000000000000000000000113368be2a531d2958d887c046fc26155436fc6a1ef44fdf16447163b7bc48fbb499506d8d5c8041d21116c4f22e685000000000000000000000000000000000b7244995b7819857f716288dc59eee9ba5ac7bfe010937ea0b67ee71388a3792e5b7feb6890a436db4f1b26df18b38c0000000000000000000000000000000009a0b73360bc0ca3b632c0116f21ffdaecf37e4d6c904c98d6225a08d7caadf5024ad6b457cf31b924118ea147ff10fb000000000000000000000000000000000a71dc159647864abd64655bf5ef956f21ad55529bdb49ac910ef628cc62a3d43b2b9ee26180232fa29f4b0e8371286b000000000000000000000000000000000c72d0fbe0a7604c9fab394b285ebf1c322c95013651bd21f88865e269eafa65e135ff90f5b249a794cef4e6cfcb56270000000000000000000000000000000019ac0043071372ba077bc8d91a4ac80fb5b8c8131981c4dfc698ba9ae50b506f93149eb73e4bc4f4ded94d6824473817000000000000000000000000000000000113368be2a531d2958d887c046fc26155436fc6a1ef44fdf16447163b7bc48fbb499506d8d5c8041d21116c4f22e685,,,invalid input parameters, G1 point is not in the expected subgroup -000000000000000000000000000000000cc6bbb9914ae46b57eaaa8d3d22274a355bd7488e5b537169c995ef2bee187ab66497423f14fdcd01373a609981b3ea000000000000000000000000000000000037d9461da369d186cd812a9ade7690b2b8b54ae386b7342a69af832ff4f51e5db9baa3c6b4a65d798a1aeb41d8787d0000000000000000000000000000000013a6e129d4dd4aa93cff5489ee879763e2a2231939e609d2d72f07e630b37d09f3057a36fd5cdfc9c81675c996f8ba0f000000000000000000000000000000000e8d7ad082e8f9a718fc2ea712853ed9ab4e8b1a8ca9988f77c70fc759f1fe2d4bd73696e539f130be13b2862efbdf770000000000000000000000000000000009897223b041568c9ef2884baa28477241e525de05f2c2f15441854a0e8660786a0c7b85a6d9d1074fed2b44d75efedb0000000000000000000000000000000007b52401891bd8003af4b07b04b15b79bd05fcb54739491352d295b5545ddba34da0b0aff36a3e7e4b433011be580174000000000000000000000000000000000cc6bbb9914ae46b57eaaa8d3d22274a355bd7488e5b537169c995ef2bee187ab66497423f14fdcd01373a609981b3ea000000000000000000000000000000000037d9461da369d186cd812a9ade7690b2b8b54ae386b7342a69af832ff4f51e5db9baa3c6b4a65d798a1aeb41d8787d000000000000000000000000000000000cca0d111237ec521889baa4987714c6bb539399b058b6635fd043821377fd6cfdb74923610c8235afe2be99188cbe820000000000000000000000000000000007fa2b99221675b38204c2eea94b2378b1d711ea5ba4f41d35c37f77ee2466f22c88725da9fcdabb6153292b7cd9aa1e000000000000000000000000000000001069adc30f99e0ddfd39775cee5ddd786fcc077cbaa8737f7031745d02f06168fd5d3c4936704d15955bcfa08b0925180000000000000000000000000000000003b388a8d9baabf0bf708e2fe28eacd7f704bc588185adbcea8e0a2bb8f9bc9b045918d97bb27b2033c6722b6e6692de,,,invalid input parameters, G2 point is not in the expected subgroup -000000000000000000000000000000001055ab14a2407bf095a954cf1c926f2c520dda187c44522a7e924e38543e5b87e7642227821a4e0b3ab0289b32161a060000000000000000000000000000000018aa24044066526fa9ed980ae7b3110a4fde7ba0a5fd289803fa5175d30766f01a266917f821169c7ec31fd46e1a14ac000000000000000000000000000000000b6e16f2a6cb821abc43c447da207cc3013f2f750c844f42f0fdf47160a38501bf502073bbeb565122bb3de61b3a5ab800000000000000000000000000000000040f5f3aab5d416e9a084fa298814f894ba599315fe10af20f836e624680582413b4a54623cda8ae2663ee094e4db775000000000000000000000000000000000d32ac715a094813c7b46ce2e932365bfd62ec5e584e047b0c56ed6eca3c58268ae01be31b833be7ba5c2588ebb9859d000000000000000000000000000000000850b9044f129e51658a02cfa49d40a2b09239823cba4d8fe423fa1b4815750811daf745e7e02b317a7318aad0734ddc000000000000000000000000000000000765a76c441227592ba30d6b1d3d9898467352398efc0e8416e0be8c9f87bcac8d5eaa5d7b2a8adfae8303909bef28da00000000000000000000000000000000107c0eff2fa09afb743c294408408451e3039da8db8c0beef32f07864223817075fa557a89244cdc293d631311773947000000000000000000000000000000000b6e16f2a6cb821abc43c447da207cc3013f2f750c844f42f0fdf47160a38501bf502073bbeb565122bb3de61b3a5ab800000000000000000000000000000000040f5f3aab5d416e9a084fa298814f894ba599315fe10af20f836e624680582413b4a54623cda8ae2663ee094e4db775000000000000000000000000000000000d32ac715a094813c7b46ce2e932365bfd62ec5e584e047b0c56ed6eca3c58268ae01be31b833be7ba5c2588ebb9859d000000000000000000000000000000000850b9044f129e51658a02cfa49d40a2b09239823cba4d8fe423fa1b4815750811daf745e7e02b317a7318aad0734ddc,,,invalid input parameters, G1 point is not in the expected subgroup -00000000000000000000000000000000182197c7a0cefeb530f51c664dcf8a74f9f70165ffc416ba454e9c356bade393e30d037347b1a020dcefb09ee65590a6000000000000000000000000000000001030be8d38736ac8e555d1681b14f73f2ca58faebeaff17b6006bf7876e733642d229075c8dfb0a9ba4e832e384aeb8b0000000000000000000000000000000019094370a6f19e946f587e9b117332ce5ad91860cc103015e94c6aac6d2c00f3e71471c241ea1d425e391707b27b851d0000000000000000000000000000000009ad1d1312011907676574a7867ac02059d9b0e29dab709f6ffc1b75b3598658427f10ab52d1129417ef42c30998f55f0000000000000000000000000000000003103495c759d8901898acd98679d92e048ca41244782045a6d9419b3ff87c351f97a333899fb445b8620099f7b9cce100000000000000000000000000000000051f7aaac39348f70109ae7a016026ea52c03e4ec90d03ce05aeea74f66bbf82e17be35cc45f492f50246f0de8dc68c500000000000000000000000000000000182197c7a0cefeb530f51c664dcf8a74f9f70165ffc416ba454e9c356bade393e30d037347b1a020dcefb09ee65590a6000000000000000000000000000000001030be8d38736ac8e555d1681b14f73f2ca58faebeaff17b6006bf7876e733642d229075c8dfb0a9ba4e832e384aeb8b0000000000000000000000000000000014229a1108fcd75131295caee98f8e4e075cf4bb5e169024e07a533f65316cb5d19193d3cfee8b2216663829be6d374600000000000000000000000000000000156cdf98f622a393d920b200e6d9efede7413137eceb79d66f85a18e33ef6946a515737c58e198f877fa39458877b99300000000000000000000000000000000006e5cee8e0f47c0ee4a574fcca6e150901a7de58f3f2eb3480f1ff8c14effa4bb9d00837501f22f6cc465e4026c9d7100000000000000000000000000000000124b6c0836bdd10657a3e1f978b48b9221b1cfc2767b6b99319fb69c5fdcc1b133f1c2fd093c62d6d1e398f32c4e8b71,,,invalid input parameters, G2 point is not in the expected subgroup -0000000000000000000000000000000019c9b755000f9f1b6ff22885f45bc1f5f65d080ecc129d29e1cd60aa14fd20646643be51d2fb3417cbbd39361bc72b62000000000000000000000000000000001741fd3c4a7e883094c0e84d851f45cc1b81af5bcace67dfddd3f19e8817697a386d1965a4e17c60b00ecbff84779b97000000000000000000000000000000000e87ea967f6c4dd7135efcd9a59368a2d19dd1385aefa34d7d9bd7f5094d779a7150667dcec463c9ab63d2ffc8ee4f6d000000000000000000000000000000000a3a010f176efe1a7bdb77dedf6b6271c845d662dca5062ebbac4e9c3b8946db0adfff37a6faa3196a99fb3ef05f09c5000000000000000000000000000000000350ad257d47f270c4340e3cb124ce961316573dea14c9584d20221d922a43c2e94324ec14bd1e4a1eb955861783a8f100000000000000000000000000000000070edff58ac1f8c13f62327cf0adbd748285fcd84ed7be23dfc82a0ae32f8c8f5f6b0679f795874cb0082718fb07a1ca000000000000000000000000000000000d5be6f99bb9a2379d1e542ece048164fa5d14e0c6c459180717b3da46e8446e9def576635ac1124e1390196fe97f39e000000000000000000000000000000001482d8339b402e3bffe61aaa298c8bae4286f1fbfc877a66e21cfe239bbee383d701d95a6c2b8193d67df5a551bb7aba000000000000000000000000000000000e87ea967f6c4dd7135efcd9a59368a2d19dd1385aefa34d7d9bd7f5094d779a7150667dcec463c9ab63d2ffc8ee4f6d000000000000000000000000000000000a3a010f176efe1a7bdb77dedf6b6271c845d662dca5062ebbac4e9c3b8946db0adfff37a6faa3196a99fb3ef05f09c5000000000000000000000000000000000350ad257d47f270c4340e3cb124ce961316573dea14c9584d20221d922a43c2e94324ec14bd1e4a1eb955861783a8f100000000000000000000000000000000070edff58ac1f8c13f62327cf0adbd748285fcd84ed7be23dfc82a0ae32f8c8f5f6b0679f795874cb0082718fb07a1ca,,,invalid input parameters, G1 point is not in the expected subgroup -00000000000000000000000000000000104c749e3f7b40bf6df55f9414bd146ac306b46a6210ae4ceff6fe2a58220ddbc69208ada5f692120dcfce39b1e43fb5000000000000000000000000000000000663a0e62ea68ac23a6e27958baabbb5deca3905aa138a54d6198724e5fdf0abb9288cdb52cf1d44e93f06571a654f75000000000000000000000000000000001116ecf077865395ea40fa9cf05753b87ac29ccf9ecfebfa1031fef0defa1d77634c2177647f069532e00f7fb657577f0000000000000000000000000000000005c7960dd84874fc00ab199d00e8bf1ea035a7eec443328bf2bc28d0006979f5032763a4d33f031e698895e03b27314f0000000000000000000000000000000004e00e32a506bff708c51fcc4101c8ebe7f1695d6a4606b6648b04710fdae313b99219963921451d0fc78dd59970ea8b0000000000000000000000000000000019dc4b721ec4a4303809c47da68099fc10706eb08cd4f6f91641ac680661e93a91e2067a84c12f9f55f84e27ed76ae2700000000000000000000000000000000104c749e3f7b40bf6df55f9414bd146ac306b46a6210ae4ceff6fe2a58220ddbc69208ada5f692120dcfce39b1e43fb5000000000000000000000000000000000663a0e62ea68ac23a6e27958baabbb5deca3905aa138a54d6198724e5fdf0abb9288cdb52cf1d44e93f06571a654f75000000000000000000000000000000000da3982205a45000b16e1ec7a48effad4ae1affd4acd8bd13fcdf2bf05b6845ebda9be2df6d6325389d711111641aae500000000000000000000000000000000150c1bb67fe3d88dbfb452d5b4582d9a1c350ac01cc209740be70d63e266c926cc6b0171eaea913b7456daf595b83ce900000000000000000000000000000000138d0bbb52fb6248731c8fbb6818d1379fc5c2549a5a0d663a56c41b3b2e8c7c4fd77830c455a40e59aaa65124ebcee50000000000000000000000000000000015e6b4628b75f9786ee26e41cb8b86c6e6a97ac18aa7662b39e9c96e169a3192b64b863d7f9739237255fea6cab12fcb,,,invalid input parameters, G2 point is not in the expected subgroup -000000000000000000000000000000001638395680014bc04e2ca42bf864dde47a0d708ae81ba4a6aa2e2476837750aaf5f9f6e41a5a23df432ae92fd221737e0000000000000000000000000000000009419792539e0ae995b8d853d9ef513bc54766475e37bb3dc2dae3d7fb9b02b0eb2327f24a751d2de344b9f5131ef23700000000000000000000000000000000197ff997d6c5efa3d7de8e16f26082bf13a2401d6df5f5c33c6614c36105f347e40216c907bdad9c1df6ebbd44f41c3f000000000000000000000000000000000f27a0bf92329730d776a83583177993b2b354a212a9c004f9f8892a750c477b8d1e68c13127f03b1629bc8392d06f5b0000000000000000000000000000000011b239cc6914a321385d907527b85713a0d842f5be80752f4c5758586dc1de944b6e4578bbe324f16838115e9c866bca0000000000000000000000000000000000cf93c5b48cd9de51ccaa45124217cabf466d07d6fdf4a7bb810443339ec4af5b74931bd07eb9fd31c284c05f3f539e0000000000000000000000000000000010b91e082484fff0da28b06f06e02c699d741f2ef788250e3fbf2ba8fc1d7d78a1ca63b76dadfb71015fbefc0eb70eef000000000000000000000000000000000c2fe842c659c875af0f2cb1a978ac9058981cc6c76ff057f326162d4322805974505e6a35499bd0c58b5d6db3aa222900000000000000000000000000000000197ff997d6c5efa3d7de8e16f26082bf13a2401d6df5f5c33c6614c36105f347e40216c907bdad9c1df6ebbd44f41c3f000000000000000000000000000000000f27a0bf92329730d776a83583177993b2b354a212a9c004f9f8892a750c477b8d1e68c13127f03b1629bc8392d06f5b0000000000000000000000000000000011b239cc6914a321385d907527b85713a0d842f5be80752f4c5758586dc1de944b6e4578bbe324f16838115e9c866bca0000000000000000000000000000000000cf93c5b48cd9de51ccaa45124217cabf466d07d6fdf4a7bb810443339ec4af5b74931bd07eb9fd31c284c05f3f539e,,,invalid input parameters, G1 point is not in the expected subgroup -000000000000000000000000000000000ac27e4d19924f4bfe30432554f25d456cdb4724c106409e46612e1c91e8cf5fc2cdcd6b6fd6bfe040e910795441befd0000000000000000000000000000000007e9227d849e467fbf5fadcc016dedcc04f4c66f23464195782746fde628a107d77ca5b5c9bcc8bbb14fc14208fa5de300000000000000000000000000000000094860f23d182a14d1a64d9693ce9309ef4e775f24aa3807571c9b8281fc0d6157cdb5a00b34b66be1849994c264c4b000000000000000000000000000000000062b4a3ef95b2522c894c0b492673c3800fdf8645998a899e27dc3a23c0530d96b558d1c6364477943726740cdbc88f0000000000000000000000000000000000daa2f2f2c1020339666be4b1c1e12f8d44625a9508bc5590314789d02fe0e2e676d8d240bff89b669b9290fe1d0f8a8000000000000000000000000000000000f7a710af0b04d20b7d515f2627b572a5a17a13975ee81bcb8fd90600d5fb2f161a9ab3635bd16649c95385bcd604f5f000000000000000000000000000000000ac27e4d19924f4bfe30432554f25d456cdb4724c106409e46612e1c91e8cf5fc2cdcd6b6fd6bfe040e910795441befd0000000000000000000000000000000007e9227d849e467fbf5fadcc016dedcc04f4c66f23464195782746fde628a107d77ca5b5c9bcc8bbb14fc14208fa5de300000000000000000000000000000000055d8c63d7c04bf5db81465f2fc372b798d77ab0ecf795bf57debeafbbc8998f91f71b0dbcc440e70df3d5a1cb682ad8000000000000000000000000000000001497d9519e835c0644d30ae38ee66faf39b1939320c2e0a45b7862508ea3bd7eaa3a754a679bff81af26c6aa141adae00000000000000000000000000000000001be6ce3109582f31e02051ef0e4d266f310048e04a7ac8dc5e04d2b7f2766440f1ae63e5da6dbf831b21fd7cb9cc0a80000000000000000000000000000000003d4acbd20192ee2fc55acd5c90cf5b897cb42a4c0a777970d11955cdf11d5ab22444ac9cfb666c3e509ce832cef219f,,,invalid input parameters, G2 point is not in the expected subgroup -0000000000000000000000000000000015866ee89fe4f68e45155fb98124e8453e1ca25347d84f70ebfc32cf76c5d48e3a3e5ccfb1b505db7b493cfcc73ef92d0000000000000000000000000000000013deaec2d2482c457050256d157968ea3d15f9b61b4573353e83daf824b28289343bcbc3bf97ecec9d65ad08804861440000000000000000000000000000000013467fcb424ae0eb012228fd2083d92e6d242427670ca6e2cc1166166edee5a94b78d2c2f8715a996bf2b4e5112e49f0000000000000000000000000000000000c23c01e0061b0fc7579723e072b12e86c8f12f4c2a039bdc5b1f3384441ccefec187e0380efae31a819d92fd6462ce80000000000000000000000000000000014f9a055a5e468955f6d7485fdffed2b33174777f99d9d0af160b0a083912b05da45f35c73053120f61525c173a24e59000000000000000000000000000000000cfdcb6adf8f04fac2cba8f322339fb0614f46b77b0d91f0ec167eca06fcce080ee0e63023fb94712dbe7591843b6fe1000000000000000000000000000000000d90bd38049f2a8de869d8a748c9ff3120542f38fca6e8d5fbbff86baaabf0f19dbf449cf23c043dfea322d99837f7110000000000000000000000000000000000ede89c8bb8299726ec685765f10167c5b844e427d3c15da6ec2c1d97de174819d52caa96d5cc938e93dd09bbd1e0d80000000000000000000000000000000013467fcb424ae0eb012228fd2083d92e6d242427670ca6e2cc1166166edee5a94b78d2c2f8715a996bf2b4e5112e49f0000000000000000000000000000000000c23c01e0061b0fc7579723e072b12e86c8f12f4c2a039bdc5b1f3384441ccefec187e0380efae31a819d92fd6462ce80000000000000000000000000000000014f9a055a5e468955f6d7485fdffed2b33174777f99d9d0af160b0a083912b05da45f35c73053120f61525c173a24e59000000000000000000000000000000000cfdcb6adf8f04fac2cba8f322339fb0614f46b77b0d91f0ec167eca06fcce080ee0e63023fb94712dbe7591843b6fe1,,,invalid input parameters, G1 point is not in the expected subgroup -00000000000000000000000000000000119c7c85e5efaf08b91dc496758b962098cc0eb60f4a770bfafa91809ae4a95b43f96b69c8ddc897701487f22d2e049c0000000000000000000000000000000007467ac896ae9f7d2cfdfbab082c89d3c17a6dfdf1f69b4b38fe6d5ede6848a45e8b0d728eb8c68752ec59c8e0504dcd000000000000000000000000000000001047ce33c70d58e3191a558ce2fd95c20bb62abae7d924cec8a4067fb33e8dacd796d65c049be7bacdb969f61db5b26500000000000000000000000000000000096e7081a7b2377331f86d8418bd577cd5cc1d45e60d39b519ff2b3a50ddb2d5f6dccc0066167f42498a3d29ef5ce2e30000000000000000000000000000000011159939a04c129b007f2aa2d59ae006e8d89c41dd465cba551737d06d3fb2c1161aee98e86cb8c0321f42e514316030000000000000000000000000000000000c25d9cdc8dbeec82c47d5ef12f21a7e58a8eddc1e738e635ba04f2ebe12440090f432c0d1518217a5531266441f1c2500000000000000000000000000000000119c7c85e5efaf08b91dc496758b962098cc0eb60f4a770bfafa91809ae4a95b43f96b69c8ddc897701487f22d2e049c0000000000000000000000000000000007467ac896ae9f7d2cfdfbab082c89d3c17a6dfdf1f69b4b38fe6d5ede6848a45e8b0d728eb8c68752ec59c8e0504dcd0000000000000000000000000000000013a11383f2d3a3c28e3ea750fece5790e37f66b306ecca417c83840bed70c034e4b82b0850f719fb0b3b203a25dffae40000000000000000000000000000000017d067d9cfbbcf605c5da3532b2eda5900d71340508f08c05d0051772e65b0f85b9efe5b6d63a7b64b25ede8df7f25c9000000000000000000000000000000000e44847884ee8eacd5417e042e8299af8313ce177ecdd034a91d3bdd441437510808d44e328e810c46bd851ceb6085dc0000000000000000000000000000000013288506fd52bf37aaa975b533f1182a824b79d2d876ad6ff705efeec7f732bed99d2da8f31c00a2db4d97c4118bcb88,,,invalid input parameters, G2 point is not in the expected subgroup -000000000000000000000000000000000b7aa89ed719e2af5ad32ca923f1d2d52d767f6bd33d8967d2619b54472c8881ad06441b2595931d734a0fd10ccd7f190000000000000000000000000000000014bd6118d65e19e4cb79af164f523f1c80b0f0a0f0063cf1d28e11ae7987381c0b9707e43754b75f36ca8523bc5f7da600000000000000000000000000000000056a29b523b0cf85ab04b0a496e078dba5529cb9699e567ca42f9ee3e3f07b61ae29b0ce17cad23131375f624a366157000000000000000000000000000000000acb91d1f057c7aec1f7561614a95f8db2252cc879bbc2595a5f607d8b0ecd6e6e3ec19849eacfca62d870b049ce84910000000000000000000000000000000010d9459e07178af8e125c2f66de699cfafb5f87a63454e24d0ed88b6c804a9ff204f146ecf4d6db62234ace0a944acb20000000000000000000000000000000007256a68e23b43a3b6475b3cf209ec108bac13631ca448cc860672c65c1760a8299fe941ed5bcbbbcf63a683e86806ae0000000000000000000000000000000005d4453da747eaef90007eb8ebf6088e8617dad362f2a95638fca7312bc5cdd8200f32b17a0b483052e6784d286c2cb80000000000000000000000000000000012f0e56ed3e3f628a13493d0ade2321310cf62927b40887202042981fc9a81d6cc69be130346b7bc244a2119b2632a5600000000000000000000000000000000056a29b523b0cf85ab04b0a496e078dba5529cb9699e567ca42f9ee3e3f07b61ae29b0ce17cad23131375f624a366157000000000000000000000000000000000acb91d1f057c7aec1f7561614a95f8db2252cc879bbc2595a5f607d8b0ecd6e6e3ec19849eacfca62d870b049ce84910000000000000000000000000000000010d9459e07178af8e125c2f66de699cfafb5f87a63454e24d0ed88b6c804a9ff204f146ecf4d6db62234ace0a944acb20000000000000000000000000000000007256a68e23b43a3b6475b3cf209ec108bac13631ca448cc860672c65c1760a8299fe941ed5bcbbbcf63a683e86806ae,,,invalid input parameters, G1 point is not in the expected subgroup -0000000000000000000000000000000015827c619b2a73a750f6469160ff323c15adaf55e893933a5c2e5c2f0df8bc426421408773a3e8cb8b1695973f7c0b760000000000000000000000000000000000af4a7d29f10cd080d9989b341fc030a5dd51512f776fb1da7a46d542c2a6a2ad7c1309af30423b717825fd5dc0356300000000000000000000000000000000198d09947dc088c1d33d776d64765766b508764f12a28fe0119277d6e171af7c9ff83f6823558e8b1a4284857663afb700000000000000000000000000000000130d5e5315f8df8d0142d06bad7a51b08e5b3c2d49b84c9d6b177b9bb628a852ff65c1a93982dcb1b31a2dc0941904750000000000000000000000000000000018cb011868591c6b44b7ce49f82470aa6461a737173e1d88d249c0e83fc6e4e6a15f8397e515efe7dc7302ccc2e369ae0000000000000000000000000000000004de1c5539b2ef536a66c8f3d7cd49ed948c081c08cba8826d2ccdf9d159b931ea10eeb8b3f465dce0143b179059169f0000000000000000000000000000000015827c619b2a73a750f6469160ff323c15adaf55e893933a5c2e5c2f0df8bc426421408773a3e8cb8b1695973f7c0b760000000000000000000000000000000000af4a7d29f10cd080d9989b341fc030a5dd51512f776fb1da7a46d542c2a6a2ad7c1309af30423b717825fd5dc035630000000000000000000000000000000004286a9efe902158cc624080ebc5fd9b5e0e6e31554c745d5f0c34ef1de2a487f77d405577559dac59babc731ca779110000000000000000000000000000000009c09c9c9e2c75bc6a81357c03b339668c7d8cc8a3f65790ad53b62f4c21acbf64fa66fdd75dc24c05214b712ad7fdb60000000000000000000000000000000018bf7e4fe271fe195377639c5743c1ef3eccb09c86d64d2a4dad2d7d4ff0feb46252d749f82a27141dc0007649b032bb0000000000000000000000000000000018113c4584b81eb814a9f1ebd041062d0db8bec46c2c1ffb7f863bdd2fc3fac470b01c32b6f2453ab048eefe362aa1b8,,,invalid input parameters, G2 point is not in the expected subgroup -000000000000000000000000000000000c3f4ece90cf7d380efd3f81e66110a5923bd604422fca0fac2a16fb9a8d8b34cc1fb86a15009e8cc2c0d9fd8fbc0fac0000000000000000000000000000000012ea55d042ae590abd4c2687e0f152384d37665ddf26787d49bc9f6d40a579bcb23521c59ce91c418b9f4801375892aa00000000000000000000000000000000098af17ffd4d28bad76ce1ee669e7cdac1eec9facc260440636be88618302ab5a0826141b4fc914a389816d04597826a0000000000000000000000000000000011bef78afedf5c62daee5e86386c45826a524352fea40f68b07b7794df8eced4eaf0fb55b6990b4fb417ecc597b61e48000000000000000000000000000000000d64f0a4df4f858defde17b31476045c3dea78de4ec8082822c1699c0b9619464c75f0e57ebd12ad9e4e2e6b291b538c00000000000000000000000000000000031f12dc8a9c5445d575f99e2a4b4217ba5c0be58ac00977236440ab0ac7e2c8dab72a64464e4480aab7eaf1d629c7e700000000000000000000000000000000033f3c31337bc48622d27a9a3224a2acdb5c538a59b497a4a85840c81cff667ed0a0e4e3f4bb23a9ae53c1e79ea54cbb000000000000000000000000000000000cf0dc22af4530260cde26aa0eedc83a0ec3ae87d024e6907f3d22070e1054b3d4f24d5ace7218ed44763af6ec3f25ee00000000000000000000000000000000098af17ffd4d28bad76ce1ee669e7cdac1eec9facc260440636be88618302ab5a0826141b4fc914a389816d04597826a0000000000000000000000000000000011bef78afedf5c62daee5e86386c45826a524352fea40f68b07b7794df8eced4eaf0fb55b6990b4fb417ecc597b61e48000000000000000000000000000000000d64f0a4df4f858defde17b31476045c3dea78de4ec8082822c1699c0b9619464c75f0e57ebd12ad9e4e2e6b291b538c00000000000000000000000000000000031f12dc8a9c5445d575f99e2a4b4217ba5c0be58ac00977236440ab0ac7e2c8dab72a64464e4480aab7eaf1d629c7e7,,,invalid input parameters, G1 point is not in the expected subgroup -000000000000000000000000000000001679e0889aac1501b67c4ccee84942e05b1720f48b6390ab82ff76c0ab95defb79b4371770f2e07a9e7ee8de4d76b43500000000000000000000000000000000162fa6099ca3e5e8e27dea6ea0d4d13c5c150d281fd6beb2079ddf2d714bf9458184100c88440109d7526812ee0f56e000000000000000000000000000000000087bda5b07cf72c2b350e663670f094c352097330b307cbe2f7b4224841b6eb23c36ba62d4ee591e5ca68383ec0256f6000000000000000000000000000000001163d4985e0f25d36a1f8dd97b61413b0015a966a88d98eddb2ea2d5eabdd83a44fb7e37cee90cc50df2f95dbfa97979000000000000000000000000000000001652067ee82320191cc5b188e61ee2d1b94c781e8e5798c89224920ed1d12a2cb41066f69cdeffe8a4d5e3aa1be4c83300000000000000000000000000000000139cd806423ee99d913e8b0e5ddfb6b1b62478254fe39d6836fbc632de9435e1464a556b1f9466efebe93636dfde7749000000000000000000000000000000001679e0889aac1501b67c4ccee84942e05b1720f48b6390ab82ff76c0ab95defb79b4371770f2e07a9e7ee8de4d76b43500000000000000000000000000000000162fa6099ca3e5e8e27dea6ea0d4d13c5c150d281fd6beb2079ddf2d714bf9458184100c88440109d7526812ee0f56e00000000000000000000000000000000017028dd744482e290c523ae5944c8a149afd9d344fea7ac0171ee3a5ff0c2add53ab20c477a584bf61e007af5840eb4a000000000000000000000000000000000863382ee8a43f02396030768905e44c8f9504b7315b00e379b92060e4f01e1b4e0f837b24cb42354e7211419a5516480000000000000000000000000000000007e2af64687f7d581d5a2bbdf225d1ab3dbea326ec89c08852807696c8d13cc907ef4289bf5ef9826c1fb27673b28bfb000000000000000000000000000000000ffc910160c8a0b826600fcdbec027e7d4874c9774324bddd2dd4428eb81c22618a49378502917ad9fcd96bdb1371285,,,invalid input parameters, G2 point is not in the expected subgroup -000000000000000000000000000000001902b8c58eae3ca8d2261a637902587c2c0e75d32abc894967b6837ea34252e4558966f931789ccd76c1bbe3e092b180000000000000000000000000000000000dd20f71f5054c79d5e357f69f8d7345b5a036241774a72743271f2dc8f6e8c29a3babc2b65ed8193cc0636fb2e86f740000000000000000000000000000000003e06e2dcfbd695e9bda0baee1276ceab637fd1fbe2d2d6458c923c35b00edc7edf4f9e797aea59ff8cfceada0615a02000000000000000000000000000000000a04a2ed5e42fac7f064b43d64151a6c517ecf22dbc7563a3e9f35f555a9992fe45cf6a728ba94607df7c96f7e0a334b00000000000000000000000000000000090fac97f9f524168bc930d26ea1627ceaf187398d6bfc5a019c8467d75cd31a41c7eb9fda35fc85bd92b4cfca92dbff000000000000000000000000000000000f37b91dc935c28668c27d38328a511148c1739b65f2816dc53e42a8f059c9b2be7417a6f97c9a2597b1a0f06b7afc65000000000000000000000000000000001687dbd36c7f96f8be47f08bb75bc72f91e63e26d0157a9a9c8f531f3e73bfbd9870fe9abd0a7a3fe73b997e48d0ffb8000000000000000000000000000000000183ba882bdaf1dc850cb4e98158895effda1734fa64810cb15640e6cc027bd006e5c1a088cc2c65e8af29b64fe41d4c0000000000000000000000000000000003e06e2dcfbd695e9bda0baee1276ceab637fd1fbe2d2d6458c923c35b00edc7edf4f9e797aea59ff8cfceada0615a02000000000000000000000000000000000a04a2ed5e42fac7f064b43d64151a6c517ecf22dbc7563a3e9f35f555a9992fe45cf6a728ba94607df7c96f7e0a334b00000000000000000000000000000000090fac97f9f524168bc930d26ea1627ceaf187398d6bfc5a019c8467d75cd31a41c7eb9fda35fc85bd92b4cfca92dbff000000000000000000000000000000000f37b91dc935c28668c27d38328a511148c1739b65f2816dc53e42a8f059c9b2be7417a6f97c9a2597b1a0f06b7afc65,,,invalid input parameters, G1 point is not in the expected subgroup -0000000000000000000000000000000010f38e6e4f562be50152c1d10eee8f8990cb8f884035bdce111e178d1286afe2f2f02c3a36858ae2ce902d6a2872ff1000000000000000000000000000000000141dc64999baf42240b933f30ee895188b561b880f90b5f1ca8df0ac75be7d95bc15d55e321720c172171e9c4c59e800000000000000000000000000000000000548814c4b6d72cfb817b49b3141302be7d7b378e50ff9f7d66e31cd04e1f024bba334110817990264d26cbcff7170510000000000000000000000000000000011f9d186fab00b9ede155a82ec5a5e587a1c6091005c4c6e90672d15c434953426440799c5ede15a7976f18bf345595a0000000000000000000000000000000018d480ece4609a56220d4db100b68ca06ee4271b84e1a81112fbb0616cb34d2b0ec974de31f7d6957b186dbd8a8f8ad3000000000000000000000000000000000c3c1b79130f73d516c1bbe38c572be2616991b523a9370c98df9313be9f5015c3e8d51947201c6b27e8cb9c7291bd660000000000000000000000000000000010f38e6e4f562be50152c1d10eee8f8990cb8f884035bdce111e178d1286afe2f2f02c3a36858ae2ce902d6a2872ff1000000000000000000000000000000000141dc64999baf42240b933f30ee895188b561b880f90b5f1ca8df0ac75be7d95bc15d55e321720c172171e9c4c59e8000000000000000000000000000000000006d89d908b733aba090432e795c564d1badd5b8529fc53507c4850e3d97978062b38790ef45562f3d4978491b5ae893b0000000000000000000000000000000003f7fc037328c13d13fdf4b2c251ce10c41ac5d042122f0e4e4f5a71cc9e1463f62d96aed44123d0e612e5296b53fdb80000000000000000000000000000000000aa2e027a929f7637f437b333a795a2e8d1a92cda31feb5a72fa1c66fadd23813177f9360204b0512d8f460b5bb161d00000000000000000000000000000000139a2a989d462e1793caba250c2ba9c46f31b3a06f43a0f4cbaa021b5d52d254f18d9517ddf3c21780f2a2c59533c5db,,,invalid input parameters, G2 point is not in the expected subgroup -0000000000000000000000000000000003ac8ec0fbf8c4a6774d8567a45b033a4a622d88d8b2025eecd746d084617b67342cb1030068ef6dceea78cf97210b6a00000000000000000000000000000000090b3a144dd409afa163ef513af313e545330a66c33d45b32d61cbdeccc66f78062060a2bfab2a88ec0cc47ec3525f19000000000000000000000000000000000d542ceffc583a6022306479b2365171c3610b7f615619802caf2f81d78f2b5166114485dfaacfdfc27c6450f8c344550000000000000000000000000000000010f5a12712658a5359c0a310f6d833c0b4623c51da6c035dfddcc4c201ccb27ac0a534da459a82488c32e1d4ced9b8af000000000000000000000000000000001878dfc18d1744c6f837b36436b82cd9c270916e5206f709e7eb30fcbd4157f65639103f367f1af2684a51d93e3dc7fb000000000000000000000000000000000ca3a300efdfd9812b6213a848d7a2f865d3fbe8c73527997f18460485626921063bd5b7842b8a47ccadcebb5539a54b0000000000000000000000000000000009aafc73979c000236c08e089828880f54645b5ff4c1dcfea0ff41ffe8e3fce8ba0dbcebf0d4205bb6616a737b6d3542000000000000000000000000000000001399a2072604d50f92ee186924ce32c4e887803dc258b7495aa2f3d2187571045db7f360d2614b198f83bc8024b06559000000000000000000000000000000000d542ceffc583a6022306479b2365171c3610b7f615619802caf2f81d78f2b5166114485dfaacfdfc27c6450f8c344550000000000000000000000000000000010f5a12712658a5359c0a310f6d833c0b4623c51da6c035dfddcc4c201ccb27ac0a534da459a82488c32e1d4ced9b8af000000000000000000000000000000001878dfc18d1744c6f837b36436b82cd9c270916e5206f709e7eb30fcbd4157f65639103f367f1af2684a51d93e3dc7fb000000000000000000000000000000000ca3a300efdfd9812b6213a848d7a2f865d3fbe8c73527997f18460485626921063bd5b7842b8a47ccadcebb5539a54b,,,invalid input parameters, G1 point is not in the expected subgroup -0000000000000000000000000000000013a366c2748305c4ca702c053ddcf15df4a4a7858cda813d001f59bdbb419de6ae3fd24b22fbeebe58d5278caf04c0c800000000000000000000000000000000140759404192c97274c06a69609a1f927195dc0e9df312f483b075e0647a9df1225c22284edece061a2a1c3dd6c4af030000000000000000000000000000000018059cd50cc71b1060ee01c10860bccaf2abbf84cc09266f2818b7625be9368138784dfacf0a1413f19bed9c09294fed00000000000000000000000000000000138939b9b91fcc8ee3aeb35de9476576cc84adbfc513a72fb74c6b897a9d6bb2037d65489709de062b238c5d0587345f000000000000000000000000000000000a9f2a8303b70df25b27158d7fbe06db9b71f6b30b8d8f3d3ad3e81ed310af6ba00eaa104c4c8755c3c24b37b5a9bae90000000000000000000000000000000014297a57a543d963d777ce5e3e5b07d19d69f56ff3efafa2753889522f10dac3fcabcc77466ef236d331361955b571670000000000000000000000000000000013a366c2748305c4ca702c053ddcf15df4a4a7858cda813d001f59bdbb419de6ae3fd24b22fbeebe58d5278caf04c0c800000000000000000000000000000000140759404192c97274c06a69609a1f927195dc0e9df312f483b075e0647a9df1225c22284edece061a2a1c3dd6c4af030000000000000000000000000000000009a457949f0a3a5ef91fbe3beb52dcf95a9f71db70bef860d2fd60cf9330b99e1d103eea022f32f0db603a635925f2940000000000000000000000000000000018e2ce9366745f5691d3c8f907bffed5f9da928cf9c9997db1311bc47b34d9d0a076ea5b7845e0dbf1c3dab60edca5de00000000000000000000000000000000089bcfe3a5596fe5f3c61326de93eb63abb0f56a7b9a5c5f4ebd883ea681607352b955deb581b57da99e4fd302e136c70000000000000000000000000000000007cb502742faf77a7223dc713a243af8998652e45f51b32dabe766c7a771bf4642ea9f25fd924e61a0f0a6e0f27c99dd,,,invalid input parameters, G2 point is not in the expected subgroup -0000000000000000000000000000000003f23275ed56b4aa4a1fe367219e8c84142d60d6b9983e0abb8ca21a88e008286a902b2b92369ec14d7f45f7b66b9a0300000000000000000000000000000000130b8d95a4672e467f122fc010ac3ef7f6b6d0ecd044413e51f7c27ed22f7ab7a28f60245b9ba83d4ffc98b9a990510e000000000000000000000000000000000e5af1420546c1a5a0e0c2bd9241bb7c7a26dd52f4f358fc868bea457a60bd4f6bc5b60b27069fb4f6760813a91ada740000000000000000000000000000000017426a65d239b1d9505bef2b476799c394fcc7bfdca36a1ee5a600351334dadc238b64cf8a667a25d4880a31b73c53a9000000000000000000000000000000000f151587944aad17429b51b1c16193c1e1c93cb412538d1475473666c997e012ce618eb841c4e9e064a08ab83d7fa60e0000000000000000000000000000000015c2e049c532db585807319c23ec077a51f288fcffb2cb6528d3697221e8542e3fc85d18b079ea1b217fae30858a36f20000000000000000000000000000000010a1fe14b9981a917e49b71f549b7b548629ad0003b43a9eff26e2cfa7fd8ddb21056e26dc78c88d30c32e62af40a83d0000000000000000000000000000000019f408194aa79434edd5f2a3adcc5c55ee9c1f616641b29ef21fbba8cae342df67ef438095dd7677ea1959f9a855974d000000000000000000000000000000000e5af1420546c1a5a0e0c2bd9241bb7c7a26dd52f4f358fc868bea457a60bd4f6bc5b60b27069fb4f6760813a91ada740000000000000000000000000000000017426a65d239b1d9505bef2b476799c394fcc7bfdca36a1ee5a600351334dadc238b64cf8a667a25d4880a31b73c53a9000000000000000000000000000000000f151587944aad17429b51b1c16193c1e1c93cb412538d1475473666c997e012ce618eb841c4e9e064a08ab83d7fa60e0000000000000000000000000000000015c2e049c532db585807319c23ec077a51f288fcffb2cb6528d3697221e8542e3fc85d18b079ea1b217fae30858a36f2,,,invalid input parameters, G1 point is not in the expected subgroup -000000000000000000000000000000000bc43aa42d656bdc233b332698247bad1904aff059eaa3f9b943ce5d4ae4f414dd361062a243f38129b954f17389ec280000000000000000000000000000000018dc8ec1d798981f662a8ce10f25f31197a2d168d3c047d2f6a214f1554202d072baf004c61b6d58f4f0410a4520b985000000000000000000000000000000001217fe0908fca8686b63337b0de6d3b3e4853466a990d8feb8a127cec95fd8dfc97be2ac57587d5f9ae1f5c10848e5910000000000000000000000000000000005c60861ac4863f7b9c38952daa88c2414ec8ac14f99fc765042b718da08136537765dcbc28cc6a0c279d491cf95b4b500000000000000000000000000000000154b289077530a86091d21c8be9c25ccd250da8d77caf853955b0d169e1ac40b5e0fd539b09b61b293035ebcbd0e21f5000000000000000000000000000000000356ddbe9454937c441dcfc98fe7b0cf8a746464f77230229328cafe6ad9ad1b5cc7a60e50bd8431b0996e3c42882777000000000000000000000000000000000bc43aa42d656bdc233b332698247bad1904aff059eaa3f9b943ce5d4ae4f414dd361062a243f38129b954f17389ec280000000000000000000000000000000018dc8ec1d798981f662a8ce10f25f31197a2d168d3c047d2f6a214f1554202d072baf004c61b6d58f4f0410a4520b9850000000000000000000000000000000001874e45ffd1349b4ed2e361dd7093a2ba41281b2d78f123bf9f6f73892962a0bcd6dc6e4159e505509cf7839aa79a20000000000000000000000000000000000ae0404355b78d20c1c3f5d65373d905696b166e76de62feb33f819dba26d39ef78621f819e998f6f2c82c65ddc22fc90000000000000000000000000000000008a499023de01bbe12958e10a3ca967f0f6047c705345beb8fb835c26df4eee908448b39191321f3eacfbd0951861c40000000000000000000000000000000000a56e3272f0474f980511540610b29e9a722a868025ac424ce8f76f342721a92d2544a420d3472f13186a0837d7e2c43,,,invalid input parameters, G2 point is not in the expected subgroup -0000000000000000000000000000000003e157886f141c2ce7d9ff32af44df6b7407af027005aac1149ebbe74b3b810f834b019b3e67a04531e2554f122d959600000000000000000000000000000000159eef0ff7bbe471a7ef8e666ffe35f427e3ef5bf9eeb4693dd4127467cf2615fa6b289be07452bec5c35b6d8d8ef2a100000000000000000000000000000000028316eaa131ef5303b012bfdd145bcb3106b362f410ce05810b8c83e10b1a8f80167b546b8b86c1368d7099fb5a0deb000000000000000000000000000000000bb3a353a2c16bd73c62fefd820927898dfced930d9639c5f63e62d8e8d31fa028cefb0d57ed16299eccdf3700b62bf200000000000000000000000000000000198272cf5c6e8a4f4cf4692fb7363687d7ba52deae88a7b976863309feb4a475db150073593567352ab62a150d862ca20000000000000000000000000000000019af00f2cf92494f532052962b62c34d0999a984b4bf36abd74a485fb9089ee0967071886b97f541ae80c6f7b8bc73070000000000000000000000000000000014bcf3f26683234584d79b436cc608462f1e2c20b5ecc5019988d8e30137859a4b6d0e1135dd5bbea0781b8ed3f0653700000000000000000000000000000000090ef29bf63ca97ae8388588227e1d1a0653c43b16a35a63f2ab4f0b11fd8005d9a85d30a7406491d983f347e4dfb9f100000000000000000000000000000000028316eaa131ef5303b012bfdd145bcb3106b362f410ce05810b8c83e10b1a8f80167b546b8b86c1368d7099fb5a0deb000000000000000000000000000000000bb3a353a2c16bd73c62fefd820927898dfced930d9639c5f63e62d8e8d31fa028cefb0d57ed16299eccdf3700b62bf200000000000000000000000000000000198272cf5c6e8a4f4cf4692fb7363687d7ba52deae88a7b976863309feb4a475db150073593567352ab62a150d862ca20000000000000000000000000000000019af00f2cf92494f532052962b62c34d0999a984b4bf36abd74a485fb9089ee0967071886b97f541ae80c6f7b8bc7307,,,invalid input parameters, G1 point is not in the expected subgroup -0000000000000000000000000000000003b6f466571daced9c0d6dd76b5f7cc91f20d92c0fc2f051a97524aee838be57eb977af49bf020a252db1b49693892ee00000000000000000000000000000000002b99dffcb6c171f66632d0cbc9aac74e6f4823fa4690e273a5c16baef618b80d2daf81d8c6b4c5240e1c329ba91b41000000000000000000000000000000000a32e330b87bb0c2984ce443412953a879f396221cd21c2f7ae46699b02c76352d3b13759d70541fc67cdc0e65fa6d4f0000000000000000000000000000000006a134cfd54f8e524544b170a4ae0b3da02da61b56633ace68b05c511a425a0a17d3e3e155a592e6176f707100174d1f00000000000000000000000000000000132f34e6b61e7fc7764b3113a4761cde446de56d3bfadc7f285bcf11132ce8d52c656cd9cddf176755dc228277557dbc0000000000000000000000000000000019d74adf4504a87de20b5a53d4e668be279d5850dc13b1699769d2279a23903f6f789dd897c2180ed895351e4f90d7e50000000000000000000000000000000003b6f466571daced9c0d6dd76b5f7cc91f20d92c0fc2f051a97524aee838be57eb977af49bf020a252db1b49693892ee00000000000000000000000000000000002b99dffcb6c171f66632d0cbc9aac74e6f4823fa4690e273a5c16baef618b80d2daf81d8c6b4c5240e1c329ba91b4100000000000000000000000000000000025c97744f862c85507620fef6d4b90a1e37ab2d6c5ed2d794880b43bdf854ea77e87e90b5a487c56fe29e28bf7ce01100000000000000000000000000000000120515b8665151db933e51722fdac7a83d2f299623a38529508b25218f0d57aeb0c6f260e0ef3741ea1f89bc653e5d700000000000000000000000000000000019d1111f074ac541a381472a4d9dc6b76cf64e86d92018460e977460b46e17924dfa522a5bfaccbfd8bd0711950f41f6000000000000000000000000000000000433ad85586f9392cc6079c1f4f37eed99fc65da9a32206912465116f879efcf9e83d8b325433ee31235142aff89a49c,,,invalid input parameters, G2 point is not in the expected subgroup -0000000000000000000000000000000009b488e21aeb418e8913f6bf721b3398693a3875788a3e013717fbba3c6ddaafb4073378d121cc1f2f99c072b7f8eba600000000000000000000000000000000144346f013254cec17d8423f534d54e2496df08193ed65304fe300b47a68c8d322b6ad84f748529928d64298be5ac1f200000000000000000000000000000000102c92272571b73a7df754728d7293fd8050d9dd2b8605c3f7722e6de541b7fc6a81b01c1cf15e5241ee4ee1f81ab39d000000000000000000000000000000000af1cd6f23bbd3e9ef75eed6d6d99a7cdd24574881b3609e45c4adbf82e08259d14701fcc5b6338ecf52166aecca003700000000000000000000000000000000026a1a4c3eb54de2ba4509dc806db9efc7e26247d501cb59c525b8dd15d03b91abafa9ba5816c22e1f8ca159cda34bd500000000000000000000000000000000170b510ec227fe8534a2cbb0f405756491c4f6832df552bd23980ab0946725371b3c24fa8b93a38bdcd47e1026e1d2a0000000000000000000000000000000000d327350067f7401a228c4fbcc7375f2edb058505ab34341df865a82781448d8e053b478e97a3ff79458b264a0dc186a0000000000000000000000000000000014a92d6662933a9eec6134002fb0e23a0930a964bed5bf84886bc3819516af19fb8bee2c0291c518119f4f4198eb67dc00000000000000000000000000000000102c92272571b73a7df754728d7293fd8050d9dd2b8605c3f7722e6de541b7fc6a81b01c1cf15e5241ee4ee1f81ab39d000000000000000000000000000000000af1cd6f23bbd3e9ef75eed6d6d99a7cdd24574881b3609e45c4adbf82e08259d14701fcc5b6338ecf52166aecca003700000000000000000000000000000000026a1a4c3eb54de2ba4509dc806db9efc7e26247d501cb59c525b8dd15d03b91abafa9ba5816c22e1f8ca159cda34bd500000000000000000000000000000000170b510ec227fe8534a2cbb0f405756491c4f6832df552bd23980ab0946725371b3c24fa8b93a38bdcd47e1026e1d2a0,,,invalid input parameters, G1 point is not in the expected subgroup -000000000000000000000000000000001756d051ce0ee9ac0fd83b9a069086cfb62164d5131a2c7be22122cc64fe74590ab5b69e02b37a6075384df9552d1d6b0000000000000000000000000000000013826bf44ff233e612a9dc8d47cbb3aff4f1fb5abf0ffbd35f4124531bca696371357301d12ed89a2974de5027c2c59f000000000000000000000000000000000ec934504ad116a80cf15a8d9a3a0bd5db18139560adbc6de32b5871198df9ecfe122369dbce5a19eeeffffd510f403b00000000000000000000000000000000007e3f75ccfc96dbe63e7b877420bccfccf2a7a56994fcea725c1b9f1823d93b0913ba1293f32493983ebe18ae27ce6b000000000000000000000000000000000ce8b2413d344263a5e598900af1524bf863e92fc3c8a2b1f335e9029081de05c70b50b97bef75044d8083e92f99b88a000000000000000000000000000000000a47a4c7b8b35b0729b43db9785a9f15c7357815e5d1ddf02d14003923120a734a1edd931d39d9261b55c145f8c69443000000000000000000000000000000001756d051ce0ee9ac0fd83b9a069086cfb62164d5131a2c7be22122cc64fe74590ab5b69e02b37a6075384df9552d1d6b0000000000000000000000000000000013826bf44ff233e612a9dc8d47cbb3aff4f1fb5abf0ffbd35f4124531bca696371357301d12ed89a2974de5027c2c59f000000000000000000000000000000000f3f5ca684120f4b7132153ba02995e88c50ac830aa65e23978ea6be09bc838249adf113e9b463cb01fe0eee43262d5f000000000000000000000000000000001270984624e5da5aeff659f5b75d3e7e5ec655ba342e318b0643672f6e71b84916ef767c58daea149f8029bb046e548700000000000000000000000000000000064c7217b420841cff11994a5f9ba682f7df02be4c8ba2027b67d33bb51b0b956137f61ac037d5551d5ca2b880e4140c000000000000000000000000000000001813131d845fc7bd523c7a295f2738580d9b39f6198ff19112b9dd38276c3045942e74c59b4392f59de70e7cd2ee87b0,,,invalid input parameters, G2 point is not in the expected subgroup -0000000000000000000000000000000003dfcd47087531272c3fe93d82878c5a689eba15fd67534bc2fa045b1995eca650e19e020455f0b1cbe599fb27b8352d0000000000000000000000000000000014cc297621e8b9d4ac8b1ced78c53d61261e899de0077b73f4f119e6fc50d5aa10b5111640eb3390057510825a20213e000000000000000000000000000000001150494bc162c0f414d31816adb18256b7d9fc6593f89b30b76522566667dc302050acfba7106031e99bf580fad24aad0000000000000000000000000000000005c920cd2ddd5d660e3246962b466f34a28449fe1790b9312f81fa70e13c1835970d4b807352cf7d89efa093120d527a000000000000000000000000000000000d384fa4729576214cf631ac1e6e2af54176954bd63f13cf15f2cd3c1db4cde4758d260ea4ffc0606aae700bca7ca7ff000000000000000000000000000000001824caf3b35915f528dfbc82bc5d56b5f8e7ba2b02056f6e27cbdbb0a54de8d4749446f14b116ff36b9fa773808c647d0000000000000000000000000000000011d4918642919c801fff0962062a387a4dffe693ec09cd3d0286a18e3a22c84fc09e8396ca82e6054d8535cd888179230000000000000000000000000000000016a1f0c7fec5647dcce688d3e4e526749bbf23c1fcd9e9168ace47399f9198c9b3a6b8aeca68febde1b7beeea0641aa2000000000000000000000000000000001150494bc162c0f414d31816adb18256b7d9fc6593f89b30b76522566667dc302050acfba7106031e99bf580fad24aad0000000000000000000000000000000005c920cd2ddd5d660e3246962b466f34a28449fe1790b9312f81fa70e13c1835970d4b807352cf7d89efa093120d527a000000000000000000000000000000000d384fa4729576214cf631ac1e6e2af54176954bd63f13cf15f2cd3c1db4cde4758d260ea4ffc0606aae700bca7ca7ff000000000000000000000000000000001824caf3b35915f528dfbc82bc5d56b5f8e7ba2b02056f6e27cbdbb0a54de8d4749446f14b116ff36b9fa773808c647d,,,invalid input parameters, G1 point is not in the expected subgroup -00000000000000000000000000000000111650bcc4c7deaa92ef43d8355198c1c0bc402fd758933765495eaf2a6c11ea6b5b6fb4a89b00040c900fdec791c7b20000000000000000000000000000000005519640447380e96adae5042193695193484d61ce0cf26acca8c96932be68e61ad6cd23515f13f8fa4fbdd6ca5390e40000000000000000000000000000000000c6f11a5306aff663038d949d08092275c7c507f68605bf9a4b591138f578f9c454ce12176d4759e1c95f3243185b9b0000000000000000000000000000000018b28c875d620249ecc25cff0ced2b3766aa66254906c69b7157b6e418a332293723b4b268d6f9d97f566b4998997adf000000000000000000000000000000000ce5e55ebe8326ee5650122f4b39dc96fe95aa4c48d26f70580fd97be90782bebfdb2d94e784786c4188ef99ecc33f55000000000000000000000000000000000632c0e5c998679e92ad269e587e831da5dbeaff3eda614d904e11c0e4dba3c87b40101cfe2f579e8015731d0ff22ac000000000000000000000000000000000111650bcc4c7deaa92ef43d8355198c1c0bc402fd758933765495eaf2a6c11ea6b5b6fb4a89b00040c900fdec791c7b20000000000000000000000000000000005519640447380e96adae5042193695193484d61ce0cf26acca8c96932be68e61ad6cd23515f13f8fa4fbdd6ca5390e4000000000000000000000000000000001780ae947388f0e055883d231f8809eb8fcc5e30eec44cbfaf11c52d4fc14bf54480c439e805559f64bd6f2085e12f1600000000000000000000000000000000142aaed1757c6f6ed83d532333e6f8f340625864fae2e71101d1ca6787045189dcb408c433caa3a19e9220f623398aa5000000000000000000000000000000000e29f5acc8998ea0d02d72559230f119ab9f8c4a013c63baa553e6ef7f5a5d38427f5b1e82b0879201ffb5ff3e23911c0000000000000000000000000000000000b934ca967385631e767483d6279afb80ea063b624491d5d837bbe4509e1f54a90b9ccb153039fbec7716dc77e28755,,,invalid input parameters, G2 point is not in the expected subgroup -0000000000000000000000000000000018bccb5411a58583445efe99e16d0b1fbb8ec71c6c8175a73e8d289f102d6925b68374d8986bbe9353640565fe30d3200000000000000000000000000000000013036f4649ab1dddd84a12d5a3efb93f8187824211bda276cef8376ffc90f5728bdef3b5b1bcafd59fd9ecf3bf9acb76000000000000000000000000000000000a43335eb6ff3bf2daeeb1eaf44c2782eeb517e82e55203a247b7a396e26fdf85f93695753c52c68819b58c95f361820000000000000000000000000000000000c240b7896b3dd0c318dc9ffcaa001d20bff288def3ce42752d660fd705e1544e292a5a0aa3a9a80ae91cb47cb938989000000000000000000000000000000000e5195bcc4ee8b149a769322165b6a3157ee7d04546643390adc812b6296675dbd31168b268df869a6722a7c8f51c79d00000000000000000000000000000000004af7dc8a5c552f00d55b996d193a9571173ea829eba8fadfa7becc2f4149ee7c6c4d2c8c7b1970df33cc56e4506573000000000000000000000000000000000d7cf8be632d98ad21137a983fa55acd08492a9d1e9d6caaf520713a10f5cd71c9a155ce9ba65044f42228959e893556000000000000000000000000000000000ddbd265cad3a9c525a30ebab137fb1857a9847e66c3381d51de1040a48835701a1f5627281f6cb36181d8c1c337e58b000000000000000000000000000000000a43335eb6ff3bf2daeeb1eaf44c2782eeb517e82e55203a247b7a396e26fdf85f93695753c52c68819b58c95f361820000000000000000000000000000000000c240b7896b3dd0c318dc9ffcaa001d20bff288def3ce42752d660fd705e1544e292a5a0aa3a9a80ae91cb47cb938989000000000000000000000000000000000e5195bcc4ee8b149a769322165b6a3157ee7d04546643390adc812b6296675dbd31168b268df869a6722a7c8f51c79d00000000000000000000000000000000004af7dc8a5c552f00d55b996d193a9571173ea829eba8fadfa7becc2f4149ee7c6c4d2c8c7b1970df33cc56e4506573,,,invalid input parameters, G1 point is not in the expected subgroup -00000000000000000000000000000000042f294cc86c53cbc520ce6368a7149676d8bc4acf708485057c8caae31409ee1586a735c3e1f416104aede85e40a38300000000000000000000000000000000153de67ca08cdb77e92091e8f04f75d17ee5525c5ec3ccdaca907b5ebc1cfcb6ce9d6a4358999cb00ae5e824d008e7fa0000000000000000000000000000000007e00b1cd95e3f9cbb2bf80404abd9768da125c42b746c2afde0121fccfdcc2431c618d646764bc5137657d2f0fcbda3000000000000000000000000000000001170cf72d827f929cb9efef52b559f8459cdd4d60464e0b3bc6e55bb6cf83cc2e9d6314b2b80e4e4f6a3c6292d1517b50000000000000000000000000000000012a7806f98848dd9c79f74e4a25812a6fae59ca73472fd20db2ecb8f732ea59294647831e03b58c60f7a71d9892ff26700000000000000000000000000000000165e6e0a602c7a1a3334a880ee47c4c440c27cfc1ab1ea6d9df592e98d21f85519d1ddf402f48ce7dc8a87439b3f42f600000000000000000000000000000000042f294cc86c53cbc520ce6368a7149676d8bc4acf708485057c8caae31409ee1586a735c3e1f416104aede85e40a38300000000000000000000000000000000153de67ca08cdb77e92091e8f04f75d17ee5525c5ec3ccdaca907b5ebc1cfcb6ce9d6a4358999cb00ae5e824d008e7fa000000000000000000000000000000000c8373f2969862e64e7a4c319a5e4db5019391ee2fd502c86bd074de5b3a1eff7917b3517175eb28efb9aa10057df87b000000000000000000000000000000000648b6bee01e4bd215ff4b51580d254e09a9b88d879ec2a0a42b0fe80792da10a9fc4d1c47058cabddbb48e94f0df98b000000000000000000000000000000000286667f7ed2e43aa08ba81a8ae4dd0487a4d11425b1e572359783ebda7c181b7dd62857a28ae3b05302cf2773f72bc5000000000000000000000000000000000349436e7b0b86db8e77d7a4dcbeb16c541b994e6f71c45098fd198991a27b4fb48025d0808000d54fe6b9500da80db7,,,invalid input parameters, G2 point is not in the expected subgroup -000000000000000000000000000000000b09f1c099c4743404de9034dadea6120bb4b120e81d415d047d575423d8261af3aeadeca04610d4bbefcd5fbd48d7360000000000000000000000000000000019e08ce27700db908d40e8907434068819f874b79b1540a03b856ba8898be43bf7d97b17685ab54de67602b8fc41f90700000000000000000000000000000000010714e7b0316ac3ddc1836a569befe3965800dc3cd2d9ecca097f2eebfebcce7cdc92df0110e4b872a673d5a0ebbda40000000000000000000000000000000016700d8c04f159b7a019cd0f7ade116448e0657880d364f19d1f6ea099222abab3b766d3088bd9eb870cdb3eece5ee4d00000000000000000000000000000000054f6e8c85be6d914162702dbdeb82801d598e504bfec39a2edd1035f69deccb605af437fd4ecdb23979e993904edbfe00000000000000000000000000000000183e494cd0b25d5ee1e8f1ca4054fffa4d730f547e072af920c88b9d613deb21dac38043c385fc9f9bbd6e708602ae1b00000000000000000000000000000000155d3e886cce6f257513529e40c21b5657ef1ff1f4e71bc32b968db3e05652b1ac780da573fe1a1b94b7fef86e7c260f000000000000000000000000000000001184cf09544ec2826d0101d2b79095da6e5f77d453203c52ea17b6476360ccf166ef092eccf86dbe3a260f7fd25a279400000000000000000000000000000000010714e7b0316ac3ddc1836a569befe3965800dc3cd2d9ecca097f2eebfebcce7cdc92df0110e4b872a673d5a0ebbda40000000000000000000000000000000016700d8c04f159b7a019cd0f7ade116448e0657880d364f19d1f6ea099222abab3b766d3088bd9eb870cdb3eece5ee4d00000000000000000000000000000000054f6e8c85be6d914162702dbdeb82801d598e504bfec39a2edd1035f69deccb605af437fd4ecdb23979e993904edbfe00000000000000000000000000000000183e494cd0b25d5ee1e8f1ca4054fffa4d730f547e072af920c88b9d613deb21dac38043c385fc9f9bbd6e708602ae1b,,,invalid input parameters, G1 point is not in the expected subgroup -00000000000000000000000000000000065a0b9822a814adda6f22f58f0ce0d6db9b32dbb2766077b6fb9bdf084ba584dc749d746740804f826d17634509875f000000000000000000000000000000000d4284a951847bad1b602396a5d5193c3a794826f58122c9c16c6e8e18f6ec2d0e17d8ca3cda9c3bbc92c51794ec7fb600000000000000000000000000000000177f2a7306144321cec932fbc1a10d58073d6915bf9ca97a05b54fe05f525ed0c327dbdb1205b70bf7ef8cf35a61c4e400000000000000000000000000000000089dfb5d4a99380761f75a94deeb6a48854164687f1055b22328d45b9792cf884ae597db1d1a93f3f2633d14969bb260000000000000000000000000000000000b6598d4c8c590f2fbbea7c48899ff43d73087becda4974184eb3ebab605e8f90497caa2fce915f7214dfe244277a437000000000000000000000000000000000acbeeaa0ddf12bb717fd32ea32ef63d137e61b5294c162d3b67e02dcf1075838bd0208d7f8edaf15f023611b774c14a00000000000000000000000000000000065a0b9822a814adda6f22f58f0ce0d6db9b32dbb2766077b6fb9bdf084ba584dc749d746740804f826d17634509875f000000000000000000000000000000000d4284a951847bad1b602396a5d5193c3a794826f58122c9c16c6e8e18f6ec2d0e17d8ca3cda9c3bbc92c51794ec7fb6000000000000000000000000000000001a002703d6da9def84f6ce69f02ce952562a7bab2413e8d58631a3387a1f4556402fba6a39b37bda22d08a68b0230b17000000000000000000000000000000001366c2a752aad0e111adb716b75459c067e275c692bc440731510d56135c3238b410538dae3ec328bcd817384d8a6b6e0000000000000000000000000000000003321a09e7290272d75882b64d2c958d4434df3499c65fbbd1236add534db804081d29b0b34167e05f4de1d8065b5b530000000000000000000000000000000001b6e16cbfe9bd8a291dcadd4599f6edb147e261bb76caca726bc89b3fa1863922e202bd5fc9afa5bfec9923f43fb526,,,invalid input parameters, G2 point is not in the expected subgroup -0000000000000000000000000000000012e6297c3ba79bbec9a84699ee4268a37617d21e3ce984ba1134041e539f0a5f0ac11165e835ed1aba23d3b2c5f804d50000000000000000000000000000000006c8881033aa6aef80b52f0744c0c9058f6ee2d7eeba8a749ab15af41b19be8d6aae30d820ed0a0b50ce327c7baa1a2b0000000000000000000000000000000012ff0494d308d3e7321ad4c4000e9dcd19552d5e4bce8504760f066e2fb2509279b01f1568e3c3f6216bd5328cbf72db000000000000000000000000000000000038c6e8f0fab30b5c8e4323c1fd29527845c29e1a26c70b8e5284f7ca55fb55ad4ad5389b5280927b98907132f26b76000000000000000000000000000000000aef946b9b9e9fcabb36507c1cf441df2f5ccd71ef9281dafa5e25bf07d69556e4143ab402dfb38aa756bb6ee009a6890000000000000000000000000000000015f69bc7b0a6f2cb64fd0897b421e339fcc8637efced8bf33f5aed809a38b49a2e6376d18b1bff0ef70df1b7187ad04800000000000000000000000000000000019a5a9faf36413a1e48a97458b7c416a634e1ed92fbd89fbe4593f42abad0ada72f50f7a1e1a802158ccdf923b497e4000000000000000000000000000000000e0b851da6a8005b83b2afd272a6cd017bec39d9f55b3230b600c50fb9bd5cc1bd229671f6b2c7f1d78652e4534745190000000000000000000000000000000012ff0494d308d3e7321ad4c4000e9dcd19552d5e4bce8504760f066e2fb2509279b01f1568e3c3f6216bd5328cbf72db000000000000000000000000000000000038c6e8f0fab30b5c8e4323c1fd29527845c29e1a26c70b8e5284f7ca55fb55ad4ad5389b5280927b98907132f26b76000000000000000000000000000000000aef946b9b9e9fcabb36507c1cf441df2f5ccd71ef9281dafa5e25bf07d69556e4143ab402dfb38aa756bb6ee009a6890000000000000000000000000000000015f69bc7b0a6f2cb64fd0897b421e339fcc8637efced8bf33f5aed809a38b49a2e6376d18b1bff0ef70df1b7187ad048,,,invalid input parameters, G1 point is not in the expected subgroup -000000000000000000000000000000000c321b54ea1ae6e893f2c28e72a3e4bed4a9aebaf147716178d3392c959e79b6f3393d738f3722a0339c773da3ae56760000000000000000000000000000000005d2c477e1c9333eb642bb40709b042816cc54134fad935942cc08eb2db0c1582f9bf06518d4fd5577df4634332e70e50000000000000000000000000000000019123b0d9c362184620c90834730c58ec5f9becdb2f3c6c00fd157ac83c16a815efb5057011d00c774d0de626274d58a000000000000000000000000000000001936fe98ecb82299a85304213a3e30c02d90ea871661b34f664a825184c2d1ebad84d144df88c479b9526222a7fe9ead00000000000000000000000000000000081a6abf02a0a236ba6006a95a8ab3f186e72f05b00f2b686049cf980898d64a71bf2e41b6b276ed6556cf83a3247b6e0000000000000000000000000000000012162cab3a7d92acc12efec9672ecb4cb30ae208eabc77608748e968a84ec0de81678df45d1655e45a19162b06354a99000000000000000000000000000000000c321b54ea1ae6e893f2c28e72a3e4bed4a9aebaf147716178d3392c959e79b6f3393d738f3722a0339c773da3ae56760000000000000000000000000000000005d2c477e1c9333eb642bb40709b042816cc54134fad935942cc08eb2db0c1582f9bf06518d4fd5577df4634332e70e50000000000000000000000000000000008b24839939deb424bb0c7bb171064e01453008ada6e3f14fd3a86db79162d0f9a851eb6abcb7dd27f93df0f7ff3320300000000000000000000000000000000036bdf42585414a8fd616bf967ed2ad4eb2b30a7581a58691c6d58e5d54fa152b42427c98fb3094c718943d9d014730c0000000000000000000000000000000002b542c2d6e8862495b2a6937f1fefbba53c228af512918bcc5b39083125c41340f1b5f1c60696c7c07f6705dfbcae9100000000000000000000000000000000030516a5aa32954dc083531035c55aa623d5f53c07b7bcff54cb9bf04d567a293ee55b2027cdcb864b133eac0f3d5274,,,invalid input parameters, G2 point is not in the expected subgroup -00000000000000000000000000000000018a649f727e9ac88994760a97b129d3347d30174d54a1442542123a76f805e1a48e7a71f3704eaca90b3c17c538d26b000000000000000000000000000000000a5c006871d73a11d525df1921d256f880c2a3c0aea04ed27e83d5c264d3f2196c997347299fb04149c4083876bbf3d5000000000000000000000000000000000995b9bb378a7c98ed661b493ad17b3aca367cc6aa6db24fc421d82455bca4edae6c891c191023ef2113f3c7eba79662000000000000000000000000000000000213eb30b55a6ab8efdaa67c6c99362dc62022041a6ee76f7c72cc13ffaffddf88bc68ce3d4ed36d54285b177bffc1eb000000000000000000000000000000001202977411cd6674c957c74471e269ded8140f72483b5bf81846ec60be1748080e67e38c8520b0b71793f2be9d2a5b1b000000000000000000000000000000000d49d0b96d12bbb9ae56cae73bf240cac03daa2743557e6a78f029883752ba011cbe216618b28cc173a186750602eb7800000000000000000000000000000000076ed600ed860f16ec5dbae3f09471302bf85fde7702b3376b0d670f93560e77699bed969e7001570f44dc5e37aaa830000000000000000000000000000000000c993a8b08d2eb00bcee05e1c09e8a37834fac53643643402f60fbfe2cc7d795f5c68f3d6a32c8604c37211585830426000000000000000000000000000000000995b9bb378a7c98ed661b493ad17b3aca367cc6aa6db24fc421d82455bca4edae6c891c191023ef2113f3c7eba79662000000000000000000000000000000000213eb30b55a6ab8efdaa67c6c99362dc62022041a6ee76f7c72cc13ffaffddf88bc68ce3d4ed36d54285b177bffc1eb000000000000000000000000000000001202977411cd6674c957c74471e269ded8140f72483b5bf81846ec60be1748080e67e38c8520b0b71793f2be9d2a5b1b000000000000000000000000000000000d49d0b96d12bbb9ae56cae73bf240cac03daa2743557e6a78f029883752ba011cbe216618b28cc173a186750602eb78,,,invalid input parameters, G1 point is not in the expected subgroup -00000000000000000000000000000000012065f7dc3b8d6d6dded1106ecd071ac0e5f73c2aea8d088bda7687ccbb34625e2da53befb200d0885b25c228b3637a000000000000000000000000000000000d222a3c0a560f9e8a6624d9100b72e62f515f1d9384ac966d99c1761264ff8e88f308e57ddc94f156655dc310b3976e00000000000000000000000000000000109fe60cebfba62b89ae166733a097629026ccee41c95ad0260c96b772293e1403247b0451d149d527212c228ca6733a000000000000000000000000000000000a497d6c0285f7d5434c42605077528e24eee8185a615c39d2caabc570bcc01b40eadb937d78e6ceb8572115671053c8000000000000000000000000000000000f0d14ceab429a46e5568200034dba88a713899a12602529fd015e2c792191d8ef492a4d685ed09a75f638ad56f02ef10000000000000000000000000000000004d4b477fa154cd86a0934130c27f4eefed4b986da5afadf558d4fa003d2480a93b351798a24c2232e3c09c0bc33e7a400000000000000000000000000000000012065f7dc3b8d6d6dded1106ecd071ac0e5f73c2aea8d088bda7687ccbb34625e2da53befb200d0885b25c228b3637a000000000000000000000000000000000d222a3c0a560f9e8a6624d9100b72e62f515f1d9384ac966d99c1761264ff8e88f308e57ddc94f156655dc310b3976e00000000000000000000000000000000129c37bc44471eeb38b484699156862250e40df9415876f8a0da3d2f2504bd5dfe76e7b67f103a94c20751a656c5c1020000000000000000000000000000000011f24e9760017ed9120e3e0c25f57ff9e70f4f15265cf884d9d978225996f21905b32c0f918e5ac30e095767779cac8f00000000000000000000000000000000012e10463254df4bb4765a10ba47f47b6ca7ccf1ed289b8a9ccc4ee5cffde83a45077c3f093d0da6aaa5f38ebc3e5f0d0000000000000000000000000000000006755c3c202da2f65be8880e12485e2f8ea85b8e6c4b21b559e2a45b5f0977e01bba8685e4d7acb4fdc045a4cb6bba9d,,,invalid input parameters, G2 point is not in the expected subgroup -00000000000000000000000000000000182c68fe02eb491e1c0939304135485dcd2955c643ec67198d4a07075f0ec96441ffc1274e75dd36b103053660811643000000000000000000000000000000001308eb23be0860718e6ce06c2f24f9f94b7a72c557559ba8e1a9e3bc4eb4df009472adbfb26689900a65ee80b976a5c200000000000000000000000000000000030cc52d7901d0360d10f344cecc8325412788cc30a912d5de3fa9bdab18db44efea235c5d34bab526f3b8ecee2cbb8d000000000000000000000000000000000cda35f561c19ebd85a445ce8bb1618b446c7013c07606ce58e0b5627a5c9e7cb200e2b8ee12a0564730279e75b469b500000000000000000000000000000000055ad0655a96f6dab5a432e7d2fef57a6a11113070444089df23b4b911e0994b90aaaaa2c62d06756f4704fa218f7c350000000000000000000000000000000011d22438d7c162d34802a664c254abaae07659902e1f1bfc2bdffa6c17eb11bff5276474cc3cec9507e28685f1c21bb00000000000000000000000000000000005711605edddc03aee2e53b0945162616b969fc4ad2c15819df360533120dd2ded321aa929d67dbc84ecefeed531a49d0000000000000000000000000000000012adb2a59f85343c923642ea4be500595ec8c76755c0c219e5484a7a0f53a4c3f9740cf6973aab349973295791472e5900000000000000000000000000000000030cc52d7901d0360d10f344cecc8325412788cc30a912d5de3fa9bdab18db44efea235c5d34bab526f3b8ecee2cbb8d000000000000000000000000000000000cda35f561c19ebd85a445ce8bb1618b446c7013c07606ce58e0b5627a5c9e7cb200e2b8ee12a0564730279e75b469b500000000000000000000000000000000055ad0655a96f6dab5a432e7d2fef57a6a11113070444089df23b4b911e0994b90aaaaa2c62d06756f4704fa218f7c350000000000000000000000000000000011d22438d7c162d34802a664c254abaae07659902e1f1bfc2bdffa6c17eb11bff5276474cc3cec9507e28685f1c21bb0,,,invalid input parameters, G1 point is not in the expected subgroup -0000000000000000000000000000000001d70e0c28a776a0fef6d7d6a729f03d59c20a4c1f28bcb28645b996c307483837361d146b73fc808041893ac1738365000000000000000000000000000000000a68b5a13a6e5ffb88ad2618be4a197271d08e55781d21c367209c08fab2545b99f8e1e0b523854f075a915856f7483d0000000000000000000000000000000008c7569bb4e8d3b213dff2c132e5954e9622edc874dc82fcd674405cfda14dbeeb323d1605d06a92231f44339952333300000000000000000000000000000000092decf1271f8cb90a67c6cbf7eb0cca0c2d71c698470193ef495e494a8a1ac3b6bd78fa6e4367874ba18a00f6eca025000000000000000000000000000000000dfeff0f041a1868cd0ede471164f24dcac619c56515b8eec5c8aea870a79a2d03f0e1526eb1e8cbcba908969b5e952700000000000000000000000000000000109aa32bee0a83dae428e388a39ece51fd3f392ec841ffaa2554972528b7f55ca36b19ef6ae585e91995a50c0848cccf0000000000000000000000000000000001d70e0c28a776a0fef6d7d6a729f03d59c20a4c1f28bcb28645b996c307483837361d146b73fc808041893ac1738365000000000000000000000000000000000a68b5a13a6e5ffb88ad2618be4a197271d08e55781d21c367209c08fab2545b99f8e1e0b523854f075a915856f7483d00000000000000000000000000000000065860fd6efa478810b70e56ca788706bccb63191649d7b9e92941efe264bd4720b1f536d90a034b681ec9ee16f50b5c0000000000000000000000000000000014e4277fc0e4827510d55f27162d85d362f99ce57a7baf74f62567d42efd3afefb61782a6ba85d4d0e27184dc15b30ea0000000000000000000000000000000004a18f9b07e2c61210d7b00d54dd1e2895692b928adc0a4597d4ff7efbfd7215e764572275cb78f29d106aec578ed1a200000000000000000000000000000000025c5527f68d69ca8d86ffaaa3330784b9a9e32069cdc2e147c81d9a39eb181e39592a126d428e6f7963d34292f44e4c,,,invalid input parameters, G2 point is not in the expected subgroup -0000000000000000000000000000000010f18fc4c3d422a64f6c8935636cade47636934cc6c7d5077428ca6e2641068f4668a792a20c6bd4890da09de9765409000000000000000000000000000000000795df122ae83682617000aa2f80fb82cf933b2e5765fde4409249ac06d8eaf2a92938fb7bf4cc5717e4c604b68afc1f000000000000000000000000000000001825f573c335f0e3ad6ca9f721b529ab1a84585094c034058fce2f84185d99ab78e568b7cf129adb65501c266db679ff00000000000000000000000000000000114d2a8a69b83b46acc0dc3cde307b4690d2335c18b583874a0f5f6ed6b4e4ae63fb114d32479d56d3d2ce6393a128a900000000000000000000000000000000088c08b1b66f37b98e443f9d390b9934ee8edee075788a6ff9620c386f8ec4c1f6455704574b65086170c8a37f1728be000000000000000000000000000000000366a281910a6cb906b8acdb68180c6068b555c00d84b2cd3153ce5b8dc64532b3977d186202d1d6c00673b7ffe42c1a00000000000000000000000000000000067458ca402c19488e2515037abf9323ab8288e0e11f7cdee18b3da50cfa377435cfde1f63dcdc451ce65a05641cae370000000000000000000000000000000010ed9c895629bdafae66ea176388be4e4ce45cb13ecbe0869ce57f0f48852b6b8c47bcc4a14fc5327f1df372ad9f5d4a000000000000000000000000000000001825f573c335f0e3ad6ca9f721b529ab1a84585094c034058fce2f84185d99ab78e568b7cf129adb65501c266db679ff00000000000000000000000000000000114d2a8a69b83b46acc0dc3cde307b4690d2335c18b583874a0f5f6ed6b4e4ae63fb114d32479d56d3d2ce6393a128a900000000000000000000000000000000088c08b1b66f37b98e443f9d390b9934ee8edee075788a6ff9620c386f8ec4c1f6455704574b65086170c8a37f1728be000000000000000000000000000000000366a281910a6cb906b8acdb68180c6068b555c00d84b2cd3153ce5b8dc64532b3977d186202d1d6c00673b7ffe42c1a,,,invalid input parameters, G1 point is not in the expected subgroup -0000000000000000000000000000000018339c70bcf5f8cbf7f3d67dcc7b40a937045b53243d6bcd417d467b1a264b960793171fda821c4206d10b4fe8488e170000000000000000000000000000000017907a4fd66b2a8b113352975ed70c0833a6fb51568ada67bf9f8cdc770e30a3a5fa305200691f4e8dbf210cbefeb002000000000000000000000000000000000b46ea3a7acd5615741210a761f7ef55e7381f52593f02e20aedc0753861acfabb5333dc5bfd829656511070b642e7fb0000000000000000000000000000000000989e2bbad608bc55d0749e0de844e001934d28a58178377d8607a1c5d5c85eb346ab94bd527b36b965626457f6aa300000000000000000000000000000000016ffa6209c14e0803789f94886e96bfbab47e07ef745557f1d1dd48e887086424cac57dd9a624de73bb7f3521de3fbe2000000000000000000000000000000000fac98b30fb441d9426f61bcdbb149b103fa9ec3b85cbd5f755d57474bbeebe796b96fac0ba1d4b75897dea8e54796970000000000000000000000000000000018339c70bcf5f8cbf7f3d67dcc7b40a937045b53243d6bcd417d467b1a264b960793171fda821c4206d10b4fe8488e170000000000000000000000000000000017907a4fd66b2a8b113352975ed70c0833a6fb51568ada67bf9f8cdc770e30a3a5fa305200691f4e8dbf210cbefeb002000000000000000000000000000000000b349ddaccbdd1381d9eb4ae7e65db31733fe3c24f38c21f5a20298bd8e01db7ebbe3c703327a5f81c89c040a5e17c67000000000000000000000000000000000dbadd08c77f8c210439d48fb55c741dc83aa9adbe7153bee1ddf1d3df824938c14d85a528c285db28df1d0fb22b8e820000000000000000000000000000000014d76b082d032e23130d6e55c0560080a5aa607f6cdfcd683d4e2450aa0788a99a005ccbdefdb3f626a045fd7cb9ed6400000000000000000000000000000000124130e29fb52ffc0d8e8ec760619de7397813b8ce598afe97f9076899f13dbe35417a6f94a2c4bc0341c933ab8c30b1,,,invalid input parameters, G2 point is not in the expected subgroup -000000000000000000000000000000001977147ab98c2e88f46f038c821e85fdf476bfe7bf7b7fd633ecfcf1fd2ef339b3b5cc686f4a8937e16dfa29ad8123f7000000000000000000000000000000000ef669778c61c21dbd4681483c51269a74a3ba1b1f75796b4680f0e30a286aa0173147b206f91c84731ec8ead074d187000000000000000000000000000000000e0f7595e4c136b4d8bbd1eeb021df7dd2bcf1d9f98e4fa293f7edab635e019af87c138275fefacd806213177af40eca0000000000000000000000000000000005dc209d6c86f1871637998c10490a70371f9e00a68d1363dfaeb62046473dfb4bbd3b18b943439f75c45a1ee7f264a90000000000000000000000000000000003d215567d1e8f504a72658d48fa51374ac77234552c17db4033af780133d8516bb0769678ecb50b8b9eb950c2dd73e80000000000000000000000000000000004d780849b731012e1e5732d5f6d32c659a95c3e1c8f5ef4841fe82afc6f0aa309b1e02dc2554a4a4ee781be2be2149f000000000000000000000000000000000073439cedc08916d00609c6152ee2844be85550ff5c199e9e9dddf09bedfc00d907dc85255651cff3e28a74d3b4836c000000000000000000000000000000000e57e74af4f2d6c08843152cce6d095d00679998463bfb41bef9c57ba427e14715e9e0da0e8c5193a798cf92590b34b4000000000000000000000000000000000e0f7595e4c136b4d8bbd1eeb021df7dd2bcf1d9f98e4fa293f7edab635e019af87c138275fefacd806213177af40eca0000000000000000000000000000000005dc209d6c86f1871637998c10490a70371f9e00a68d1363dfaeb62046473dfb4bbd3b18b943439f75c45a1ee7f264a90000000000000000000000000000000003d215567d1e8f504a72658d48fa51374ac77234552c17db4033af780133d8516bb0769678ecb50b8b9eb950c2dd73e80000000000000000000000000000000004d780849b731012e1e5732d5f6d32c659a95c3e1c8f5ef4841fe82afc6f0aa309b1e02dc2554a4a4ee781be2be2149f,,,invalid input parameters, G1 point is not in the expected subgroup -0000000000000000000000000000000005585544fc7ed448c7939c42235549edc98c5d9a793ec918274b49687e8b9267d53c2e5d66a44d889e8f2e94abab43490000000000000000000000000000000002a091dc69d5af394d408a3b5b60debffddac4db228c613b2e2f98b932aa8f90d9f5a77129fc0fe69b93ca64b0081eb9000000000000000000000000000000000f694959a69b0d692e167e95524555d58d06621d77f46c54b7f0da0a45c4cabdc8ac916b0f2052cb99b6f0f5bca36fd9000000000000000000000000000000000df814c1cf62a7a089984a3afe3f7636157ee17bbe0dde1aa2e56fe7168a3fee7c6102999dfd55b282f1a6a4ca0e0cda0000000000000000000000000000000002ce0806a288c2b9d7e03204f573b06c440be782469cf7f1478f53d5b017fa9ea3b1025cc5de378e2186c150cbd1bc0f0000000000000000000000000000000007d3c1d2c5806e73119cafe9efda5a8419679c89d17f7a90fa6302485d4efe9e44b287f573d576d7f45589c7501e40ff0000000000000000000000000000000005585544fc7ed448c7939c42235549edc98c5d9a793ec918274b49687e8b9267d53c2e5d66a44d889e8f2e94abab43490000000000000000000000000000000002a091dc69d5af394d408a3b5b60debffddac4db228c613b2e2f98b932aa8f90d9f5a77129fc0fe69b93ca64b0081eb900000000000000000000000000000000199d1db3ab960c003575ba7a53f489159aa2005bc9a30bc23e952b57ac892a2340a8adbe21eb07bcbac255be231c49120000000000000000000000000000000014303bc0d1c9748ebbbc187486650cd7651e51ebeb1bb428e153ca5e83fc4b118c7575efc03ac0ba500c6149f91db23f000000000000000000000000000000000b6383243f6914d41d2947ee74ccd299a20741e33bdad3aff2d05de662fb4d7b9b9266085bb71dee8c13dfbb121cdd320000000000000000000000000000000005d515210d948c48ee9f7ced4c23a5eb12c6bc26c974d518af4e14c1b2b2c5a286c2bc4d51ff5974eb939b4395f9d8ed,,,invalid input parameters, G2 point is not in the expected subgroup -000000000000000000000000000000000ba91d035c7a2da7e14c400bb137b66a4d8f563004bcf57a01f21223225b93f860eaab9c429b915a130115c8f61c606b00000000000000000000000000000000196c7f0f6b99772d1a5e97afd92a6ab4916a2f2df709bf6393a60fe29623b25dbdc989f22715fda427bf8cb84cdfd033000000000000000000000000000000000b362ce289c7edfb507b579fc8d344c5e7bfa8d58bf3629a41af7ec1faecfb9b95139d9a8159804691047e4b18bc1cd600000000000000000000000000000000112bac785b4033f11b08e845c8c5ce78e40138b0cc0b998dd8e0213bbfe0e5b96a83ff2b53ee9699b18efffdf879602a00000000000000000000000000000000157885a39334664681d8425bd60e9c1d12dd1ef45b9a3c40956df105cd3534ff9378203755119ed302a54adba9e5858d0000000000000000000000000000000008237a9ffe95f89a24e1e3a82d8f127766e2173505a9ef0e715b1ec711619664a12d86d247e530049ee542ee4d20cc7000000000000000000000000000000000072c644635936a91dcaee40e3b4794e634c315a39a9cb5cb99ef6784b332fdcfaafdc80e228cd19d0104d5796f584c350000000000000000000000000000000002318bea9077484e9c1937dfa63774b5ecf6fc63ff06e5cb653553d5111a981c09c907069ffe11b5704ea60a99873283000000000000000000000000000000000b362ce289c7edfb507b579fc8d344c5e7bfa8d58bf3629a41af7ec1faecfb9b95139d9a8159804691047e4b18bc1cd600000000000000000000000000000000112bac785b4033f11b08e845c8c5ce78e40138b0cc0b998dd8e0213bbfe0e5b96a83ff2b53ee9699b18efffdf879602a00000000000000000000000000000000157885a39334664681d8425bd60e9c1d12dd1ef45b9a3c40956df105cd3534ff9378203755119ed302a54adba9e5858d0000000000000000000000000000000008237a9ffe95f89a24e1e3a82d8f127766e2173505a9ef0e715b1ec711619664a12d86d247e530049ee542ee4d20cc70,,,invalid input parameters, G1 point is not in the expected subgroup -00000000000000000000000000000000077dfb9ac791b3471c6cbcb0b37b65adb0bc4e40341b85c13867bfdaf32365ddfb749ebfd965abfa22996773eab505540000000000000000000000000000000015e771a0f0149cfad7910a4a1971b39323948bc7530936db5d99a53b51bd656bdce093cc2b91ebad0f91a95034afa0e3000000000000000000000000000000000200775a5848ac14b5e762ae7d4b492d2dc0bd5e80ef7fc760d42ea6fb07ffd2944409052cfb773875df676a188da65b00000000000000000000000000000000140ec7de210c890e4c795eed394d32d77f6acad0a3628da2ec805d4cf2de9822b5a73f06bdbeeba0fc1068c26da675b20000000000000000000000000000000018e7877a3f27c5400b08bd2769616745e4657f6fe262f9d7b88330917f977efa463b3226f3433da95a82568d990b1fa50000000000000000000000000000000015801af4934193336cc67fe8f4be5d2093909006f8bdd3382d60fd5c6bce4b86071370eefbce7a04dbcfb825858f90eb00000000000000000000000000000000077dfb9ac791b3471c6cbcb0b37b65adb0bc4e40341b85c13867bfdaf32365ddfb749ebfd965abfa22996773eab505540000000000000000000000000000000015e771a0f0149cfad7910a4a1971b39323948bc7530936db5d99a53b51bd656bdce093cc2b91ebad0f91a95034afa0e30000000000000000000000000000000017bbbfef68883fbf6fa9cdcef37ef145d7fbe9532164530e9c08d196ee41f38784b257087ad53f4939426451fb5f955c0000000000000000000000000000000018bb97090375c21600b6d3ee0629cff78116aa59d7b665c08590add8cdff8247c38b588a25e0b11eee5111c63f8c619e000000000000000000000000000000000e181f7327776df8ec16258115303029c68e1b72fcad6395c6d7d477368e1697076333a2102447a225fb3f3d725b3b0b000000000000000000000000000000000291d82b95e9a2c3f766994c304dae7f19f1efc789f68c4e58eda102da36cd0d7eec3d5a1b1e88c63462c8ec0e4393a4,,,invalid input parameters, G2 point is not in the expected subgroup -00000000000000000000000000000000121a9b867c86195dc4aee07081c1ad62f066b471bb5a14f296943b263fb9a25e6805e3171624e7e7e45b78f175a1861300000000000000000000000000000000071e1c35979d6f43170e79c0db5cceccff01f17cc2980b771a6cc38e0b27438a9db8e00eb943142d992c6a395fe4aacc000000000000000000000000000000001819d13cf4522a9362bbeb0bbbb0a498c3f34da1c9e3b2c54d08f7c8acd9ee756983fe80405579effb79d673407390ef000000000000000000000000000000000f870e5978f4a6e3b655fb2a05541ac0673e7b10136adaf28be4dfc9022d4cc8a60e17d125dfe53fbe10c644ff37e02a0000000000000000000000000000000010207ef774cddd10db2bca0a051ceb12900c407ee265dea4615553c193d7475b5ba3198b7e0160740e4fd015dca33e1d0000000000000000000000000000000017937be546e06fd2eab4c969a029534c02fb770646d43edeb5e6c8bc0c2b5f35576c375bf860fd1087ce099d4377d24e0000000000000000000000000000000001a8b8cdcd160565a1df9cb5ccb06a62fbaf32b2cac4ec9a552773313c940688638775983815cb246d4eaafe91c3451100000000000000000000000000000000082a1237c161831a37589ff711f7873d5e092d8a4690b983c9ccbbf980422ed177a3ebbd4b4ae4b557bcb3ae532f1823000000000000000000000000000000001819d13cf4522a9362bbeb0bbbb0a498c3f34da1c9e3b2c54d08f7c8acd9ee756983fe80405579effb79d673407390ef000000000000000000000000000000000f870e5978f4a6e3b655fb2a05541ac0673e7b10136adaf28be4dfc9022d4cc8a60e17d125dfe53fbe10c644ff37e02a0000000000000000000000000000000010207ef774cddd10db2bca0a051ceb12900c407ee265dea4615553c193d7475b5ba3198b7e0160740e4fd015dca33e1d0000000000000000000000000000000017937be546e06fd2eab4c969a029534c02fb770646d43edeb5e6c8bc0c2b5f35576c375bf860fd1087ce099d4377d24e,,,invalid input parameters, G1 point is not in the expected subgroup -000000000000000000000000000000000a86f90fcd9b63a0cd5f53356c170699d78d03f180d59c38ff770560bda30bf412fdcf236b6720d94684ef1aab97bafc00000000000000000000000000000000030bcbb272ab20a2f27d45295875e3c29a8ad088bb8173feb6f6f4d2c81bbc91d673c23239e36bdafada8c7d50b54b440000000000000000000000000000000011e01c96294c726ed3ef22a5c6597d8202604c4fb14058bf44fa64ae6d342f6f77f151c8ecd99f793e79f0ad29c309f40000000000000000000000000000000000e186664d8c2a2e136ff1be2192573b94c083bf242b2c01c984a792e43a11a10599481a9a79f6a8d5b074bc16019725000000000000000000000000000000000fc48ade56f841489c4824411130fb5b7e0e83b613fa09099f318cef207ce035d5d6e7ecff5057c15ee764ec8a7fa20300000000000000000000000000000000003f1b261043887af57fab48b505ed7aa44132457d71a390646b70fcd073e677a7e275a89dd0a2bf32beae3b2bcbd6e9000000000000000000000000000000000a86f90fcd9b63a0cd5f53356c170699d78d03f180d59c38ff770560bda30bf412fdcf236b6720d94684ef1aab97bafc00000000000000000000000000000000030bcbb272ab20a2f27d45295875e3c29a8ad088bb8173feb6f6f4d2c81bbc91d673c23239e36bdafada8c7d50b54b44000000000000000000000000000000000781404020a416e2596ab361e02674e25cfb365420d35d5db7146f563a7675a942383da44ae4df49c45b38e371c82a2a0000000000000000000000000000000010c546bda090a13ccf0fec03bdcb87b41f5aed3b4e6740690afb9dadc57d773aae2d22a2d8323336c5b1dc5798725495000000000000000000000000000000000bea6aaaadbbe8102212279f1458c461d3a0d54e341c91b5e16e0ce5ba1517a13cd1d43e1d0b25a63b7cc57ece5369f3000000000000000000000000000000000b0b676e5cc2f6ac383f5dd42d379c552579f601de0cf4f34ac637383a31e393df40f5c0f95b5a8f57cd6fa4de01caeb,,,invalid input parameters, G2 point is not in the expected subgroup -0000000000000000000000000000000014372fb746da15863e9ee4e06099c7e513bdbe53ca772a4b61c81eaa7f841399422f7902893d5ee7f7d59d530e3674b10000000000000000000000000000000006ba991efa65ef8dfac8b07915cab83b5267babba1291e4662a81fdcb455faf33596f6730b6f5b3eac2076054a4ccf6600000000000000000000000000000000042ee88071289a2adeb69cbab5a3ac8c7935576bc434062091cdf1cada4b67a2501c179b5980b53256f623840a5aee5700000000000000000000000000000000063b0819dd470047a704f20f5f7c65ea0899f25603dfc7e8b8d5f0d0d323180aa921e43d63b45acc8fe9054326a8d9bb000000000000000000000000000000000615e2e5b0389017cd3ce7c15740caf3b897fbe4a59c68247c3c4229bf661257f56bcc10f55fc722f96424f5617d259700000000000000000000000000000000166f7cadf7cb9ac5a8cfa83fe4aaac0e32fd4de3e38e0d39e010d50f5b3d383243d6870505f2a285b7c5f6fc1b13f0f0000000000000000000000000000000000d1ed017ef4702bcd3bfbbcff36000af6a1d26ab363e68ea5629027e0b90352bf1d8e03c13a7955da6c15507cc1c9f47000000000000000000000000000000000e09830e54fe9eddd416479a1740f6f1b7693f2d153d322f27779b16bb6451d7657df85a55da75a4aee0a2e33b3a46e600000000000000000000000000000000042ee88071289a2adeb69cbab5a3ac8c7935576bc434062091cdf1cada4b67a2501c179b5980b53256f623840a5aee5700000000000000000000000000000000063b0819dd470047a704f20f5f7c65ea0899f25603dfc7e8b8d5f0d0d323180aa921e43d63b45acc8fe9054326a8d9bb000000000000000000000000000000000615e2e5b0389017cd3ce7c15740caf3b897fbe4a59c68247c3c4229bf661257f56bcc10f55fc722f96424f5617d259700000000000000000000000000000000166f7cadf7cb9ac5a8cfa83fe4aaac0e32fd4de3e38e0d39e010d50f5b3d383243d6870505f2a285b7c5f6fc1b13f0f0,,,invalid input parameters, G1 point is not in the expected subgroup -0000000000000000000000000000000009f0c6f9fac38e8c83183499b8918a1ffbc52f2400882edb66594f496ff38ffec77368f28e4f20767257e200f48255700000000000000000000000000000000002a05bfde9523ac13ba3518cd5b308c4985484f996e7192140d681d9934d501111a81445031d84d4a47a9727202c07620000000000000000000000000000000003004acd2a95d932b84233e80bebb9fd92b302809725d5ca0921a5d8983950ff521d89bcc2d1bc1e7c186c702bf7aa270000000000000000000000000000000011744ffc7092744a79e345be8b51569c5df8eb10b4e49957ade8df4ee4ede566b3825eec89027d70d188ff858a8b6cf4000000000000000000000000000000000e46cd26b21a8a933eac05ed526a2b8fe195e5a5435e79c7f385fb69a90190acd06e25e9b63af7862616c79add032597000000000000000000000000000000000ad60c22b3690c78c23682ba902a18e708e88430a55a9038975a43b4606ef4c6e2b8e648a25097b3a34bf6e4024d00280000000000000000000000000000000009f0c6f9fac38e8c83183499b8918a1ffbc52f2400882edb66594f496ff38ffec77368f28e4f20767257e200f48255700000000000000000000000000000000002a05bfde9523ac13ba3518cd5b308c4985484f996e7192140d681d9934d501111a81445031d84d4a47a9727202c07620000000000000000000000000000000007d87d13752c52bf0510cee94274f6f4a6e0675de9a4a864ba5058dd8771b6c5000e957cfca5279e64f09c21111322ec0000000000000000000000000000000007999819b5b57104c9432a9d4dc6ad377f0c6f0dd630155fc489aed1f8d18ce0386222813726cb786635778b74967bce0000000000000000000000000000000016b66e0ebcbf6043f6a7fe52bf527a9b763cd68d901933068966e6dbb9817e1287ebc2de9c3729df8b4228a4f92d9732000000000000000000000000000000000ee19b863d5ce19afce76e489e122948597ac6a5ee07e2d856a49377285ac93d6674cc5429e02bbd051d4edf7988ba89,,,invalid input parameters, G2 point is not in the expected subgroup -000000000000000000000000000000001269c2717ba196d5004865af806d4a99b8c238583db14f9c02da70b0275cf35a3a5276eec0c8e6934f11e0d5cc8b7c9f0000000000000000000000000000000017971814f15aaf3f6672b3a720cf6726aa042dbd82ac508a8f7ac5ddf17f377891199ba2fd01d990868347d45e3b37ae0000000000000000000000000000000001587e32753adc85c98cf1322115772b0e282ef4e6a75944fc86091e81aad076508e3d727f4df0e30924fff6b67c312e000000000000000000000000000000000ae96d3a1b79985e56f80df8ac4d9792229ca580b156dbbe71a9db470447fa4dfa19fc8a8a2e2f0fae28a24b7d6153d100000000000000000000000000000000114101ad0d29ddfd2fc436d2a270711c444c8c257785f4b4c549e9c795f6dd9834d3744995d2188c0c968752a7f68892000000000000000000000000000000000d30d9cc1e2273af745dd47a596a2202ca4fb655f9f9beeb0a87631e2461f29206163fd921761fde69654cb02e23505c0000000000000000000000000000000010cda048fed479f7bcd388a0acaa977b134055f5ea92b2a689793e301d58190c67031920ccf1cd97ecf9f429f5a022e00000000000000000000000000000000014c410faae20d54049aa7c644ec1ef0388367ac847f6781e62ec88eb9262ffff5f19cf5f4ebe791a44ad9a84fd78aca70000000000000000000000000000000001587e32753adc85c98cf1322115772b0e282ef4e6a75944fc86091e81aad076508e3d727f4df0e30924fff6b67c312e000000000000000000000000000000000ae96d3a1b79985e56f80df8ac4d9792229ca580b156dbbe71a9db470447fa4dfa19fc8a8a2e2f0fae28a24b7d6153d100000000000000000000000000000000114101ad0d29ddfd2fc436d2a270711c444c8c257785f4b4c549e9c795f6dd9834d3744995d2188c0c968752a7f68892000000000000000000000000000000000d30d9cc1e2273af745dd47a596a2202ca4fb655f9f9beeb0a87631e2461f29206163fd921761fde69654cb02e23505c,,,invalid input parameters, G1 point is not in the expected subgroup -000000000000000000000000000000001252aaecb588ffcdee3e4fd92ff5164feaf9aa39acbc71c704d8180611d30fe13e59bba805101dc1cecf77b254bc65510000000000000000000000000000000009dc3de2e8aa94dbcc25c8775e9bd0ae0fa8581df790e562e67f24c08efaab59a0a8062478a09c262040c5f0558971c3000000000000000000000000000000000b0a6f9e0b58db3015e1dc63f9d377895d25f48e8a05371ad90c3ef5f3085a76b888d38693eefdf3b1eedf80eab1736200000000000000000000000000000000006dfb36e1c281cf1c5a8be9a631cab94aa956bacf8e9e787c0e2bab4440f03f0efc56d5a058fde2e18696c569676d3b00000000000000000000000000000000118791bba7507725b7106bc889b68c3daa56dc3100d8378cf156268f249dbafd01025cb722d58246c95ac856dd5d0411000000000000000000000000000000000f942ab8fd1e71f6d4498403116ef41954e7967222f894b93ae31f061cafaa1ed3464520dc5123aad4b0a352a85efbf8000000000000000000000000000000001252aaecb588ffcdee3e4fd92ff5164feaf9aa39acbc71c704d8180611d30fe13e59bba805101dc1cecf77b254bc65510000000000000000000000000000000009dc3de2e8aa94dbcc25c8775e9bd0ae0fa8581df790e562e67f24c08efaab59a0a8062478a09c262040c5f0558971c3000000000000000000000000000000000c13d99118e4946773d0ae54a37895411e39ba0de604c5f69d0b3ddcd50c4261c38c510bc1e018dbdf449e303e398d820000000000000000000000000000000018427393a7ed2dee713e83e58a6537c5c6baeb69ceac3b574e02af78215d99b8cd01f0c944d075300d35176099b0aa8100000000000000000000000000000000140ab2527b79327e07344a673e688debec28aa29219a5b1646a3c2b599a9d374cf5e139ab00aa237bb8e29d021d766ea0000000000000000000000000000000017164f154d26566ecc983d38d77d694208864c024c3ffc69f19f84550e86eddd8dbb055a8cf543717ce3d65e1c64c53a,,,invalid input parameters, G2 point is not in the expected subgroup +000000000000000000000000000000000ded5634c6bab9610e70f3a9be2bb39c51f2ddd762d22d6c3f0961af19350c4ca4bae333bf4cf586d8cd1e0a0a6c674e0000000000000000000000000000000012309fe1d843245e2cb58d419ff06ed8e93ec901c01d0c5be453e11d10f930afa0c35428ef0c8dc13ce99c990af166630000000000000000000000000000000017c9fcf0504e62d3553b2f089b64574150aa5117bd3d2e89a8c1ed59bb7f70fb83215975ef31976e757abf60a75a1d9f0000000000000000000000000000000008f5a53d704298fe0cfc955e020442874fe87d5c729c7126abbdcbed355eef6c8f07277bee6d49d56c4ebaf334848624000000000000000000000000000000001302dcc50c6ce4c28086f8e1b43f9f65543cf598be440123816765ab6bc93f62bceda80045fbcad8598d4f32d03ee8fa000000000000000000000000000000000bbb4eb37628d60b035a3e0c45c0ea8c4abef5a6ddc5625e0560097ef9caab208221062e81cd77ef72162923a1906a400000000000000000000000000000000012196c5a43d69224d8713389285f26b98f86ee910ab3dd668e413738282003cc5b7357af9a7af54bb713d62255e80f560000000000000000000000000000000006ba8102bfbeea4416b710c73e8cce3032c31c6269c44906f8ac4f7874ce99fb17559992486528963884ce429a992fee0000000000000000000000000000000017c9fcf0504e62d3553b2f089b64574150aa5117bd3d2e89a8c1ed59bb7f70fb83215975ef31976e757abf60a75a1d9f0000000000000000000000000000000008f5a53d704298fe0cfc955e020442874fe87d5c729c7126abbdcbed355eef6c8f07277bee6d49d56c4ebaf334848624000000000000000000000000000000001302dcc50c6ce4c28086f8e1b43f9f65543cf598be440123816765ab6bc93f62bceda80045fbcad8598d4f32d03ee8fa000000000000000000000000000000000bbb4eb37628d60b035a3e0c45c0ea8c4abef5a6ddc5625e0560097ef9caab208221062e81cd77ef72162923a1906a40,,,invalid point: subgroup check failed +0000000000000000000000000000000014881e90a100e5c1e07588d68c69b9b217d2c57b2bd8782ea7579abfac3a38275677a8dee7e689c1b185712ea38bf0ba00000000000000000000000000000000061e48ceb68db1cb84ed39f9772f937922198b47082d7517c8258e46a490fc20e4e01971711853ab653d064f8adc79e200000000000000000000000000000000173518c27d76414f3027ed3e4936ad1b6aaebf0a98462df3e3a55aa38e19fb121acc6eeadb7689c84fec18580b63784c0000000000000000000000000000000007c116829ccc1d5505dcce029f5c8b7c8a9cbc9dd562a874766a5654483aec977a0fb9e611f9471d2f0c91fd6534892f000000000000000000000000000000001560b267e66200e69d6298250456d88500a0d79ea69870358a6cb39609fb6596e539b28bfea9d1c7054b5b51a4c0f3950000000000000000000000000000000000cc196f93e5a2dd3a41a1ba23fd2e53bf376c910117e9216663e30091b96c897080bca189ce3107720dac1c54dc4fc70000000000000000000000000000000014881e90a100e5c1e07588d68c69b9b217d2c57b2bd8782ea7579abfac3a38275677a8dee7e689c1b185712ea38bf0ba00000000000000000000000000000000061e48ceb68db1cb84ed39f9772f937922198b47082d7517c8258e46a490fc20e4e01971711853ab653d064f8adc79e20000000000000000000000000000000015237996817e97b29ef5b4ee49e6aea7129bdc4a46707f99df3ab8af36eb4123e93496d94846f7807b3bd2c87d3ca039000000000000000000000000000000000df666f7728483689a746e5b39f4848a9f2d831cb17d4e5f7fb67de5d497f6399de5f37ba9e6ab76937e26450000d600000000000000000000000000000000000e4ffecf86b371ddc9ee6a72b5ada74790b590acc51c6c5c479c43c532a9507b4b4909bdc901b00932371a109fd38b7e000000000000000000000000000000000354f92ccabccc9390072671ccc8d3ea0a0c44f85816f20bd6e8b485e648e8ba0d5b845a8835395ce65b8101015ea83f,,,invalid point: subgroup check failed +00000000000000000000000000000000199fa649608972d295befae38d36940663d2b67bb286a3d549c75deef39ef8068728bbba2cafac44c102499601e4bd860000000000000000000000000000000002dac960f96822774a4956fc0ba97a235d0a2c10d81d9adf7b88215250c934b68c3de07a97adcaee2aaad0d3d84ecf6800000000000000000000000000000000000eb3c91515d4a41209a73564741a8ccf901a624df9db22e195a5d02d24b7bc0a12756b15b8d006cb991a7e088eaef1000000000000000000000000000000000704ce8afc808b0161f6f61b22d990d713ae398779e6e74e9b5771daf006ce0bba3a8088edf75156f0e48b92ee8409b00000000000000000000000000000000018fe81e05aff0620f4bdbe4a715e015650497afab62921eba0ab86b649e5a2fd3d54041868928519f537e36448688a0d00000000000000000000000000000000162bd97161201ea3c26f8dd1204a9c6b61b762bdf573cb5d20b6b255f30208ca7d96aa47b46fb8c6bf0922075f1c1ca8000000000000000000000000000000000d5bb4fa8b494c0adf4b695477d4a05f0ce48f7f971ef53952f685e9fb69dc8db1603e4a58292ddab7129bb5911d6cea0000000000000000000000000000000004a568c556641f0e0a2f44124b77ba70e4e560d7e030f1a21eff41eeec0d3c437b43488c535cdabf19a70acc777bacca00000000000000000000000000000000000eb3c91515d4a41209a73564741a8ccf901a624df9db22e195a5d02d24b7bc0a12756b15b8d006cb991a7e088eaef1000000000000000000000000000000000704ce8afc808b0161f6f61b22d990d713ae398779e6e74e9b5771daf006ce0bba3a8088edf75156f0e48b92ee8409b00000000000000000000000000000000018fe81e05aff0620f4bdbe4a715e015650497afab62921eba0ab86b649e5a2fd3d54041868928519f537e36448688a0d00000000000000000000000000000000162bd97161201ea3c26f8dd1204a9c6b61b762bdf573cb5d20b6b255f30208ca7d96aa47b46fb8c6bf0922075f1c1ca8,,,invalid point: subgroup check failed +0000000000000000000000000000000009d928f478fea86b1e3c1ebf59b230af42e4a539dd43ff17b9ca250605401273edc42806bf2cb887c6093729238fc0560000000000000000000000000000000005b6040ce6d0802719af5b9c0fe48366c5a97bcad2c6ec25f64cd73f39dc73a22d0084c69f2e86637c584d2de55d6064000000000000000000000000000000000aaeceb367eaf2ab8afb5070b5f5611f19fed17e16f6b01cd20f5f1a7e550d4689c89d6490878877c46492e8fbc9db600000000000000000000000000000000019dc59fbefa7abf12f1aa92e420f52595a06e819e974c07b62a3ae459c62545922016abd8e91301aca8f48ed793b91af0000000000000000000000000000000012f5352825a95ff0a0f0948b150e5eb1ab53d6591dc54ca8b37941fa94a0fa68af8c35aaa26c73951d2dd52e9c7a55bf000000000000000000000000000000000531e610f3706a1c67b31909a97232acef0e23c35c657dc82d9508fcf33bfff777386dc8265accb52d0da207957d25160000000000000000000000000000000009d928f478fea86b1e3c1ebf59b230af42e4a539dd43ff17b9ca250605401273edc42806bf2cb887c6093729238fc0560000000000000000000000000000000005b6040ce6d0802719af5b9c0fe48366c5a97bcad2c6ec25f64cd73f39dc73a22d0084c69f2e86637c584d2de55d6064000000000000000000000000000000000cf95f6bc3f14cc8a657da35f212d55d3633ca0d224794ac1e49cbf1e1db7757dac2bb08880f7b13f2ac0c2b95ff483c00000000000000000000000000000000115bf27014a31726503f0665301f9e183de41e002db568916aaaeaa4c8046475860db3b993b2ac2af58b12614f0b9f2d000000000000000000000000000000000983ee62076e9c5f8e6ac3ba8e5f98823a37ff20432f0b4e7d9e008660965f551bb5538e6ba28541ad514e87d128da1b0000000000000000000000000000000019c9930e3e009986608463c80aa0049fcac5e897474e519b52c80960f1dada5a48332d810f1f9a34ee479383b5b556b3,,,invalid point: subgroup check failed +000000000000000000000000000000000f240a4daf7acbe8f4c5a9cb40ccc6d99dd712b8dae4c13e9d3839b0c88c5eef6f050144a4b731267e2132a81b1a635c000000000000000000000000000000001931c93a957ba9005fa69004c7e984b9dc86f45ec03eeed77addb3e1bee3c2424105df8e8faacae2b07623cd3cc7261e000000000000000000000000000000000805892f21889cab3cfe62226eaff6a8d3586d4396692b379efc7e90b0eaad4c9afbdf0f56b30f0c07ae0bc4013343b30000000000000000000000000000000007853f0e75c8dee034c2444299da58c98f22de367a90550dbc635fb52c9a8f61ccc100f70f10208944e48d09507fdce100000000000000000000000000000000064afd6b3ef7ff7ec34f1fa330877b42958a46a7698c6d21adf73bfdfcab7793b312e21e5988652e655f2d42edb8a673000000000000000000000000000000000ea8a2217c3dbcc0f6e562de9cb2f334c896577d0b3a7108d96b1aba2d705dbf531e870d4023cec2c0533455013242330000000000000000000000000000000019c822a4d44ac22f6fbaef356c37ceff93c1d6933e8c8f3b55784cfe62e5705930be48607c3f7a4a2ca146945cad6242000000000000000000000000000000000353d6521a17474856ad69582ce225f27d60f5a8319bea8cefded2c3f6b862d76fe633c77ed8ccdf99d2b10430253fc8000000000000000000000000000000000805892f21889cab3cfe62226eaff6a8d3586d4396692b379efc7e90b0eaad4c9afbdf0f56b30f0c07ae0bc4013343b30000000000000000000000000000000007853f0e75c8dee034c2444299da58c98f22de367a90550dbc635fb52c9a8f61ccc100f70f10208944e48d09507fdce100000000000000000000000000000000064afd6b3ef7ff7ec34f1fa330877b42958a46a7698c6d21adf73bfdfcab7793b312e21e5988652e655f2d42edb8a673000000000000000000000000000000000ea8a2217c3dbcc0f6e562de9cb2f334c896577d0b3a7108d96b1aba2d705dbf531e870d4023cec2c053345501324233,,,invalid point: subgroup check failed +0000000000000000000000000000000012d75b62dd32798ea12b99f51a496bbf61bca93cd233dd288e00259893dbe7c73b6342860d41fd86878a6de608dba0ed00000000000000000000000000000000018e963e1cdb31ce3f636091952c17ab4c03c0f55940196b5772002850c6c86a3da13a9a5fbfaa8256fb0a9c4139bfc60000000000000000000000000000000018330d288ddc1786744f95c4b3bacbdfd10ab560fc283c1ecde1bcbdc53cb284198f340241242763c77b4cd3b8c729200000000000000000000000000000000019a3d86d9b3ff0b03da1686c3234bb2b8109ab12ffd7599ef9e3489fcee40e50036dd952f7a4129473340fb725458cc50000000000000000000000000000000010f70de44c7e0510c8ff8327dd83ea4087f9f8b5a53fbe18615fa31a3b57862b52a7726b3e9403afe93dcafc5606dfe500000000000000000000000000000000199e6da569d0eb7938d52b396c9bc6d8b563dd6e64edd60e2e25c493475a0cbd953e7ff54309d189eba2b3827ad614180000000000000000000000000000000012d75b62dd32798ea12b99f51a496bbf61bca93cd233dd288e00259893dbe7c73b6342860d41fd86878a6de608dba0ed00000000000000000000000000000000018e963e1cdb31ce3f636091952c17ab4c03c0f55940196b5772002850c6c86a3da13a9a5fbfaa8256fb0a9c4139bfc600000000000000000000000000000000192b17cf1539a57ee64701bcd07ed0b067a6ab12ef17408ad3ba1db0d94889cc481c877588fd70270287aa8f279659af000000000000000000000000000000001779c74b7e83c8d931510b555de206dee2d9edbb49b473c586c5b7046d1389e6f612cf96ee76446a21b02f135492fa1c0000000000000000000000000000000007165050fd4407a69143a98001c290f8b1aef02d64d28ee046744009f4afa376da95b4f6a3dd36427a297ed25e6bb3320000000000000000000000000000000005a9238272385614f6df896801f7f9af9cda1ac0ce3c816174693bd52b1799386c4f6355fc36f9ecd566a3a4b20e612b,,,invalid point: subgroup check failed +000000000000000000000000000000000d612430d9b8956188fefa4cd839ec8dffee18678f83d4984b08e227880ec127e63860bf5d7a27c309fb425b90c0afa500000000000000000000000000000000100556e6391ac2a05b15e552e67d6509e21c4770cfe2f8126fd1d9663995839420a4915656d6292d0767892833369bbc000000000000000000000000000000000aeb5c087644595d0912879f61959d2731ff55260c682ed2bc5fc55c13964ef7c1f70aeb55876d2264d558c31371ca69000000000000000000000000000000000e173848f4570525b03a2b2c86f4dcdb8b28dd6d18c1354cad31028eb1b8b44432c2346edaace093e3954c7fa6d338a4000000000000000000000000000000001949b0902506d111ef6318edcd7a58ca4d69f5804a028aee73c3786cb2db168c6a73b77194f7a021ae6ae43ac78ade340000000000000000000000000000000017c5e28ba6103d97e2f3d3611c0c78f06406e0da8a49ae29c7d460b52f75136920784cd500aa3593858b877697eb84240000000000000000000000000000000007dc719ae9e3f1e11d3ed4747a546a7b973ccb1967adb1b3066645a8bde9632bcfa3530e768f088ddbc022b169e67cbf000000000000000000000000000000000bbf9cf884b19c84045da1cead7dcd9fdbf39d764ff1ad60d83ed1e4fd0ce0554f0fb618203952cf02a7c4ba466c66b8000000000000000000000000000000000aeb5c087644595d0912879f61959d2731ff55260c682ed2bc5fc55c13964ef7c1f70aeb55876d2264d558c31371ca69000000000000000000000000000000000e173848f4570525b03a2b2c86f4dcdb8b28dd6d18c1354cad31028eb1b8b44432c2346edaace093e3954c7fa6d338a4000000000000000000000000000000001949b0902506d111ef6318edcd7a58ca4d69f5804a028aee73c3786cb2db168c6a73b77194f7a021ae6ae43ac78ade340000000000000000000000000000000017c5e28ba6103d97e2f3d3611c0c78f06406e0da8a49ae29c7d460b52f75136920784cd500aa3593858b877697eb8424,,,invalid point: subgroup check failed +0000000000000000000000000000000013b23b5a61ad3ed0ed74a57023285338c77c01dd93e17fd93d4225d27a7168dbdae3fff0c8ebcfc30887df348deea7ae000000000000000000000000000000001245282782135d41eee4dbd9b69a586e1ae2e17426643494427eabec93ba3c056089ce9c8a667727c3464178f7c87655000000000000000000000000000000000d35887ecdfce840b79f60f77af0e7cc01289ff20e1558a14b57a73f3fdd8e66ca496a73ce888d1c8cd0888d8219412b000000000000000000000000000000000cca9ce1b3c5bb6d02d5c36549438a4854dacacab7b173b434d09e496256edc2372a08edb2de26e5369af03dd0e2d73e00000000000000000000000000000000152d022429b54ac4bb70dacc888a2a3409cd7d2db0614ba0afe236c7bff311967718a70eb7943f93a6dbc88d3c008e8b00000000000000000000000000000000191e99ff1e02809121098597de4d176dfc85586d3e13609b3399c08da7c9cd6fa006e8b95551878a74e140cf166625c30000000000000000000000000000000013b23b5a61ad3ed0ed74a57023285338c77c01dd93e17fd93d4225d27a7168dbdae3fff0c8ebcfc30887df348deea7ae000000000000000000000000000000001245282782135d41eee4dbd9b69a586e1ae2e17426643494427eabec93ba3c056089ce9c8a667727c3464178f7c8765500000000000000000000000000000000179657b434fbb3ecb4857b4559c8cdaa1448b2a4bf4314349341a45bd3a2cdeb2aa6be75ee1aaaef0f90d086df55ccc40000000000000000000000000000000011ec9abd1a497dc7cc4b4b9e2cef8a7abc767969703d79ff51d7a4f1ab93ae9fc7e8bd4852da22ec067d326fffa54757000000000000000000000000000000000a45435d1f78ad93aeef8a88dad39aebc0cf38cc16fbb02c571a269bbec773e71b5ee9d09a505afc9a7fe11b06f040cd0000000000000000000000000000000000b6ee9d2b0fbd996455169ef07afa3be3c6535d65545c8503c3d77dd0576eecd2f81b50dabbb62328edfe236981d5c1,,,invalid point: subgroup check failed +000000000000000000000000000000000b14b12ecaa94f9656be54772be9b22a2495d4ff873b0bb971c27ab1d8b940c84cabcf921f6f75e93942c38cddeb8751000000000000000000000000000000000c9ad793ae80ad0e1c39670876d679bc7f930c1df1f9202593d1901079687b77f18e4b1536bd7c4152ec197321dc945a0000000000000000000000000000000006a90568fa25b401756e3f86b5300c4d3b626dc6274f4685e8a9f56ec5ca2afce36a1fdc6d3414edc8780c4e650f10dc0000000000000000000000000000000012e41e8e0dd10b3ee31fa866753aa5d9db7669153b141114cdb2ef7fa6df5db27aef0cc70e76a741eae504b038ecf2300000000000000000000000000000000005c35f3372f1ec9845bd04ea722fbed2be1388abf59e622dd3dafb4b3af49bc5fba9e20235e7e58973fedf4b8b720691000000000000000000000000000000001111d18d621070509805d306a31c109701288fd55d4c0644349deb080c6591b6e852b4f7e009b80019513de7f2fce17d00000000000000000000000000000000000707c711f77bb425cddc71ecf96a18b6eb0bed7f012c4f6cc9431003f2e1ac17f7c1f68c4965a4fcc273a3db93451d000000000000000000000000000000001211464c91c7e78b00fe156da874407e4eeb7f422dbd698effb9a83357bf226d3f189f2db541eb17db3ed555084e91ec0000000000000000000000000000000006a90568fa25b401756e3f86b5300c4d3b626dc6274f4685e8a9f56ec5ca2afce36a1fdc6d3414edc8780c4e650f10dc0000000000000000000000000000000012e41e8e0dd10b3ee31fa866753aa5d9db7669153b141114cdb2ef7fa6df5db27aef0cc70e76a741eae504b038ecf2300000000000000000000000000000000005c35f3372f1ec9845bd04ea722fbed2be1388abf59e622dd3dafb4b3af49bc5fba9e20235e7e58973fedf4b8b720691000000000000000000000000000000001111d18d621070509805d306a31c109701288fd55d4c0644349deb080c6591b6e852b4f7e009b80019513de7f2fce17d,,,invalid point: subgroup check failed +000000000000000000000000000000000e96f4879493d577aa02e9793aba3c680de9296dadef569d70484297398cca1e3d8acadc6c188345d98d5208f5b2d7800000000000000000000000000000000003bee60fe5a42f31ae4218a6c6fff2ffb51329c86f8d3c381fb090bba0274eef8cf0d351fb4bbe2d51e25d9f7b2094ee000000000000000000000000000000001664847d2bfb8939cccda0bc7b7ef02fcc1188fcade83341db7c4dfdd4a1a3bdd627379544dd405bcdb58caf4be39cb40000000000000000000000000000000001a293caf801299370cd133fd54d2086c6d1aa96ec32a1c9c57679f45785c9e6fa91018720c2d0515b38790914ab61d20000000000000000000000000000000017efcbccb71f6bbfa515e89d59b5fcdda4bf37c90fc6dafe9c6b0fe3d42a372ad9c66e5d60e04eff30ea7c1952f3fed30000000000000000000000000000000018893c6a3c621ba6c1119529a07d6c2f9c1d4bee5e0090c4c0204d8d4f3e200ab3300dcdf1cfe61370d68849806ddd8e000000000000000000000000000000000e96f4879493d577aa02e9793aba3c680de9296dadef569d70484297398cca1e3d8acadc6c188345d98d5208f5b2d7800000000000000000000000000000000003bee60fe5a42f31ae4218a6c6fff2ffb51329c86f8d3c381fb090bba0274eef8cf0d351fb4bbe2d51e25d9f7b2094ee00000000000000000000000000000000060a0cdf9ea84b21c7399b21e337dab42f357c30f50b076b4f95bf8623b88e557cc8b346e41a996adbfbaf0a3697ae8e00000000000000000000000000000000003746a481d5760263d43ee3c2ed6493caddcc59754fb8534ff57ff9bf167f356d901277b9935210ddac4dfff8f21161000000000000000000000000000000000d80e40583153e6e0adf9f95ebc4fd501f5aa426ff77038b69f0fe8259268f9224628ead1a63b7ecb4218ba825ee45b60000000000000000000000000000000005d0421b213f88469887d67c68316a98c18d2035a601dec994f6a4b91fb6c3b7e5ac7741cd07c956908869e1023dd32d,,,invalid point: subgroup check failed +000000000000000000000000000000001576c6f620bbe36a7df78985dbffd355c032bb667f4757501bb27a426c99e1949a1bc65afebaeac0668ff3d375b7837d000000000000000000000000000000001651783a82f2a8e1e389923bfb53836492c00e447b288873071bd8682a0ef30864f4d0fc9a626bf701bdfe1a48f4479f000000000000000000000000000000001335276775545fbb4c701beb57cb34312108c9f1d46b4aa4b09a16faf0e648b4e80848bf5e75ed8730715f0107afc9820000000000000000000000000000000006ffff8736bab41b4ee5681b741a81fc870e648001027161144254d04c678e4f954e9f191bd8b26201aec681cbf0654b00000000000000000000000000000000026ede90d14fa0885baad21f9631bae058573251cbef5757bb8cfad061f3bdc78834fa5862dea19a2236c014b0f1652e0000000000000000000000000000000009844d0cf7f6f3401145d8d720defa577ca46b49e04e39c4c139ec6811a574e7dd5ce3acd00d1ce9496f10dd15c6d946000000000000000000000000000000000a6ff5f01a97c0f3c89ac0a460861dc9040f00693bfae22d81ea9a46b6c570436f0688ed0deef5cdcc5e2142f195b5c000000000000000000000000000000000193a17880edffe5b2ebedf0dc25e479cac3b136db9b6b24009ea0a9ca526d6dd9714d10d64c999d4334baa081b9f2fbe000000000000000000000000000000001335276775545fbb4c701beb57cb34312108c9f1d46b4aa4b09a16faf0e648b4e80848bf5e75ed8730715f0107afc9820000000000000000000000000000000006ffff8736bab41b4ee5681b741a81fc870e648001027161144254d04c678e4f954e9f191bd8b26201aec681cbf0654b00000000000000000000000000000000026ede90d14fa0885baad21f9631bae058573251cbef5757bb8cfad061f3bdc78834fa5862dea19a2236c014b0f1652e0000000000000000000000000000000009844d0cf7f6f3401145d8d720defa577ca46b49e04e39c4c139ec6811a574e7dd5ce3acd00d1ce9496f10dd15c6d946,,,invalid point: subgroup check failed +0000000000000000000000000000000016e8fb30c523be94fed64c81cefcbed03d7a2c85ce975601a441a920d70980be8b7c682ebf2aa3cc36ad1bf2d98a711e00000000000000000000000000000000056d7a36324b92ce3bf1644a2a0f6e717b0e9d94e9e5231f0c999c0f6eac936f5c1b1ff4aef04b821454a951882fd45000000000000000000000000000000000069ce7ace071ac2f7034200da8eb9252c55cbb50a591c563684013fa8071d7289a44ce5b100db6af1e8732b8e5b3b7fb0000000000000000000000000000000019535c703e9dec227c92db508c5c0553b986b93e3a90b35f472ad8e5b217bc7658ceb7ea452b76984d3d17859fbd7fc300000000000000000000000000000000008b3677ecfb10faae0478be5be5c72fcd7137042b5972fffbd15ac95d6104687a81fa3db232edbbb8703280412eddd30000000000000000000000000000000012a628e23e5c7f0225eaa75b6c9199d1d3a0316d474d1fa729640c295ec156ce3bd49f193d993165b9a69ad6cb2ed75c0000000000000000000000000000000016e8fb30c523be94fed64c81cefcbed03d7a2c85ce975601a441a920d70980be8b7c682ebf2aa3cc36ad1bf2d98a711e00000000000000000000000000000000056d7a36324b92ce3bf1644a2a0f6e717b0e9d94e9e5231f0c999c0f6eac936f5c1b1ff4aef04b821454a951882fd4500000000000000000000000000000000005b6ff8cf47cdedab38d984013db8401fa4783e7c8e78160c7a420de86636683b8dc292e1f0494dba5865f217e33e7c40000000000000000000000000000000008287d216fc45ee3e210630f0dc4893dfbba90b3bfd34986b64b04a2ec6fea0496cb0f2910cbb99a70896e5afcf809e8000000000000000000000000000000000a1a11f1b52c35b9e061c57b7b7f5f76f4db764607c93c2dddf245170f4c6fcf5915d72130e6f8f0c0c5b29a4970aeb30000000000000000000000000000000009255413a3db5889608069b7a72879b659ee5e1e71165752a9173cf1ef749050fefb86584ce90cbd3c3aa3db023b3322,,,invalid point: subgroup check failed +00000000000000000000000000000000117e2e3a8753660374fb2b812038bfd8f15d36d26c7b07fb546610405cd4442c79166060c8b8e767ea4084a583bbbcca0000000000000000000000000000000011247def4be1da163e724a175f74afde615df1417cdc2491158fd560442e56ebbcb61f51f9712ac93131024e27a1caa90000000000000000000000000000000001cdfae9234096578b9413f926ef8c6831f2c0f700e25d7553a746aef44238e493f8032e09f67f2fed9676c9611f60e70000000000000000000000000000000019c8bae08d3926997146f7827f00cde863684dd4050ea5da64f6798e7a930d3c1f34046bea0f44232594f5469db566280000000000000000000000000000000013574b997ee8988aa81db0e2ddb98be2e7005603076fac5cb246f65c869aa7bb3f148c8dde970e34e5e5efce023e633c000000000000000000000000000000000998bc9d41c5d527360fc4e68ba067d3778cf5cf00e5959b5ec52c1595aabe6e2e92d40cb34faa84513d150568c8cfc00000000000000000000000000000000009ec00ea2da59d937d3154d86dbed2957667253401bce9de80e0ffe6df32f36b06404b9e3af08e912a0b4ef091f93efb000000000000000000000000000000000dd8d1bd66f4accbc9d0c7dabef7af72f51c67a0d61384647533ad92bba44a312f0be0fa52163176f1aff4e64c00aefb0000000000000000000000000000000001cdfae9234096578b9413f926ef8c6831f2c0f700e25d7553a746aef44238e493f8032e09f67f2fed9676c9611f60e70000000000000000000000000000000019c8bae08d3926997146f7827f00cde863684dd4050ea5da64f6798e7a930d3c1f34046bea0f44232594f5469db566280000000000000000000000000000000013574b997ee8988aa81db0e2ddb98be2e7005603076fac5cb246f65c869aa7bb3f148c8dde970e34e5e5efce023e633c000000000000000000000000000000000998bc9d41c5d527360fc4e68ba067d3778cf5cf00e5959b5ec52c1595aabe6e2e92d40cb34faa84513d150568c8cfc0,,,invalid point: subgroup check failed +0000000000000000000000000000000018de31d75ba31dc1441bee38f5fb9e9d347e0243e6c3220de664e04a0af17c776fbb483f63ebeac48c7811adc0fff6bc000000000000000000000000000000001053f5c7a65dfb41b7631a22e60337769beabd663fa76eaa1e01f0c0e3c901f40a22b34adfb13b38e298eb83f08d7b1400000000000000000000000000000000079daf601b5fdd1c00552382a819e1924a517226864aa3565d384dc399e6e124c3ad61b236e19321078eab585579572d0000000000000000000000000000000008ff51b4d60d9fb1718c5622b1a3353675ca0144e12e68875481394755107b7f3364d1320283ce34737d5ea0b7d9b40f0000000000000000000000000000000000f430d35de439bf8ef82df4dc61459cf9783d66531e8075f323dbf102035032972a4830ba6bf391b568e6b691723ea600000000000000000000000000000000042df3a5c7b534c48c9af9f48e5cb296e2e514e3322630989c3da9696485797fe2ae036e13484e26cb59b48a479d3f520000000000000000000000000000000018de31d75ba31dc1441bee38f5fb9e9d347e0243e6c3220de664e04a0af17c776fbb483f63ebeac48c7811adc0fff6bc000000000000000000000000000000001053f5c7a65dfb41b7631a22e60337769beabd663fa76eaa1e01f0c0e3c901f40a22b34adfb13b38e298eb83f08d7b1400000000000000000000000000000000180168b2c9a59a9bedcf002336a6ce5d5ff36937948f5d3aa9fc1ef1912d9fed526edcaa00b5ede76906c40994937da00000000000000000000000000000000018d47a4f6e4320a230b8a4e5f5eea7807fb5b0dccc72af182e8bb811f2470dfd485f291b8197899af84332e3674d56950000000000000000000000000000000000dbfed96298ad2f57fe7b1eff4791abdae5fd0ca3573e66270f8c9f6adcbf6e54a746789a496714f5cc06eb2b8190070000000000000000000000000000000002939de2a2f7ec3d44dc5ae679967a5d7efcf80df8a21d9708c036c602a5050487f80a39cc36c7e587f0f2610fed86b2,,,invalid point: subgroup check failed +0000000000000000000000000000000001ac9e5f4fdccfe8d2979ad5329b07b23b497c2b7f26283f8c79548387610580568bdd9dc040261d6c265aac581b4665000000000000000000000000000000000eaf31d6368bb9d762ea067eed73b008dcb4d84643471dc1d64104eaefaf500858d9a9323b7fa2ba3c22bf15e7db6b9d0000000000000000000000000000000007457f2601621a99050d8993244f026b9a62ff7055b325e6f1edd1cf54065785f003cf7c8a4bb1f7bdf14e220e490ada000000000000000000000000000000000928eb76b428dde37546a27f3d77605c293738f448fbdd6d618747b0de04004aa4419cc5601600419c6e1d470c15982e0000000000000000000000000000000008074e9f5473492dd2e536f7b305be4e5c564cfc9218934d03dde6dc5118064ebaa5c26fdd1123a9c31336c37c1234900000000000000000000000000000000002bba1f9b7da6abd2b322c8f11c749b2a284552eab25a77d21b38b028da477a3ffec1901a015e81fe2893576a41e4c0b00000000000000000000000000000000172447291285a20c3ffcdef805260f00fbd4c5d3a42ee5b17d5ec05a723aadf4c2acc49f839e222155f29d0c6384bb0a000000000000000000000000000000001490dae85f858ed057fdb61c22ebf3d45c3af02afa53f32b2542808bb4db5bb1b9603e377f0b6d214e03050379f8006c0000000000000000000000000000000007457f2601621a99050d8993244f026b9a62ff7055b325e6f1edd1cf54065785f003cf7c8a4bb1f7bdf14e220e490ada000000000000000000000000000000000928eb76b428dde37546a27f3d77605c293738f448fbdd6d618747b0de04004aa4419cc5601600419c6e1d470c15982e0000000000000000000000000000000008074e9f5473492dd2e536f7b305be4e5c564cfc9218934d03dde6dc5118064ebaa5c26fdd1123a9c31336c37c1234900000000000000000000000000000000002bba1f9b7da6abd2b322c8f11c749b2a284552eab25a77d21b38b028da477a3ffec1901a015e81fe2893576a41e4c0b,,,invalid point: subgroup check failed +000000000000000000000000000000000515390641039576df1debf767b899deed928bba057d8564e7d117b324dd7f45e38939ffa1056fea35e1df8ba38815ad000000000000000000000000000000000013af9258135a09e5710a22dc437a4efdfee1f6c25cc08fb026c7ea2accddb9446333a91a532742c7713f6639e0cc460000000000000000000000000000000017203225f7e7b55e52793698b8a1166de5cb3d130c7df6f74ae428c4f39e7d042d41eb3aed266ca8cd3be1618cfcbdf60000000000000000000000000000000016b8053ab19a08a8c23a166bfe7a89be6eed05f305525146d9ff6e03e47ba125403cb2f000672d08a2b59051242f61ea000000000000000000000000000000001136f9a9369aa3561d65e54869f36ae9d6945654ac16335aaf717e0f848463ad401a99e83b3581c79d4221f65d649e9c000000000000000000000000000000000302ecf71033b917efac49d7a22db2e5c59b656639c4d0aefdb431749718d560b7e5580b4532048a693ccc09fb8a44a6000000000000000000000000000000000515390641039576df1debf767b899deed928bba057d8564e7d117b324dd7f45e38939ffa1056fea35e1df8ba38815ad000000000000000000000000000000000013af9258135a09e5710a22dc437a4efdfee1f6c25cc08fb026c7ea2accddb9446333a91a532742c7713f6639e0cc46000000000000000000000000000000001330e5c71d9b0209c8f8c04b4a28ad70d826b2c781493ac50fe58d0d6b740de3ed08f9829aa9b207ecf623a36dc8de610000000000000000000000000000000019a81ae1c6c08004a75b8fb5426ec899a09becce68dfb63fa7335420f05075bcf42c85dfa688ae75398c3ae5e4d28d12000000000000000000000000000000001597318859306f3814d20faee54926d5e8ec01005fae8aa408989afd5a1d7add8956d8fd3e75f9e446fb8b2a31050b6b00000000000000000000000000000000151e7c5bbcaf1e9581ac48e2b9bc63bf4576ee5d938981550f00fe9e3a42d389d6b56acd0ac9254ceaa71519b5049a4c,,,invalid point: subgroup check failed +000000000000000000000000000000000a2e9dcb8461de77fffb1281df7360c947108baef671602902c3bfa4afe60e0b4810cd46bd91276cd58e33fbf4973301000000000000000000000000000000000c039ea7e94fca4a32a275691131df8e3d470d6026aa306c8ae855e9e411878247368615094621e6af5486809b467a7d00000000000000000000000000000000138ddc71e9709e595ce2631c9155069818d07f225f80511eac21c5655721df83f83e2abbf56e2d5ebc9698f9128f0579000000000000000000000000000000000080f7ae78277c94833c0f12aa2cd98285621e0d92a89b45cac848f5a75ea652e98cd085150b2d7babaa9a365123d90e000000000000000000000000000000001147cec62010d42cd84651ec61ad8263699786f0f34aa7f9de75ac841861fae2e8ce3795fde8e7038c8506f573cf0e0f00000000000000000000000000000000138ed243889db13546c69583c1aa93ee98366220ad80c590ad112adcb4b7c87fb48a34483e76d4a5c55a30f2adf1a6a6000000000000000000000000000000000077b7a4c4644b21ac3ef56db1163f7b2e07a817cfd9d4c6830a97d0ae0b620e0b235376d590162c378899ba12eadb5900000000000000000000000000000000022beafe4b4ab44434c9dabae45a395b5b8da15da2fc2e723c1b30b5efc95e880846844f27eb47dfae8657fa27ab64ef00000000000000000000000000000000138ddc71e9709e595ce2631c9155069818d07f225f80511eac21c5655721df83f83e2abbf56e2d5ebc9698f9128f0579000000000000000000000000000000000080f7ae78277c94833c0f12aa2cd98285621e0d92a89b45cac848f5a75ea652e98cd085150b2d7babaa9a365123d90e000000000000000000000000000000001147cec62010d42cd84651ec61ad8263699786f0f34aa7f9de75ac841861fae2e8ce3795fde8e7038c8506f573cf0e0f00000000000000000000000000000000138ed243889db13546c69583c1aa93ee98366220ad80c590ad112adcb4b7c87fb48a34483e76d4a5c55a30f2adf1a6a6,,,invalid point: subgroup check failed +0000000000000000000000000000000004db2336ff5016a6f0f34b2881eb80cfbb35f557ef492f2dc54a654c8c574651fc89f3f211a46510ebffcf5c890e5ee700000000000000000000000000000000103d17d59c26d8c85426b73593843e3863cd672043b7a392cdb05bf5dd69cd11583423a4b146dcd3fbcde4ef4349bd78000000000000000000000000000000000e07265d2762e8e398c83efe1c43452d91b90b7a4271c09ff693c83745a6c01b73561ffe3da9300c8e7e1602dbaab0bc000000000000000000000000000000000375579c16a167fd9f9f61d5177705f157aa0df3451971029a9444432db119fb33b8c07de33fc822eab46ed4ae47cf8200000000000000000000000000000000098cee454129e946d758f95e649a601b6e682467093cf32c76e5cd1328111f9d48cbb2850d4d2faafe429161b090f8ab0000000000000000000000000000000012a3fdf296743b2eb3f389eb6dbea52da21e7dbaad180177184afb7976e06fd4ad488399d39b760ca146278cb3759d7e0000000000000000000000000000000004db2336ff5016a6f0f34b2881eb80cfbb35f557ef492f2dc54a654c8c574651fc89f3f211a46510ebffcf5c890e5ee700000000000000000000000000000000103d17d59c26d8c85426b73593843e3863cd672043b7a392cdb05bf5dd69cd11583423a4b146dcd3fbcde4ef4349bd78000000000000000000000000000000000e87688c9f6f48450528cec78f874d87dcfab499bce391e964a0abd601d675eec8a2b4cc6c44811cbe918913a230975c000000000000000000000000000000000451c1a17567b55123da563e173b2d92ab635c4957d116fdff8eb5a3e00bfbe079abead42b9c990b56db919719d066160000000000000000000000000000000003206eb27b9e53bc451bdbe5059133a51d656d9d80654647163a070741761af3e712e2042acc5ca29fe72cafb3a98ec7000000000000000000000000000000001869b7fd294c230aa5901db9cca31e6d3801069e0795e4c7c63dea8adc1e4a5709ec62670e2abeeb040031b7fcc8521a,,,invalid point: subgroup check failed +0000000000000000000000000000000007248a496f2cc918cc3cf0240c5c3d0dce36228a199766106999205b5767db09c2ff5cc720691ebc6bb1c316159d1c000000000000000000000000000000000019ab8e34bc4c0ba409c7edf7bbd4d0cf03f7185a2baa3f22ebd6234503d56e9b0d84a5d8d46ef9e3ac6430029be82b2b00000000000000000000000000000000143220e1cd08ffaa6db4795ed4aa35f3b12cce724fcad005367328972f2364f34096e32f1f1cb7a4287ab636d0030322000000000000000000000000000000000f2de47a37a55edbb75ff0bcc446611d690d7f9efdd09ca1ebb6f1d64a330bed420bcc85aed8b95316fcac3aa7d1f2230000000000000000000000000000000016afb044b8b8c64547e000f80b25576aa329a4319dcd4f1bbe15d12e6f3bbdddbb52140e6297c637311ef0c7a31cafab0000000000000000000000000000000019e6803c07fbaa075093f6a69f9dde05ba3d3f58e67389d7f096e56df49f8270008ed422b64fcdadf7cbbc8334037682000000000000000000000000000000000b231eac9869c94f055f22c16ef5efb687a7399da838c9456bb2469b3e394dd21e462bcc9298d5b56173c7b76f79ee9d0000000000000000000000000000000013a1bb963b7fbe1c3f6bb78cce8c3122773428ccbd87cbb2e76f306a8c5369577267e9b4ccb3417a235fc9045e8828f100000000000000000000000000000000143220e1cd08ffaa6db4795ed4aa35f3b12cce724fcad005367328972f2364f34096e32f1f1cb7a4287ab636d0030322000000000000000000000000000000000f2de47a37a55edbb75ff0bcc446611d690d7f9efdd09ca1ebb6f1d64a330bed420bcc85aed8b95316fcac3aa7d1f2230000000000000000000000000000000016afb044b8b8c64547e000f80b25576aa329a4319dcd4f1bbe15d12e6f3bbdddbb52140e6297c637311ef0c7a31cafab0000000000000000000000000000000019e6803c07fbaa075093f6a69f9dde05ba3d3f58e67389d7f096e56df49f8270008ed422b64fcdadf7cbbc8334037682,,,invalid point: subgroup check failed +000000000000000000000000000000000ee60801e3aaacf27167207a03b42594cdca4cdfe3a1f8e5f87b0e423ad36c56725dc79a26c157f41699e89884d27c1b0000000000000000000000000000000017c92b0beee470e126830843170bf0a89d13856ff6b0209e23bbf2a68e0668bd81db29de726ec7593124bea89771da97000000000000000000000000000000000a1beec4d223edbf1d09c448ea27038327bd8621842d3c7851779286060abd8130e4a641100627057498a421b59e90a600000000000000000000000000000000076a9559f5e33a2d5bdff6a89037c12e58ef920a3d8b9b4ca2a78299dca5dbf07c80d51014ee9288af8725e6c4312225000000000000000000000000000000000755036dd19c7d703343bc29238ae9332823514aeb4779b3378e8f7a3463a4089eef3fe79608db22b703b5d88c65bd80000000000000000000000000000000000ee3d82959dc04b5d59428142411e48e7a2fcfcff91e5554b725868c62d139bfd763720c9e2727c1b1fdc0bfd60f7297000000000000000000000000000000000ee60801e3aaacf27167207a03b42594cdca4cdfe3a1f8e5f87b0e423ad36c56725dc79a26c157f41699e89884d27c1b0000000000000000000000000000000017c92b0beee470e126830843170bf0a89d13856ff6b0209e23bbf2a68e0668bd81db29de726ec7593124bea89771da97000000000000000000000000000000000360e8bf07554b56d6f27de6a4b1f9184adb7980311e8f4128f619d9c8e64e98bcfca8eb3cab93e183882827fce2d06800000000000000000000000000000000010b0b114b55b17531576f782b6bee122cb5fb1e40d5af37ebaa1d4dad55a0f5d130c9a58cf27b1594eebd0b1492c0400000000000000000000000000000000018b70f0c047aaf7e17cb96015642e0d32f3135999de6dd8bded2c600866485ea75ab3a3e37581ae7dcfa1f54381f542300000000000000000000000000000000028cbef4b476a9cfb8daa35b1321a486b8c94f8b8df2352a0c8d509325706eee328b8dc3657122afb81be1fa2e60aafe,,,invalid point: subgroup check failed +000000000000000000000000000000001573cb3b6f4e841fe97549f42e06db33abeb2bc481cc0bc8c5e7bd81948432dcbd34b64c5766e1e491bc131e77a011aa000000000000000000000000000000000e205be14db0dfb21e58b302d45916de4f4bb48ac95228326cf49c50e6c8588a655a343b90645f73dd03c9aa51c5659a000000000000000000000000000000000a109e3cf72bba0e695bd756478c72884210868c95f0dd6ced22b7254eed0432c2345bbf8addbbd11349fec6e354d2350000000000000000000000000000000018aaf98535812ee760e17ad933acbe6b57bc1310b6fef550210053f06a611ce9df5dfcfdb028497468802c08cc2117320000000000000000000000000000000007590fa8cb07f9dc2ce7b2090685730104ca65a101c8f93965264913bf1deae794b71ff226a805a273248dc641225585000000000000000000000000000000000fbca4e20854a6069c298224eca9a064b7ddc4d834f8671ac45cb5d1d39265fa435ff1750cde5135e170824e516d6d2c000000000000000000000000000000001510f39616d7f576980055d0547c603d882dbe85dd0b634577fae134f210736007345d035d815306db660de4a07fc24300000000000000000000000000000000064d356ad7bd2edcd3622b1fc225fe319f86b5f7da875cd57fe5adc5bdb6443c5b09d676950e2d069bd4303b8f920692000000000000000000000000000000000a109e3cf72bba0e695bd756478c72884210868c95f0dd6ced22b7254eed0432c2345bbf8addbbd11349fec6e354d2350000000000000000000000000000000018aaf98535812ee760e17ad933acbe6b57bc1310b6fef550210053f06a611ce9df5dfcfdb028497468802c08cc2117320000000000000000000000000000000007590fa8cb07f9dc2ce7b2090685730104ca65a101c8f93965264913bf1deae794b71ff226a805a273248dc641225585000000000000000000000000000000000fbca4e20854a6069c298224eca9a064b7ddc4d834f8671ac45cb5d1d39265fa435ff1750cde5135e170824e516d6d2c,,,invalid point: subgroup check failed +0000000000000000000000000000000002ff87f9bcde30db0919444e2582a5e987fdda67264ed7abf60a93b37288143dd44db75403988cb5b3bcd8d34ebdb4e2000000000000000000000000000000000c672f8bf6e9e747cccb9438be047e56d1cfbd0808864e601de59b0b28b5438cdd10f1194ff5abe8694a598ff3dc1481000000000000000000000000000000000c01823cb218303c7e611f6caf6994615cc3805bb4310bb0bb82b56740c4314ed0a2f9409c8fa6b9f10dead667880fe000000000000000000000000000000000013eb3436ceac3f12dcdd9e71707b85b7cd872ce144c502078d4fd3ec8b4ee579410cbaf2e3db1df9ba6b55f14fbbb0c000000000000000000000000000000000ecb26e5814d5bc66fbbcdff5dd5934a597c4344487e7e63138c31d47a8201433be5ce14205660cae129891f5b7aa8e000000000000000000000000000000000040241f695cc864e99e1dcb04440135c4f3d90a86310441647ab265e9fedf51592b0c11d5e91d2d28ac4ed19245e9cc90000000000000000000000000000000002ff87f9bcde30db0919444e2582a5e987fdda67264ed7abf60a93b37288143dd44db75403988cb5b3bcd8d34ebdb4e2000000000000000000000000000000000c672f8bf6e9e747cccb9438be047e56d1cfbd0808864e601de59b0b28b5438cdd10f1194ff5abe8694a598ff3dc1481000000000000000000000000000000000a2e0129c31f3427340e234df5facbb5d1994a4c8a058fe84f7d5c62c7d00013cc0133d8b0faf497aa8f7c04abc59c3400000000000000000000000000000000160da6086a089fc1a31b89a0f0c95ff2bd85debf5f0d1372f3ca6fc26348d8a8d0b03525b27f7d7db6603f0e55d3a08f000000000000000000000000000000001893edc299faf35510b92c97ef665f458b19e4097299b4f8b0f8a2ea1f31343c9d2f4c35dbdfb36bf7f3e30686e8c3240000000000000000000000000000000009b8731ed8df8ae90ec344c9dea1eeee98f4000b5fe30460e58f30e4ea17821389d613458c7721fd1d759ec4f2bcb325,,,invalid point: subgroup check failed +000000000000000000000000000000000e42f5097dabc6b0fef4dccbfc659da40b66671d7efbc19dbc14a42a368402156469c818f233ad911574899db01ed86d00000000000000000000000000000000128bbee344b7a19212b549cefaaec31c0644c986ab863005e4d3ecf532be633597ac3906e53ca79b22de916ab92b4ad70000000000000000000000000000000009003b42c08b5c7d3ee9f6abb96e08e6f537da25cd0cf7eb85a49067746c03566e133b54153380286ef5725db5b41058000000000000000000000000000000000f09b7b754c255e0e3b8435ade64d6960285759495659dfdb9b117806397baf8d3c87e30bee02c9e1b22fa3efcc58f300000000000000000000000000000000003582c08a8de4bbd20ebfa833517a75682618fba2702b6c71a4785f70dbdede4e86ad8e04aae1f50a6bb75842ab74aea000000000000000000000000000000000ec013f22e64a4d4fb6f964e8319feb1ddbcfb71329186545d9b9d7f97d1f6a56c8aad03d20e9c30966ca932e1f2bc670000000000000000000000000000000002f78becf8a5717fbfcbe110bd6d4ba683658c1a45afeaeecf7742502d3df54b262de4fe30bd41ed0019cc79b595b5ad000000000000000000000000000000000dbae184899af1ad6221b75fc62cadcd61c623e011672b691a5aa498684f49796220fc5a73ea7170ed2fa44b9f3c39090000000000000000000000000000000009003b42c08b5c7d3ee9f6abb96e08e6f537da25cd0cf7eb85a49067746c03566e133b54153380286ef5725db5b41058000000000000000000000000000000000f09b7b754c255e0e3b8435ade64d6960285759495659dfdb9b117806397baf8d3c87e30bee02c9e1b22fa3efcc58f300000000000000000000000000000000003582c08a8de4bbd20ebfa833517a75682618fba2702b6c71a4785f70dbdede4e86ad8e04aae1f50a6bb75842ab74aea000000000000000000000000000000000ec013f22e64a4d4fb6f964e8319feb1ddbcfb71329186545d9b9d7f97d1f6a56c8aad03d20e9c30966ca932e1f2bc67,,,invalid point: subgroup check failed +0000000000000000000000000000000002dd02e23d8a9b7aaba94e8ce97a2d988291b6efb1d4d8d1c53b65581b737f992a428cb72ad38d4c6d470d6b50c869f0000000000000000000000000000000000661ddb1f0edbaa208c5e1db143ff41be5a35442da7b3e12d2928310ba5b64847f4909be93f860858f752cffce5e73870000000000000000000000000000000018fc47e1aaeefc1ea653eb42543940ba58044b247eef2627331142988f3a1a4fe72583738c7caa00c562d010089754eb000000000000000000000000000000000b5f8e9d774d99c3b6d224790d5c48367d68167aafc309ad8b351d1de8b601211737235bb0ff1b01e508ecf36a40db5d0000000000000000000000000000000013509c76fe4383e47d8ea35ba6ebcba13579bbf43cee0cbe27291d2601c3d74428bc9d5d1200718c86977abd16cb77a7000000000000000000000000000000000efbeccb9e9f348ba98ce0fd191c2e81de4925d7185f01b39a51aa44b30496f1fa3be4582c539889bef7b5783f730aa70000000000000000000000000000000002dd02e23d8a9b7aaba94e8ce97a2d988291b6efb1d4d8d1c53b65581b737f992a428cb72ad38d4c6d470d6b50c869f0000000000000000000000000000000000661ddb1f0edbaa208c5e1db143ff41be5a35442da7b3e12d2928310ba5b64847f4909be93f860858f752cffce5e7387000000000000000000000000000000000629fc2184297509e1dc0707b707067fa8b9a079d95f271ca230c32705c7e783f91ce1ef0323aedc6aa2febf750392b8000000000000000000000000000000000f29cb4bdb7d53671f9f1b1ee514cc916a657b7c17f298f409ad92ad7b2ca36b0298bd0581db7837994b781b829980c30000000000000000000000000000000014b839ecd27f2d6fdb92a36792c62ef503fb0189d3174447c4b1132e5f66d7970a005e315e6906ecd2ce6c72742d210500000000000000000000000000000000091bbfcfbd929cc8ecd000cf8ccf083c2f8cbd84f19b48b1ad20781e675ca7a77887b962435520e3f707fc0631fdc8f1,,,invalid point: subgroup check failed +000000000000000000000000000000000f67855b0cf915ab52190c7e69129d40dbeffae28fe110745edefacdca42bf979c5c5da1c6ebd78b43667cbfe360874c0000000000000000000000000000000014c5523f37b011c632e9e8eb08611e5a244ace2746264706b92a5a933b34bb9932c95c493ea7e8fd049d80acddd05e860000000000000000000000000000000012b63d867bbfe5505a83f765b85b0e8f182c796857f11125e691969c8e81eae927a5e1b137c81473e8b99ea0727c873c0000000000000000000000000000000010a8241f3b30c54a5d2fd7adca9be47b001f2268973e955ffa61d57793256a2d82fefa5e449548c64fa5aefda6d933220000000000000000000000000000000008e7d2f2e34a60504a5437275f358d0e742c445080c5e46053ea459893d6865e8d20906b2b58f1d1446a100cb1c9a513000000000000000000000000000000001369bfc5f24e2a7a7ace891444764ca32a32513c8ddf654f418c6eb7690e2cba77a4c4d4b98eb546d4e4046dd3c3267200000000000000000000000000000000153310de30b7a485753dd8443f8638c12b21083f6133a1c093648bcb566b33f73631c6fc558f32abeb0d6df8430e61a900000000000000000000000000000000005be397e9f77556ad952dba0540f46cbc7db910d5203cb976e168a7be3a3b8557c5f08d51cca9379552694a291d67fb0000000000000000000000000000000012b63d867bbfe5505a83f765b85b0e8f182c796857f11125e691969c8e81eae927a5e1b137c81473e8b99ea0727c873c0000000000000000000000000000000010a8241f3b30c54a5d2fd7adca9be47b001f2268973e955ffa61d57793256a2d82fefa5e449548c64fa5aefda6d933220000000000000000000000000000000008e7d2f2e34a60504a5437275f358d0e742c445080c5e46053ea459893d6865e8d20906b2b58f1d1446a100cb1c9a513000000000000000000000000000000001369bfc5f24e2a7a7ace891444764ca32a32513c8ddf654f418c6eb7690e2cba77a4c4d4b98eb546d4e4046dd3c32672,,,invalid point: subgroup check failed +000000000000000000000000000000000f3300926ec62bbc0a73e4e0404de3a55dc0ad4fdc393b291ccf9f80818b6a69c0a3f9c6edf024db295a353b6aa71a5400000000000000000000000000000000195b21606667c62a181b275184014fcef97218b451c3642e2e4dcf5502d03cbcc88839e827732feb32e77e52f702529c00000000000000000000000000000000198fe6684d3de4ec9c9ed5c59c9e662c4eb1b026995859db3a753ffa96c6cef7a063a607fc54599f706820fb864d7b0500000000000000000000000000000000116af6c03511ba2bcc32ea54c2fe2bedfb0848d2ee3017547cb25acf892400203e3ce4ea1986ecde0cdd383d42b61e180000000000000000000000000000000004a22ed8f30766b6b1dfc7286616066ccc262875e3de42e2c9528f6d23a7fda67ddb371f9ec419ae4dec48a354ffe21300000000000000000000000000000000086651d7ab0a4b1dfb9a56e42443f42d48c1f16866338d997adba078736d32bf4387b95da2da33e714662f800838a077000000000000000000000000000000000f3300926ec62bbc0a73e4e0404de3a55dc0ad4fdc393b291ccf9f80818b6a69c0a3f9c6edf024db295a353b6aa71a5400000000000000000000000000000000195b21606667c62a181b275184014fcef97218b451c3642e2e4dcf5502d03cbcc88839e827732feb32e77e52f702529c000000000000000000000000000000001367e0843d866d010ab03723026aa9ab1f930d3579daeabadc1fdefc06047ade30b36326d79bbae74293d3daf2e6c7a4000000000000000000000000000000000550be918ba9e28ddacb89ec526db63072bc14a62ec7ac06775f951de5b32af93d2d8f95389a6384cde62dffb941fb5a0000000000000000000000000000000014f59aa4f0603d5f166caa5692d9b068ee10a6f45670c6f4d492a4d1fa7a13a5146efcae33a841b5acf75a32b853b2770000000000000000000000000000000010ca0d9ba50c730006c95bc5439e2d39a40a9055ddac935a900bdeafe7141990db20ad0a840d3297c4b9b5f69aada6df,,,invalid point: subgroup check failed +000000000000000000000000000000000b9590b1d0d292d9967d759060a551f4e8e4c1c0066a9a3c0be515085847fa26b77462e3bae9e2621f28e01f897df0bf000000000000000000000000000000000a00d39c6c14d18dc5888b8a8835c3ef6f83ead2fa380be24ae857677b904b3868ceabdbb3abf3c186c5353a67fad0a60000000000000000000000000000000017d978d60fc89b0429c1a6424231fe9274cedad5d78d9c4ac5aa2dd5e70e8238a0bb1904bb4b6ee5de5cd1ac514c62a8000000000000000000000000000000000d4ce85a95dbc40f405f4e7ebf9121cdcd22766737c39618ad0fb3e10a6e53be1faceaa96073b2a877ab808483ec9b6f0000000000000000000000000000000016c61599ae4da787fa6db233fc28f5c56f7133d403901800ab5fa19d058fb27ecb34ca2e56ffa7628ed004c9e62092700000000000000000000000000000000001e64e4adfdafbb423b1b9f8973738c690713911f68f658d234e57dc35b9554e0f7ba345dd7920b429a12b9c74775222000000000000000000000000000000000c453b5a2f6c721f0303b6b9205e51ccab7829345e0cf13e457491ff35e0f38dc5ac2e5b0d8195e3d322704c38d3280600000000000000000000000000000000092ddd55120b22e2853983dd3dea9bad3e4bf23e46dce297aa3db85856907d1b980185c5a6e02890f24a5463e7895b950000000000000000000000000000000017d978d60fc89b0429c1a6424231fe9274cedad5d78d9c4ac5aa2dd5e70e8238a0bb1904bb4b6ee5de5cd1ac514c62a8000000000000000000000000000000000d4ce85a95dbc40f405f4e7ebf9121cdcd22766737c39618ad0fb3e10a6e53be1faceaa96073b2a877ab808483ec9b6f0000000000000000000000000000000016c61599ae4da787fa6db233fc28f5c56f7133d403901800ab5fa19d058fb27ecb34ca2e56ffa7628ed004c9e62092700000000000000000000000000000000001e64e4adfdafbb423b1b9f8973738c690713911f68f658d234e57dc35b9554e0f7ba345dd7920b429a12b9c74775222,,,invalid point: subgroup check failed +000000000000000000000000000000000eb7d975030858b57bae3e7a8a7e297f9d7d6b2bcf27fa8bb9b73cf60a1a1a5e6638adc726eb2e7fd5500353de95179e0000000000000000000000000000000015c783845a98d2b12a8cada673e1df4c266b34302cf7d004e00612584d0913283d43150337c36dc3912bbd757e6a370b0000000000000000000000000000000014a0222d6d0a809cb5598db18e35f5b7f5c49ec5574fbb5d801d9f890ede23d20c62a22321394b6efd1a45b9780a4efd0000000000000000000000000000000017c8bc1b8f7ebbbcd6203f6ffcc758a787a96533a77290affc18b76fc6dce7c2ba8f169dd8ecdb8b240c92664852bfc70000000000000000000000000000000001a673ad0af4bdd53027b145472d1e8dfa05029b7ba5bcb7dcc63b5e6369b2e693f27e5665167a8dc8b6d3c9b85eccbb00000000000000000000000000000000085efb596145e58b4eae7aedc8f7aff6949f1edf8fbe0c88e6dcad46423cf7b2d5f8f54bbdcf8f1427438e6a4da71914000000000000000000000000000000000eb7d975030858b57bae3e7a8a7e297f9d7d6b2bcf27fa8bb9b73cf60a1a1a5e6638adc726eb2e7fd5500353de95179e0000000000000000000000000000000015c783845a98d2b12a8cada673e1df4c266b34302cf7d004e00612584d0913283d43150337c36dc3912bbd757e6a370b000000000000000000000000000000001425d6d5cfd04d310d8ef3ff1a3b3d227771f3bb3cb552c64ca1debd3e2e75e7a96b9a0d5768ff041098d743de445e790000000000000000000000000000000008b12959963c17ce7247490d9806e0ab02f9aeed8d8faf4591b955885f5aae509358a19c1eab19dacb72cb67b9c22c46000000000000000000000000000000000a7108fb7442fa6c50b472dda60d6c277bba83aa21ac1630bd3df6f116c8a58e60e8c4a303a041b9825b65301d388e410000000000000000000000000000000000faf3042f00060eff3e5e13e1a964c9dd605677596c49cbeccd6d0374c6a4ab9742cac63d1801631d5fa5e00d399fd7,,,invalid point: subgroup check failed +000000000000000000000000000000000f6d131c756d031041ba97dd20719cbfc864de16dddf00d282f6c41de683d193a015a781232ea5513321c131505fa4ee0000000000000000000000000000000008d754d62b8f1fb0d0e9dfe4746d9c5f9e4a296c6799d6379a4a1a07583d0959c62b05011b636b72cdb87d3c92d94f3600000000000000000000000000000000061bf88e4c5f6bfacbf1e2e72566d9c44a001237f22d7f6a7240ee0bd3c8d175786f7c2ace267774fa5615d7bd3ec8f800000000000000000000000000000000192c987bed20d707400d3211e480b8760021a33dfbaef829b1e865f92b37cd3962e56a38d4c06c5ad73bea5e7321b176000000000000000000000000000000000dbc62270cf7623e571f6ebcd29f426f214cf1c8f71edf9aeefbeb6037b7e71bfe41a55828cd4353bae2e1e927812aa80000000000000000000000000000000005f6e7064a9708e20bce8e5002c352b13d4531d87be1320bcf3322d5e2b851a54aefaf6f9ae26e277ecad307c448511c00000000000000000000000000000000041fd1625afa48a446454d6613c17cc6a65b3ec8b8f2125c0eb7b8e5d07968397d43969a6579226f496d9b24dbb71b820000000000000000000000000000000006131c506f243b5ac40354f826ac1838839eee9f61301aabd88e499d40e57df3122edc8b36f0a8b16b72f9ac783efd3e00000000000000000000000000000000061bf88e4c5f6bfacbf1e2e72566d9c44a001237f22d7f6a7240ee0bd3c8d175786f7c2ace267774fa5615d7bd3ec8f800000000000000000000000000000000192c987bed20d707400d3211e480b8760021a33dfbaef829b1e865f92b37cd3962e56a38d4c06c5ad73bea5e7321b176000000000000000000000000000000000dbc62270cf7623e571f6ebcd29f426f214cf1c8f71edf9aeefbeb6037b7e71bfe41a55828cd4353bae2e1e927812aa80000000000000000000000000000000005f6e7064a9708e20bce8e5002c352b13d4531d87be1320bcf3322d5e2b851a54aefaf6f9ae26e277ecad307c448511c,,,invalid point: subgroup check failed +000000000000000000000000000000000c9856c54b638559ce67cffb3e784b9649bbeabe135c89ecb8108341a16ef3c5ac49e9243144792a4f9371f2d6f8f6b6000000000000000000000000000000000e17a67cdee23e13c95e5b951c5f51703660ff614fbba363e5a73ea74b86af6893ae90a929df3d7e2af8852dbad77a01000000000000000000000000000000000c01d2e1592a61cda87dab7fb2a45d7468a8ce56f74fd7c8d401e224b9610d675cbdc0d4719dd2dc10f47547bc641dd90000000000000000000000000000000002d57ac9ac9b4cd7a477e162965c763ec1d0c5752b478449839e0ebd7a1110374fe90aaa2006bd03f08f9242c0419e99000000000000000000000000000000000d50b11e1ea90ef8ef0f7a95ad41ce2cd30cf804e46a96762fadbc275ad513827e6e75b95968a00b42085aa89bb0839e000000000000000000000000000000001250e40358d42dd3a6aa2dc93d89010f2a7b33e5b426ffd7e6eeb9bc02f8f22fd6e91c4fae603f14ed682617dd503eda000000000000000000000000000000000c9856c54b638559ce67cffb3e784b9649bbeabe135c89ecb8108341a16ef3c5ac49e9243144792a4f9371f2d6f8f6b6000000000000000000000000000000000e17a67cdee23e13c95e5b951c5f51703660ff614fbba363e5a73ea74b86af6893ae90a929df3d7e2af8852dbad77a0100000000000000000000000000000000048dfa619f3f77c794d119ff97e04826b5bf49d71591b778b502205875b97b17c9c9d2ae95c8d7035e9d2ade10a511ff0000000000000000000000000000000002fe9b3108c8911b07e4ee52a8d4df17bebc8153f837665513ad5c8af53cd7387100204fafefc2febb2f5e18c9d958b10000000000000000000000000000000016c98a41fac6665657b00bfe9336942e7aa145bea3131224ffa35ec9b9cd4d629b4ceeca98a15ad07e03ffcf898f8a390000000000000000000000000000000011a0d16ccdf98beffdb0953c509261f18567a1656acdd895395b480ebf8843e7d3b965e2151c58e9b610e9e3b5491832,,,invalid point: subgroup check failed +000000000000000000000000000000000f4eebd0bb8233e020629f72258d3cec7fcd3c181fa913977a405ef7437f6fdc0ee34fe6a7e349730e695f383e4478ad00000000000000000000000000000000080577fec3a6cc706037b43cd39f4bace98191511cb26cc606c11659b63112b519123a00b62158ab7a24dfe086705b470000000000000000000000000000000011e8ecf1e341f0146c59a79a8428bb01d2399d3f87d90d057f63e6cb9837432154d17975f70df175a016735caf85120a0000000000000000000000000000000002a5bd53e4f4c5b9682e1af1f7e09dd305e7342d1688f62885b5e59f173a9fc731cec481559ad693030004a5fbd90a9d000000000000000000000000000000000f9601f95e12bf05c35deb204558d44a60fd630c05f4060b7bd9ff943946e8eab507422afe00a3e7706b8ed013f712c20000000000000000000000000000000003bf6fecc0c7414a69c2b48e2c16e88d988ea8ae9d8b59017ecb89394732a20e4321cb5e4fb071aec7d2736220a455370000000000000000000000000000000018fe22fe0b39f508823e2332712f988efcce291d93c416c544272e88cc0902d79e41b01af005feddaaef6c42a26c824700000000000000000000000000000000164fe8d2934cda6f0b863bb42d13f91c52a49706182f8d337d6a629da65113818d1c177508d6735cc86a6b3837ce49320000000000000000000000000000000011e8ecf1e341f0146c59a79a8428bb01d2399d3f87d90d057f63e6cb9837432154d17975f70df175a016735caf85120a0000000000000000000000000000000002a5bd53e4f4c5b9682e1af1f7e09dd305e7342d1688f62885b5e59f173a9fc731cec481559ad693030004a5fbd90a9d000000000000000000000000000000000f9601f95e12bf05c35deb204558d44a60fd630c05f4060b7bd9ff943946e8eab507422afe00a3e7706b8ed013f712c20000000000000000000000000000000003bf6fecc0c7414a69c2b48e2c16e88d988ea8ae9d8b59017ecb89394732a20e4321cb5e4fb071aec7d2736220a45537,,,invalid point: subgroup check failed +000000000000000000000000000000000d6e0830ba9839db89621518e1ed86e9d035d7fb03b18d8a615acd58ff5c8c3dbdcf1acfcb8a910e8d3d0da770057cde0000000000000000000000000000000018c38d6e458e22cdd381010568606d26770b9eaaeb38e02a80cd0a0d584577fca7b391bbabe902825a3338682f7d3173000000000000000000000000000000000e5d5bfbe5ab3da8c033663cc457cf69062e1de6bcda6420826301d4e5fb4c47a5c90432f15608aa50678ad083f618c700000000000000000000000000000000146cd56ad5d977fa6471f7c12ee3fd66dfbe4b276b846cf4a74619cfae4a5101e85d01db615e0e6d28a5eca7a92cd05d0000000000000000000000000000000010fa99a243f1de85f40bf6a08e3e9ed3e478562468f0975bb79b1b80c9eef8c433c18ccf6e5149eb99c21f74494eed6e0000000000000000000000000000000018504d4687cf9f055c5cf8360fda2cb2123ea3a3e9c8f58853a68063e60a7ba24f2d1c153090ba2e77156cbb5ded79d7000000000000000000000000000000000d6e0830ba9839db89621518e1ed86e9d035d7fb03b18d8a615acd58ff5c8c3dbdcf1acfcb8a910e8d3d0da770057cde0000000000000000000000000000000018c38d6e458e22cdd381010568606d26770b9eaaeb38e02a80cd0a0d584577fca7b391bbabe902825a3338682f7d31730000000000000000000000000000000016267be431a654019b3f02389fb2f2f307f3bb56590c3ff1924554b2ee6fbbb68381b5ba4a8668fc541dd7e3fe9afc9a000000000000000000000000000000000c41d1daa258be71001babb484d98501c9ea015aad96e398aa6015b9ef618f6a56a45d45383dc34c70ca05242490ae18000000000000000000000000000000000dadc282d8cc0c066f28881cf440fb5a621449dc16488d02e34492fe8af53fd1749886fe6df2e377190e4043d6e3dd290000000000000000000000000000000018a30f1ae8927af27147ee5ea3c7aa848b0e303d16018fc2c3ca4bd088ec5ad3a808e7699ca009a4bf6f5b707edc1fd8,,,invalid point: subgroup check failed +0000000000000000000000000000000009f71faeb58c4d442272ea0116a03f106008ed68030bce1bc53a3964ec4f9758f508735c8c17017645ccb77124b46cb40000000000000000000000000000000016a2ea9e548342538ccfdae6806ec9ce0b7b892875155f898017929d7105001e8de041bfcab7398cccd060dcee3b6e84000000000000000000000000000000000579462f03502615d26d76e05c758a7f835e4e70f1adfdec8c7ef26580544326d66ba4e23be3c078e1f187ab498ab9dc0000000000000000000000000000000000d386d0af32f630bdf6c13ee82fd35e42961ec4b11ee8fa196d69bed775b8ecfe74409693c531631aa716957e5fe6d7000000000000000000000000000000000ce8a020608c1e7d70d7a03d11b84f48d6b3b77c5836b7c914627f3a84d3d0b3de513029c1379b20ee38a19928e57f44000000000000000000000000000000000dd10882001be7fa52ff21f1a0adab02e688539f098901fe515b61fbdbca02c4146f6c17f7ad7cf59f5e8acd85da60b000000000000000000000000000000000128e019ff92e7171d3c791bd4cf75b0f47c2a9d8722b4a8279f1178db6dddf8a4c00083a935168518a1c26a56b23624f0000000000000000000000000000000008d0c5f3300e73682f4756e6ff1d6722dde576beb587301ded34427d6935e59e76cc8a8cb0ea5f659db9ad5435851e53000000000000000000000000000000000579462f03502615d26d76e05c758a7f835e4e70f1adfdec8c7ef26580544326d66ba4e23be3c078e1f187ab498ab9dc0000000000000000000000000000000000d386d0af32f630bdf6c13ee82fd35e42961ec4b11ee8fa196d69bed775b8ecfe74409693c531631aa716957e5fe6d7000000000000000000000000000000000ce8a020608c1e7d70d7a03d11b84f48d6b3b77c5836b7c914627f3a84d3d0b3de513029c1379b20ee38a19928e57f44000000000000000000000000000000000dd10882001be7fa52ff21f1a0adab02e688539f098901fe515b61fbdbca02c4146f6c17f7ad7cf59f5e8acd85da60b0,,,invalid point: subgroup check failed +00000000000000000000000000000000167a40d69e2d2e5683ec69af7b226c5456d05241d9c9eb24e988ee2dba845eab361a956cdea64cf971dafea08f0056260000000000000000000000000000000014e5b8ae5032a924da081d3063f31889da110d00330903c6f988684b7d77b7b1bdcbefbf70941d0eb5a34bcb010a3bf200000000000000000000000000000000043a000741027fbd191e2399b7cb5fdb4db3728d81d8b9d25362e8a1d397ec99d1b2339a3a511d0969e7e727f98d4163000000000000000000000000000000000cbda70eab332bf962d123aaf08b8b96680055f1946dd5fdb8818fbb330b816d83062ffaa79e18f1f4f6d53deda53cf200000000000000000000000000000000160a7048e508da288270e8ac5793e9461eaa282b85ce5350b6a661209efa6699874aae71515dc4265125d490a5771ff900000000000000000000000000000000041aa7292f258125d729c1761a3a6f7979a7a92ff179be678ebe301de3ffe12e4a863becbfb2bd0067e42aefc5f5617200000000000000000000000000000000167a40d69e2d2e5683ec69af7b226c5456d05241d9c9eb24e988ee2dba845eab361a956cdea64cf971dafea08f0056260000000000000000000000000000000014e5b8ae5032a924da081d3063f31889da110d00330903c6f988684b7d77b7b1bdcbefbf70941d0eb5a34bcb010a3bf200000000000000000000000000000000158feb06ab69f5da37037c554aa8b4b511e9de7e13a08c2f9a8899f5a504b191195e4de1ab7d937913f60e24a1b3d3f8000000000000000000000000000000000beeea216d85a767af2facfa7fa0399c095a23b7a974ddc3d36b7e79822d7691e53f85c976b8cc948e155f196b7f168c0000000000000000000000000000000009802e94ad5cd6b071a0911cbbc1de29a79a5a4fc145cc79db03119c3c8dac88fa3740bdb35b0b0e6e34127ee1bb081c0000000000000000000000000000000004599d1e0bfe642ff275fbf1dc86bbf83b87c241de09570183faf4e2c1cefc6b8b2354aa2be4aa9f69d6d61546d3a685,,,invalid point: subgroup check failed +000000000000000000000000000000000130761fb4d4720b8e69b849e1472f15c24cf909920c598aaecd34c5b420a1989a6ea95f89c362a61e4a11f88982f9a6000000000000000000000000000000000d707b24e8720ecd4a14d9f658060303d233253caa63bafd0f475b2985fcebd326924c936a9d66b21b9a75085aaeb54e0000000000000000000000000000000009faa74f66ec0384f0458893c0026f73688c764e8df9ce056a88a2ed0b84ed8f88d1b683443a3269a3db838f8aeb808a000000000000000000000000000000000949c4be2708c1aac86aff39290ab6a8e0f332e7a098bbd64227a175473d9dfe136e07548b282f69a94a15e2c32dada10000000000000000000000000000000014f2c7c7da781e2f50803e3a948381c3c439b127949f79824df1e5722c206efccd6c0ec5dd75ef63d8b1fa301c83356900000000000000000000000000000000176753460d241f38aff41bafdad51688ab0dc9a5fb3643977c7b9d282ad4532fcca1e725715227780ec28bf1c32bbc1d0000000000000000000000000000000010ad2405965f283c845edf92cf34508c0ca625816690d739fec9776d261784a946e083112d11c0776edd04403eaa5b820000000000000000000000000000000007e400896eaaddf797643b05a53f612f73737a2c438762d3f6216d53761f28bc88f402a4f02f36d26bbb431616b1b5690000000000000000000000000000000009faa74f66ec0384f0458893c0026f73688c764e8df9ce056a88a2ed0b84ed8f88d1b683443a3269a3db838f8aeb808a000000000000000000000000000000000949c4be2708c1aac86aff39290ab6a8e0f332e7a098bbd64227a175473d9dfe136e07548b282f69a94a15e2c32dada10000000000000000000000000000000014f2c7c7da781e2f50803e3a948381c3c439b127949f79824df1e5722c206efccd6c0ec5dd75ef63d8b1fa301c83356900000000000000000000000000000000176753460d241f38aff41bafdad51688ab0dc9a5fb3643977c7b9d282ad4532fcca1e725715227780ec28bf1c32bbc1d,,,invalid point: subgroup check failed +000000000000000000000000000000000220d192e0c635f05870113aac899f996622cd21ad251fb4c300a0ae0051dfd93b0b622f54e149fc4e5bf280ef31b0c6000000000000000000000000000000000dcfd7def563a0937b5173d20f830e6a2350a9d6f1b8a2193e5f755142e850bb7f95519ca187dfe735c197c21688528c0000000000000000000000000000000002479a989dbf27141bd9f467447218dfa6ef60781a7231f089d5f1f1d8dca2ce9606a75c09f63f37f9cc1ee61dceb32500000000000000000000000000000000037c2f1b96170f6847138232bac663e4940bca602717c877f58ff7f5259778246085d499ec6bbeaade18f738df333cc700000000000000000000000000000000115a30e7b71e48efc7166b9a8d2e1ecec6c6e4c058065a18277ca547cf1ebc193e635eb9b65d14c9c94ebde3c83a55dc000000000000000000000000000000000b68916150436f74c61b071a339909f78701d1f3045f7201f076991d7447570fd90887126ca54d96c1310e59ad489190000000000000000000000000000000000220d192e0c635f05870113aac899f996622cd21ad251fb4c300a0ae0051dfd93b0b622f54e149fc4e5bf280ef31b0c6000000000000000000000000000000000dcfd7def563a0937b5173d20f830e6a2350a9d6f1b8a2193e5f755142e850bb7f95519ca187dfe735c197c21688528c00000000000000000000000000000000147610c1075d625dc36388a2bd451ad2c15eae8cbd30393bb9fa30fc233b29a0f5483579752a748bc0f5ca9c90875e0e0000000000000000000000000000000003dff69511f2a53e859b6769ef4c257acf31062eb72f8668f57da60f225ac052badef9df25d43148b4d3baa64c29eccc0000000000000000000000000000000006d2a71dd9c1b302e22c4cecd14dc385e068e63e28e167c060de3ceac8410461d83f961c9292cad30afc0084855ebf1d000000000000000000000000000000000890ce53931aa18e42f00379b40c8e205582f71707a67761acced851fc91755505ae960951dec4ef46353b66e0b928c1,,,invalid point: subgroup check failed +00000000000000000000000000000000050ae21faa31371d791e3f6163f1c18c577367badb337aa6fa7c8214ec58bacfb24300a81d8226e81d7f47730c734386000000000000000000000000000000000987a0c7abd7c72140bcdba9cf171389ea7971493187c567b0970f05d129b4202124d72bd01038bc77023171de379762000000000000000000000000000000000d4b71595321913e94b9e6ee6ae2391cd5037e8b55e61fd96c745539bcb4bc4fcbab678749f6d47fd2c95001da4715f70000000000000000000000000000000005436e1be9029a2f7cfac51a305fbb7e760a9171c79a5bfce6b161493fb2855df09b3345ddbc8b04318c6b2e0225b74a000000000000000000000000000000000b8f317d36c50c8d039ad137f7d9adbefb3fc147a9cfd6cceb02c75b95fe307c3d6f673a216484f3211f045c2ba9012c000000000000000000000000000000000156bc67e17c8eaa905fb7d9f3f251cc81eeecc86de791c8be30c34aea896755fe2bac28cdb035222afe6237614878c300000000000000000000000000000000065856fe1dcbef934cef47b177ecb7df76cc8796624400d5c0518aa9438bcadf397234808d099bed89ab674560ffbb1800000000000000000000000000000000071b2ff64379ed3e20cda000602c3504616dd673aebbe7690e797d6428ecfbdb29f11138169f3462dffd319cad68b96e000000000000000000000000000000000d4b71595321913e94b9e6ee6ae2391cd5037e8b55e61fd96c745539bcb4bc4fcbab678749f6d47fd2c95001da4715f70000000000000000000000000000000005436e1be9029a2f7cfac51a305fbb7e760a9171c79a5bfce6b161493fb2855df09b3345ddbc8b04318c6b2e0225b74a000000000000000000000000000000000b8f317d36c50c8d039ad137f7d9adbefb3fc147a9cfd6cceb02c75b95fe307c3d6f673a216484f3211f045c2ba9012c000000000000000000000000000000000156bc67e17c8eaa905fb7d9f3f251cc81eeecc86de791c8be30c34aea896755fe2bac28cdb035222afe6237614878c3,,,invalid point: subgroup check failed +000000000000000000000000000000000e4bfbc392b1de6b17a32387d694f634cb484be4531f425d72833a30ed5aa73a958d5081b30cf98484762ba51542f87b0000000000000000000000000000000010e6acae9df1b5567854f4bbca0ab07c6a0e726bc6ec7a1d2ce8b04e1677776d0ee2642950db040365d581a52a41832300000000000000000000000000000000036a2ac8ecf17fc72ed792c0d8939060117aa0d6c13854fdcf56ed0d1ed3b39da9a67aadfdff484850f9cdf439495712000000000000000000000000000000000a1bd875b74e1ebec19591eb137e68ca7f0db1b3056d341b6bad28c3f45e87688e73fe28e9ef44c7d494442ee0b9472e0000000000000000000000000000000002e26e5a36c008bddc431048d999b7fb44961bb4d931b2dec0cb1d1b0987587f44cd31d429a6cef05d3c060ac828ba7d00000000000000000000000000000000050640087ed6c04ffed759f63e211ff5880c8b06933c1e812954a7a4240a9c644175c4ca3048a4ed68d034f6cbdcf175000000000000000000000000000000000e4bfbc392b1de6b17a32387d694f634cb484be4531f425d72833a30ed5aa73a958d5081b30cf98484762ba51542f87b0000000000000000000000000000000010e6acae9df1b5567854f4bbca0ab07c6a0e726bc6ec7a1d2ce8b04e1677776d0ee2642950db040365d581a52a4183230000000000000000000000000000000003fea73d9ecfb879ea601865d3279ef9b271fdeb14e1094745d5718bf214f1fba99245746716bbf012e2ccff5e22887d0000000000000000000000000000000011b1aa3049157abfa01f3bef33583635873d4bc66801785f41ca51b9a11d95b49a8bbaa543fbe68db86c3560ae258954000000000000000000000000000000001740661de7e1b6e1eff626acc4e37c877d00a0ceb8008d99e76a1dfe826b4dd0ee69b150535caa20386d644394dcf6b800000000000000000000000000000000090c0bc61286187a58f2cf49e2ce6f49d721b4146d973dd7716db271da770450dcba33b7aae37d6842a43063c88704e8,,,invalid point: subgroup check failed +0000000000000000000000000000000002cd3682c1f87aac1ea91b3f4ac577f0c9531c7702864c444b4163435b4770c9a2ebf94fae2d45a63adecc314d9d536400000000000000000000000000000000103a1eaebc0ee53e21d5bda78bd912f20cc28a13e5e209e062a52ddec3453fa9c364a6b403a68d9db8a40a07755ee1eb00000000000000000000000000000000024494aab30849df790185a4f939954b724c387c9a366fbe833b628577654174f705d05e7d7dbcd29b8873aecd55df0b000000000000000000000000000000000863054fe3e4838d2caec7103e3d0453e86a17fff0dfdb84dd819f31756032e9e97b7be89b636e5e0b642718f6da217b0000000000000000000000000000000015c8bb4fcb6d9cf941b722136d8d76d847fd6d5c643f4c0049c9746e76e49726fd463ce7899f4df66d04e5d48e523e6a000000000000000000000000000000000f101bea4e1bf610d2782ede91da95eb2b0be9ce60485465b9e94cbb9530b416c4394862f0ba7ee8067bb48e94c07c530000000000000000000000000000000001b32ce5c51441e1abbbcc0b6af95380f2de24876ba377ebea44fede8886acbe23aa18681bb08130252bc04193939853000000000000000000000000000000000e5d718c9980140b41fb971fe596070982bf92937df77ef44040ffc27162bb443a60f5c64411ffefc24524ff32fa17ff00000000000000000000000000000000024494aab30849df790185a4f939954b724c387c9a366fbe833b628577654174f705d05e7d7dbcd29b8873aecd55df0b000000000000000000000000000000000863054fe3e4838d2caec7103e3d0453e86a17fff0dfdb84dd819f31756032e9e97b7be89b636e5e0b642718f6da217b0000000000000000000000000000000015c8bb4fcb6d9cf941b722136d8d76d847fd6d5c643f4c0049c9746e76e49726fd463ce7899f4df66d04e5d48e523e6a000000000000000000000000000000000f101bea4e1bf610d2782ede91da95eb2b0be9ce60485465b9e94cbb9530b416c4394862f0ba7ee8067bb48e94c07c53,,,invalid point: subgroup check failed +0000000000000000000000000000000006e340bc57495a5c01bd44eb6dee60e94feadd69bd0274e7c9755f7b0e7b4e59eb70a2cd7e4da9d1a5f60d93a5df19080000000000000000000000000000000013d7c393a2191ac8d13a0743fecd768a7e15d279be409ccea1d58ba39e91f592b425955ddfc8443861a2899de02cd0fc000000000000000000000000000000000369067d9012509bbc75333fcfa37cd42dc3d6331a55b4720f9efb937916692ed7c7cf4739142ea13fb9130e9dae92fa0000000000000000000000000000000005306d73dd33e26ece5d8cf2ea8d7e25976f7b95dc7091420c2e91b1d0b2ef96db69a364c3cdc3b24a49ec5e307553490000000000000000000000000000000008a9fe15ea4e16e675c42c25b29655683844949b9aff4448f0b79ff08ec2a6526cad973f80123943b863ba9f30b45666000000000000000000000000000000001754caabe499e1ad04ae65d696507096939dc826578db55738e5024601eb052a9fc15f20b601253533847f79a5f6a6ae0000000000000000000000000000000006e340bc57495a5c01bd44eb6dee60e94feadd69bd0274e7c9755f7b0e7b4e59eb70a2cd7e4da9d1a5f60d93a5df19080000000000000000000000000000000013d7c393a2191ac8d13a0743fecd768a7e15d279be409ccea1d58ba39e91f592b425955ddfc8443861a2899de02cd0fc000000000000000000000000000000000ddc7df1bb36d54beb969a244a67c3ae87cab2eddce9397869421999497ab00a3e0ee29e384f3182b52158304790b05c0000000000000000000000000000000006f527de4412dd61845ab1e4536a114c7ac2bee2f3d22c16c660b3189b1666849f70462d6d650846331dc630dfaa075e0000000000000000000000000000000015aae1fad9e6cb3adc8bd93c432c9321a9d2f7cb961671c8e517da7024d1e35b519a2cc662d795173441479fa35f2e830000000000000000000000000000000008485999f40a4a363ddb3da273f7522344f284fb5bcee383a590c7c1287baa10f21312428d6818eebc96ec59d716fae1,,,invalid point: subgroup check failed +0000000000000000000000000000000015845de9692590d7fbf4187b50f4b2d067983b0a2209ed2bc6d60914be106decc5dfefba112baaf98ba3bf9e4d102b660000000000000000000000000000000004f2ca0858d056f769bc8e6ebf7cca745ca647ba497940b25b31c0541297626cd26ac10f8ae8476b5c868a95226da290000000000000000000000000000000000b1374a47c7c1c833f3856b0fe5ecaefaf2a8f96148eb540482288b56897d9e7e4269ea3a2c3742993b751bd9e484f2d000000000000000000000000000000000bc7fadac70d0a401e61683562cc83ffe107924ba1788bb6e06b0c60f22de0d93b10b63afcca343cad0572209b03b12b000000000000000000000000000000000c22c75d826d2700a8bad4e9c271d8b505ab2911dc257909c69dfdde2bcf332e5f13592eccabf578f48f6078550c1e9c00000000000000000000000000000000057db54159019d1e291131d28a936ac1337f2884f0c4bfc4d8adaa75bc0edf8b0f3030725e33a3d1a2e7e9ea39512fc70000000000000000000000000000000000232940188006769a382a4958383aa6702b2cbfb9c2907a989938ac618f23e241767b021e8ae11c23617ab393d4f85a0000000000000000000000000000000016a672061fe76ed943e36b2d6fa4aadf579db96eba5e4c60cda2884ddcbb0f37668638a3167d8858cd296917eaeff8e0000000000000000000000000000000000b1374a47c7c1c833f3856b0fe5ecaefaf2a8f96148eb540482288b56897d9e7e4269ea3a2c3742993b751bd9e484f2d000000000000000000000000000000000bc7fadac70d0a401e61683562cc83ffe107924ba1788bb6e06b0c60f22de0d93b10b63afcca343cad0572209b03b12b000000000000000000000000000000000c22c75d826d2700a8bad4e9c271d8b505ab2911dc257909c69dfdde2bcf332e5f13592eccabf578f48f6078550c1e9c00000000000000000000000000000000057db54159019d1e291131d28a936ac1337f2884f0c4bfc4d8adaa75bc0edf8b0f3030725e33a3d1a2e7e9ea39512fc7,,,invalid point: subgroup check failed +0000000000000000000000000000000018611593c7663a36330e0640bc912221a17d0ec9d2a250f1701303249655c7088bdc07b024878a260753d1dde306fd4900000000000000000000000000000000069d26308af5907c15532f31dca8c884b9e54a0da5e428c66fd79d980774cca106e2ccf3f93fe3e01669c594b9770a800000000000000000000000000000000001a38d296c4b7b8351164b935b915c08caf6af9d5233ecfe609e4ed855589bdbc9fb0adc55bb5cc6a2526bd82ab9287f00000000000000000000000000000000184ac28f62c7101bec49879af5da794740f9ba99afab4fcb576fa1149f3b701079915934c624f022b0d3213adc884c2c0000000000000000000000000000000004f64835227f459e76aae3397dfe53eddb1e97c8afd8beaba09382fe79ab378c3f03d6962dfee823c426cab426e51d2d000000000000000000000000000000000577263fd875f6388b723f6abc78aa3b0cc2e6b0ab53beb59286e30d1e982114c161fc0ef490bb1347fd8a3f3cba72710000000000000000000000000000000018611593c7663a36330e0640bc912221a17d0ec9d2a250f1701303249655c7088bdc07b024878a260753d1dde306fd4900000000000000000000000000000000069d26308af5907c15532f31dca8c884b9e54a0da5e428c66fd79d980774cca106e2ccf3f93fe3e01669c594b9770a800000000000000000000000000000000000c072a812b26927b5a672359032e71597002d8c45572db6c575e25c81181a522ca304867b1bcb583c58b2ad6bb1695d0000000000000000000000000000000003c4f5f548f50e835f402105cbd315081e0e8773dd91f3874687ace6fd5ffa66b6ebf6dac4580357b870f8835ed15cdd000000000000000000000000000000000f039e2e73334386b28ed4cc52db09b69c942c0c87f81328a9b7fbe8553eed48a60224ae9d52baf4f62a3fb0d58d451d000000000000000000000000000000001974da8867204f048b81d0c7a90d224dc5b87f3c4f47d1dfb09afc292430bf51d69e3538fdd13ca0749dee76c2ba9b17,,,invalid point: subgroup check failed +000000000000000000000000000000000754f3a9ea93a01fa244ef6badeac64fbb4dc81d3489c4195a01148e268e2af46011e6c593b4b873fa1470eecc6f79ef0000000000000000000000000000000018043830aa55a8c7efd5dc246622c71bbb4bc6a5d69cf594f46f62d8c3e2a5d4ba1d3990b5445f8b446e404a00259a8a000000000000000000000000000000000e49e94cfa35d8ade2b76865cc8be04737d00b48b195078c8085cbe782232a544cdb548373bd8ad0282674ba5c96fe0700000000000000000000000000000000047d59661f095c41bcc27da5f260f13a3fce334bba216b45df548894bdebc691fe779ccd63d99a9872973ab165a90c01000000000000000000000000000000000772e9a9c22bc7352fdf74915bc464de99ecd96420ef1af6e8bd5a05d73fff89c78e28eb340d4967e906f28afe1320490000000000000000000000000000000018bccff27bf9d7cb2159b9f2d1faabbf8591b53ca8e67e661d9f44f6dba6296e3e46ac32c50128bb5fb076cb8f214e27000000000000000000000000000000000252149178c606d2d6c0311e9f4a66cf348869efc09ec887cf99088ec754c01551796aaf168dc1a09cb741ab3c9d6891000000000000000000000000000000000db7baeeb5acfb22d680e032965a4d417b2f2f6717d3667d786e006327140c1288ff44842142eb1d2730b3be64fcf420000000000000000000000000000000000e49e94cfa35d8ade2b76865cc8be04737d00b48b195078c8085cbe782232a544cdb548373bd8ad0282674ba5c96fe0700000000000000000000000000000000047d59661f095c41bcc27da5f260f13a3fce334bba216b45df548894bdebc691fe779ccd63d99a9872973ab165a90c01000000000000000000000000000000000772e9a9c22bc7352fdf74915bc464de99ecd96420ef1af6e8bd5a05d73fff89c78e28eb340d4967e906f28afe1320490000000000000000000000000000000018bccff27bf9d7cb2159b9f2d1faabbf8591b53ca8e67e661d9f44f6dba6296e3e46ac32c50128bb5fb076cb8f214e27,,,invalid point: subgroup check failed +0000000000000000000000000000000003455a16c1cf9a408bf17cbb0b8ec2a5f24ba41d5b8a06a10750797f3371bcf361d3b6902d73949df3a24f5a8b9977c10000000000000000000000000000000016480e13653604d05f025b8264fb35a2cf06dc6a90ec7751ed80ee81cd064864655d133ce398e293c289a572dd98605e0000000000000000000000000000000015015aeb1965917cb5b55092d7eeb54915e21fbd5b9a62530b3dd5b8ae07d6f491df46e1987f565223a83cbc90f91735000000000000000000000000000000000658266a6bb01958b791b288ea9f5e138316724398218be522bf816ee5b5b34ef4acc83b82959f52792af6940816bb41000000000000000000000000000000000bf8d18b55a57e67c76882f1a1ad845480196f28556ef569a6a6054426bfa39459ac030b594201be76968cc33c301dd4000000000000000000000000000000000fd8b264f9bd71e00e3987cd221d2e9fbbee34ddcc5c563f02dd150451050bd20b3bd3a6ce1284fb0ebff0c6c1318fa10000000000000000000000000000000003455a16c1cf9a408bf17cbb0b8ec2a5f24ba41d5b8a06a10750797f3371bcf361d3b6902d73949df3a24f5a8b9977c10000000000000000000000000000000016480e13653604d05f025b8264fb35a2cf06dc6a90ec7751ed80ee81cd064864655d133ce398e293c289a572dd98605e000000000000000000000000000000000c5c8e759f71292c8b25dca51bfd40daec58d2d2befe991b27993ae32489b3ef70c0c3f873b3f47ffb013fd31732f763000000000000000000000000000000000a78f4e402668544cada859953182f14421c54446c264312daa5f27cb18a3955a277e5620b0f28f4f9bf233c49f3341f000000000000000000000000000000000e27d9b1bf12c01ab05fa5ed5b2e70444c0582aa5b430d0e10feb69dcddddadeec88c024ec87e23737ec1385461edaad00000000000000000000000000000000065984e81590e368aa6de051129761e94ca218df58ec0132ec22aa7d4128b9ace20e7da35c56a674ed1031d202e9f313,,,invalid point: subgroup check failed +0000000000000000000000000000000005a54ee5e3dc05c38ade7a42c71baf5a1467938f97c0cdf0742441cd339f22542b1ca6cd215d385b3fd6ba74ec996a520000000000000000000000000000000005f63d18f8bbc1c7b119ee0d58b688477129b2558be0084865297fe119224aec83b3633a646a3d423029cb52f0294aa20000000000000000000000000000000015e2547357626e6160105e5254d8deb80155c42d7b0c13bbe350c3395317913ccea5db61494aa2634857a8c83baa42a0000000000000000000000000000000000629ebc8d1798e2f9280493d2de7c159c558156782487d307ba358fd2bf696c29518d6cf2f975509bdefa89033f1cfa20000000000000000000000000000000011e3f568b9d1793519d5a8cd3bac7cf35091665f981ecb7a9e942f630c5f18fe7cd9747ff539816993b70573410410ac000000000000000000000000000000000889dedf6f29ed9959d8eb7276ae6122fec5a1bfae72c793902e1e3062be444b89a95129dd59f74ea0849b5a2aefd48b000000000000000000000000000000001963e29f92f6f72be2afa4635221b0d2f6afe9ada4582bd7ca4b77eb77fc4503578f38fb49aa1838751db8cf1ca0b0cd0000000000000000000000000000000009856a48f12966554afbcde1971499ee3ae40c9c5c3aef13bc415fddb97545ed84d5f50d2a26b9c16c4403a487dca6140000000000000000000000000000000015e2547357626e6160105e5254d8deb80155c42d7b0c13bbe350c3395317913ccea5db61494aa2634857a8c83baa42a0000000000000000000000000000000000629ebc8d1798e2f9280493d2de7c159c558156782487d307ba358fd2bf696c29518d6cf2f975509bdefa89033f1cfa20000000000000000000000000000000011e3f568b9d1793519d5a8cd3bac7cf35091665f981ecb7a9e942f630c5f18fe7cd9747ff539816993b70573410410ac000000000000000000000000000000000889dedf6f29ed9959d8eb7276ae6122fec5a1bfae72c793902e1e3062be444b89a95129dd59f74ea0849b5a2aefd48b,,,invalid point: subgroup check failed +0000000000000000000000000000000010df7793a66234599791ae07db9953bba83492389b150a05063105c191c6f32559b9533f1875ed154fa813586e84d0c40000000000000000000000000000000018de32e27e5c97b8b39380dde927e2143bca5d5591d770b2a7a77d7b59bdd533f04c41aef3a5a60df55ed90742869b7400000000000000000000000000000000182f0aa672674c27d8f3fbcc0fc7c1608c01188cf5c28b8ac08d6f99a4e3e214aa3ba61a19607b513b4d01f1d4424a990000000000000000000000000000000000b47be5b5249eab6f67aca9c9349d4a83956550cd21856485132c26e3be3ca133050d79507e2e8cafb67b44a7f4b4da00000000000000000000000000000000060efe7e7a4ca52063b49f6c839666deebe2e8e563de18b210fb477e86420aefa38f89e926cc41334e80f4d47d810d97000000000000000000000000000000000c2243c2a34286b146462a643979a72e75f7ff31f9f043164a5514d3e5da8b0cd891e97af2dd3d6c6f3584b390e5faf60000000000000000000000000000000010df7793a66234599791ae07db9953bba83492389b150a05063105c191c6f32559b9533f1875ed154fa813586e84d0c40000000000000000000000000000000018de32e27e5c97b8b39380dde927e2143bca5d5591d770b2a7a77d7b59bdd533f04c41aef3a5a60df55ed90742869b740000000000000000000000000000000015f7e6dbb904f4f1fbef282667d77c846c0dac6d78f4daaf32123b4326f1c6e42b15cb06ed7b3b46c8877e684ca7f9de00000000000000000000000000000000004a87f0ef3285709a3ded240f529e8e10991a82c7fb40de0bd256a9fafdbc212eabb8121f52c6bf67a45bf36246921c00000000000000000000000000000000156a1d58dd64734149b1e37b1b69fa4ea4452c40d2d041f5cf3de3adadf3bfdf433626fb96c46f9104b1c16114108599000000000000000000000000000000000fc3a0e58ed3fb583e2e1c3b0db5fac2a6d75694aa3d0732243b5a75688fa0ffb5fc9023545b9585df224ee9f6c5d171,,,invalid point: subgroup check failed +000000000000000000000000000000001639642196e9d6d720e17ace198232d1c0a7c05660c2766b9d28147504308ee48d949755ffcd1c95e024fa299657c8d10000000000000000000000000000000017a5975410b3a80e339b200ec63d7b7d550514653726e3ae6a97a383545118bd4221bba3e27922a826057b244ad025f30000000000000000000000000000000017aa7a3f1ebbdec6abe12abea12ef50a3daabbf96a5f2ebfb517885f0b7aba1e927c682b15521529cb9e1f87c59be99e0000000000000000000000000000000016e23f7effbb9dd34ec1f6974115e7f0d23cc4553d86e6d61a0c98f47d09510e06b3f987c5bcf4bc30e20ae9684da74e000000000000000000000000000000000f3905dd4f99cfcfa6152db53106b4d1f6e24518a822da9388d8ca1dd654a4b8315697328571691f105d1abe9aad3dae0000000000000000000000000000000006bfd10d33df9326a55b35aa6d2bc3e831d4c3b5959aaa35613156e5e19343b74e34ed2670c43ba1a45cd3d91f055c9a000000000000000000000000000000000024c53fb66f77329f70394626073ae298c6aaba115aa6af7bdaf3d2fb74a07441d46eeb398feec036727e86891db2030000000000000000000000000000000016b96c27d4342c47caafa584ec9847c79870eaebcce158535d8da95d7a847ecdc5057425fb3dd862303d1ac03162317e0000000000000000000000000000000017aa7a3f1ebbdec6abe12abea12ef50a3daabbf96a5f2ebfb517885f0b7aba1e927c682b15521529cb9e1f87c59be99e0000000000000000000000000000000016e23f7effbb9dd34ec1f6974115e7f0d23cc4553d86e6d61a0c98f47d09510e06b3f987c5bcf4bc30e20ae9684da74e000000000000000000000000000000000f3905dd4f99cfcfa6152db53106b4d1f6e24518a822da9388d8ca1dd654a4b8315697328571691f105d1abe9aad3dae0000000000000000000000000000000006bfd10d33df9326a55b35aa6d2bc3e831d4c3b5959aaa35613156e5e19343b74e34ed2670c43ba1a45cd3d91f055c9a,,,invalid point: subgroup check failed +000000000000000000000000000000000680d1062d24bb96b09d9dc9791364b5138e7c36c163589f919354101459de2fa76440616351d1d9bcd961673b106684000000000000000000000000000000000ca650f50b670befbf16d65b486e5c98dea6857862cf23d7bdd2dee2abc0855273495b047431ed03bb1c72b5403c2a4e0000000000000000000000000000000015b2586a23d909e6fd7ef6e58595817bec1389faed80db6d59db219435e7fb1b6492178a849c12bf6418341529d141330000000000000000000000000000000013ee3539c49e0c26e78f46c67b1e3993eed56c72dda43936b419e1340a3aa223ca09a2dca3ca56f2f9578b4a3f885aa00000000000000000000000000000000018e5fd242eca2314b3ade4a1e913177a499d72b539907839c5025b7de69efa24b08b3eb1e85fd05724db82b29edac344000000000000000000000000000000000478706e91d6213e4d4fd9a6c5051c88d86c7271aed7c74ef3b43e904f8ccfe4108f94660807316e8f1eabb85b734d50000000000000000000000000000000000680d1062d24bb96b09d9dc9791364b5138e7c36c163589f919354101459de2fa76440616351d1d9bcd961673b106684000000000000000000000000000000000ca650f50b670befbf16d65b486e5c98dea6857862cf23d7bdd2dee2abc0855273495b047431ed03bb1c72b5403c2a4e000000000000000000000000000000001600e44d53c706898736f5cccab585af5d04f7da91cad6f97b991b51adbc22ce27744f12c0a24804b6fc3dcc53011a59000000000000000000000000000000000751b090922b29f5c299340b12a56a77fd9c32f27995a59cd032cd09ead834d9faf5e151fbf7a0d810738de1beba5b4100000000000000000000000000000000114e35fcef45e87312a90fca21fef50c46b8a0f114df5c67ac9872ccadf858f319977138f03279ddd1edcab4602838eb000000000000000000000000000000000145c6cd707efd8d271dda5b9af26173e337a169c01b28a44f5d4ad06b125a05e867f0b1f873bbc048ea6cec06967c33,,,invalid point: subgroup check failed +000000000000000000000000000000000d6427dedfdcd624c896ca8e1ef717e212985ae23a4f830ee466c75b37ea2e994e7653b9717928f1be4583aae73f70040000000000000000000000000000000017be03dd7c9c14000aaec774812a8d8bc4aa2f1ecca9a894fd1385864b28a38091d3fb5706ee7c36086c7d50e35eb5b9000000000000000000000000000000000ce359fe7d997e151b94af2f5e167aa4834caf5a07ff056fe049d4b2c2780b35e8ecf9426444da4725a3e66de6691d960000000000000000000000000000000004c7ff987f866ff3919fb4769cc704928af09406c8f5a39e6fdcde5f4ef8a188cff406f853261bd3abd0f67c6cad1f3f000000000000000000000000000000000914584031ca57b9b0bcc35fbe76d967aee164b5eeeaa5e29c02901194fb0f88f5a249040c37ab47a715d34b2329a2b30000000000000000000000000000000007a42352ff521b8e6267a5d0dd1eadcb63db1fec68cff31bee1b2080b451ac731caf0efb86758b26b0c78df5cee8864800000000000000000000000000000000141d878adfaa6a3982cd0de93b4d64ba840a07c026ca443d6d4c2b6c36cf882e109d80df63b1626c112f9a89809788080000000000000000000000000000000005a5888d22a2f654a58d9a03c68d59cde9ab5e5356b2288033ba58fe2dbacf533e59344bdf30eed07698261d6269fc70000000000000000000000000000000000ce359fe7d997e151b94af2f5e167aa4834caf5a07ff056fe049d4b2c2780b35e8ecf9426444da4725a3e66de6691d960000000000000000000000000000000004c7ff987f866ff3919fb4769cc704928af09406c8f5a39e6fdcde5f4ef8a188cff406f853261bd3abd0f67c6cad1f3f000000000000000000000000000000000914584031ca57b9b0bcc35fbe76d967aee164b5eeeaa5e29c02901194fb0f88f5a249040c37ab47a715d34b2329a2b30000000000000000000000000000000007a42352ff521b8e6267a5d0dd1eadcb63db1fec68cff31bee1b2080b451ac731caf0efb86758b26b0c78df5cee88648,,,invalid point: subgroup check failed +000000000000000000000000000000000da87318eb51b90ca822bff1df4dbc040fb1d74129242d832e1096e813dec5d91f950f44bbb07980dcaaee3366f03a0c00000000000000000000000000000000157d5f5c8ad06af803b9362b22519a23def6dbb700db517c85a663bf1bef9665d6e81e9b02ccaac97f0940d223b83ac400000000000000000000000000000000176835484cf24c47b154b7c35877eaf5194e0e1d8f053842fb5ff8fa833dabebc887f3d34b825fe9cf2c374a2066124a000000000000000000000000000000000d31805157ecafb751536c484fd0c81664de9524a1420c969d54260dd5264bc5454a3234d1e5b090bbb8ee1066b685ee00000000000000000000000000000000196b4f58c12a7d7ac4d720cf9b6c44efdab88e06dad0023a01572cc2ba7bc0a4baf7fa45c06f04ff3d067ba191a84e6000000000000000000000000000000000038cb5d328ac9d1fab9c402b8ed9e72ccd462ca80075132f6be141457ec25a6c84a15e42b78cb64cf05ef18b003e4652000000000000000000000000000000000da87318eb51b90ca822bff1df4dbc040fb1d74129242d832e1096e813dec5d91f950f44bbb07980dcaaee3366f03a0c00000000000000000000000000000000157d5f5c8ad06af803b9362b22519a23def6dbb700db517c85a663bf1bef9665d6e81e9b02ccaac97f0940d223b83ac4000000000000000000000000000000000065c10395b93e8d04f5eb67d8e06e8649139d261ad8fbf5ff2c7d6d364c87837fa8e744834ec9341c714318195896770000000000000000000000000000000009fcc05ee486d42c3b2d480a309e4bb19563f7a27b4a10182ccb2d233ed42943ba472681d1f847249cbd11e4d79ea51f00000000000000000000000000000000053a516998d7c2b2bfa70349bf3f5e3967df827f65044634071450761ae8860e893824b1ae3f204b0ffbf8b091ddd277000000000000000000000000000000000d7cd03cc2cf97a164c7dd65b961df2866e82bf6fa979e56d0ca3f9638319772f56eab2e2134a33515dbcc137da8ec8e,,,invalid point: subgroup check failed +000000000000000000000000000000000be4cb58fd1dab8fccaa410e1c301be4fd2e7bae95cc1717d2aecaa705d717c67d7f20611dd1403d9350798642fa021d00000000000000000000000000000000075100bfbdb3f6271e5d8bcd4472580e56fd507b73aef3c3c5084d77e11a61b69bea0b85ba62885f7da36d223fca20760000000000000000000000000000000007649efeb3e0bee49b9adb13f8e5d7db1c06d7fde08a3f3082194153bf4b3615aff1450e47fae88ac93f55a389a319da0000000000000000000000000000000008334731582fb1b6125d7ee1da0124fe88f0c70a0a3f6188636976c31ba6a72beed927fe598386f328e4ae534729a57c0000000000000000000000000000000010b57d80fce5cdc90bc93b3bc7a1affadd19fb00aeec2ca9a6287bf4e40fb74616986a44f2f7d945f58501a965f37f3000000000000000000000000000000000180dcae46ee41bccd422b3cc2b34cad26f6816dd08ba51b2f12835e7439ae2d46933de28ac04bbcad68a188e7e90ee8d000000000000000000000000000000000a869358fd3d64849fd62e513db8fce1ab2618d3524acecbd04fef6b8c77703258cc557587f316cbb74bc5af5cb5551100000000000000000000000000000000059eb0e90e0910c24ee2145921ccee83707d8f89a188dcaae7d5c75b7113cacff92a2a030e67927bfec0da39f2bf65ed0000000000000000000000000000000007649efeb3e0bee49b9adb13f8e5d7db1c06d7fde08a3f3082194153bf4b3615aff1450e47fae88ac93f55a389a319da0000000000000000000000000000000008334731582fb1b6125d7ee1da0124fe88f0c70a0a3f6188636976c31ba6a72beed927fe598386f328e4ae534729a57c0000000000000000000000000000000010b57d80fce5cdc90bc93b3bc7a1affadd19fb00aeec2ca9a6287bf4e40fb74616986a44f2f7d945f58501a965f37f3000000000000000000000000000000000180dcae46ee41bccd422b3cc2b34cad26f6816dd08ba51b2f12835e7439ae2d46933de28ac04bbcad68a188e7e90ee8d,,,invalid point: subgroup check failed +0000000000000000000000000000000010eeac4d171a17d607dc544c559226db50d40193b435ce7528086eee21ec437e986c89dbe05931083768221e4bf06ede00000000000000000000000000000000140ef3af9f3dfe760e8c9dbe8d24abecfe611699ad337a97481a1553e9cabdb2e8a8cb48bc032bd02738cd26cd1388c300000000000000000000000000000000165bb8a97dd4b60ed7fa432f019f7f09a19c8e7a9b70e7370ae668d4597a3cf12c06fe062d880611e34ad9e586c193c00000000000000000000000000000000008c684f30de5c67f675e98400d854397e8cc6a139dca7e9ee179309a9617ce0ae034bfbd0faba7a2f9e7ee39de8770c900000000000000000000000000000000030e524c87a658e44df117fa0a877afcf8a4907979c932921a631a209dd58ddcaf693c7321c537e7e2a5adafe5761fa0000000000000000000000000000000000cd44b77f2d92706b3db5e374f13f6f12e3b030c6341d31e1c55d627e6af06a1b64498e590dbff08ee6354902263ff260000000000000000000000000000000010eeac4d171a17d607dc544c559226db50d40193b435ce7528086eee21ec437e986c89dbe05931083768221e4bf06ede00000000000000000000000000000000140ef3af9f3dfe760e8c9dbe8d24abecfe611699ad337a97481a1553e9cabdb2e8a8cb48bc032bd02738cd26cd1388c300000000000000000000000000000000062e54c21986cff68cd57903594d0e9f2f8348191aea6abc19e8b895e6ca59bf2eb731d10e426ad98726c51adc2d53b4000000000000000000000000000000000594d2a92e0b979c95daf6f78216be8c33ef23f0bebcda479326a1d63ec8234b283ee29fff7fccd441ab4ea6e17371a40000000000000000000000000000000019179f35ebf4ad9f8f9dd577b2db1ed58a988954b4bf4232301b713809be318e746f5b2bd663a21de755125f414bae9700000000000000000000000000000000172d8ad43611623865bff86df2bea58a02b7d6a2c41b85b98d6a2bd4f5e1bef25c978ac0bbb7f4746297c6e0e40b4e23,,,invalid point: subgroup check failed +00000000000000000000000000000000054dce4bc0b703b8957539c594d8d443fec161c3cb2f806f8eaa8158a665d84cfd551c0b7c0a08bede0cbeb780a6ca5b000000000000000000000000000000000cb3d3f9bbda28f8fe597907a76a8250567f4e481b6e9409e03ead60eab77153cf8f25ffcebb243a310094740cc2e2a9000000000000000000000000000000000a71dc159647864abd64655bf5ef956f21ad55529bdb49ac910ef628cc62a3d43b2b9ee26180232fa29f4b0e8371286b000000000000000000000000000000000c72d0fbe0a7604c9fab394b285ebf1c322c95013651bd21f88865e269eafa65e135ff90f5b249a794cef4e6cfcb56270000000000000000000000000000000019ac0043071372ba077bc8d91a4ac80fb5b8c8131981c4dfc698ba9ae50b506f93149eb73e4bc4f4ded94d6824473817000000000000000000000000000000000113368be2a531d2958d887c046fc26155436fc6a1ef44fdf16447163b7bc48fbb499506d8d5c8041d21116c4f22e685000000000000000000000000000000000b7244995b7819857f716288dc59eee9ba5ac7bfe010937ea0b67ee71388a3792e5b7feb6890a436db4f1b26df18b38c0000000000000000000000000000000009a0b73360bc0ca3b632c0116f21ffdaecf37e4d6c904c98d6225a08d7caadf5024ad6b457cf31b924118ea147ff10fb000000000000000000000000000000000a71dc159647864abd64655bf5ef956f21ad55529bdb49ac910ef628cc62a3d43b2b9ee26180232fa29f4b0e8371286b000000000000000000000000000000000c72d0fbe0a7604c9fab394b285ebf1c322c95013651bd21f88865e269eafa65e135ff90f5b249a794cef4e6cfcb56270000000000000000000000000000000019ac0043071372ba077bc8d91a4ac80fb5b8c8131981c4dfc698ba9ae50b506f93149eb73e4bc4f4ded94d6824473817000000000000000000000000000000000113368be2a531d2958d887c046fc26155436fc6a1ef44fdf16447163b7bc48fbb499506d8d5c8041d21116c4f22e685,,,invalid point: subgroup check failed +000000000000000000000000000000000cc6bbb9914ae46b57eaaa8d3d22274a355bd7488e5b537169c995ef2bee187ab66497423f14fdcd01373a609981b3ea000000000000000000000000000000000037d9461da369d186cd812a9ade7690b2b8b54ae386b7342a69af832ff4f51e5db9baa3c6b4a65d798a1aeb41d8787d0000000000000000000000000000000013a6e129d4dd4aa93cff5489ee879763e2a2231939e609d2d72f07e630b37d09f3057a36fd5cdfc9c81675c996f8ba0f000000000000000000000000000000000e8d7ad082e8f9a718fc2ea712853ed9ab4e8b1a8ca9988f77c70fc759f1fe2d4bd73696e539f130be13b2862efbdf770000000000000000000000000000000009897223b041568c9ef2884baa28477241e525de05f2c2f15441854a0e8660786a0c7b85a6d9d1074fed2b44d75efedb0000000000000000000000000000000007b52401891bd8003af4b07b04b15b79bd05fcb54739491352d295b5545ddba34da0b0aff36a3e7e4b433011be580174000000000000000000000000000000000cc6bbb9914ae46b57eaaa8d3d22274a355bd7488e5b537169c995ef2bee187ab66497423f14fdcd01373a609981b3ea000000000000000000000000000000000037d9461da369d186cd812a9ade7690b2b8b54ae386b7342a69af832ff4f51e5db9baa3c6b4a65d798a1aeb41d8787d000000000000000000000000000000000cca0d111237ec521889baa4987714c6bb539399b058b6635fd043821377fd6cfdb74923610c8235afe2be99188cbe820000000000000000000000000000000007fa2b99221675b38204c2eea94b2378b1d711ea5ba4f41d35c37f77ee2466f22c88725da9fcdabb6153292b7cd9aa1e000000000000000000000000000000001069adc30f99e0ddfd39775cee5ddd786fcc077cbaa8737f7031745d02f06168fd5d3c4936704d15955bcfa08b0925180000000000000000000000000000000003b388a8d9baabf0bf708e2fe28eacd7f704bc588185adbcea8e0a2bb8f9bc9b045918d97bb27b2033c6722b6e6692de,,,invalid point: subgroup check failed +000000000000000000000000000000001055ab14a2407bf095a954cf1c926f2c520dda187c44522a7e924e38543e5b87e7642227821a4e0b3ab0289b32161a060000000000000000000000000000000018aa24044066526fa9ed980ae7b3110a4fde7ba0a5fd289803fa5175d30766f01a266917f821169c7ec31fd46e1a14ac000000000000000000000000000000000b6e16f2a6cb821abc43c447da207cc3013f2f750c844f42f0fdf47160a38501bf502073bbeb565122bb3de61b3a5ab800000000000000000000000000000000040f5f3aab5d416e9a084fa298814f894ba599315fe10af20f836e624680582413b4a54623cda8ae2663ee094e4db775000000000000000000000000000000000d32ac715a094813c7b46ce2e932365bfd62ec5e584e047b0c56ed6eca3c58268ae01be31b833be7ba5c2588ebb9859d000000000000000000000000000000000850b9044f129e51658a02cfa49d40a2b09239823cba4d8fe423fa1b4815750811daf745e7e02b317a7318aad0734ddc000000000000000000000000000000000765a76c441227592ba30d6b1d3d9898467352398efc0e8416e0be8c9f87bcac8d5eaa5d7b2a8adfae8303909bef28da00000000000000000000000000000000107c0eff2fa09afb743c294408408451e3039da8db8c0beef32f07864223817075fa557a89244cdc293d631311773947000000000000000000000000000000000b6e16f2a6cb821abc43c447da207cc3013f2f750c844f42f0fdf47160a38501bf502073bbeb565122bb3de61b3a5ab800000000000000000000000000000000040f5f3aab5d416e9a084fa298814f894ba599315fe10af20f836e624680582413b4a54623cda8ae2663ee094e4db775000000000000000000000000000000000d32ac715a094813c7b46ce2e932365bfd62ec5e584e047b0c56ed6eca3c58268ae01be31b833be7ba5c2588ebb9859d000000000000000000000000000000000850b9044f129e51658a02cfa49d40a2b09239823cba4d8fe423fa1b4815750811daf745e7e02b317a7318aad0734ddc,,,invalid point: subgroup check failed +00000000000000000000000000000000182197c7a0cefeb530f51c664dcf8a74f9f70165ffc416ba454e9c356bade393e30d037347b1a020dcefb09ee65590a6000000000000000000000000000000001030be8d38736ac8e555d1681b14f73f2ca58faebeaff17b6006bf7876e733642d229075c8dfb0a9ba4e832e384aeb8b0000000000000000000000000000000019094370a6f19e946f587e9b117332ce5ad91860cc103015e94c6aac6d2c00f3e71471c241ea1d425e391707b27b851d0000000000000000000000000000000009ad1d1312011907676574a7867ac02059d9b0e29dab709f6ffc1b75b3598658427f10ab52d1129417ef42c30998f55f0000000000000000000000000000000003103495c759d8901898acd98679d92e048ca41244782045a6d9419b3ff87c351f97a333899fb445b8620099f7b9cce100000000000000000000000000000000051f7aaac39348f70109ae7a016026ea52c03e4ec90d03ce05aeea74f66bbf82e17be35cc45f492f50246f0de8dc68c500000000000000000000000000000000182197c7a0cefeb530f51c664dcf8a74f9f70165ffc416ba454e9c356bade393e30d037347b1a020dcefb09ee65590a6000000000000000000000000000000001030be8d38736ac8e555d1681b14f73f2ca58faebeaff17b6006bf7876e733642d229075c8dfb0a9ba4e832e384aeb8b0000000000000000000000000000000014229a1108fcd75131295caee98f8e4e075cf4bb5e169024e07a533f65316cb5d19193d3cfee8b2216663829be6d374600000000000000000000000000000000156cdf98f622a393d920b200e6d9efede7413137eceb79d66f85a18e33ef6946a515737c58e198f877fa39458877b99300000000000000000000000000000000006e5cee8e0f47c0ee4a574fcca6e150901a7de58f3f2eb3480f1ff8c14effa4bb9d00837501f22f6cc465e4026c9d7100000000000000000000000000000000124b6c0836bdd10657a3e1f978b48b9221b1cfc2767b6b99319fb69c5fdcc1b133f1c2fd093c62d6d1e398f32c4e8b71,,,invalid point: subgroup check failed +0000000000000000000000000000000019c9b755000f9f1b6ff22885f45bc1f5f65d080ecc129d29e1cd60aa14fd20646643be51d2fb3417cbbd39361bc72b62000000000000000000000000000000001741fd3c4a7e883094c0e84d851f45cc1b81af5bcace67dfddd3f19e8817697a386d1965a4e17c60b00ecbff84779b97000000000000000000000000000000000e87ea967f6c4dd7135efcd9a59368a2d19dd1385aefa34d7d9bd7f5094d779a7150667dcec463c9ab63d2ffc8ee4f6d000000000000000000000000000000000a3a010f176efe1a7bdb77dedf6b6271c845d662dca5062ebbac4e9c3b8946db0adfff37a6faa3196a99fb3ef05f09c5000000000000000000000000000000000350ad257d47f270c4340e3cb124ce961316573dea14c9584d20221d922a43c2e94324ec14bd1e4a1eb955861783a8f100000000000000000000000000000000070edff58ac1f8c13f62327cf0adbd748285fcd84ed7be23dfc82a0ae32f8c8f5f6b0679f795874cb0082718fb07a1ca000000000000000000000000000000000d5be6f99bb9a2379d1e542ece048164fa5d14e0c6c459180717b3da46e8446e9def576635ac1124e1390196fe97f39e000000000000000000000000000000001482d8339b402e3bffe61aaa298c8bae4286f1fbfc877a66e21cfe239bbee383d701d95a6c2b8193d67df5a551bb7aba000000000000000000000000000000000e87ea967f6c4dd7135efcd9a59368a2d19dd1385aefa34d7d9bd7f5094d779a7150667dcec463c9ab63d2ffc8ee4f6d000000000000000000000000000000000a3a010f176efe1a7bdb77dedf6b6271c845d662dca5062ebbac4e9c3b8946db0adfff37a6faa3196a99fb3ef05f09c5000000000000000000000000000000000350ad257d47f270c4340e3cb124ce961316573dea14c9584d20221d922a43c2e94324ec14bd1e4a1eb955861783a8f100000000000000000000000000000000070edff58ac1f8c13f62327cf0adbd748285fcd84ed7be23dfc82a0ae32f8c8f5f6b0679f795874cb0082718fb07a1ca,,,invalid point: subgroup check failed +00000000000000000000000000000000104c749e3f7b40bf6df55f9414bd146ac306b46a6210ae4ceff6fe2a58220ddbc69208ada5f692120dcfce39b1e43fb5000000000000000000000000000000000663a0e62ea68ac23a6e27958baabbb5deca3905aa138a54d6198724e5fdf0abb9288cdb52cf1d44e93f06571a654f75000000000000000000000000000000001116ecf077865395ea40fa9cf05753b87ac29ccf9ecfebfa1031fef0defa1d77634c2177647f069532e00f7fb657577f0000000000000000000000000000000005c7960dd84874fc00ab199d00e8bf1ea035a7eec443328bf2bc28d0006979f5032763a4d33f031e698895e03b27314f0000000000000000000000000000000004e00e32a506bff708c51fcc4101c8ebe7f1695d6a4606b6648b04710fdae313b99219963921451d0fc78dd59970ea8b0000000000000000000000000000000019dc4b721ec4a4303809c47da68099fc10706eb08cd4f6f91641ac680661e93a91e2067a84c12f9f55f84e27ed76ae2700000000000000000000000000000000104c749e3f7b40bf6df55f9414bd146ac306b46a6210ae4ceff6fe2a58220ddbc69208ada5f692120dcfce39b1e43fb5000000000000000000000000000000000663a0e62ea68ac23a6e27958baabbb5deca3905aa138a54d6198724e5fdf0abb9288cdb52cf1d44e93f06571a654f75000000000000000000000000000000000da3982205a45000b16e1ec7a48effad4ae1affd4acd8bd13fcdf2bf05b6845ebda9be2df6d6325389d711111641aae500000000000000000000000000000000150c1bb67fe3d88dbfb452d5b4582d9a1c350ac01cc209740be70d63e266c926cc6b0171eaea913b7456daf595b83ce900000000000000000000000000000000138d0bbb52fb6248731c8fbb6818d1379fc5c2549a5a0d663a56c41b3b2e8c7c4fd77830c455a40e59aaa65124ebcee50000000000000000000000000000000015e6b4628b75f9786ee26e41cb8b86c6e6a97ac18aa7662b39e9c96e169a3192b64b863d7f9739237255fea6cab12fcb,,,invalid point: subgroup check failed +000000000000000000000000000000001638395680014bc04e2ca42bf864dde47a0d708ae81ba4a6aa2e2476837750aaf5f9f6e41a5a23df432ae92fd221737e0000000000000000000000000000000009419792539e0ae995b8d853d9ef513bc54766475e37bb3dc2dae3d7fb9b02b0eb2327f24a751d2de344b9f5131ef23700000000000000000000000000000000197ff997d6c5efa3d7de8e16f26082bf13a2401d6df5f5c33c6614c36105f347e40216c907bdad9c1df6ebbd44f41c3f000000000000000000000000000000000f27a0bf92329730d776a83583177993b2b354a212a9c004f9f8892a750c477b8d1e68c13127f03b1629bc8392d06f5b0000000000000000000000000000000011b239cc6914a321385d907527b85713a0d842f5be80752f4c5758586dc1de944b6e4578bbe324f16838115e9c866bca0000000000000000000000000000000000cf93c5b48cd9de51ccaa45124217cabf466d07d6fdf4a7bb810443339ec4af5b74931bd07eb9fd31c284c05f3f539e0000000000000000000000000000000010b91e082484fff0da28b06f06e02c699d741f2ef788250e3fbf2ba8fc1d7d78a1ca63b76dadfb71015fbefc0eb70eef000000000000000000000000000000000c2fe842c659c875af0f2cb1a978ac9058981cc6c76ff057f326162d4322805974505e6a35499bd0c58b5d6db3aa222900000000000000000000000000000000197ff997d6c5efa3d7de8e16f26082bf13a2401d6df5f5c33c6614c36105f347e40216c907bdad9c1df6ebbd44f41c3f000000000000000000000000000000000f27a0bf92329730d776a83583177993b2b354a212a9c004f9f8892a750c477b8d1e68c13127f03b1629bc8392d06f5b0000000000000000000000000000000011b239cc6914a321385d907527b85713a0d842f5be80752f4c5758586dc1de944b6e4578bbe324f16838115e9c866bca0000000000000000000000000000000000cf93c5b48cd9de51ccaa45124217cabf466d07d6fdf4a7bb810443339ec4af5b74931bd07eb9fd31c284c05f3f539e,,,invalid point: subgroup check failed +000000000000000000000000000000000ac27e4d19924f4bfe30432554f25d456cdb4724c106409e46612e1c91e8cf5fc2cdcd6b6fd6bfe040e910795441befd0000000000000000000000000000000007e9227d849e467fbf5fadcc016dedcc04f4c66f23464195782746fde628a107d77ca5b5c9bcc8bbb14fc14208fa5de300000000000000000000000000000000094860f23d182a14d1a64d9693ce9309ef4e775f24aa3807571c9b8281fc0d6157cdb5a00b34b66be1849994c264c4b000000000000000000000000000000000062b4a3ef95b2522c894c0b492673c3800fdf8645998a899e27dc3a23c0530d96b558d1c6364477943726740cdbc88f0000000000000000000000000000000000daa2f2f2c1020339666be4b1c1e12f8d44625a9508bc5590314789d02fe0e2e676d8d240bff89b669b9290fe1d0f8a8000000000000000000000000000000000f7a710af0b04d20b7d515f2627b572a5a17a13975ee81bcb8fd90600d5fb2f161a9ab3635bd16649c95385bcd604f5f000000000000000000000000000000000ac27e4d19924f4bfe30432554f25d456cdb4724c106409e46612e1c91e8cf5fc2cdcd6b6fd6bfe040e910795441befd0000000000000000000000000000000007e9227d849e467fbf5fadcc016dedcc04f4c66f23464195782746fde628a107d77ca5b5c9bcc8bbb14fc14208fa5de300000000000000000000000000000000055d8c63d7c04bf5db81465f2fc372b798d77ab0ecf795bf57debeafbbc8998f91f71b0dbcc440e70df3d5a1cb682ad8000000000000000000000000000000001497d9519e835c0644d30ae38ee66faf39b1939320c2e0a45b7862508ea3bd7eaa3a754a679bff81af26c6aa141adae00000000000000000000000000000000001be6ce3109582f31e02051ef0e4d266f310048e04a7ac8dc5e04d2b7f2766440f1ae63e5da6dbf831b21fd7cb9cc0a80000000000000000000000000000000003d4acbd20192ee2fc55acd5c90cf5b897cb42a4c0a777970d11955cdf11d5ab22444ac9cfb666c3e509ce832cef219f,,,invalid point: subgroup check failed +0000000000000000000000000000000015866ee89fe4f68e45155fb98124e8453e1ca25347d84f70ebfc32cf76c5d48e3a3e5ccfb1b505db7b493cfcc73ef92d0000000000000000000000000000000013deaec2d2482c457050256d157968ea3d15f9b61b4573353e83daf824b28289343bcbc3bf97ecec9d65ad08804861440000000000000000000000000000000013467fcb424ae0eb012228fd2083d92e6d242427670ca6e2cc1166166edee5a94b78d2c2f8715a996bf2b4e5112e49f0000000000000000000000000000000000c23c01e0061b0fc7579723e072b12e86c8f12f4c2a039bdc5b1f3384441ccefec187e0380efae31a819d92fd6462ce80000000000000000000000000000000014f9a055a5e468955f6d7485fdffed2b33174777f99d9d0af160b0a083912b05da45f35c73053120f61525c173a24e59000000000000000000000000000000000cfdcb6adf8f04fac2cba8f322339fb0614f46b77b0d91f0ec167eca06fcce080ee0e63023fb94712dbe7591843b6fe1000000000000000000000000000000000d90bd38049f2a8de869d8a748c9ff3120542f38fca6e8d5fbbff86baaabf0f19dbf449cf23c043dfea322d99837f7110000000000000000000000000000000000ede89c8bb8299726ec685765f10167c5b844e427d3c15da6ec2c1d97de174819d52caa96d5cc938e93dd09bbd1e0d80000000000000000000000000000000013467fcb424ae0eb012228fd2083d92e6d242427670ca6e2cc1166166edee5a94b78d2c2f8715a996bf2b4e5112e49f0000000000000000000000000000000000c23c01e0061b0fc7579723e072b12e86c8f12f4c2a039bdc5b1f3384441ccefec187e0380efae31a819d92fd6462ce80000000000000000000000000000000014f9a055a5e468955f6d7485fdffed2b33174777f99d9d0af160b0a083912b05da45f35c73053120f61525c173a24e59000000000000000000000000000000000cfdcb6adf8f04fac2cba8f322339fb0614f46b77b0d91f0ec167eca06fcce080ee0e63023fb94712dbe7591843b6fe1,,,invalid point: subgroup check failed +00000000000000000000000000000000119c7c85e5efaf08b91dc496758b962098cc0eb60f4a770bfafa91809ae4a95b43f96b69c8ddc897701487f22d2e049c0000000000000000000000000000000007467ac896ae9f7d2cfdfbab082c89d3c17a6dfdf1f69b4b38fe6d5ede6848a45e8b0d728eb8c68752ec59c8e0504dcd000000000000000000000000000000001047ce33c70d58e3191a558ce2fd95c20bb62abae7d924cec8a4067fb33e8dacd796d65c049be7bacdb969f61db5b26500000000000000000000000000000000096e7081a7b2377331f86d8418bd577cd5cc1d45e60d39b519ff2b3a50ddb2d5f6dccc0066167f42498a3d29ef5ce2e30000000000000000000000000000000011159939a04c129b007f2aa2d59ae006e8d89c41dd465cba551737d06d3fb2c1161aee98e86cb8c0321f42e514316030000000000000000000000000000000000c25d9cdc8dbeec82c47d5ef12f21a7e58a8eddc1e738e635ba04f2ebe12440090f432c0d1518217a5531266441f1c2500000000000000000000000000000000119c7c85e5efaf08b91dc496758b962098cc0eb60f4a770bfafa91809ae4a95b43f96b69c8ddc897701487f22d2e049c0000000000000000000000000000000007467ac896ae9f7d2cfdfbab082c89d3c17a6dfdf1f69b4b38fe6d5ede6848a45e8b0d728eb8c68752ec59c8e0504dcd0000000000000000000000000000000013a11383f2d3a3c28e3ea750fece5790e37f66b306ecca417c83840bed70c034e4b82b0850f719fb0b3b203a25dffae40000000000000000000000000000000017d067d9cfbbcf605c5da3532b2eda5900d71340508f08c05d0051772e65b0f85b9efe5b6d63a7b64b25ede8df7f25c9000000000000000000000000000000000e44847884ee8eacd5417e042e8299af8313ce177ecdd034a91d3bdd441437510808d44e328e810c46bd851ceb6085dc0000000000000000000000000000000013288506fd52bf37aaa975b533f1182a824b79d2d876ad6ff705efeec7f732bed99d2da8f31c00a2db4d97c4118bcb88,,,invalid point: subgroup check failed +000000000000000000000000000000000b7aa89ed719e2af5ad32ca923f1d2d52d767f6bd33d8967d2619b54472c8881ad06441b2595931d734a0fd10ccd7f190000000000000000000000000000000014bd6118d65e19e4cb79af164f523f1c80b0f0a0f0063cf1d28e11ae7987381c0b9707e43754b75f36ca8523bc5f7da600000000000000000000000000000000056a29b523b0cf85ab04b0a496e078dba5529cb9699e567ca42f9ee3e3f07b61ae29b0ce17cad23131375f624a366157000000000000000000000000000000000acb91d1f057c7aec1f7561614a95f8db2252cc879bbc2595a5f607d8b0ecd6e6e3ec19849eacfca62d870b049ce84910000000000000000000000000000000010d9459e07178af8e125c2f66de699cfafb5f87a63454e24d0ed88b6c804a9ff204f146ecf4d6db62234ace0a944acb20000000000000000000000000000000007256a68e23b43a3b6475b3cf209ec108bac13631ca448cc860672c65c1760a8299fe941ed5bcbbbcf63a683e86806ae0000000000000000000000000000000005d4453da747eaef90007eb8ebf6088e8617dad362f2a95638fca7312bc5cdd8200f32b17a0b483052e6784d286c2cb80000000000000000000000000000000012f0e56ed3e3f628a13493d0ade2321310cf62927b40887202042981fc9a81d6cc69be130346b7bc244a2119b2632a5600000000000000000000000000000000056a29b523b0cf85ab04b0a496e078dba5529cb9699e567ca42f9ee3e3f07b61ae29b0ce17cad23131375f624a366157000000000000000000000000000000000acb91d1f057c7aec1f7561614a95f8db2252cc879bbc2595a5f607d8b0ecd6e6e3ec19849eacfca62d870b049ce84910000000000000000000000000000000010d9459e07178af8e125c2f66de699cfafb5f87a63454e24d0ed88b6c804a9ff204f146ecf4d6db62234ace0a944acb20000000000000000000000000000000007256a68e23b43a3b6475b3cf209ec108bac13631ca448cc860672c65c1760a8299fe941ed5bcbbbcf63a683e86806ae,,,invalid point: subgroup check failed +0000000000000000000000000000000015827c619b2a73a750f6469160ff323c15adaf55e893933a5c2e5c2f0df8bc426421408773a3e8cb8b1695973f7c0b760000000000000000000000000000000000af4a7d29f10cd080d9989b341fc030a5dd51512f776fb1da7a46d542c2a6a2ad7c1309af30423b717825fd5dc0356300000000000000000000000000000000198d09947dc088c1d33d776d64765766b508764f12a28fe0119277d6e171af7c9ff83f6823558e8b1a4284857663afb700000000000000000000000000000000130d5e5315f8df8d0142d06bad7a51b08e5b3c2d49b84c9d6b177b9bb628a852ff65c1a93982dcb1b31a2dc0941904750000000000000000000000000000000018cb011868591c6b44b7ce49f82470aa6461a737173e1d88d249c0e83fc6e4e6a15f8397e515efe7dc7302ccc2e369ae0000000000000000000000000000000004de1c5539b2ef536a66c8f3d7cd49ed948c081c08cba8826d2ccdf9d159b931ea10eeb8b3f465dce0143b179059169f0000000000000000000000000000000015827c619b2a73a750f6469160ff323c15adaf55e893933a5c2e5c2f0df8bc426421408773a3e8cb8b1695973f7c0b760000000000000000000000000000000000af4a7d29f10cd080d9989b341fc030a5dd51512f776fb1da7a46d542c2a6a2ad7c1309af30423b717825fd5dc035630000000000000000000000000000000004286a9efe902158cc624080ebc5fd9b5e0e6e31554c745d5f0c34ef1de2a487f77d405577559dac59babc731ca779110000000000000000000000000000000009c09c9c9e2c75bc6a81357c03b339668c7d8cc8a3f65790ad53b62f4c21acbf64fa66fdd75dc24c05214b712ad7fdb60000000000000000000000000000000018bf7e4fe271fe195377639c5743c1ef3eccb09c86d64d2a4dad2d7d4ff0feb46252d749f82a27141dc0007649b032bb0000000000000000000000000000000018113c4584b81eb814a9f1ebd041062d0db8bec46c2c1ffb7f863bdd2fc3fac470b01c32b6f2453ab048eefe362aa1b8,,,invalid point: subgroup check failed +000000000000000000000000000000000c3f4ece90cf7d380efd3f81e66110a5923bd604422fca0fac2a16fb9a8d8b34cc1fb86a15009e8cc2c0d9fd8fbc0fac0000000000000000000000000000000012ea55d042ae590abd4c2687e0f152384d37665ddf26787d49bc9f6d40a579bcb23521c59ce91c418b9f4801375892aa00000000000000000000000000000000098af17ffd4d28bad76ce1ee669e7cdac1eec9facc260440636be88618302ab5a0826141b4fc914a389816d04597826a0000000000000000000000000000000011bef78afedf5c62daee5e86386c45826a524352fea40f68b07b7794df8eced4eaf0fb55b6990b4fb417ecc597b61e48000000000000000000000000000000000d64f0a4df4f858defde17b31476045c3dea78de4ec8082822c1699c0b9619464c75f0e57ebd12ad9e4e2e6b291b538c00000000000000000000000000000000031f12dc8a9c5445d575f99e2a4b4217ba5c0be58ac00977236440ab0ac7e2c8dab72a64464e4480aab7eaf1d629c7e700000000000000000000000000000000033f3c31337bc48622d27a9a3224a2acdb5c538a59b497a4a85840c81cff667ed0a0e4e3f4bb23a9ae53c1e79ea54cbb000000000000000000000000000000000cf0dc22af4530260cde26aa0eedc83a0ec3ae87d024e6907f3d22070e1054b3d4f24d5ace7218ed44763af6ec3f25ee00000000000000000000000000000000098af17ffd4d28bad76ce1ee669e7cdac1eec9facc260440636be88618302ab5a0826141b4fc914a389816d04597826a0000000000000000000000000000000011bef78afedf5c62daee5e86386c45826a524352fea40f68b07b7794df8eced4eaf0fb55b6990b4fb417ecc597b61e48000000000000000000000000000000000d64f0a4df4f858defde17b31476045c3dea78de4ec8082822c1699c0b9619464c75f0e57ebd12ad9e4e2e6b291b538c00000000000000000000000000000000031f12dc8a9c5445d575f99e2a4b4217ba5c0be58ac00977236440ab0ac7e2c8dab72a64464e4480aab7eaf1d629c7e7,,,invalid point: subgroup check failed +000000000000000000000000000000001679e0889aac1501b67c4ccee84942e05b1720f48b6390ab82ff76c0ab95defb79b4371770f2e07a9e7ee8de4d76b43500000000000000000000000000000000162fa6099ca3e5e8e27dea6ea0d4d13c5c150d281fd6beb2079ddf2d714bf9458184100c88440109d7526812ee0f56e000000000000000000000000000000000087bda5b07cf72c2b350e663670f094c352097330b307cbe2f7b4224841b6eb23c36ba62d4ee591e5ca68383ec0256f6000000000000000000000000000000001163d4985e0f25d36a1f8dd97b61413b0015a966a88d98eddb2ea2d5eabdd83a44fb7e37cee90cc50df2f95dbfa97979000000000000000000000000000000001652067ee82320191cc5b188e61ee2d1b94c781e8e5798c89224920ed1d12a2cb41066f69cdeffe8a4d5e3aa1be4c83300000000000000000000000000000000139cd806423ee99d913e8b0e5ddfb6b1b62478254fe39d6836fbc632de9435e1464a556b1f9466efebe93636dfde7749000000000000000000000000000000001679e0889aac1501b67c4ccee84942e05b1720f48b6390ab82ff76c0ab95defb79b4371770f2e07a9e7ee8de4d76b43500000000000000000000000000000000162fa6099ca3e5e8e27dea6ea0d4d13c5c150d281fd6beb2079ddf2d714bf9458184100c88440109d7526812ee0f56e00000000000000000000000000000000017028dd744482e290c523ae5944c8a149afd9d344fea7ac0171ee3a5ff0c2add53ab20c477a584bf61e007af5840eb4a000000000000000000000000000000000863382ee8a43f02396030768905e44c8f9504b7315b00e379b92060e4f01e1b4e0f837b24cb42354e7211419a5516480000000000000000000000000000000007e2af64687f7d581d5a2bbdf225d1ab3dbea326ec89c08852807696c8d13cc907ef4289bf5ef9826c1fb27673b28bfb000000000000000000000000000000000ffc910160c8a0b826600fcdbec027e7d4874c9774324bddd2dd4428eb81c22618a49378502917ad9fcd96bdb1371285,,,invalid point: subgroup check failed +000000000000000000000000000000001902b8c58eae3ca8d2261a637902587c2c0e75d32abc894967b6837ea34252e4558966f931789ccd76c1bbe3e092b180000000000000000000000000000000000dd20f71f5054c79d5e357f69f8d7345b5a036241774a72743271f2dc8f6e8c29a3babc2b65ed8193cc0636fb2e86f740000000000000000000000000000000003e06e2dcfbd695e9bda0baee1276ceab637fd1fbe2d2d6458c923c35b00edc7edf4f9e797aea59ff8cfceada0615a02000000000000000000000000000000000a04a2ed5e42fac7f064b43d64151a6c517ecf22dbc7563a3e9f35f555a9992fe45cf6a728ba94607df7c96f7e0a334b00000000000000000000000000000000090fac97f9f524168bc930d26ea1627ceaf187398d6bfc5a019c8467d75cd31a41c7eb9fda35fc85bd92b4cfca92dbff000000000000000000000000000000000f37b91dc935c28668c27d38328a511148c1739b65f2816dc53e42a8f059c9b2be7417a6f97c9a2597b1a0f06b7afc65000000000000000000000000000000001687dbd36c7f96f8be47f08bb75bc72f91e63e26d0157a9a9c8f531f3e73bfbd9870fe9abd0a7a3fe73b997e48d0ffb8000000000000000000000000000000000183ba882bdaf1dc850cb4e98158895effda1734fa64810cb15640e6cc027bd006e5c1a088cc2c65e8af29b64fe41d4c0000000000000000000000000000000003e06e2dcfbd695e9bda0baee1276ceab637fd1fbe2d2d6458c923c35b00edc7edf4f9e797aea59ff8cfceada0615a02000000000000000000000000000000000a04a2ed5e42fac7f064b43d64151a6c517ecf22dbc7563a3e9f35f555a9992fe45cf6a728ba94607df7c96f7e0a334b00000000000000000000000000000000090fac97f9f524168bc930d26ea1627ceaf187398d6bfc5a019c8467d75cd31a41c7eb9fda35fc85bd92b4cfca92dbff000000000000000000000000000000000f37b91dc935c28668c27d38328a511148c1739b65f2816dc53e42a8f059c9b2be7417a6f97c9a2597b1a0f06b7afc65,,,invalid point: subgroup check failed +0000000000000000000000000000000010f38e6e4f562be50152c1d10eee8f8990cb8f884035bdce111e178d1286afe2f2f02c3a36858ae2ce902d6a2872ff1000000000000000000000000000000000141dc64999baf42240b933f30ee895188b561b880f90b5f1ca8df0ac75be7d95bc15d55e321720c172171e9c4c59e800000000000000000000000000000000000548814c4b6d72cfb817b49b3141302be7d7b378e50ff9f7d66e31cd04e1f024bba334110817990264d26cbcff7170510000000000000000000000000000000011f9d186fab00b9ede155a82ec5a5e587a1c6091005c4c6e90672d15c434953426440799c5ede15a7976f18bf345595a0000000000000000000000000000000018d480ece4609a56220d4db100b68ca06ee4271b84e1a81112fbb0616cb34d2b0ec974de31f7d6957b186dbd8a8f8ad3000000000000000000000000000000000c3c1b79130f73d516c1bbe38c572be2616991b523a9370c98df9313be9f5015c3e8d51947201c6b27e8cb9c7291bd660000000000000000000000000000000010f38e6e4f562be50152c1d10eee8f8990cb8f884035bdce111e178d1286afe2f2f02c3a36858ae2ce902d6a2872ff1000000000000000000000000000000000141dc64999baf42240b933f30ee895188b561b880f90b5f1ca8df0ac75be7d95bc15d55e321720c172171e9c4c59e8000000000000000000000000000000000006d89d908b733aba090432e795c564d1badd5b8529fc53507c4850e3d97978062b38790ef45562f3d4978491b5ae893b0000000000000000000000000000000003f7fc037328c13d13fdf4b2c251ce10c41ac5d042122f0e4e4f5a71cc9e1463f62d96aed44123d0e612e5296b53fdb80000000000000000000000000000000000aa2e027a929f7637f437b333a795a2e8d1a92cda31feb5a72fa1c66fadd23813177f9360204b0512d8f460b5bb161d00000000000000000000000000000000139a2a989d462e1793caba250c2ba9c46f31b3a06f43a0f4cbaa021b5d52d254f18d9517ddf3c21780f2a2c59533c5db,,,invalid point: subgroup check failed +0000000000000000000000000000000003ac8ec0fbf8c4a6774d8567a45b033a4a622d88d8b2025eecd746d084617b67342cb1030068ef6dceea78cf97210b6a00000000000000000000000000000000090b3a144dd409afa163ef513af313e545330a66c33d45b32d61cbdeccc66f78062060a2bfab2a88ec0cc47ec3525f19000000000000000000000000000000000d542ceffc583a6022306479b2365171c3610b7f615619802caf2f81d78f2b5166114485dfaacfdfc27c6450f8c344550000000000000000000000000000000010f5a12712658a5359c0a310f6d833c0b4623c51da6c035dfddcc4c201ccb27ac0a534da459a82488c32e1d4ced9b8af000000000000000000000000000000001878dfc18d1744c6f837b36436b82cd9c270916e5206f709e7eb30fcbd4157f65639103f367f1af2684a51d93e3dc7fb000000000000000000000000000000000ca3a300efdfd9812b6213a848d7a2f865d3fbe8c73527997f18460485626921063bd5b7842b8a47ccadcebb5539a54b0000000000000000000000000000000009aafc73979c000236c08e089828880f54645b5ff4c1dcfea0ff41ffe8e3fce8ba0dbcebf0d4205bb6616a737b6d3542000000000000000000000000000000001399a2072604d50f92ee186924ce32c4e887803dc258b7495aa2f3d2187571045db7f360d2614b198f83bc8024b06559000000000000000000000000000000000d542ceffc583a6022306479b2365171c3610b7f615619802caf2f81d78f2b5166114485dfaacfdfc27c6450f8c344550000000000000000000000000000000010f5a12712658a5359c0a310f6d833c0b4623c51da6c035dfddcc4c201ccb27ac0a534da459a82488c32e1d4ced9b8af000000000000000000000000000000001878dfc18d1744c6f837b36436b82cd9c270916e5206f709e7eb30fcbd4157f65639103f367f1af2684a51d93e3dc7fb000000000000000000000000000000000ca3a300efdfd9812b6213a848d7a2f865d3fbe8c73527997f18460485626921063bd5b7842b8a47ccadcebb5539a54b,,,invalid point: subgroup check failed +0000000000000000000000000000000013a366c2748305c4ca702c053ddcf15df4a4a7858cda813d001f59bdbb419de6ae3fd24b22fbeebe58d5278caf04c0c800000000000000000000000000000000140759404192c97274c06a69609a1f927195dc0e9df312f483b075e0647a9df1225c22284edece061a2a1c3dd6c4af030000000000000000000000000000000018059cd50cc71b1060ee01c10860bccaf2abbf84cc09266f2818b7625be9368138784dfacf0a1413f19bed9c09294fed00000000000000000000000000000000138939b9b91fcc8ee3aeb35de9476576cc84adbfc513a72fb74c6b897a9d6bb2037d65489709de062b238c5d0587345f000000000000000000000000000000000a9f2a8303b70df25b27158d7fbe06db9b71f6b30b8d8f3d3ad3e81ed310af6ba00eaa104c4c8755c3c24b37b5a9bae90000000000000000000000000000000014297a57a543d963d777ce5e3e5b07d19d69f56ff3efafa2753889522f10dac3fcabcc77466ef236d331361955b571670000000000000000000000000000000013a366c2748305c4ca702c053ddcf15df4a4a7858cda813d001f59bdbb419de6ae3fd24b22fbeebe58d5278caf04c0c800000000000000000000000000000000140759404192c97274c06a69609a1f927195dc0e9df312f483b075e0647a9df1225c22284edece061a2a1c3dd6c4af030000000000000000000000000000000009a457949f0a3a5ef91fbe3beb52dcf95a9f71db70bef860d2fd60cf9330b99e1d103eea022f32f0db603a635925f2940000000000000000000000000000000018e2ce9366745f5691d3c8f907bffed5f9da928cf9c9997db1311bc47b34d9d0a076ea5b7845e0dbf1c3dab60edca5de00000000000000000000000000000000089bcfe3a5596fe5f3c61326de93eb63abb0f56a7b9a5c5f4ebd883ea681607352b955deb581b57da99e4fd302e136c70000000000000000000000000000000007cb502742faf77a7223dc713a243af8998652e45f51b32dabe766c7a771bf4642ea9f25fd924e61a0f0a6e0f27c99dd,,,invalid point: subgroup check failed +0000000000000000000000000000000003f23275ed56b4aa4a1fe367219e8c84142d60d6b9983e0abb8ca21a88e008286a902b2b92369ec14d7f45f7b66b9a0300000000000000000000000000000000130b8d95a4672e467f122fc010ac3ef7f6b6d0ecd044413e51f7c27ed22f7ab7a28f60245b9ba83d4ffc98b9a990510e000000000000000000000000000000000e5af1420546c1a5a0e0c2bd9241bb7c7a26dd52f4f358fc868bea457a60bd4f6bc5b60b27069fb4f6760813a91ada740000000000000000000000000000000017426a65d239b1d9505bef2b476799c394fcc7bfdca36a1ee5a600351334dadc238b64cf8a667a25d4880a31b73c53a9000000000000000000000000000000000f151587944aad17429b51b1c16193c1e1c93cb412538d1475473666c997e012ce618eb841c4e9e064a08ab83d7fa60e0000000000000000000000000000000015c2e049c532db585807319c23ec077a51f288fcffb2cb6528d3697221e8542e3fc85d18b079ea1b217fae30858a36f20000000000000000000000000000000010a1fe14b9981a917e49b71f549b7b548629ad0003b43a9eff26e2cfa7fd8ddb21056e26dc78c88d30c32e62af40a83d0000000000000000000000000000000019f408194aa79434edd5f2a3adcc5c55ee9c1f616641b29ef21fbba8cae342df67ef438095dd7677ea1959f9a855974d000000000000000000000000000000000e5af1420546c1a5a0e0c2bd9241bb7c7a26dd52f4f358fc868bea457a60bd4f6bc5b60b27069fb4f6760813a91ada740000000000000000000000000000000017426a65d239b1d9505bef2b476799c394fcc7bfdca36a1ee5a600351334dadc238b64cf8a667a25d4880a31b73c53a9000000000000000000000000000000000f151587944aad17429b51b1c16193c1e1c93cb412538d1475473666c997e012ce618eb841c4e9e064a08ab83d7fa60e0000000000000000000000000000000015c2e049c532db585807319c23ec077a51f288fcffb2cb6528d3697221e8542e3fc85d18b079ea1b217fae30858a36f2,,,invalid point: subgroup check failed +000000000000000000000000000000000bc43aa42d656bdc233b332698247bad1904aff059eaa3f9b943ce5d4ae4f414dd361062a243f38129b954f17389ec280000000000000000000000000000000018dc8ec1d798981f662a8ce10f25f31197a2d168d3c047d2f6a214f1554202d072baf004c61b6d58f4f0410a4520b985000000000000000000000000000000001217fe0908fca8686b63337b0de6d3b3e4853466a990d8feb8a127cec95fd8dfc97be2ac57587d5f9ae1f5c10848e5910000000000000000000000000000000005c60861ac4863f7b9c38952daa88c2414ec8ac14f99fc765042b718da08136537765dcbc28cc6a0c279d491cf95b4b500000000000000000000000000000000154b289077530a86091d21c8be9c25ccd250da8d77caf853955b0d169e1ac40b5e0fd539b09b61b293035ebcbd0e21f5000000000000000000000000000000000356ddbe9454937c441dcfc98fe7b0cf8a746464f77230229328cafe6ad9ad1b5cc7a60e50bd8431b0996e3c42882777000000000000000000000000000000000bc43aa42d656bdc233b332698247bad1904aff059eaa3f9b943ce5d4ae4f414dd361062a243f38129b954f17389ec280000000000000000000000000000000018dc8ec1d798981f662a8ce10f25f31197a2d168d3c047d2f6a214f1554202d072baf004c61b6d58f4f0410a4520b9850000000000000000000000000000000001874e45ffd1349b4ed2e361dd7093a2ba41281b2d78f123bf9f6f73892962a0bcd6dc6e4159e505509cf7839aa79a20000000000000000000000000000000000ae0404355b78d20c1c3f5d65373d905696b166e76de62feb33f819dba26d39ef78621f819e998f6f2c82c65ddc22fc90000000000000000000000000000000008a499023de01bbe12958e10a3ca967f0f6047c705345beb8fb835c26df4eee908448b39191321f3eacfbd0951861c40000000000000000000000000000000000a56e3272f0474f980511540610b29e9a722a868025ac424ce8f76f342721a92d2544a420d3472f13186a0837d7e2c43,,,invalid point: subgroup check failed +0000000000000000000000000000000003e157886f141c2ce7d9ff32af44df6b7407af027005aac1149ebbe74b3b810f834b019b3e67a04531e2554f122d959600000000000000000000000000000000159eef0ff7bbe471a7ef8e666ffe35f427e3ef5bf9eeb4693dd4127467cf2615fa6b289be07452bec5c35b6d8d8ef2a100000000000000000000000000000000028316eaa131ef5303b012bfdd145bcb3106b362f410ce05810b8c83e10b1a8f80167b546b8b86c1368d7099fb5a0deb000000000000000000000000000000000bb3a353a2c16bd73c62fefd820927898dfced930d9639c5f63e62d8e8d31fa028cefb0d57ed16299eccdf3700b62bf200000000000000000000000000000000198272cf5c6e8a4f4cf4692fb7363687d7ba52deae88a7b976863309feb4a475db150073593567352ab62a150d862ca20000000000000000000000000000000019af00f2cf92494f532052962b62c34d0999a984b4bf36abd74a485fb9089ee0967071886b97f541ae80c6f7b8bc73070000000000000000000000000000000014bcf3f26683234584d79b436cc608462f1e2c20b5ecc5019988d8e30137859a4b6d0e1135dd5bbea0781b8ed3f0653700000000000000000000000000000000090ef29bf63ca97ae8388588227e1d1a0653c43b16a35a63f2ab4f0b11fd8005d9a85d30a7406491d983f347e4dfb9f100000000000000000000000000000000028316eaa131ef5303b012bfdd145bcb3106b362f410ce05810b8c83e10b1a8f80167b546b8b86c1368d7099fb5a0deb000000000000000000000000000000000bb3a353a2c16bd73c62fefd820927898dfced930d9639c5f63e62d8e8d31fa028cefb0d57ed16299eccdf3700b62bf200000000000000000000000000000000198272cf5c6e8a4f4cf4692fb7363687d7ba52deae88a7b976863309feb4a475db150073593567352ab62a150d862ca20000000000000000000000000000000019af00f2cf92494f532052962b62c34d0999a984b4bf36abd74a485fb9089ee0967071886b97f541ae80c6f7b8bc7307,,,invalid point: subgroup check failed +0000000000000000000000000000000003b6f466571daced9c0d6dd76b5f7cc91f20d92c0fc2f051a97524aee838be57eb977af49bf020a252db1b49693892ee00000000000000000000000000000000002b99dffcb6c171f66632d0cbc9aac74e6f4823fa4690e273a5c16baef618b80d2daf81d8c6b4c5240e1c329ba91b41000000000000000000000000000000000a32e330b87bb0c2984ce443412953a879f396221cd21c2f7ae46699b02c76352d3b13759d70541fc67cdc0e65fa6d4f0000000000000000000000000000000006a134cfd54f8e524544b170a4ae0b3da02da61b56633ace68b05c511a425a0a17d3e3e155a592e6176f707100174d1f00000000000000000000000000000000132f34e6b61e7fc7764b3113a4761cde446de56d3bfadc7f285bcf11132ce8d52c656cd9cddf176755dc228277557dbc0000000000000000000000000000000019d74adf4504a87de20b5a53d4e668be279d5850dc13b1699769d2279a23903f6f789dd897c2180ed895351e4f90d7e50000000000000000000000000000000003b6f466571daced9c0d6dd76b5f7cc91f20d92c0fc2f051a97524aee838be57eb977af49bf020a252db1b49693892ee00000000000000000000000000000000002b99dffcb6c171f66632d0cbc9aac74e6f4823fa4690e273a5c16baef618b80d2daf81d8c6b4c5240e1c329ba91b4100000000000000000000000000000000025c97744f862c85507620fef6d4b90a1e37ab2d6c5ed2d794880b43bdf854ea77e87e90b5a487c56fe29e28bf7ce01100000000000000000000000000000000120515b8665151db933e51722fdac7a83d2f299623a38529508b25218f0d57aeb0c6f260e0ef3741ea1f89bc653e5d700000000000000000000000000000000019d1111f074ac541a381472a4d9dc6b76cf64e86d92018460e977460b46e17924dfa522a5bfaccbfd8bd0711950f41f6000000000000000000000000000000000433ad85586f9392cc6079c1f4f37eed99fc65da9a32206912465116f879efcf9e83d8b325433ee31235142aff89a49c,,,invalid point: subgroup check failed +0000000000000000000000000000000009b488e21aeb418e8913f6bf721b3398693a3875788a3e013717fbba3c6ddaafb4073378d121cc1f2f99c072b7f8eba600000000000000000000000000000000144346f013254cec17d8423f534d54e2496df08193ed65304fe300b47a68c8d322b6ad84f748529928d64298be5ac1f200000000000000000000000000000000102c92272571b73a7df754728d7293fd8050d9dd2b8605c3f7722e6de541b7fc6a81b01c1cf15e5241ee4ee1f81ab39d000000000000000000000000000000000af1cd6f23bbd3e9ef75eed6d6d99a7cdd24574881b3609e45c4adbf82e08259d14701fcc5b6338ecf52166aecca003700000000000000000000000000000000026a1a4c3eb54de2ba4509dc806db9efc7e26247d501cb59c525b8dd15d03b91abafa9ba5816c22e1f8ca159cda34bd500000000000000000000000000000000170b510ec227fe8534a2cbb0f405756491c4f6832df552bd23980ab0946725371b3c24fa8b93a38bdcd47e1026e1d2a0000000000000000000000000000000000d327350067f7401a228c4fbcc7375f2edb058505ab34341df865a82781448d8e053b478e97a3ff79458b264a0dc186a0000000000000000000000000000000014a92d6662933a9eec6134002fb0e23a0930a964bed5bf84886bc3819516af19fb8bee2c0291c518119f4f4198eb67dc00000000000000000000000000000000102c92272571b73a7df754728d7293fd8050d9dd2b8605c3f7722e6de541b7fc6a81b01c1cf15e5241ee4ee1f81ab39d000000000000000000000000000000000af1cd6f23bbd3e9ef75eed6d6d99a7cdd24574881b3609e45c4adbf82e08259d14701fcc5b6338ecf52166aecca003700000000000000000000000000000000026a1a4c3eb54de2ba4509dc806db9efc7e26247d501cb59c525b8dd15d03b91abafa9ba5816c22e1f8ca159cda34bd500000000000000000000000000000000170b510ec227fe8534a2cbb0f405756491c4f6832df552bd23980ab0946725371b3c24fa8b93a38bdcd47e1026e1d2a0,,,invalid point: subgroup check failed +000000000000000000000000000000001756d051ce0ee9ac0fd83b9a069086cfb62164d5131a2c7be22122cc64fe74590ab5b69e02b37a6075384df9552d1d6b0000000000000000000000000000000013826bf44ff233e612a9dc8d47cbb3aff4f1fb5abf0ffbd35f4124531bca696371357301d12ed89a2974de5027c2c59f000000000000000000000000000000000ec934504ad116a80cf15a8d9a3a0bd5db18139560adbc6de32b5871198df9ecfe122369dbce5a19eeeffffd510f403b00000000000000000000000000000000007e3f75ccfc96dbe63e7b877420bccfccf2a7a56994fcea725c1b9f1823d93b0913ba1293f32493983ebe18ae27ce6b000000000000000000000000000000000ce8b2413d344263a5e598900af1524bf863e92fc3c8a2b1f335e9029081de05c70b50b97bef75044d8083e92f99b88a000000000000000000000000000000000a47a4c7b8b35b0729b43db9785a9f15c7357815e5d1ddf02d14003923120a734a1edd931d39d9261b55c145f8c69443000000000000000000000000000000001756d051ce0ee9ac0fd83b9a069086cfb62164d5131a2c7be22122cc64fe74590ab5b69e02b37a6075384df9552d1d6b0000000000000000000000000000000013826bf44ff233e612a9dc8d47cbb3aff4f1fb5abf0ffbd35f4124531bca696371357301d12ed89a2974de5027c2c59f000000000000000000000000000000000f3f5ca684120f4b7132153ba02995e88c50ac830aa65e23978ea6be09bc838249adf113e9b463cb01fe0eee43262d5f000000000000000000000000000000001270984624e5da5aeff659f5b75d3e7e5ec655ba342e318b0643672f6e71b84916ef767c58daea149f8029bb046e548700000000000000000000000000000000064c7217b420841cff11994a5f9ba682f7df02be4c8ba2027b67d33bb51b0b956137f61ac037d5551d5ca2b880e4140c000000000000000000000000000000001813131d845fc7bd523c7a295f2738580d9b39f6198ff19112b9dd38276c3045942e74c59b4392f59de70e7cd2ee87b0,,,invalid point: subgroup check failed +0000000000000000000000000000000003dfcd47087531272c3fe93d82878c5a689eba15fd67534bc2fa045b1995eca650e19e020455f0b1cbe599fb27b8352d0000000000000000000000000000000014cc297621e8b9d4ac8b1ced78c53d61261e899de0077b73f4f119e6fc50d5aa10b5111640eb3390057510825a20213e000000000000000000000000000000001150494bc162c0f414d31816adb18256b7d9fc6593f89b30b76522566667dc302050acfba7106031e99bf580fad24aad0000000000000000000000000000000005c920cd2ddd5d660e3246962b466f34a28449fe1790b9312f81fa70e13c1835970d4b807352cf7d89efa093120d527a000000000000000000000000000000000d384fa4729576214cf631ac1e6e2af54176954bd63f13cf15f2cd3c1db4cde4758d260ea4ffc0606aae700bca7ca7ff000000000000000000000000000000001824caf3b35915f528dfbc82bc5d56b5f8e7ba2b02056f6e27cbdbb0a54de8d4749446f14b116ff36b9fa773808c647d0000000000000000000000000000000011d4918642919c801fff0962062a387a4dffe693ec09cd3d0286a18e3a22c84fc09e8396ca82e6054d8535cd888179230000000000000000000000000000000016a1f0c7fec5647dcce688d3e4e526749bbf23c1fcd9e9168ace47399f9198c9b3a6b8aeca68febde1b7beeea0641aa2000000000000000000000000000000001150494bc162c0f414d31816adb18256b7d9fc6593f89b30b76522566667dc302050acfba7106031e99bf580fad24aad0000000000000000000000000000000005c920cd2ddd5d660e3246962b466f34a28449fe1790b9312f81fa70e13c1835970d4b807352cf7d89efa093120d527a000000000000000000000000000000000d384fa4729576214cf631ac1e6e2af54176954bd63f13cf15f2cd3c1db4cde4758d260ea4ffc0606aae700bca7ca7ff000000000000000000000000000000001824caf3b35915f528dfbc82bc5d56b5f8e7ba2b02056f6e27cbdbb0a54de8d4749446f14b116ff36b9fa773808c647d,,,invalid point: subgroup check failed +00000000000000000000000000000000111650bcc4c7deaa92ef43d8355198c1c0bc402fd758933765495eaf2a6c11ea6b5b6fb4a89b00040c900fdec791c7b20000000000000000000000000000000005519640447380e96adae5042193695193484d61ce0cf26acca8c96932be68e61ad6cd23515f13f8fa4fbdd6ca5390e40000000000000000000000000000000000c6f11a5306aff663038d949d08092275c7c507f68605bf9a4b591138f578f9c454ce12176d4759e1c95f3243185b9b0000000000000000000000000000000018b28c875d620249ecc25cff0ced2b3766aa66254906c69b7157b6e418a332293723b4b268d6f9d97f566b4998997adf000000000000000000000000000000000ce5e55ebe8326ee5650122f4b39dc96fe95aa4c48d26f70580fd97be90782bebfdb2d94e784786c4188ef99ecc33f55000000000000000000000000000000000632c0e5c998679e92ad269e587e831da5dbeaff3eda614d904e11c0e4dba3c87b40101cfe2f579e8015731d0ff22ac000000000000000000000000000000000111650bcc4c7deaa92ef43d8355198c1c0bc402fd758933765495eaf2a6c11ea6b5b6fb4a89b00040c900fdec791c7b20000000000000000000000000000000005519640447380e96adae5042193695193484d61ce0cf26acca8c96932be68e61ad6cd23515f13f8fa4fbdd6ca5390e4000000000000000000000000000000001780ae947388f0e055883d231f8809eb8fcc5e30eec44cbfaf11c52d4fc14bf54480c439e805559f64bd6f2085e12f1600000000000000000000000000000000142aaed1757c6f6ed83d532333e6f8f340625864fae2e71101d1ca6787045189dcb408c433caa3a19e9220f623398aa5000000000000000000000000000000000e29f5acc8998ea0d02d72559230f119ab9f8c4a013c63baa553e6ef7f5a5d38427f5b1e82b0879201ffb5ff3e23911c0000000000000000000000000000000000b934ca967385631e767483d6279afb80ea063b624491d5d837bbe4509e1f54a90b9ccb153039fbec7716dc77e28755,,,invalid point: subgroup check failed +0000000000000000000000000000000018bccb5411a58583445efe99e16d0b1fbb8ec71c6c8175a73e8d289f102d6925b68374d8986bbe9353640565fe30d3200000000000000000000000000000000013036f4649ab1dddd84a12d5a3efb93f8187824211bda276cef8376ffc90f5728bdef3b5b1bcafd59fd9ecf3bf9acb76000000000000000000000000000000000a43335eb6ff3bf2daeeb1eaf44c2782eeb517e82e55203a247b7a396e26fdf85f93695753c52c68819b58c95f361820000000000000000000000000000000000c240b7896b3dd0c318dc9ffcaa001d20bff288def3ce42752d660fd705e1544e292a5a0aa3a9a80ae91cb47cb938989000000000000000000000000000000000e5195bcc4ee8b149a769322165b6a3157ee7d04546643390adc812b6296675dbd31168b268df869a6722a7c8f51c79d00000000000000000000000000000000004af7dc8a5c552f00d55b996d193a9571173ea829eba8fadfa7becc2f4149ee7c6c4d2c8c7b1970df33cc56e4506573000000000000000000000000000000000d7cf8be632d98ad21137a983fa55acd08492a9d1e9d6caaf520713a10f5cd71c9a155ce9ba65044f42228959e893556000000000000000000000000000000000ddbd265cad3a9c525a30ebab137fb1857a9847e66c3381d51de1040a48835701a1f5627281f6cb36181d8c1c337e58b000000000000000000000000000000000a43335eb6ff3bf2daeeb1eaf44c2782eeb517e82e55203a247b7a396e26fdf85f93695753c52c68819b58c95f361820000000000000000000000000000000000c240b7896b3dd0c318dc9ffcaa001d20bff288def3ce42752d660fd705e1544e292a5a0aa3a9a80ae91cb47cb938989000000000000000000000000000000000e5195bcc4ee8b149a769322165b6a3157ee7d04546643390adc812b6296675dbd31168b268df869a6722a7c8f51c79d00000000000000000000000000000000004af7dc8a5c552f00d55b996d193a9571173ea829eba8fadfa7becc2f4149ee7c6c4d2c8c7b1970df33cc56e4506573,,,invalid point: subgroup check failed +00000000000000000000000000000000042f294cc86c53cbc520ce6368a7149676d8bc4acf708485057c8caae31409ee1586a735c3e1f416104aede85e40a38300000000000000000000000000000000153de67ca08cdb77e92091e8f04f75d17ee5525c5ec3ccdaca907b5ebc1cfcb6ce9d6a4358999cb00ae5e824d008e7fa0000000000000000000000000000000007e00b1cd95e3f9cbb2bf80404abd9768da125c42b746c2afde0121fccfdcc2431c618d646764bc5137657d2f0fcbda3000000000000000000000000000000001170cf72d827f929cb9efef52b559f8459cdd4d60464e0b3bc6e55bb6cf83cc2e9d6314b2b80e4e4f6a3c6292d1517b50000000000000000000000000000000012a7806f98848dd9c79f74e4a25812a6fae59ca73472fd20db2ecb8f732ea59294647831e03b58c60f7a71d9892ff26700000000000000000000000000000000165e6e0a602c7a1a3334a880ee47c4c440c27cfc1ab1ea6d9df592e98d21f85519d1ddf402f48ce7dc8a87439b3f42f600000000000000000000000000000000042f294cc86c53cbc520ce6368a7149676d8bc4acf708485057c8caae31409ee1586a735c3e1f416104aede85e40a38300000000000000000000000000000000153de67ca08cdb77e92091e8f04f75d17ee5525c5ec3ccdaca907b5ebc1cfcb6ce9d6a4358999cb00ae5e824d008e7fa000000000000000000000000000000000c8373f2969862e64e7a4c319a5e4db5019391ee2fd502c86bd074de5b3a1eff7917b3517175eb28efb9aa10057df87b000000000000000000000000000000000648b6bee01e4bd215ff4b51580d254e09a9b88d879ec2a0a42b0fe80792da10a9fc4d1c47058cabddbb48e94f0df98b000000000000000000000000000000000286667f7ed2e43aa08ba81a8ae4dd0487a4d11425b1e572359783ebda7c181b7dd62857a28ae3b05302cf2773f72bc5000000000000000000000000000000000349436e7b0b86db8e77d7a4dcbeb16c541b994e6f71c45098fd198991a27b4fb48025d0808000d54fe6b9500da80db7,,,invalid point: subgroup check failed +000000000000000000000000000000000b09f1c099c4743404de9034dadea6120bb4b120e81d415d047d575423d8261af3aeadeca04610d4bbefcd5fbd48d7360000000000000000000000000000000019e08ce27700db908d40e8907434068819f874b79b1540a03b856ba8898be43bf7d97b17685ab54de67602b8fc41f90700000000000000000000000000000000010714e7b0316ac3ddc1836a569befe3965800dc3cd2d9ecca097f2eebfebcce7cdc92df0110e4b872a673d5a0ebbda40000000000000000000000000000000016700d8c04f159b7a019cd0f7ade116448e0657880d364f19d1f6ea099222abab3b766d3088bd9eb870cdb3eece5ee4d00000000000000000000000000000000054f6e8c85be6d914162702dbdeb82801d598e504bfec39a2edd1035f69deccb605af437fd4ecdb23979e993904edbfe00000000000000000000000000000000183e494cd0b25d5ee1e8f1ca4054fffa4d730f547e072af920c88b9d613deb21dac38043c385fc9f9bbd6e708602ae1b00000000000000000000000000000000155d3e886cce6f257513529e40c21b5657ef1ff1f4e71bc32b968db3e05652b1ac780da573fe1a1b94b7fef86e7c260f000000000000000000000000000000001184cf09544ec2826d0101d2b79095da6e5f77d453203c52ea17b6476360ccf166ef092eccf86dbe3a260f7fd25a279400000000000000000000000000000000010714e7b0316ac3ddc1836a569befe3965800dc3cd2d9ecca097f2eebfebcce7cdc92df0110e4b872a673d5a0ebbda40000000000000000000000000000000016700d8c04f159b7a019cd0f7ade116448e0657880d364f19d1f6ea099222abab3b766d3088bd9eb870cdb3eece5ee4d00000000000000000000000000000000054f6e8c85be6d914162702dbdeb82801d598e504bfec39a2edd1035f69deccb605af437fd4ecdb23979e993904edbfe00000000000000000000000000000000183e494cd0b25d5ee1e8f1ca4054fffa4d730f547e072af920c88b9d613deb21dac38043c385fc9f9bbd6e708602ae1b,,,invalid point: subgroup check failed +00000000000000000000000000000000065a0b9822a814adda6f22f58f0ce0d6db9b32dbb2766077b6fb9bdf084ba584dc749d746740804f826d17634509875f000000000000000000000000000000000d4284a951847bad1b602396a5d5193c3a794826f58122c9c16c6e8e18f6ec2d0e17d8ca3cda9c3bbc92c51794ec7fb600000000000000000000000000000000177f2a7306144321cec932fbc1a10d58073d6915bf9ca97a05b54fe05f525ed0c327dbdb1205b70bf7ef8cf35a61c4e400000000000000000000000000000000089dfb5d4a99380761f75a94deeb6a48854164687f1055b22328d45b9792cf884ae597db1d1a93f3f2633d14969bb260000000000000000000000000000000000b6598d4c8c590f2fbbea7c48899ff43d73087becda4974184eb3ebab605e8f90497caa2fce915f7214dfe244277a437000000000000000000000000000000000acbeeaa0ddf12bb717fd32ea32ef63d137e61b5294c162d3b67e02dcf1075838bd0208d7f8edaf15f023611b774c14a00000000000000000000000000000000065a0b9822a814adda6f22f58f0ce0d6db9b32dbb2766077b6fb9bdf084ba584dc749d746740804f826d17634509875f000000000000000000000000000000000d4284a951847bad1b602396a5d5193c3a794826f58122c9c16c6e8e18f6ec2d0e17d8ca3cda9c3bbc92c51794ec7fb6000000000000000000000000000000001a002703d6da9def84f6ce69f02ce952562a7bab2413e8d58631a3387a1f4556402fba6a39b37bda22d08a68b0230b17000000000000000000000000000000001366c2a752aad0e111adb716b75459c067e275c692bc440731510d56135c3238b410538dae3ec328bcd817384d8a6b6e0000000000000000000000000000000003321a09e7290272d75882b64d2c958d4434df3499c65fbbd1236add534db804081d29b0b34167e05f4de1d8065b5b530000000000000000000000000000000001b6e16cbfe9bd8a291dcadd4599f6edb147e261bb76caca726bc89b3fa1863922e202bd5fc9afa5bfec9923f43fb526,,,invalid point: subgroup check failed +0000000000000000000000000000000012e6297c3ba79bbec9a84699ee4268a37617d21e3ce984ba1134041e539f0a5f0ac11165e835ed1aba23d3b2c5f804d50000000000000000000000000000000006c8881033aa6aef80b52f0744c0c9058f6ee2d7eeba8a749ab15af41b19be8d6aae30d820ed0a0b50ce327c7baa1a2b0000000000000000000000000000000012ff0494d308d3e7321ad4c4000e9dcd19552d5e4bce8504760f066e2fb2509279b01f1568e3c3f6216bd5328cbf72db000000000000000000000000000000000038c6e8f0fab30b5c8e4323c1fd29527845c29e1a26c70b8e5284f7ca55fb55ad4ad5389b5280927b98907132f26b76000000000000000000000000000000000aef946b9b9e9fcabb36507c1cf441df2f5ccd71ef9281dafa5e25bf07d69556e4143ab402dfb38aa756bb6ee009a6890000000000000000000000000000000015f69bc7b0a6f2cb64fd0897b421e339fcc8637efced8bf33f5aed809a38b49a2e6376d18b1bff0ef70df1b7187ad04800000000000000000000000000000000019a5a9faf36413a1e48a97458b7c416a634e1ed92fbd89fbe4593f42abad0ada72f50f7a1e1a802158ccdf923b497e4000000000000000000000000000000000e0b851da6a8005b83b2afd272a6cd017bec39d9f55b3230b600c50fb9bd5cc1bd229671f6b2c7f1d78652e4534745190000000000000000000000000000000012ff0494d308d3e7321ad4c4000e9dcd19552d5e4bce8504760f066e2fb2509279b01f1568e3c3f6216bd5328cbf72db000000000000000000000000000000000038c6e8f0fab30b5c8e4323c1fd29527845c29e1a26c70b8e5284f7ca55fb55ad4ad5389b5280927b98907132f26b76000000000000000000000000000000000aef946b9b9e9fcabb36507c1cf441df2f5ccd71ef9281dafa5e25bf07d69556e4143ab402dfb38aa756bb6ee009a6890000000000000000000000000000000015f69bc7b0a6f2cb64fd0897b421e339fcc8637efced8bf33f5aed809a38b49a2e6376d18b1bff0ef70df1b7187ad048,,,invalid point: subgroup check failed +000000000000000000000000000000000c321b54ea1ae6e893f2c28e72a3e4bed4a9aebaf147716178d3392c959e79b6f3393d738f3722a0339c773da3ae56760000000000000000000000000000000005d2c477e1c9333eb642bb40709b042816cc54134fad935942cc08eb2db0c1582f9bf06518d4fd5577df4634332e70e50000000000000000000000000000000019123b0d9c362184620c90834730c58ec5f9becdb2f3c6c00fd157ac83c16a815efb5057011d00c774d0de626274d58a000000000000000000000000000000001936fe98ecb82299a85304213a3e30c02d90ea871661b34f664a825184c2d1ebad84d144df88c479b9526222a7fe9ead00000000000000000000000000000000081a6abf02a0a236ba6006a95a8ab3f186e72f05b00f2b686049cf980898d64a71bf2e41b6b276ed6556cf83a3247b6e0000000000000000000000000000000012162cab3a7d92acc12efec9672ecb4cb30ae208eabc77608748e968a84ec0de81678df45d1655e45a19162b06354a99000000000000000000000000000000000c321b54ea1ae6e893f2c28e72a3e4bed4a9aebaf147716178d3392c959e79b6f3393d738f3722a0339c773da3ae56760000000000000000000000000000000005d2c477e1c9333eb642bb40709b042816cc54134fad935942cc08eb2db0c1582f9bf06518d4fd5577df4634332e70e50000000000000000000000000000000008b24839939deb424bb0c7bb171064e01453008ada6e3f14fd3a86db79162d0f9a851eb6abcb7dd27f93df0f7ff3320300000000000000000000000000000000036bdf42585414a8fd616bf967ed2ad4eb2b30a7581a58691c6d58e5d54fa152b42427c98fb3094c718943d9d014730c0000000000000000000000000000000002b542c2d6e8862495b2a6937f1fefbba53c228af512918bcc5b39083125c41340f1b5f1c60696c7c07f6705dfbcae9100000000000000000000000000000000030516a5aa32954dc083531035c55aa623d5f53c07b7bcff54cb9bf04d567a293ee55b2027cdcb864b133eac0f3d5274,,,invalid point: subgroup check failed +00000000000000000000000000000000018a649f727e9ac88994760a97b129d3347d30174d54a1442542123a76f805e1a48e7a71f3704eaca90b3c17c538d26b000000000000000000000000000000000a5c006871d73a11d525df1921d256f880c2a3c0aea04ed27e83d5c264d3f2196c997347299fb04149c4083876bbf3d5000000000000000000000000000000000995b9bb378a7c98ed661b493ad17b3aca367cc6aa6db24fc421d82455bca4edae6c891c191023ef2113f3c7eba79662000000000000000000000000000000000213eb30b55a6ab8efdaa67c6c99362dc62022041a6ee76f7c72cc13ffaffddf88bc68ce3d4ed36d54285b177bffc1eb000000000000000000000000000000001202977411cd6674c957c74471e269ded8140f72483b5bf81846ec60be1748080e67e38c8520b0b71793f2be9d2a5b1b000000000000000000000000000000000d49d0b96d12bbb9ae56cae73bf240cac03daa2743557e6a78f029883752ba011cbe216618b28cc173a186750602eb7800000000000000000000000000000000076ed600ed860f16ec5dbae3f09471302bf85fde7702b3376b0d670f93560e77699bed969e7001570f44dc5e37aaa830000000000000000000000000000000000c993a8b08d2eb00bcee05e1c09e8a37834fac53643643402f60fbfe2cc7d795f5c68f3d6a32c8604c37211585830426000000000000000000000000000000000995b9bb378a7c98ed661b493ad17b3aca367cc6aa6db24fc421d82455bca4edae6c891c191023ef2113f3c7eba79662000000000000000000000000000000000213eb30b55a6ab8efdaa67c6c99362dc62022041a6ee76f7c72cc13ffaffddf88bc68ce3d4ed36d54285b177bffc1eb000000000000000000000000000000001202977411cd6674c957c74471e269ded8140f72483b5bf81846ec60be1748080e67e38c8520b0b71793f2be9d2a5b1b000000000000000000000000000000000d49d0b96d12bbb9ae56cae73bf240cac03daa2743557e6a78f029883752ba011cbe216618b28cc173a186750602eb78,,,invalid point: subgroup check failed +00000000000000000000000000000000012065f7dc3b8d6d6dded1106ecd071ac0e5f73c2aea8d088bda7687ccbb34625e2da53befb200d0885b25c228b3637a000000000000000000000000000000000d222a3c0a560f9e8a6624d9100b72e62f515f1d9384ac966d99c1761264ff8e88f308e57ddc94f156655dc310b3976e00000000000000000000000000000000109fe60cebfba62b89ae166733a097629026ccee41c95ad0260c96b772293e1403247b0451d149d527212c228ca6733a000000000000000000000000000000000a497d6c0285f7d5434c42605077528e24eee8185a615c39d2caabc570bcc01b40eadb937d78e6ceb8572115671053c8000000000000000000000000000000000f0d14ceab429a46e5568200034dba88a713899a12602529fd015e2c792191d8ef492a4d685ed09a75f638ad56f02ef10000000000000000000000000000000004d4b477fa154cd86a0934130c27f4eefed4b986da5afadf558d4fa003d2480a93b351798a24c2232e3c09c0bc33e7a400000000000000000000000000000000012065f7dc3b8d6d6dded1106ecd071ac0e5f73c2aea8d088bda7687ccbb34625e2da53befb200d0885b25c228b3637a000000000000000000000000000000000d222a3c0a560f9e8a6624d9100b72e62f515f1d9384ac966d99c1761264ff8e88f308e57ddc94f156655dc310b3976e00000000000000000000000000000000129c37bc44471eeb38b484699156862250e40df9415876f8a0da3d2f2504bd5dfe76e7b67f103a94c20751a656c5c1020000000000000000000000000000000011f24e9760017ed9120e3e0c25f57ff9e70f4f15265cf884d9d978225996f21905b32c0f918e5ac30e095767779cac8f00000000000000000000000000000000012e10463254df4bb4765a10ba47f47b6ca7ccf1ed289b8a9ccc4ee5cffde83a45077c3f093d0da6aaa5f38ebc3e5f0d0000000000000000000000000000000006755c3c202da2f65be8880e12485e2f8ea85b8e6c4b21b559e2a45b5f0977e01bba8685e4d7acb4fdc045a4cb6bba9d,,,invalid point: subgroup check failed +00000000000000000000000000000000182c68fe02eb491e1c0939304135485dcd2955c643ec67198d4a07075f0ec96441ffc1274e75dd36b103053660811643000000000000000000000000000000001308eb23be0860718e6ce06c2f24f9f94b7a72c557559ba8e1a9e3bc4eb4df009472adbfb26689900a65ee80b976a5c200000000000000000000000000000000030cc52d7901d0360d10f344cecc8325412788cc30a912d5de3fa9bdab18db44efea235c5d34bab526f3b8ecee2cbb8d000000000000000000000000000000000cda35f561c19ebd85a445ce8bb1618b446c7013c07606ce58e0b5627a5c9e7cb200e2b8ee12a0564730279e75b469b500000000000000000000000000000000055ad0655a96f6dab5a432e7d2fef57a6a11113070444089df23b4b911e0994b90aaaaa2c62d06756f4704fa218f7c350000000000000000000000000000000011d22438d7c162d34802a664c254abaae07659902e1f1bfc2bdffa6c17eb11bff5276474cc3cec9507e28685f1c21bb00000000000000000000000000000000005711605edddc03aee2e53b0945162616b969fc4ad2c15819df360533120dd2ded321aa929d67dbc84ecefeed531a49d0000000000000000000000000000000012adb2a59f85343c923642ea4be500595ec8c76755c0c219e5484a7a0f53a4c3f9740cf6973aab349973295791472e5900000000000000000000000000000000030cc52d7901d0360d10f344cecc8325412788cc30a912d5de3fa9bdab18db44efea235c5d34bab526f3b8ecee2cbb8d000000000000000000000000000000000cda35f561c19ebd85a445ce8bb1618b446c7013c07606ce58e0b5627a5c9e7cb200e2b8ee12a0564730279e75b469b500000000000000000000000000000000055ad0655a96f6dab5a432e7d2fef57a6a11113070444089df23b4b911e0994b90aaaaa2c62d06756f4704fa218f7c350000000000000000000000000000000011d22438d7c162d34802a664c254abaae07659902e1f1bfc2bdffa6c17eb11bff5276474cc3cec9507e28685f1c21bb0,,,invalid point: subgroup check failed +0000000000000000000000000000000001d70e0c28a776a0fef6d7d6a729f03d59c20a4c1f28bcb28645b996c307483837361d146b73fc808041893ac1738365000000000000000000000000000000000a68b5a13a6e5ffb88ad2618be4a197271d08e55781d21c367209c08fab2545b99f8e1e0b523854f075a915856f7483d0000000000000000000000000000000008c7569bb4e8d3b213dff2c132e5954e9622edc874dc82fcd674405cfda14dbeeb323d1605d06a92231f44339952333300000000000000000000000000000000092decf1271f8cb90a67c6cbf7eb0cca0c2d71c698470193ef495e494a8a1ac3b6bd78fa6e4367874ba18a00f6eca025000000000000000000000000000000000dfeff0f041a1868cd0ede471164f24dcac619c56515b8eec5c8aea870a79a2d03f0e1526eb1e8cbcba908969b5e952700000000000000000000000000000000109aa32bee0a83dae428e388a39ece51fd3f392ec841ffaa2554972528b7f55ca36b19ef6ae585e91995a50c0848cccf0000000000000000000000000000000001d70e0c28a776a0fef6d7d6a729f03d59c20a4c1f28bcb28645b996c307483837361d146b73fc808041893ac1738365000000000000000000000000000000000a68b5a13a6e5ffb88ad2618be4a197271d08e55781d21c367209c08fab2545b99f8e1e0b523854f075a915856f7483d00000000000000000000000000000000065860fd6efa478810b70e56ca788706bccb63191649d7b9e92941efe264bd4720b1f536d90a034b681ec9ee16f50b5c0000000000000000000000000000000014e4277fc0e4827510d55f27162d85d362f99ce57a7baf74f62567d42efd3afefb61782a6ba85d4d0e27184dc15b30ea0000000000000000000000000000000004a18f9b07e2c61210d7b00d54dd1e2895692b928adc0a4597d4ff7efbfd7215e764572275cb78f29d106aec578ed1a200000000000000000000000000000000025c5527f68d69ca8d86ffaaa3330784b9a9e32069cdc2e147c81d9a39eb181e39592a126d428e6f7963d34292f44e4c,,,invalid point: subgroup check failed +0000000000000000000000000000000010f18fc4c3d422a64f6c8935636cade47636934cc6c7d5077428ca6e2641068f4668a792a20c6bd4890da09de9765409000000000000000000000000000000000795df122ae83682617000aa2f80fb82cf933b2e5765fde4409249ac06d8eaf2a92938fb7bf4cc5717e4c604b68afc1f000000000000000000000000000000001825f573c335f0e3ad6ca9f721b529ab1a84585094c034058fce2f84185d99ab78e568b7cf129adb65501c266db679ff00000000000000000000000000000000114d2a8a69b83b46acc0dc3cde307b4690d2335c18b583874a0f5f6ed6b4e4ae63fb114d32479d56d3d2ce6393a128a900000000000000000000000000000000088c08b1b66f37b98e443f9d390b9934ee8edee075788a6ff9620c386f8ec4c1f6455704574b65086170c8a37f1728be000000000000000000000000000000000366a281910a6cb906b8acdb68180c6068b555c00d84b2cd3153ce5b8dc64532b3977d186202d1d6c00673b7ffe42c1a00000000000000000000000000000000067458ca402c19488e2515037abf9323ab8288e0e11f7cdee18b3da50cfa377435cfde1f63dcdc451ce65a05641cae370000000000000000000000000000000010ed9c895629bdafae66ea176388be4e4ce45cb13ecbe0869ce57f0f48852b6b8c47bcc4a14fc5327f1df372ad9f5d4a000000000000000000000000000000001825f573c335f0e3ad6ca9f721b529ab1a84585094c034058fce2f84185d99ab78e568b7cf129adb65501c266db679ff00000000000000000000000000000000114d2a8a69b83b46acc0dc3cde307b4690d2335c18b583874a0f5f6ed6b4e4ae63fb114d32479d56d3d2ce6393a128a900000000000000000000000000000000088c08b1b66f37b98e443f9d390b9934ee8edee075788a6ff9620c386f8ec4c1f6455704574b65086170c8a37f1728be000000000000000000000000000000000366a281910a6cb906b8acdb68180c6068b555c00d84b2cd3153ce5b8dc64532b3977d186202d1d6c00673b7ffe42c1a,,,invalid point: subgroup check failed +0000000000000000000000000000000018339c70bcf5f8cbf7f3d67dcc7b40a937045b53243d6bcd417d467b1a264b960793171fda821c4206d10b4fe8488e170000000000000000000000000000000017907a4fd66b2a8b113352975ed70c0833a6fb51568ada67bf9f8cdc770e30a3a5fa305200691f4e8dbf210cbefeb002000000000000000000000000000000000b46ea3a7acd5615741210a761f7ef55e7381f52593f02e20aedc0753861acfabb5333dc5bfd829656511070b642e7fb0000000000000000000000000000000000989e2bbad608bc55d0749e0de844e001934d28a58178377d8607a1c5d5c85eb346ab94bd527b36b965626457f6aa300000000000000000000000000000000016ffa6209c14e0803789f94886e96bfbab47e07ef745557f1d1dd48e887086424cac57dd9a624de73bb7f3521de3fbe2000000000000000000000000000000000fac98b30fb441d9426f61bcdbb149b103fa9ec3b85cbd5f755d57474bbeebe796b96fac0ba1d4b75897dea8e54796970000000000000000000000000000000018339c70bcf5f8cbf7f3d67dcc7b40a937045b53243d6bcd417d467b1a264b960793171fda821c4206d10b4fe8488e170000000000000000000000000000000017907a4fd66b2a8b113352975ed70c0833a6fb51568ada67bf9f8cdc770e30a3a5fa305200691f4e8dbf210cbefeb002000000000000000000000000000000000b349ddaccbdd1381d9eb4ae7e65db31733fe3c24f38c21f5a20298bd8e01db7ebbe3c703327a5f81c89c040a5e17c67000000000000000000000000000000000dbadd08c77f8c210439d48fb55c741dc83aa9adbe7153bee1ddf1d3df824938c14d85a528c285db28df1d0fb22b8e820000000000000000000000000000000014d76b082d032e23130d6e55c0560080a5aa607f6cdfcd683d4e2450aa0788a99a005ccbdefdb3f626a045fd7cb9ed6400000000000000000000000000000000124130e29fb52ffc0d8e8ec760619de7397813b8ce598afe97f9076899f13dbe35417a6f94a2c4bc0341c933ab8c30b1,,,invalid point: subgroup check failed +000000000000000000000000000000001977147ab98c2e88f46f038c821e85fdf476bfe7bf7b7fd633ecfcf1fd2ef339b3b5cc686f4a8937e16dfa29ad8123f7000000000000000000000000000000000ef669778c61c21dbd4681483c51269a74a3ba1b1f75796b4680f0e30a286aa0173147b206f91c84731ec8ead074d187000000000000000000000000000000000e0f7595e4c136b4d8bbd1eeb021df7dd2bcf1d9f98e4fa293f7edab635e019af87c138275fefacd806213177af40eca0000000000000000000000000000000005dc209d6c86f1871637998c10490a70371f9e00a68d1363dfaeb62046473dfb4bbd3b18b943439f75c45a1ee7f264a90000000000000000000000000000000003d215567d1e8f504a72658d48fa51374ac77234552c17db4033af780133d8516bb0769678ecb50b8b9eb950c2dd73e80000000000000000000000000000000004d780849b731012e1e5732d5f6d32c659a95c3e1c8f5ef4841fe82afc6f0aa309b1e02dc2554a4a4ee781be2be2149f000000000000000000000000000000000073439cedc08916d00609c6152ee2844be85550ff5c199e9e9dddf09bedfc00d907dc85255651cff3e28a74d3b4836c000000000000000000000000000000000e57e74af4f2d6c08843152cce6d095d00679998463bfb41bef9c57ba427e14715e9e0da0e8c5193a798cf92590b34b4000000000000000000000000000000000e0f7595e4c136b4d8bbd1eeb021df7dd2bcf1d9f98e4fa293f7edab635e019af87c138275fefacd806213177af40eca0000000000000000000000000000000005dc209d6c86f1871637998c10490a70371f9e00a68d1363dfaeb62046473dfb4bbd3b18b943439f75c45a1ee7f264a90000000000000000000000000000000003d215567d1e8f504a72658d48fa51374ac77234552c17db4033af780133d8516bb0769678ecb50b8b9eb950c2dd73e80000000000000000000000000000000004d780849b731012e1e5732d5f6d32c659a95c3e1c8f5ef4841fe82afc6f0aa309b1e02dc2554a4a4ee781be2be2149f,,,invalid point: subgroup check failed +0000000000000000000000000000000005585544fc7ed448c7939c42235549edc98c5d9a793ec918274b49687e8b9267d53c2e5d66a44d889e8f2e94abab43490000000000000000000000000000000002a091dc69d5af394d408a3b5b60debffddac4db228c613b2e2f98b932aa8f90d9f5a77129fc0fe69b93ca64b0081eb9000000000000000000000000000000000f694959a69b0d692e167e95524555d58d06621d77f46c54b7f0da0a45c4cabdc8ac916b0f2052cb99b6f0f5bca36fd9000000000000000000000000000000000df814c1cf62a7a089984a3afe3f7636157ee17bbe0dde1aa2e56fe7168a3fee7c6102999dfd55b282f1a6a4ca0e0cda0000000000000000000000000000000002ce0806a288c2b9d7e03204f573b06c440be782469cf7f1478f53d5b017fa9ea3b1025cc5de378e2186c150cbd1bc0f0000000000000000000000000000000007d3c1d2c5806e73119cafe9efda5a8419679c89d17f7a90fa6302485d4efe9e44b287f573d576d7f45589c7501e40ff0000000000000000000000000000000005585544fc7ed448c7939c42235549edc98c5d9a793ec918274b49687e8b9267d53c2e5d66a44d889e8f2e94abab43490000000000000000000000000000000002a091dc69d5af394d408a3b5b60debffddac4db228c613b2e2f98b932aa8f90d9f5a77129fc0fe69b93ca64b0081eb900000000000000000000000000000000199d1db3ab960c003575ba7a53f489159aa2005bc9a30bc23e952b57ac892a2340a8adbe21eb07bcbac255be231c49120000000000000000000000000000000014303bc0d1c9748ebbbc187486650cd7651e51ebeb1bb428e153ca5e83fc4b118c7575efc03ac0ba500c6149f91db23f000000000000000000000000000000000b6383243f6914d41d2947ee74ccd299a20741e33bdad3aff2d05de662fb4d7b9b9266085bb71dee8c13dfbb121cdd320000000000000000000000000000000005d515210d948c48ee9f7ced4c23a5eb12c6bc26c974d518af4e14c1b2b2c5a286c2bc4d51ff5974eb939b4395f9d8ed,,,invalid point: subgroup check failed +000000000000000000000000000000000ba91d035c7a2da7e14c400bb137b66a4d8f563004bcf57a01f21223225b93f860eaab9c429b915a130115c8f61c606b00000000000000000000000000000000196c7f0f6b99772d1a5e97afd92a6ab4916a2f2df709bf6393a60fe29623b25dbdc989f22715fda427bf8cb84cdfd033000000000000000000000000000000000b362ce289c7edfb507b579fc8d344c5e7bfa8d58bf3629a41af7ec1faecfb9b95139d9a8159804691047e4b18bc1cd600000000000000000000000000000000112bac785b4033f11b08e845c8c5ce78e40138b0cc0b998dd8e0213bbfe0e5b96a83ff2b53ee9699b18efffdf879602a00000000000000000000000000000000157885a39334664681d8425bd60e9c1d12dd1ef45b9a3c40956df105cd3534ff9378203755119ed302a54adba9e5858d0000000000000000000000000000000008237a9ffe95f89a24e1e3a82d8f127766e2173505a9ef0e715b1ec711619664a12d86d247e530049ee542ee4d20cc7000000000000000000000000000000000072c644635936a91dcaee40e3b4794e634c315a39a9cb5cb99ef6784b332fdcfaafdc80e228cd19d0104d5796f584c350000000000000000000000000000000002318bea9077484e9c1937dfa63774b5ecf6fc63ff06e5cb653553d5111a981c09c907069ffe11b5704ea60a99873283000000000000000000000000000000000b362ce289c7edfb507b579fc8d344c5e7bfa8d58bf3629a41af7ec1faecfb9b95139d9a8159804691047e4b18bc1cd600000000000000000000000000000000112bac785b4033f11b08e845c8c5ce78e40138b0cc0b998dd8e0213bbfe0e5b96a83ff2b53ee9699b18efffdf879602a00000000000000000000000000000000157885a39334664681d8425bd60e9c1d12dd1ef45b9a3c40956df105cd3534ff9378203755119ed302a54adba9e5858d0000000000000000000000000000000008237a9ffe95f89a24e1e3a82d8f127766e2173505a9ef0e715b1ec711619664a12d86d247e530049ee542ee4d20cc70,,,invalid point: subgroup check failed +00000000000000000000000000000000077dfb9ac791b3471c6cbcb0b37b65adb0bc4e40341b85c13867bfdaf32365ddfb749ebfd965abfa22996773eab505540000000000000000000000000000000015e771a0f0149cfad7910a4a1971b39323948bc7530936db5d99a53b51bd656bdce093cc2b91ebad0f91a95034afa0e3000000000000000000000000000000000200775a5848ac14b5e762ae7d4b492d2dc0bd5e80ef7fc760d42ea6fb07ffd2944409052cfb773875df676a188da65b00000000000000000000000000000000140ec7de210c890e4c795eed394d32d77f6acad0a3628da2ec805d4cf2de9822b5a73f06bdbeeba0fc1068c26da675b20000000000000000000000000000000018e7877a3f27c5400b08bd2769616745e4657f6fe262f9d7b88330917f977efa463b3226f3433da95a82568d990b1fa50000000000000000000000000000000015801af4934193336cc67fe8f4be5d2093909006f8bdd3382d60fd5c6bce4b86071370eefbce7a04dbcfb825858f90eb00000000000000000000000000000000077dfb9ac791b3471c6cbcb0b37b65adb0bc4e40341b85c13867bfdaf32365ddfb749ebfd965abfa22996773eab505540000000000000000000000000000000015e771a0f0149cfad7910a4a1971b39323948bc7530936db5d99a53b51bd656bdce093cc2b91ebad0f91a95034afa0e30000000000000000000000000000000017bbbfef68883fbf6fa9cdcef37ef145d7fbe9532164530e9c08d196ee41f38784b257087ad53f4939426451fb5f955c0000000000000000000000000000000018bb97090375c21600b6d3ee0629cff78116aa59d7b665c08590add8cdff8247c38b588a25e0b11eee5111c63f8c619e000000000000000000000000000000000e181f7327776df8ec16258115303029c68e1b72fcad6395c6d7d477368e1697076333a2102447a225fb3f3d725b3b0b000000000000000000000000000000000291d82b95e9a2c3f766994c304dae7f19f1efc789f68c4e58eda102da36cd0d7eec3d5a1b1e88c63462c8ec0e4393a4,,,invalid point: subgroup check failed +00000000000000000000000000000000121a9b867c86195dc4aee07081c1ad62f066b471bb5a14f296943b263fb9a25e6805e3171624e7e7e45b78f175a1861300000000000000000000000000000000071e1c35979d6f43170e79c0db5cceccff01f17cc2980b771a6cc38e0b27438a9db8e00eb943142d992c6a395fe4aacc000000000000000000000000000000001819d13cf4522a9362bbeb0bbbb0a498c3f34da1c9e3b2c54d08f7c8acd9ee756983fe80405579effb79d673407390ef000000000000000000000000000000000f870e5978f4a6e3b655fb2a05541ac0673e7b10136adaf28be4dfc9022d4cc8a60e17d125dfe53fbe10c644ff37e02a0000000000000000000000000000000010207ef774cddd10db2bca0a051ceb12900c407ee265dea4615553c193d7475b5ba3198b7e0160740e4fd015dca33e1d0000000000000000000000000000000017937be546e06fd2eab4c969a029534c02fb770646d43edeb5e6c8bc0c2b5f35576c375bf860fd1087ce099d4377d24e0000000000000000000000000000000001a8b8cdcd160565a1df9cb5ccb06a62fbaf32b2cac4ec9a552773313c940688638775983815cb246d4eaafe91c3451100000000000000000000000000000000082a1237c161831a37589ff711f7873d5e092d8a4690b983c9ccbbf980422ed177a3ebbd4b4ae4b557bcb3ae532f1823000000000000000000000000000000001819d13cf4522a9362bbeb0bbbb0a498c3f34da1c9e3b2c54d08f7c8acd9ee756983fe80405579effb79d673407390ef000000000000000000000000000000000f870e5978f4a6e3b655fb2a05541ac0673e7b10136adaf28be4dfc9022d4cc8a60e17d125dfe53fbe10c644ff37e02a0000000000000000000000000000000010207ef774cddd10db2bca0a051ceb12900c407ee265dea4615553c193d7475b5ba3198b7e0160740e4fd015dca33e1d0000000000000000000000000000000017937be546e06fd2eab4c969a029534c02fb770646d43edeb5e6c8bc0c2b5f35576c375bf860fd1087ce099d4377d24e,,,invalid point: subgroup check failed +000000000000000000000000000000000a86f90fcd9b63a0cd5f53356c170699d78d03f180d59c38ff770560bda30bf412fdcf236b6720d94684ef1aab97bafc00000000000000000000000000000000030bcbb272ab20a2f27d45295875e3c29a8ad088bb8173feb6f6f4d2c81bbc91d673c23239e36bdafada8c7d50b54b440000000000000000000000000000000011e01c96294c726ed3ef22a5c6597d8202604c4fb14058bf44fa64ae6d342f6f77f151c8ecd99f793e79f0ad29c309f40000000000000000000000000000000000e186664d8c2a2e136ff1be2192573b94c083bf242b2c01c984a792e43a11a10599481a9a79f6a8d5b074bc16019725000000000000000000000000000000000fc48ade56f841489c4824411130fb5b7e0e83b613fa09099f318cef207ce035d5d6e7ecff5057c15ee764ec8a7fa20300000000000000000000000000000000003f1b261043887af57fab48b505ed7aa44132457d71a390646b70fcd073e677a7e275a89dd0a2bf32beae3b2bcbd6e9000000000000000000000000000000000a86f90fcd9b63a0cd5f53356c170699d78d03f180d59c38ff770560bda30bf412fdcf236b6720d94684ef1aab97bafc00000000000000000000000000000000030bcbb272ab20a2f27d45295875e3c29a8ad088bb8173feb6f6f4d2c81bbc91d673c23239e36bdafada8c7d50b54b44000000000000000000000000000000000781404020a416e2596ab361e02674e25cfb365420d35d5db7146f563a7675a942383da44ae4df49c45b38e371c82a2a0000000000000000000000000000000010c546bda090a13ccf0fec03bdcb87b41f5aed3b4e6740690afb9dadc57d773aae2d22a2d8323336c5b1dc5798725495000000000000000000000000000000000bea6aaaadbbe8102212279f1458c461d3a0d54e341c91b5e16e0ce5ba1517a13cd1d43e1d0b25a63b7cc57ece5369f3000000000000000000000000000000000b0b676e5cc2f6ac383f5dd42d379c552579f601de0cf4f34ac637383a31e393df40f5c0f95b5a8f57cd6fa4de01caeb,,,invalid point: subgroup check failed +0000000000000000000000000000000014372fb746da15863e9ee4e06099c7e513bdbe53ca772a4b61c81eaa7f841399422f7902893d5ee7f7d59d530e3674b10000000000000000000000000000000006ba991efa65ef8dfac8b07915cab83b5267babba1291e4662a81fdcb455faf33596f6730b6f5b3eac2076054a4ccf6600000000000000000000000000000000042ee88071289a2adeb69cbab5a3ac8c7935576bc434062091cdf1cada4b67a2501c179b5980b53256f623840a5aee5700000000000000000000000000000000063b0819dd470047a704f20f5f7c65ea0899f25603dfc7e8b8d5f0d0d323180aa921e43d63b45acc8fe9054326a8d9bb000000000000000000000000000000000615e2e5b0389017cd3ce7c15740caf3b897fbe4a59c68247c3c4229bf661257f56bcc10f55fc722f96424f5617d259700000000000000000000000000000000166f7cadf7cb9ac5a8cfa83fe4aaac0e32fd4de3e38e0d39e010d50f5b3d383243d6870505f2a285b7c5f6fc1b13f0f0000000000000000000000000000000000d1ed017ef4702bcd3bfbbcff36000af6a1d26ab363e68ea5629027e0b90352bf1d8e03c13a7955da6c15507cc1c9f47000000000000000000000000000000000e09830e54fe9eddd416479a1740f6f1b7693f2d153d322f27779b16bb6451d7657df85a55da75a4aee0a2e33b3a46e600000000000000000000000000000000042ee88071289a2adeb69cbab5a3ac8c7935576bc434062091cdf1cada4b67a2501c179b5980b53256f623840a5aee5700000000000000000000000000000000063b0819dd470047a704f20f5f7c65ea0899f25603dfc7e8b8d5f0d0d323180aa921e43d63b45acc8fe9054326a8d9bb000000000000000000000000000000000615e2e5b0389017cd3ce7c15740caf3b897fbe4a59c68247c3c4229bf661257f56bcc10f55fc722f96424f5617d259700000000000000000000000000000000166f7cadf7cb9ac5a8cfa83fe4aaac0e32fd4de3e38e0d39e010d50f5b3d383243d6870505f2a285b7c5f6fc1b13f0f0,,,invalid point: subgroup check failed +0000000000000000000000000000000009f0c6f9fac38e8c83183499b8918a1ffbc52f2400882edb66594f496ff38ffec77368f28e4f20767257e200f48255700000000000000000000000000000000002a05bfde9523ac13ba3518cd5b308c4985484f996e7192140d681d9934d501111a81445031d84d4a47a9727202c07620000000000000000000000000000000003004acd2a95d932b84233e80bebb9fd92b302809725d5ca0921a5d8983950ff521d89bcc2d1bc1e7c186c702bf7aa270000000000000000000000000000000011744ffc7092744a79e345be8b51569c5df8eb10b4e49957ade8df4ee4ede566b3825eec89027d70d188ff858a8b6cf4000000000000000000000000000000000e46cd26b21a8a933eac05ed526a2b8fe195e5a5435e79c7f385fb69a90190acd06e25e9b63af7862616c79add032597000000000000000000000000000000000ad60c22b3690c78c23682ba902a18e708e88430a55a9038975a43b4606ef4c6e2b8e648a25097b3a34bf6e4024d00280000000000000000000000000000000009f0c6f9fac38e8c83183499b8918a1ffbc52f2400882edb66594f496ff38ffec77368f28e4f20767257e200f48255700000000000000000000000000000000002a05bfde9523ac13ba3518cd5b308c4985484f996e7192140d681d9934d501111a81445031d84d4a47a9727202c07620000000000000000000000000000000007d87d13752c52bf0510cee94274f6f4a6e0675de9a4a864ba5058dd8771b6c5000e957cfca5279e64f09c21111322ec0000000000000000000000000000000007999819b5b57104c9432a9d4dc6ad377f0c6f0dd630155fc489aed1f8d18ce0386222813726cb786635778b74967bce0000000000000000000000000000000016b66e0ebcbf6043f6a7fe52bf527a9b763cd68d901933068966e6dbb9817e1287ebc2de9c3729df8b4228a4f92d9732000000000000000000000000000000000ee19b863d5ce19afce76e489e122948597ac6a5ee07e2d856a49377285ac93d6674cc5429e02bbd051d4edf7988ba89,,,invalid point: subgroup check failed +000000000000000000000000000000001269c2717ba196d5004865af806d4a99b8c238583db14f9c02da70b0275cf35a3a5276eec0c8e6934f11e0d5cc8b7c9f0000000000000000000000000000000017971814f15aaf3f6672b3a720cf6726aa042dbd82ac508a8f7ac5ddf17f377891199ba2fd01d990868347d45e3b37ae0000000000000000000000000000000001587e32753adc85c98cf1322115772b0e282ef4e6a75944fc86091e81aad076508e3d727f4df0e30924fff6b67c312e000000000000000000000000000000000ae96d3a1b79985e56f80df8ac4d9792229ca580b156dbbe71a9db470447fa4dfa19fc8a8a2e2f0fae28a24b7d6153d100000000000000000000000000000000114101ad0d29ddfd2fc436d2a270711c444c8c257785f4b4c549e9c795f6dd9834d3744995d2188c0c968752a7f68892000000000000000000000000000000000d30d9cc1e2273af745dd47a596a2202ca4fb655f9f9beeb0a87631e2461f29206163fd921761fde69654cb02e23505c0000000000000000000000000000000010cda048fed479f7bcd388a0acaa977b134055f5ea92b2a689793e301d58190c67031920ccf1cd97ecf9f429f5a022e00000000000000000000000000000000014c410faae20d54049aa7c644ec1ef0388367ac847f6781e62ec88eb9262ffff5f19cf5f4ebe791a44ad9a84fd78aca70000000000000000000000000000000001587e32753adc85c98cf1322115772b0e282ef4e6a75944fc86091e81aad076508e3d727f4df0e30924fff6b67c312e000000000000000000000000000000000ae96d3a1b79985e56f80df8ac4d9792229ca580b156dbbe71a9db470447fa4dfa19fc8a8a2e2f0fae28a24b7d6153d100000000000000000000000000000000114101ad0d29ddfd2fc436d2a270711c444c8c257785f4b4c549e9c795f6dd9834d3744995d2188c0c968752a7f68892000000000000000000000000000000000d30d9cc1e2273af745dd47a596a2202ca4fb655f9f9beeb0a87631e2461f29206163fd921761fde69654cb02e23505c,,,invalid point: subgroup check failed +000000000000000000000000000000001252aaecb588ffcdee3e4fd92ff5164feaf9aa39acbc71c704d8180611d30fe13e59bba805101dc1cecf77b254bc65510000000000000000000000000000000009dc3de2e8aa94dbcc25c8775e9bd0ae0fa8581df790e562e67f24c08efaab59a0a8062478a09c262040c5f0558971c3000000000000000000000000000000000b0a6f9e0b58db3015e1dc63f9d377895d25f48e8a05371ad90c3ef5f3085a76b888d38693eefdf3b1eedf80eab1736200000000000000000000000000000000006dfb36e1c281cf1c5a8be9a631cab94aa956bacf8e9e787c0e2bab4440f03f0efc56d5a058fde2e18696c569676d3b00000000000000000000000000000000118791bba7507725b7106bc889b68c3daa56dc3100d8378cf156268f249dbafd01025cb722d58246c95ac856dd5d0411000000000000000000000000000000000f942ab8fd1e71f6d4498403116ef41954e7967222f894b93ae31f061cafaa1ed3464520dc5123aad4b0a352a85efbf8000000000000000000000000000000001252aaecb588ffcdee3e4fd92ff5164feaf9aa39acbc71c704d8180611d30fe13e59bba805101dc1cecf77b254bc65510000000000000000000000000000000009dc3de2e8aa94dbcc25c8775e9bd0ae0fa8581df790e562e67f24c08efaab59a0a8062478a09c262040c5f0558971c3000000000000000000000000000000000c13d99118e4946773d0ae54a37895411e39ba0de604c5f69d0b3ddcd50c4261c38c510bc1e018dbdf449e303e398d820000000000000000000000000000000018427393a7ed2dee713e83e58a6537c5c6baeb69ceac3b574e02af78215d99b8cd01f0c944d075300d35176099b0aa8100000000000000000000000000000000140ab2527b79327e07344a673e688debec28aa29219a5b1646a3c2b599a9d374cf5e139ab00aa237bb8e29d021d766ea0000000000000000000000000000000017164f154d26566ecc983d38d77d694208864c024c3ffc69f19f84550e86eddd8dbb055a8cf543717ce3d65e1c64c53a,,,invalid point: subgroup check failed diff --git a/evm/src/test/resources/org/hyperledger/besu/evm/precompile/pairing.csv b/evm/src/test/resources/org/hyperledger/besu/evm/precompile/pairing.csv index 1b5feaae6a..ea04bb5b73 100644 --- a/evm/src/test/resources/org/hyperledger/besu/evm/precompile/pairing.csv +++ b/evm/src/test/resources/org/hyperledger/besu/evm/precompile/pairing.csv @@ -95,10 +95,10 @@ input,result,gas,notes 0000000000000000000000000000000009ec00ea2da59d937d3154d86dbed2957667253401bce9de80e0ffe6df32f36b06404b9e3af08e912a0b4ef091f93efb000000000000000000000000000000000dd8d1bd66f4accbc9d0c7dabef7af72f51c67a0d61384647533ad92bba44a312f0be0fa52163176f1aff4e64c00aefb0000000000000000000000000000000001cdfae9234096578b9413f926ef8c6831f2c0f700e25d7553a746aef44238e493f8032e09f67f2fed9676c9611f60e70000000000000000000000000000000019c8bae08d3926997146f7827f00cde863684dd4050ea5da64f6798e7a930d3c1f34046bea0f44232594f5469db566280000000000000000000000000000000013574b997ee8988aa81db0e2ddb98be2e7005603076fac5cb246f65c869aa7bb3f148c8dde970e34e5e5efce023e633c000000000000000000000000000000000998bc9d41c5d527360fc4e68ba067d3778cf5cf00e5959b5ec52c1595aabe6e2e92d40cb34faa84513d150568c8cfc00000000000000000000000000000000009ec00ea2da59d937d3154d86dbed2957667253401bce9de80e0ffe6df32f36b06404b9e3af08e912a0b4ef091f93efb000000000000000000000000000000000c28402cd28b39ce814adfdb8453fd646f5ae3e41d718e5af1fd250e3b0cabf2efa01f045f3dce88c84f0b19b3fefbb00000000000000000000000000000000001cdfae9234096578b9413f926ef8c6831f2c0f700e25d7553a746aef44238e493f8032e09f67f2fed9676c9611f60e70000000000000000000000000000000019c8bae08d3926997146f7827f00cde863684dd4050ea5da64f6798e7a930d3c1f34046bea0f44232594f5469db566280000000000000000000000000000000013574b997ee8988aa81db0e2ddb98be2e7005603076fac5cb246f65c869aa7bb3f148c8dde970e34e5e5efce023e633c000000000000000000000000000000000998bc9d41c5d527360fc4e68ba067d3778cf5cf00e5959b5ec52c1595aabe6e2e92d40cb34faa84513d150568c8cfc00000000000000000000000000000000009ec00ea2da59d937d3154d86dbed2957667253401bce9de80e0ffe6df32f36b06404b9e3af08e912a0b4ef091f93efb000000000000000000000000000000000dd8d1bd66f4accbc9d0c7dabef7af72f51c67a0d61384647533ad92bba44a312f0be0fa52163176f1aff4e64c00aefb0000000000000000000000000000000001cdfae9234096578b9413f926ef8c6831f2c0f700e25d7553a746aef44238e493f8032e09f67f2fed9676c9611f60e70000000000000000000000000000000019c8bae08d3926997146f7827f00cde863684dd4050ea5da64f6798e7a930d3c1f34046bea0f44232594f5469db566280000000000000000000000000000000006a9c650ba974e0fa2fdf6d3659220f47d76f581ec156662b4e9dc4470164e68df977370d2bcf1cad4191031fdc1476f000000000000000000000000000000001068554cf7ba1173150be2cfb7ab4503ecea55b5f29f7d24086ba68b610637b5f0192bf1fe04557b68c1eafa9736daeb0000000000000000000000000000000009ec00ea2da59d937d3154d86dbed2957667253401bce9de80e0ffe6df32f36b06404b9e3af08e912a0b4ef091f93efb000000000000000000000000000000000c28402cd28b39ce814adfdb8453fd646f5ae3e41d718e5af1fd250e3b0cabf2efa01f045f3dce88c84f0b19b3fefbb00000000000000000000000000000000001cdfae9234096578b9413f926ef8c6831f2c0f700e25d7553a746aef44238e493f8032e09f67f2fed9676c9611f60e70000000000000000000000000000000019c8bae08d3926997146f7827f00cde863684dd4050ea5da64f6798e7a930d3c1f34046bea0f44232594f5469db566280000000000000000000000000000000006a9c650ba974e0fa2fdf6d3659220f47d76f581ec156662b4e9dc4470164e68df977370d2bcf1cad4191031fdc1476f000000000000000000000000000000001068554cf7ba1173150be2cfb7ab4503ecea55b5f29f7d24086ba68b610637b5f0192bf1fe04557b68c1eafa9736daeb0000000000000000000000000000000009ec00ea2da59d937d3154d86dbed2957667253401bce9de80e0ffe6df32f36b06404b9e3af08e912a0b4ef091f93efb000000000000000000000000000000000dd8d1bd66f4accbc9d0c7dabef7af72f51c67a0d61384647533ad92bba44a312f0be0fa52163176f1aff4e64c00aefb0000000000000000000000000000000001cdfae9234096578b9413f926ef8c6831f2c0f700e25d7553a746aef44238e493f8032e09f67f2fed9676c9611f60e70000000000000000000000000000000019c8bae08d3926997146f7827f00cde863684dd4050ea5da64f6798e7a930d3c1f34046bea0f44232594f5469db566280000000000000000000000000000000013574b997ee8988aa81db0e2ddb98be2e7005603076fac5cb246f65c869aa7bb3f148c8dde970e34e5e5efce023e633c000000000000000000000000000000000998bc9d41c5d527360fc4e68ba067d3778cf5cf00e5959b5ec52c1595aabe6e2e92d40cb34faa84513d150568c8cfc00000000000000000000000000000000009ec00ea2da59d937d3154d86dbed2957667253401bce9de80e0ffe6df32f36b06404b9e3af08e912a0b4ef091f93efb000000000000000000000000000000000c28402cd28b39ce814adfdb8453fd646f5ae3e41d718e5af1fd250e3b0cabf2efa01f045f3dce88c84f0b19b3fefbb00000000000000000000000000000000001cdfae9234096578b9413f926ef8c6831f2c0f700e25d7553a746aef44238e493f8032e09f67f2fed9676c9611f60e70000000000000000000000000000000019c8bae08d3926997146f7827f00cde863684dd4050ea5da64f6798e7a930d3c1f34046bea0f44232594f5469db566280000000000000000000000000000000013574b997ee8988aa81db0e2ddb98be2e7005603076fac5cb246f65c869aa7bb3f148c8dde970e34e5e5efce023e633c000000000000000000000000000000000998bc9d41c5d527360fc4e68ba067d3778cf5cf00e5959b5ec52c1595aabe6e2e92d40cb34faa84513d150568c8cfc00000000000000000000000000000000009ec00ea2da59d937d3154d86dbed2957667253401bce9de80e0ffe6df32f36b06404b9e3af08e912a0b4ef091f93efb000000000000000000000000000000000dd8d1bd66f4accbc9d0c7dabef7af72f51c67a0d61384647533ad92bba44a312f0be0fa52163176f1aff4e64c00aefb0000000000000000000000000000000001cdfae9234096578b9413f926ef8c6831f2c0f700e25d7553a746aef44238e493f8032e09f67f2fed9676c9611f60e70000000000000000000000000000000019c8bae08d3926997146f7827f00cde863684dd4050ea5da64f6798e7a930d3c1f34046bea0f44232594f5469db566280000000000000000000000000000000006a9c650ba974e0fa2fdf6d3659220f47d76f581ec156662b4e9dc4470164e68df977370d2bcf1cad4191031fdc1476f000000000000000000000000000000001068554cf7ba1173150be2cfb7ab4503ecea55b5f29f7d24086ba68b610637b5f0192bf1fe04557b68c1eafa9736daeb0000000000000000000000000000000009ec00ea2da59d937d3154d86dbed2957667253401bce9de80e0ffe6df32f36b06404b9e3af08e912a0b4ef091f93efb000000000000000000000000000000000c28402cd28b39ce814adfdb8453fd646f5ae3e41d718e5af1fd250e3b0cabf2efa01f045f3dce88c84f0b19b3fefbb00000000000000000000000000000000001cdfae9234096578b9413f926ef8c6831f2c0f700e25d7553a746aef44238e493f8032e09f67f2fed9676c9611f60e70000000000000000000000000000000019c8bae08d3926997146f7827f00cde863684dd4050ea5da64f6798e7a930d3c1f34046bea0f44232594f5469db566280000000000000000000000000000000006a9c650ba974e0fa2fdf6d3659220f47d76f581ec156662b4e9dc4470164e68df977370d2bcf1cad4191031fdc1476f000000000000000000000000000000001068554cf7ba1173150be2cfb7ab4503ecea55b5f29f7d24086ba68b610637b5f0192bf1fe04557b68c1eafa9736daeb,0000000000000000000000000000000000000000000000000000000000000001,409000, 0000000000000000000000000000000014153e01c9e495c5c01c82b3cad9eaf20cf78369ccbabf57fb160ded309cbd1caea3d3df38a7ea5490c67f168e9acec0000000000000000000000000000000001648030be79658c134e016a211d311841988065957b35e9bc1580fb6e05e291e747b7a960a50e26a2a3c0cd1634c3585000000000000000000000000000000000c78d84157dc0b102c3843e4c8e88f244cc1b2a27043e07b2fab694a58f93d47e4cf9ca1158a8e30e3d43f94a20d33b50000000000000000000000000000000004842fe0df312f735a9d8af0c2ff7c561ed9cf4add5e3e9402bcff1190f3f36ca91de8edc9472b3ebd27ee2d9afdf8770000000000000000000000000000000008c7a67b89960da4309888bc6ce31e7efe74867165a8aceda7c7290f8a92687100ccbcd39d4d5a67f21f4b63ecc638320000000000000000000000000000000001cd7978ce28629ed1a9c5433c555b1ebb584f80909599282467e7b2471f591bea1d73e7b0a247aed7de4f1fecc012040000000000000000000000000000000014153e01c9e495c5c01c82b3cad9eaf20cf78369ccbabf57fb160ded309cbd1caea3d3df38a7ea5490c67f168e9acec00000000000000000000000000000000003b90ede51e98dd9163b911431789b534aef452b9bd1b423a5d8c2ea1652cd05aa308568a7031d958fc2f32e9cb37526000000000000000000000000000000000c78d84157dc0b102c3843e4c8e88f244cc1b2a27043e07b2fab694a58f93d47e4cf9ca1158a8e30e3d43f94a20d33b50000000000000000000000000000000004842fe0df312f735a9d8af0c2ff7c561ed9cf4add5e3e9402bcff1190f3f36ca91de8edc9472b3ebd27ee2d9afdf8770000000000000000000000000000000008c7a67b89960da4309888bc6ce31e7efe74867165a8aceda7c7290f8a92687100ccbcd39d4d5a67f21f4b63ecc638320000000000000000000000000000000001cd7978ce28629ed1a9c5433c555b1ebb584f80909599282467e7b2471f591bea1d73e7b0a247aed7de4f1fecc012040000000000000000000000000000000014153e01c9e495c5c01c82b3cad9eaf20cf78369ccbabf57fb160ded309cbd1caea3d3df38a7ea5490c67f168e9acec0000000000000000000000000000000001648030be79658c134e016a211d311841988065957b35e9bc1580fb6e05e291e747b7a960a50e26a2a3c0cd1634c3585000000000000000000000000000000000c78d84157dc0b102c3843e4c8e88f244cc1b2a27043e07b2fab694a58f93d47e4cf9ca1158a8e30e3d43f94a20d33b50000000000000000000000000000000004842fe0df312f735a9d8af0c2ff7c561ed9cf4add5e3e9402bcff1190f3f36ca91de8edc9472b3ebd27ee2d9afdf8770000000000000000000000000000000011396b6eafe9d8f61a831ef9d6688e586602c5138ddc65d1bf69a9916c1e8db31ddf432b1406a597c7dfb49c1339727900000000000000000000000000000000183398716b5783fb7971e27306f651b8a91efc0462ef799742c8eaeeaf919d08348e8c1700b1b850e220b0e0133f98a70000000000000000000000000000000014153e01c9e495c5c01c82b3cad9eaf20cf78369ccbabf57fb160ded309cbd1caea3d3df38a7ea5490c67f168e9acec00000000000000000000000000000000003b90ede51e98dd9163b911431789b534aef452b9bd1b423a5d8c2ea1652cd05aa308568a7031d958fc2f32e9cb37526000000000000000000000000000000000c78d84157dc0b102c3843e4c8e88f244cc1b2a27043e07b2fab694a58f93d47e4cf9ca1158a8e30e3d43f94a20d33b50000000000000000000000000000000004842fe0df312f735a9d8af0c2ff7c561ed9cf4add5e3e9402bcff1190f3f36ca91de8edc9472b3ebd27ee2d9afdf8770000000000000000000000000000000011396b6eafe9d8f61a831ef9d6688e586602c5138ddc65d1bf69a9916c1e8db31ddf432b1406a597c7dfb49c1339727900000000000000000000000000000000183398716b5783fb7971e27306f651b8a91efc0462ef799742c8eaeeaf919d08348e8c1700b1b850e220b0e0133f98a70000000000000000000000000000000014153e01c9e495c5c01c82b3cad9eaf20cf78369ccbabf57fb160ded309cbd1caea3d3df38a7ea5490c67f168e9acec0000000000000000000000000000000001648030be79658c134e016a211d311841988065957b35e9bc1580fb6e05e291e747b7a960a50e26a2a3c0cd1634c3585000000000000000000000000000000000c78d84157dc0b102c3843e4c8e88f244cc1b2a27043e07b2fab694a58f93d47e4cf9ca1158a8e30e3d43f94a20d33b50000000000000000000000000000000004842fe0df312f735a9d8af0c2ff7c561ed9cf4add5e3e9402bcff1190f3f36ca91de8edc9472b3ebd27ee2d9afdf8770000000000000000000000000000000008c7a67b89960da4309888bc6ce31e7efe74867165a8aceda7c7290f8a92687100ccbcd39d4d5a67f21f4b63ecc638320000000000000000000000000000000001cd7978ce28629ed1a9c5433c555b1ebb584f80909599282467e7b2471f591bea1d73e7b0a247aed7de4f1fecc012040000000000000000000000000000000014153e01c9e495c5c01c82b3cad9eaf20cf78369ccbabf57fb160ded309cbd1caea3d3df38a7ea5490c67f168e9acec00000000000000000000000000000000003b90ede51e98dd9163b911431789b534aef452b9bd1b423a5d8c2ea1652cd05aa308568a7031d958fc2f32e9cb37526000000000000000000000000000000000c78d84157dc0b102c3843e4c8e88f244cc1b2a27043e07b2fab694a58f93d47e4cf9ca1158a8e30e3d43f94a20d33b50000000000000000000000000000000004842fe0df312f735a9d8af0c2ff7c561ed9cf4add5e3e9402bcff1190f3f36ca91de8edc9472b3ebd27ee2d9afdf8770000000000000000000000000000000008c7a67b89960da4309888bc6ce31e7efe74867165a8aceda7c7290f8a92687100ccbcd39d4d5a67f21f4b63ecc638320000000000000000000000000000000001cd7978ce28629ed1a9c5433c555b1ebb584f80909599282467e7b2471f591bea1d73e7b0a247aed7de4f1fecc012040000000000000000000000000000000014153e01c9e495c5c01c82b3cad9eaf20cf78369ccbabf57fb160ded309cbd1caea3d3df38a7ea5490c67f168e9acec0000000000000000000000000000000001648030be79658c134e016a211d311841988065957b35e9bc1580fb6e05e291e747b7a960a50e26a2a3c0cd1634c3585000000000000000000000000000000000c78d84157dc0b102c3843e4c8e88f244cc1b2a27043e07b2fab694a58f93d47e4cf9ca1158a8e30e3d43f94a20d33b50000000000000000000000000000000004842fe0df312f735a9d8af0c2ff7c561ed9cf4add5e3e9402bcff1190f3f36ca91de8edc9472b3ebd27ee2d9afdf8770000000000000000000000000000000011396b6eafe9d8f61a831ef9d6688e586602c5138ddc65d1bf69a9916c1e8db31ddf432b1406a597c7dfb49c1339727900000000000000000000000000000000183398716b5783fb7971e27306f651b8a91efc0462ef799742c8eaeeaf919d08348e8c1700b1b850e220b0e0133f98a70000000000000000000000000000000014153e01c9e495c5c01c82b3cad9eaf20cf78369ccbabf57fb160ded309cbd1caea3d3df38a7ea5490c67f168e9acec00000000000000000000000000000000003b90ede51e98dd9163b911431789b534aef452b9bd1b423a5d8c2ea1652cd05aa308568a7031d958fc2f32e9cb37526000000000000000000000000000000000c78d84157dc0b102c3843e4c8e88f244cc1b2a27043e07b2fab694a58f93d47e4cf9ca1158a8e30e3d43f94a20d33b50000000000000000000000000000000004842fe0df312f735a9d8af0c2ff7c561ed9cf4add5e3e9402bcff1190f3f36ca91de8edc9472b3ebd27ee2d9afdf8770000000000000000000000000000000011396b6eafe9d8f61a831ef9d6688e586602c5138ddc65d1bf69a9916c1e8db31ddf432b1406a597c7dfb49c1339727900000000000000000000000000000000183398716b5783fb7971e27306f651b8a91efc0462ef799742c8eaeeaf919d08348e8c1700b1b850e220b0e0133f98a7,0000000000000000000000000000000000000000000000000000000000000001,409000, 000000000000000000000000000000001555535228eb9a24f460df9894d59aa06fc848a8bf8d6c3b51653b1d85734b3c5a2bece161309bd478d356fa198d579500000000000000000000000000000000144401f7eb69f6321eae8dad39dbe2cf4ae58e455474701dd9f1b62c85c7536813e84eb4f9def511eb62e5194288728b000000000000000000000000000000000e619d79792ac685030311a31a21203e5172d2e5d20ecf69a1e64158e7fe903b3695fd15432d3ca35562b5a8bd9cbdc20000000000000000000000000000000012394a621a503d1d92df3306649a6c6979816cabeb8f8d27450ec883c4e75f6f7411f3bfd068dc8dee58cdb8ebbd91bd0000000000000000000000000000000001652a688dbfd63a1c89452335bdaf248c97c9c6e5a3ad5a126577a6b9ab57075b22987ea8697b459611a5ab164f328400000000000000000000000000000000058a37347c5637808632ae6e8f264e8bde14ebb0ae69828f962f51b728321fea57c5a97ab694f7db175efe7a17d36cb6000000000000000000000000000000001555535228eb9a24f460df9894d59aa06fc848a8bf8d6c3b51653b1d85734b3c5a2bece161309bd478d356fa198d57950000000000000000000000000000000005bd0ff24e15f0682c6d1a09096fca081991bd3f9f10a2a18d3f1c7470e9a2bc0ac3b149b7750aedce9c1ae6bd773820000000000000000000000000000000000e619d79792ac685030311a31a21203e5172d2e5d20ecf69a1e64158e7fe903b3695fd15432d3ca35562b5a8bd9cbdc20000000000000000000000000000000012394a621a503d1d92df3306649a6c6979816cabeb8f8d27450ec883c4e75f6f7411f3bfd068dc8dee58cdb8ebbd91bd0000000000000000000000000000000001652a688dbfd63a1c89452335bdaf248c97c9c6e5a3ad5a126577a6b9ab57075b22987ea8697b459611a5ab164f328400000000000000000000000000000000058a37347c5637808632ae6e8f264e8bde14ebb0ae69828f962f51b728321fea57c5a97ab694f7db175efe7a17d36cb6000000000000000000000000000000001555535228eb9a24f460df9894d59aa06fc848a8bf8d6c3b51653b1d85734b3c5a2bece161309bd478d356fa198d579500000000000000000000000000000000144401f7eb69f6321eae8dad39dbe2cf4ae58e455474701dd9f1b62c85c7536813e84eb4f9def511eb62e5194288728b000000000000000000000000000000000e619d79792ac685030311a31a21203e5172d2e5d20ecf69a1e64158e7fe903b3695fd15432d3ca35562b5a8bd9cbdc20000000000000000000000000000000012394a621a503d1d92df3306649a6c6979816cabeb8f8d27450ec883c4e75f6f7411f3bfd068dc8dee58cdb8ebbd91bd00000000000000000000000000000000189be781abc010602e9262930d8dfdb2d7df81be0de1656554cb5afa3d059f1cc389678008ea84ba23ed5a54e9b07827000000000000000000000000000000001476dab5bd29af19c4e8f947b4255e4b86625fd4451b902fd10180e9ce7ed639c6e65683fabf0824a2a00185e82c3df5000000000000000000000000000000001555535228eb9a24f460df9894d59aa06fc848a8bf8d6c3b51653b1d85734b3c5a2bece161309bd478d356fa198d57950000000000000000000000000000000005bd0ff24e15f0682c6d1a09096fca081991bd3f9f10a2a18d3f1c7470e9a2bc0ac3b149b7750aedce9c1ae6bd773820000000000000000000000000000000000e619d79792ac685030311a31a21203e5172d2e5d20ecf69a1e64158e7fe903b3695fd15432d3ca35562b5a8bd9cbdc20000000000000000000000000000000012394a621a503d1d92df3306649a6c6979816cabeb8f8d27450ec883c4e75f6f7411f3bfd068dc8dee58cdb8ebbd91bd00000000000000000000000000000000189be781abc010602e9262930d8dfdb2d7df81be0de1656554cb5afa3d059f1cc389678008ea84ba23ed5a54e9b07827000000000000000000000000000000001476dab5bd29af19c4e8f947b4255e4b86625fd4451b902fd10180e9ce7ed639c6e65683fabf0824a2a00185e82c3df5000000000000000000000000000000001555535228eb9a24f460df9894d59aa06fc848a8bf8d6c3b51653b1d85734b3c5a2bece161309bd478d356fa198d579500000000000000000000000000000000144401f7eb69f6321eae8dad39dbe2cf4ae58e455474701dd9f1b62c85c7536813e84eb4f9def511eb62e5194288728b000000000000000000000000000000000e619d79792ac685030311a31a21203e5172d2e5d20ecf69a1e64158e7fe903b3695fd15432d3ca35562b5a8bd9cbdc20000000000000000000000000000000012394a621a503d1d92df3306649a6c6979816cabeb8f8d27450ec883c4e75f6f7411f3bfd068dc8dee58cdb8ebbd91bd0000000000000000000000000000000001652a688dbfd63a1c89452335bdaf248c97c9c6e5a3ad5a126577a6b9ab57075b22987ea8697b459611a5ab164f328400000000000000000000000000000000058a37347c5637808632ae6e8f264e8bde14ebb0ae69828f962f51b728321fea57c5a97ab694f7db175efe7a17d36cb6000000000000000000000000000000001555535228eb9a24f460df9894d59aa06fc848a8bf8d6c3b51653b1d85734b3c5a2bece161309bd478d356fa198d57950000000000000000000000000000000005bd0ff24e15f0682c6d1a09096fca081991bd3f9f10a2a18d3f1c7470e9a2bc0ac3b149b7750aedce9c1ae6bd773820000000000000000000000000000000000e619d79792ac685030311a31a21203e5172d2e5d20ecf69a1e64158e7fe903b3695fd15432d3ca35562b5a8bd9cbdc20000000000000000000000000000000012394a621a503d1d92df3306649a6c6979816cabeb8f8d27450ec883c4e75f6f7411f3bfd068dc8dee58cdb8ebbd91bd0000000000000000000000000000000001652a688dbfd63a1c89452335bdaf248c97c9c6e5a3ad5a126577a6b9ab57075b22987ea8697b459611a5ab164f328400000000000000000000000000000000058a37347c5637808632ae6e8f264e8bde14ebb0ae69828f962f51b728321fea57c5a97ab694f7db175efe7a17d36cb6000000000000000000000000000000001555535228eb9a24f460df9894d59aa06fc848a8bf8d6c3b51653b1d85734b3c5a2bece161309bd478d356fa198d579500000000000000000000000000000000144401f7eb69f6321eae8dad39dbe2cf4ae58e455474701dd9f1b62c85c7536813e84eb4f9def511eb62e5194288728b000000000000000000000000000000000e619d79792ac685030311a31a21203e5172d2e5d20ecf69a1e64158e7fe903b3695fd15432d3ca35562b5a8bd9cbdc20000000000000000000000000000000012394a621a503d1d92df3306649a6c6979816cabeb8f8d27450ec883c4e75f6f7411f3bfd068dc8dee58cdb8ebbd91bd00000000000000000000000000000000189be781abc010602e9262930d8dfdb2d7df81be0de1656554cb5afa3d059f1cc389678008ea84ba23ed5a54e9b07827000000000000000000000000000000001476dab5bd29af19c4e8f947b4255e4b86625fd4451b902fd10180e9ce7ed639c6e65683fabf0824a2a00185e82c3df5000000000000000000000000000000001555535228eb9a24f460df9894d59aa06fc848a8bf8d6c3b51653b1d85734b3c5a2bece161309bd478d356fa198d57950000000000000000000000000000000005bd0ff24e15f0682c6d1a09096fca081991bd3f9f10a2a18d3f1c7470e9a2bc0ac3b149b7750aedce9c1ae6bd773820000000000000000000000000000000000e619d79792ac685030311a31a21203e5172d2e5d20ecf69a1e64158e7fe903b3695fd15432d3ca35562b5a8bd9cbdc20000000000000000000000000000000012394a621a503d1d92df3306649a6c6979816cabeb8f8d27450ec883c4e75f6f7411f3bfd068dc8dee58cdb8ebbd91bd00000000000000000000000000000000189be781abc010602e9262930d8dfdb2d7df81be0de1656554cb5afa3d059f1cc389678008ea84ba23ed5a54e9b07827000000000000000000000000000000001476dab5bd29af19c4e8f947b4255e4b86625fd4451b902fd10180e9ce7ed639c6e65683fabf0824a2a00185e82c3df5,0000000000000000000000000000000000000000000000000000000000000001,409000, -00000000000000000000000000000012196c5a43d69224d8713389285f26b98f86ee910ab3dd668e413738282003cc5b7357af9a7af54bb713d62255e80f560000000000000000000000000000000006ba8102bfbeea4416b710c73e8cce3032c31c6269c44906f8ac4f7874ce99fb17559992486528963884ce429a992fee0000000000000000000000000000000017c9fcf0504e62d3553b2f089b64574150aa5117bd3d2e89a8c1ed59bb7f70fb83215975ef31976e757abf60a75a1d9f0000000000000000000000000000000008f5a53d704298fe0cfc955e020442874fe87d5c729c7126abbdcbed355eef6c8f07277bee6d49d56c4ebaf334848624000000000000000000000000000000001302dcc50c6ce4c28086f8e1b43f9f65543cf598be440123816765ab6bc93f62bceda80045fbcad8598d4f32d03ee8fa000000000000000000000000000000000bbb4eb37628d60b035a3e0c45c0ea8c4abef5a6ddc5625e0560097ef9caab208221062e81cd77ef72162923a1906a40,,115000,invalid input parameters, invalid input length for pairing +00000000000000000000000000000012196c5a43d69224d8713389285f26b98f86ee910ab3dd668e413738282003cc5b7357af9a7af54bb713d62255e80f560000000000000000000000000000000006ba8102bfbeea4416b710c73e8cce3032c31c6269c44906f8ac4f7874ce99fb17559992486528963884ce429a992fee0000000000000000000000000000000017c9fcf0504e62d3553b2f089b64574150aa5117bd3d2e89a8c1ed59bb7f70fb83215975ef31976e757abf60a75a1d9f0000000000000000000000000000000008f5a53d704298fe0cfc955e020442874fe87d5c729c7126abbdcbed355eef6c8f07277bee6d49d56c4ebaf334848624000000000000000000000000000000001302dcc50c6ce4c28086f8e1b43f9f65543cf598be440123816765ab6bc93f62bceda80045fbcad8598d4f32d03ee8fa000000000000000000000000000000000bbb4eb37628d60b035a3e0c45c0ea8c4abef5a6ddc5625e0560097ef9caab208221062e81cd77ef72162923a1906a40,,115000,invalid input parameters, invalid number of pairs 000000000000000000000000000000000012196c5a43d69224d8713389285f26b98f86ee910ab3dd668e413738282003cc5b7357af9a7af54bb713d62255e80f560000000000000000000000000000000006ba8102bfbeea4416b710c73e8cce3032c31c6269c44906f8ac4f7874ce99fb17559992486528963884ce429a992fee0000000000000000000000000000000017c9fcf0504e62d3553b2f089b64574150aa5117bd3d2e89a8c1ed59bb7f70fb83215975ef31976e757abf60a75a1d9f0000000000000000000000000000000008f5a53d704298fe0cfc955e020442874fe87d5c729c7126abbdcbed355eef6c8f07277bee6d49d56c4ebaf334848624000000000000000000000000000000001302dcc50c6ce4c28086f8e1b43f9f65543cf598be440123816765ab6bc93f62bceda80045fbcad8598d4f32d03ee8fa000000000000000000000000000000000bbb4eb37628d60b035a3e0c45c0ea8c4abef5a6ddc5625e0560097ef9caab208221062e81cd77ef72162923a1906a40,,108000,invalid input parameters, invalid input length for pairing -,,115000,invalid input parameters, Invalid number of pairs -0000000000000000000000000000000012196c5a43d69224d8713389285f26b98f86ee910ab3dd668e413738282003cc5b7357af9a7af54bb713d62255e80f570000000000000000000000000000000006ba8102bfbeea4416b710c73e8cce3032c31c6269c44906f8ac4f7874ce99fb17559992486528963884ce429a992fee0000000000000000000000000000000017c9fcf0504e62d3553b2f089b64574150aa5117bd3d2e89a8c1ed59bb7f70fb83215975ef31976e757abf60a75a1d9f0000000000000000000000000000000008f5a53d704298fe0cfc955e020442874fe87d5c729c7126abbdcbed355eef6c8f07277bee6d49d56c4ebaf334848624000000000000000000000000000000001302dcc50c6ce4c28086f8e1b43f9f65543cf598be440123816765ab6bc93f62bceda80045fbcad8598d4f32d03ee8fa000000000000000000000000000000000bbb4eb37628d60b035a3e0c45c0ea8c4abef5a6ddc5625e0560097ef9caab208221062e81cd77ef72162923a1906a40,,108000,invalid input parameters, G1 point is not on curve -0000000000000000000000000000000012196c5a43d69224d8713389285f26b98f86ee910ab3dd668e413738282003cc5b7357af9a7af54bb713d62255e80f560000000000000000000000000000000006ba8102bfbeea4416b710c73e8cce3032c31c6269c44906f8ac4f7874ce99fb17559992486528963884ce429a992fee0000000000000000000000000000000017c9fcf0504e62d3553b2f089b64574150aa5117bd3d2e89a8c1ed59bb7f70fb83215975ef31976e757abf60a75a1da00000000000000000000000000000000008f5a53d704298fe0cfc955e020442874fe87d5c729c7126abbdcbed355eef6c8f07277bee6d49d56c4ebaf334848624000000000000000000000000000000001302dcc50c6ce4c28086f8e1b43f9f65543cf598be440123816765ab6bc93f62bceda80045fbcad8598d4f32d03ee8fa000000000000000000000000000000000bbb4eb37628d60b035a3e0c45c0ea8c4abef5a6ddc5625e0560097ef9caab208221062e81cd77ef72162923a1906a40,,108000,invalid input parameters, G2 point is not on curve -000000000000000000000000000000001830f52d9bff64a623c6f5259e2cd2c2a08ea17a8797aaf83174ea1e8c3bd3955c2af1d39bfa474815bfe60714b7cd80000000000000000000000000000000000874389c02d4cf1c61bc54c4c24def11dfbe7880bc998a95e70063009451ee8226fec4b278aade3a7cea55659459f1d500000000000000000000000000000000197737f831d4dc7e708475f4ca7ca15284db2f3751fcaac0c17f517f1ddab35e1a37907d7b99b39d6c8d9001cd50e79e000000000000000000000000000000000af1a3f6396f0c983e7c2d42d489a3ae5a3ff0a553d93154f73ac770cd0af7467aa0cef79f10bbd34621b3ec9583a834000000000000000000000000000000001918cb6e448ed69fb906145de3f11455ee0359d030e90d673ce050a360d796de33ccd6a941c49a1414aca1c26f9e699e0000000000000000000000000000000019a915154a13249d784093facc44520e7f3a18410ab2a3093e0b12657788e9419eec25729944f7945e732104939e7a9e000000000000000000000000000000001830f52d9bff64a623c6f5259e2cd2c2a08ea17a8797aaf83174ea1e8c3bd3955c2af1d39bfa474815bfe60714b7cd9000000000000000000000000000000000118cd94e36ab177de95f52f180fdbdc584b8d30436eb882980306fa0625f07a1f7ad3b4c38a921c53d14aa9a6ba5b8d600000000000000000000000000000000197737f831d4dc7e708475f4ca7ca15284db2f3751fcaac0c17f517f1ddab35e1a37907d7b99b39d6c8d9001cd50e79e000000000000000000000000000000000af1a3f6396f0c983e7c2d42d489a3ae5a3ff0a553d93154f73ac770cd0af7467aa0cef79f10bbd34621b3ec9583a834000000000000000000000000000000001918cb6e448ed69fb906145de3f11455ee0359d030e90d673ce050a360d796de33ccd6a941c49a1414aca1c26f9e699e0000000000000000000000000000000019a915154a13249d784093facc44520e7f3a18410ab2a3093e0b12657788e9419eec25729944f7945e732104939e7a9e,,151000,invalid input parameters, G1 point is not on curve -000000000000000000000000000000001830f52d9bff64a623c6f5259e2cd2c2a08ea17a8797aaf83174ea1e8c3bd3955c2af1d39bfa474815bfe60714b7cd80000000000000000000000000000000000874389c02d4cf1c61bc54c4c24def11dfbe7880bc998a95e70063009451ee8226fec4b278aade3a7cea55659459f1d500000000000000000000000000000000197737f831d4dc7e708475f4ca7ca15284db2f3751fcaac0c17f517f1ddab35e1a37907d7b99b39d6c8d9001cd50e79e000000000000000000000000000000000af1a3f6396f0c983e7c2d42d489a3ae5a3ff0a553d93154f73ac770cd0af7467aa0cef79f10bbd34621b3ec9583a834000000000000000000000000000000001918cb6e448ed69fb906145de3f11455ee0359d030e90d673ce050a360d796de33ccd6a941c49a1414aca1c26f9e699e0000000000000000000000000000000019a915154a13249d784093facc44520e7f3a18410ab2a3093e0b12657788e9419eec25729944f7945e732104939e7a9e000000000000000000000000000000001830f52d9bff64a623c6f5259e2cd2c2a08ea17a8797aaf83174ea1e8c3bd3955c2af1d39bfa474815bfe60714b7cd8000000000000000000000000000000000118cd94e36ab177de95f52f180fdbdc584b8d30436eb882980306fa0625f07a1f7ad3b4c38a921c53d14aa9a6ba5b8d600000000000000000000000000000000197737f831d4dc7e708475f4ca7ca15284db2f3751fcaac0c17f517f1ddab35e1a37907d7b99b39d6c8d9001cd50e79f000000000000000000000000000000000af1a3f6396f0c983e7c2d42d489a3ae5a3ff0a553d93154f73ac770cd0af7467aa0cef79f10bbd34621b3ec9583a834000000000000000000000000000000001918cb6e448ed69fb906145de3f11455ee0359d030e90d673ce050a360d796de33ccd6a941c49a1414aca1c26f9e699e0000000000000000000000000000000019a915154a13249d784093facc44520e7f3a18410ab2a3093e0b12657788e9419eec25729944f7945e732104939e7a9e,,151000,invalid input parameters, G2 point is not on curve +,,115000,invalid input parameters, invalid number of pairs +0000000000000000000000000000000012196c5a43d69224d8713389285f26b98f86ee910ab3dd668e413738282003cc5b7357af9a7af54bb713d62255e80f570000000000000000000000000000000006ba8102bfbeea4416b710c73e8cce3032c31c6269c44906f8ac4f7874ce99fb17559992486528963884ce429a992fee0000000000000000000000000000000017c9fcf0504e62d3553b2f089b64574150aa5117bd3d2e89a8c1ed59bb7f70fb83215975ef31976e757abf60a75a1d9f0000000000000000000000000000000008f5a53d704298fe0cfc955e020442874fe87d5c729c7126abbdcbed355eef6c8f07277bee6d49d56c4ebaf334848624000000000000000000000000000000001302dcc50c6ce4c28086f8e1b43f9f65543cf598be440123816765ab6bc93f62bceda80045fbcad8598d4f32d03ee8fa000000000000000000000000000000000bbb4eb37628d60b035a3e0c45c0ea8c4abef5a6ddc5625e0560097ef9caab208221062e81cd77ef72162923a1906a40,,108000,invalid point: point is not on curve +0000000000000000000000000000000012196c5a43d69224d8713389285f26b98f86ee910ab3dd668e413738282003cc5b7357af9a7af54bb713d62255e80f560000000000000000000000000000000006ba8102bfbeea4416b710c73e8cce3032c31c6269c44906f8ac4f7874ce99fb17559992486528963884ce429a992fee0000000000000000000000000000000017c9fcf0504e62d3553b2f089b64574150aa5117bd3d2e89a8c1ed59bb7f70fb83215975ef31976e757abf60a75a1da00000000000000000000000000000000008f5a53d704298fe0cfc955e020442874fe87d5c729c7126abbdcbed355eef6c8f07277bee6d49d56c4ebaf334848624000000000000000000000000000000001302dcc50c6ce4c28086f8e1b43f9f65543cf598be440123816765ab6bc93f62bceda80045fbcad8598d4f32d03ee8fa000000000000000000000000000000000bbb4eb37628d60b035a3e0c45c0ea8c4abef5a6ddc5625e0560097ef9caab208221062e81cd77ef72162923a1906a40,,108000,invalid point: point is not on curve +000000000000000000000000000000001830f52d9bff64a623c6f5259e2cd2c2a08ea17a8797aaf83174ea1e8c3bd3955c2af1d39bfa474815bfe60714b7cd80000000000000000000000000000000000874389c02d4cf1c61bc54c4c24def11dfbe7880bc998a95e70063009451ee8226fec4b278aade3a7cea55659459f1d500000000000000000000000000000000197737f831d4dc7e708475f4ca7ca15284db2f3751fcaac0c17f517f1ddab35e1a37907d7b99b39d6c8d9001cd50e79e000000000000000000000000000000000af1a3f6396f0c983e7c2d42d489a3ae5a3ff0a553d93154f73ac770cd0af7467aa0cef79f10bbd34621b3ec9583a834000000000000000000000000000000001918cb6e448ed69fb906145de3f11455ee0359d030e90d673ce050a360d796de33ccd6a941c49a1414aca1c26f9e699e0000000000000000000000000000000019a915154a13249d784093facc44520e7f3a18410ab2a3093e0b12657788e9419eec25729944f7945e732104939e7a9e000000000000000000000000000000001830f52d9bff64a623c6f5259e2cd2c2a08ea17a8797aaf83174ea1e8c3bd3955c2af1d39bfa474815bfe60714b7cd9000000000000000000000000000000000118cd94e36ab177de95f52f180fdbdc584b8d30436eb882980306fa0625f07a1f7ad3b4c38a921c53d14aa9a6ba5b8d600000000000000000000000000000000197737f831d4dc7e708475f4ca7ca15284db2f3751fcaac0c17f517f1ddab35e1a37907d7b99b39d6c8d9001cd50e79e000000000000000000000000000000000af1a3f6396f0c983e7c2d42d489a3ae5a3ff0a553d93154f73ac770cd0af7467aa0cef79f10bbd34621b3ec9583a834000000000000000000000000000000001918cb6e448ed69fb906145de3f11455ee0359d030e90d673ce050a360d796de33ccd6a941c49a1414aca1c26f9e699e0000000000000000000000000000000019a915154a13249d784093facc44520e7f3a18410ab2a3093e0b12657788e9419eec25729944f7945e732104939e7a9e,,151000,invalid point: point is not on curve +000000000000000000000000000000001830f52d9bff64a623c6f5259e2cd2c2a08ea17a8797aaf83174ea1e8c3bd3955c2af1d39bfa474815bfe60714b7cd80000000000000000000000000000000000874389c02d4cf1c61bc54c4c24def11dfbe7880bc998a95e70063009451ee8226fec4b278aade3a7cea55659459f1d500000000000000000000000000000000197737f831d4dc7e708475f4ca7ca15284db2f3751fcaac0c17f517f1ddab35e1a37907d7b99b39d6c8d9001cd50e79e000000000000000000000000000000000af1a3f6396f0c983e7c2d42d489a3ae5a3ff0a553d93154f73ac770cd0af7467aa0cef79f10bbd34621b3ec9583a834000000000000000000000000000000001918cb6e448ed69fb906145de3f11455ee0359d030e90d673ce050a360d796de33ccd6a941c49a1414aca1c26f9e699e0000000000000000000000000000000019a915154a13249d784093facc44520e7f3a18410ab2a3093e0b12657788e9419eec25729944f7945e732104939e7a9e000000000000000000000000000000001830f52d9bff64a623c6f5259e2cd2c2a08ea17a8797aaf83174ea1e8c3bd3955c2af1d39bfa474815bfe60714b7cd8000000000000000000000000000000000118cd94e36ab177de95f52f180fdbdc584b8d30436eb882980306fa0625f07a1f7ad3b4c38a921c53d14aa9a6ba5b8d600000000000000000000000000000000197737f831d4dc7e708475f4ca7ca15284db2f3751fcaac0c17f517f1ddab35e1a37907d7b99b39d6c8d9001cd50e79f000000000000000000000000000000000af1a3f6396f0c983e7c2d42d489a3ae5a3ff0a553d93154f73ac770cd0af7467aa0cef79f10bbd34621b3ec9583a834000000000000000000000000000000001918cb6e448ed69fb906145de3f11455ee0359d030e90d673ce050a360d796de33ccd6a941c49a1414aca1c26f9e699e0000000000000000000000000000000019a915154a13249d784093facc44520e7f3a18410ab2a3093e0b12657788e9419eec25729944f7945e732104939e7a9e,,151000,invalid point: point is not on curve From 5cb00f2f5ff84b66d974bc4ab2f3248e26fb03aa Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Mon, 15 Jul 2024 12:45:36 +1000 Subject: [PATCH 035/259] 6612 update changelog with removed syncmodes (#7320) * 6612: Update changelog with removal of deprecated sync modes Signed-off-by: Matilda Clerke * 6612: Update changelog with removal of deprecated sync modes Signed-off-by: Matilda Clerke * 6612: Update changelog with removal of deprecated sync modes Signed-off-by: Matilda Clerke --------- Signed-off-by: Matilda Clerke --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c8a6730a96..70714d2055 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Next release ### Breaking Changes +- Removed deprecated sync modes (X_SNAP and X_CHECKPOINT). Use SNAP and CHECKPOINT instead [#7309](https://github.com/hyperledger/besu/pull/7309) ### Additions and Improvements - `--Xsnapsync-bft-enabled` option enables experimental support for snap sync with IBFT/QBFT permissioned Bonsai-DB chains [#7140](https://github.com/hyperledger/besu/pull/7140) From 51f10dcdd2efbf31172ee1774d29d61b171c8a67 Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Sun, 14 Jul 2024 21:05:22 -0600 Subject: [PATCH 036/259] Update datacopy (#7319) Check for OOG earlier in DataCopy. Add unit tests to cover operation branches. Signed-off-by: Danno Ferrin --- .../besu/evm/operation/DataCopyOperation.java | 4 + .../evm/operations/DataCopyOperationTest.java | 179 ++++++++++++++++++ 2 files changed, 183 insertions(+) create mode 100644 evm/src/test/java/org/hyperledger/besu/evm/operations/DataCopyOperationTest.java diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/DataCopyOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/DataCopyOperation.java index 7813358eac..a7f7b01479 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/DataCopyOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/DataCopyOperation.java @@ -18,6 +18,7 @@ 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.ExceptionalHaltReason; import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.gascalculator.GasCalculator; @@ -58,6 +59,9 @@ public class DataCopyOperation extends AbstractOperation { final int sourceOffset = clampedToInt(frame.popStackItem()); final int length = clampedToInt(frame.popStackItem()); final long cost = cost(frame, memOffset, length); + if (cost > frame.getRemainingGas()) { + return new OperationResult(cost, ExceptionalHaltReason.INSUFFICIENT_GAS); + } final Bytes data = code.getData(sourceOffset, length); frame.writeMemory(memOffset, length, data); diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operations/DataCopyOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operations/DataCopyOperationTest.java new file mode 100644 index 0000000000..83d7f09e5a --- /dev/null +++ b/evm/src/test/java/org/hyperledger/besu/evm/operations/DataCopyOperationTest.java @@ -0,0 +1,179 @@ +/* + * Copyright contributors to Hyperledger Besu. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.evm.operations; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assumptions.assumeThat; + +import org.hyperledger.besu.evm.Code; +import org.hyperledger.besu.evm.EVM; +import org.hyperledger.besu.evm.MainnetEVMs; +import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; +import org.hyperledger.besu.evm.frame.MessageFrame; +import org.hyperledger.besu.evm.gascalculator.PragueGasCalculator; +import org.hyperledger.besu.evm.internal.EvmConfiguration; +import org.hyperledger.besu.evm.operation.DataCopyOperation; +import org.hyperledger.besu.evm.operation.Operation; +import org.hyperledger.besu.evm.testutils.TestMessageFrameBuilder; + +import java.util.Arrays; +import java.util.Collection; + +import org.apache.tuweni.bytes.Bytes; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +class DataCopyOperationTest { + + static EVM evm = MainnetEVMs.pragueEOF(EvmConfiguration.DEFAULT); + + static Collection datacopyTestVector() { + return Arrays.asList( + new Object[][] { + { + "Copy after, no overlap", + Bytes.fromHexString("0123456789abcdef000000000000000000000000000000000000000000000000"), + 32, + 0, + 8, + Bytes.fromHexString( + "00000000000000000000000000000000000000000000000000000000000000000123456789abcdef"), + 12L + }, + { + "copy past data limit", + Bytes.EMPTY, + 0, + 24, + 16, + Bytes.fromHexString( + "0x0000000000000000000000000000000000000000000000000000000000000000"), + 9L + }, + { + "copy from initialized + uninitialized memory", + Bytes.fromHexString( + "0x0000000000000000000000000000000000000000000000000123456789abcdef"), + 64, + 24, + 16, + Bytes.fromHexString( + "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000123456789abcdef000000000000000000000000000000000000000000000000"), + 15L + }, + { + "overlapping src < dst", + Bytes.fromHexString( + "0x0123456789abcdef000000000000000000000000000000000000000000000000"), + 4, + 0, + 8, + Bytes.fromHexString( + "0x000000000123456789abcdef0000000000000000000000000000000000000000"), + 9L + }, + { + "overlapping src > dst", + Bytes.fromHexString( + "0x00112233445566778899aabbccddeeff00000000000000000000000000000000"), + 0, + 4, + 8, + Bytes.fromHexString( + "0x445566778899aabb000000000000000000000000000000000000000000000000"), + 9L + }, + { + "overlapping src == dst", + Bytes.fromHexString( + "0x00112233445566778899aabbccddeeff00000000000000000000000000000000"), + 4, + 4, + 8, + Bytes.fromHexString( + "0x00000000445566778899aabb0000000000000000000000000000000000000000"), + 9L + }, + {"large dst offset", Bytes.EMPTY, 0x8000000000000010L, 4, 8, Bytes.EMPTY, 8796294610953L}, + { + "large src offset", + Bytes.EMPTY, + 4, + 0x8000000000000010L, + 8, + Bytes.fromHexString( + "0x0000000000000000000000000000000000000000000000000000000000000000"), + 9L + }, + {"large len", Bytes.EMPTY, 4, 4, 0x8000000000000010L, Bytes.EMPTY, 8796093284361L} + }); + } + + @SuppressWarnings("unused") + @ParameterizedTest(name = "{0}") + @MethodSource("datacopyTestVector") + void testMCopy( + final String name, + final Bytes data, + final long dst, + final long src, + final long len, + final Bytes expected, + final long gasCost) { + DataCopyOperation subject = new DataCopyOperation(new PragueGasCalculator()); + String eofCode = + "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(); + + MessageFrame frame = + new TestMessageFrameBuilder() + .pushStackItem(Bytes.ofUnsignedLong(len)) + .pushStackItem(Bytes.ofUnsignedLong(src)) + .pushStackItem(Bytes.ofUnsignedLong(dst)) + .initialGas(10_000_000) + .code(code) + .build(); + + Operation.OperationResult result = subject.execute(frame, evm); + + assertThat(frame.memoryWordSize()).isEqualTo((expected.size() + 31) / 32); + assertThat(frame.readMemory(0, expected.size())).isEqualTo(expected); + assertThat(result.getGasCost()).isEqualTo(gasCost); + } + + @Test + void legacyCallFails() { + DataCopyOperation subject = new DataCopyOperation(new PragueGasCalculator()); + Code code = evm.getCodeUncached(Bytes.fromHexString("0x600460046004d3")); + assumeThat(code.isValid()).isTrue(); + + MessageFrame frame = + new TestMessageFrameBuilder() + .pushStackItem(Bytes.ofUnsignedLong(4)) + .pushStackItem(Bytes.ofUnsignedLong(4)) + .pushStackItem(Bytes.ofUnsignedLong(4)) + .initialGas(10_000_000) + .code(code) + .pc(6) + .build(); + + Operation.OperationResult result = subject.execute(frame, evm); + assertThat(result.getGasCost()).isZero(); + assertThat(result.getHaltReason()).isEqualTo(ExceptionalHaltReason.INVALID_OPERATION); + } +} From ab513b26a2b09ebb80f9cd8fb7465a278b1a9e3f Mon Sep 17 00:00:00 2001 From: Sally MacFarlane Date: Mon, 15 Jul 2024 14:02:50 +1000 Subject: [PATCH 037/259] disable flaky test (#7308) * disable flaky test Signed-off-by: Sally MacFarlane * disable flaky test Signed-off-by: Sally MacFarlane --------- Signed-off-by: Sally MacFarlane --- .../AccountLocalAndOnchainPermissioningAcceptanceTest.java | 2 ++ .../NodeLocalAndOnchainPermissioningAcceptanceTest.java | 2 ++ 2 files changed, 4 insertions(+) diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/AccountLocalAndOnchainPermissioningAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/AccountLocalAndOnchainPermissioningAcceptanceTest.java index 1d38f7e6c7..1bd6d4cf96 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/AccountLocalAndOnchainPermissioningAcceptanceTest.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/AccountLocalAndOnchainPermissioningAcceptanceTest.java @@ -22,8 +22,10 @@ import java.math.BigInteger; import java.util.Arrays; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; +@Disabled("permissioning tests flaky with timeouts") public class AccountLocalAndOnchainPermissioningAcceptanceTest extends AccountSmartContractPermissioningAcceptanceTestBase { diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeLocalAndOnchainPermissioningAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeLocalAndOnchainPermissioningAcceptanceTest.java index 3dfdae528a..9271c0d977 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeLocalAndOnchainPermissioningAcceptanceTest.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeLocalAndOnchainPermissioningAcceptanceTest.java @@ -17,8 +17,10 @@ package org.hyperledger.besu.tests.acceptance.permissioning; import org.hyperledger.besu.tests.acceptance.dsl.node.Node; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; +@Disabled("permissioning tests flaky with timeouts") public class NodeLocalAndOnchainPermissioningAcceptanceTest extends NodeSmartContractPermissioningAcceptanceTestBase { From 17f4dc9a8a612042927232ddc0b956f80320933d Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Sun, 14 Jul 2024 22:31:18 -0600 Subject: [PATCH 038/259] Update unit test (#7317) * Update parameterized unit tests so the enumerate with --dry-run * Update the prague-withdrawal.json unit test to handle current code Signed-off-by: Danno Ferrin Co-authored-by: Sally MacFarlane --- .../blockchain/ExpectBeneficiary.java | 2 +- .../blockchain/ExpectBlockNumberAbove.java | 2 +- .../dsl/condition/clique/ExpectNonceVote.java | 2 +- .../clique/ExpectedBlockHasProposer.java | 2 +- .../besu/ForkIdsNetworkConfigTest.java | 8 +++ .../chainimport/JsonBlockImporterTest.java | 7 +++ .../cli/NetworkDeprecationMessageTest.java | 8 +++ .../clique/CliqueProtocolScheduleTest.java | 2 +- .../blockcreation/CliqueBlockCreatorTest.java | 7 ++- .../CliqueExtraDataValidationRuleTest.java | 2 +- .../VoteValidationRuleTest.java | 10 +++- .../jsonrpc/methods/CliqueProposalsTest.java | 2 +- .../besu/consensus/common/bft/VoteTest.java | 2 +- .../AbstractVoteProposerMethodTest.java | 2 +- .../consensus/ibft/BftBlockHashingTest.java | 2 +- .../methods/IbftGetPendingVotesTest.java | 2 +- .../api/graphql/EthGraphQLHttpBySpecTest.java | 9 ++++ .../JsonRpcHttpServiceParameterizedTest.java | 8 +++ .../jsonrpc/RpcErrorTypeConverterTest.java | 8 +++ .../bonsai/DebugJsonRpcHttpBySpecTest.java | 10 ++++ .../DebugTraceJsonRpcHttpBySpecTest.java | 10 ++++ .../EthByzantiumJsonRpcHttpBySpecTest.java | 10 ++++ .../bonsai/EthJsonRpcHttpBySpecTest.java | 10 ++++ .../bonsai/TraceJsonRpcHttpBySpecTest.java | 10 ++++ .../api/jsonrpc/context/ContextKeyTest.java | 8 +++ .../forest/DebugJsonRpcHttpBySpecTest.java | 10 ++++ .../DebugTraceJsonRpcHttpBySpecTest.java | 10 ++++ .../EthByzantiumJsonRpcHttpBySpecTest.java | 10 ++++ .../forest/EthJsonRpcHttpBySpecTest.java | 10 ++++ .../forest/TraceJsonRpcHttpBySpecTest.java | 10 ++++ .../internal/methods/TraceFilterTest.java | 8 +++ ...endingPermissionTransactionFilterTest.java | 8 +++ .../jsonrpc/timeout/TimeoutHandlerTest.java | 9 ++++ .../ethereum/api/query/BackendQueryTest.java | 8 +++ .../HashRateMiningCoordinatorTest.java | 8 +++ .../besu/ethereum/chain/GenesisStateTest.java | 8 +++ .../besu/ethereum/core/UtilTest.java | 2 +- .../encoding/BlobTransactionEncodingTest.java | 8 +++ .../feemarket/BaseFeeMarketBaseFeeTest.java | 8 +++ .../CoinbaseFeePriceCalculatorTest.java | 8 +++ .../TransactionPriceCalculatorTest.java | 8 +++ .../ForkIdBackwardCompatibilityTest.java | 8 +++ .../ethereum/mainnet/IntrinsicGasTest.java | 10 ++++ .../PragueWithdrawalRequestValidatorTest.java | 8 +++ .../ethereum/mainnet/RefundSstoreGasTest.java | 9 ++++ .../WithdrawalRequestValidatorTest.java | 8 +++ ...yValidationRuleFixedBaseFeeMarketTest.java | 8 +++ .../GasLimitElasticityValidationRuleTest.java | 8 +++ ...tyValidationRuleZeroBaseFeeMarketTest.java | 8 +++ ...sLimitRangeAndDeltaValidationRuleTest.java | 8 +++ .../GasUsageValidationRuleTest.java | 8 +++ .../ProofOfWorkValidationRuleTest.java | 8 +++ .../util/BlockchainUtilParameterizedTest.java | 8 +++ .../eth/sync/ChainHeadTrackerTest.java | 9 ++++ .../CheckPointSyncChainDownloaderTest.java | 14 ++++- .../fastsync/FastDownloaderFactoryTest.java | 8 +++ .../sync/fastsync/FastSyncActionsTest.java | 8 +++ .../fastsync/FastSyncChainDownloaderTest.java | 12 ++++- .../sync/fastsync/FastSyncDownloaderTest.java | 8 +++ .../fastsync/PivotBlockConfirmerTest.java | 8 +++ .../fastsync/PivotBlockRetrieverTest.java | 8 +++ .../FastWorldDownloadStateTest.java | 8 +++ .../fullsync/FullSyncChainDownloaderTest.java | 12 ++++- ...DownloaderTotalTerminalDifficultyTest.java | 12 ++++- .../sync/fullsync/FullSyncDownloaderTest.java | 12 ++++- .../fullsync/FullSyncTargetManagerTest.java | 12 ++++- .../snapsync/SnapWorldDownloadStateTest.java | 8 +++ .../StorageTrieNodeHealingRequestTest.java | 10 ++++ ...neCommonAncestorTaskParameterizedTest.java | 8 +++ .../eth/sync/tasks/PersistBlockTaskTest.java | 8 +++ ...TransactionPoolReplacementHandlerTest.java | 8 +++ ...sactionReplacementByFeeMarketRuleTest.java | 8 +++ ...nsactionReplacementByGasPriceRuleTest.java | 8 +++ .../TransactionReplacementRulesTest.java | 8 +++ .../eth/transactions/layered/LayersTest.java | 8 +++ .../besu/evmtool/EvmToolSpecTests.java | 8 +++ .../besu/evmtool/t8n/prague-withdrawal.json | 53 ++++++++++--------- .../internal/PeerRequirementCombineTest.java | 8 +++ .../ethereum/p2p/peers/EnodeURLImplTest.java | 5 ++ .../netty/TLSContextFactoryTest.java | 8 +++ .../besu/evm/code/EOFLayoutTest.java | 8 +++ .../CancunGasCalculatorTest.java | 8 +++ .../besu/evm/internal/WordsTest.java | 8 +++ .../evm/operations/ChainIdOperationTest.java | 8 +++ ...stantinopleSStoreOperationGasCostTest.java | 8 +++ .../LondonSStoreOperationGasCostTest.java | 8 +++ .../evm/operations/MCopyOperationTest.java | 8 +++ .../evm/operations/SStoreOperationTest.java | 8 +++ .../besu/evm/operations/SarOperationTest.java | 9 ++++ .../operations/SelfDestructOperationTest.java | 8 +++ .../besu/evm/operations/ShlOperationTest.java | 9 ++++ .../besu/evm/operations/ShrOperationTest.java | 9 ++++ .../BLAKE2BFPrecompileContractTest.java | 8 +++ .../BLS12G1AddPrecompiledContractTest.java | 8 +++ .../BLS12G1MulPrecompiledContractTest.java | 8 +++ ...LS12G1MultiExpPrecompiledContractTest.java | 8 +++ .../BLS12G2AddPrecompiledContractTest.java | 8 +++ .../BLS12G2MulPrecompiledContractTest.java | 8 +++ ...LS12G2MultiExpPrecompiledContractTest.java | 8 +++ ...LS12MapFp2ToG2PrecompiledContractTest.java | 8 +++ ...BLS12MapFpToG1PrecompiledContractTest.java | 8 +++ .../BLS12PairingPrecompiledContractTest.java | 8 +++ .../ECRECPrecompiledContractTest.java | 8 +++ .../KZGPointEvalPrecompileContractTest.java | 8 +++ .../MODEXPPrecompiledContractTest.java | 8 +++ 105 files changed, 817 insertions(+), 50 deletions(-) diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/blockchain/ExpectBeneficiary.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/blockchain/ExpectBeneficiary.java index 25abc07828..fe765cbeae 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/blockchain/ExpectBeneficiary.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/blockchain/ExpectBeneficiary.java @@ -14,7 +14,7 @@ */ package org.hyperledger.besu.tests.acceptance.dsl.condition.blockchain; -import static org.assertj.core.api.Java6Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThat; import org.hyperledger.besu.tests.acceptance.dsl.WaitUtils; import org.hyperledger.besu.tests.acceptance.dsl.condition.Condition; diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/blockchain/ExpectBlockNumberAbove.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/blockchain/ExpectBlockNumberAbove.java index 60fa6ad546..6919581bf6 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/blockchain/ExpectBlockNumberAbove.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/blockchain/ExpectBlockNumberAbove.java @@ -14,7 +14,7 @@ */ package org.hyperledger.besu.tests.acceptance.dsl.condition.blockchain; -import static org.assertj.core.api.Java6Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThat; import org.hyperledger.besu.tests.acceptance.dsl.WaitUtils; import org.hyperledger.besu.tests.acceptance.dsl.condition.Condition; diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/clique/ExpectNonceVote.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/clique/ExpectNonceVote.java index 6882890c14..1e8f4b8a99 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/clique/ExpectNonceVote.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/clique/ExpectNonceVote.java @@ -14,7 +14,7 @@ */ package org.hyperledger.besu.tests.acceptance.dsl.condition.clique; -import static org.assertj.core.api.Java6Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThat; import static org.hyperledger.besu.tests.acceptance.dsl.condition.clique.ExpectNonceVote.CLIQUE_NONCE_VOTE.AUTH; import org.hyperledger.besu.tests.acceptance.dsl.WaitUtils; diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/clique/ExpectedBlockHasProposer.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/clique/ExpectedBlockHasProposer.java index 53b166c714..4abba67a0d 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/clique/ExpectedBlockHasProposer.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/clique/ExpectedBlockHasProposer.java @@ -14,7 +14,7 @@ */ package org.hyperledger.besu.tests.acceptance.dsl.condition.clique; -import static org.assertj.core.api.Java6Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThat; import org.hyperledger.besu.consensus.clique.CliqueBlockHeaderFunctions; import org.hyperledger.besu.consensus.clique.CliqueExtraData; diff --git a/besu/src/test/java/org/hyperledger/besu/ForkIdsNetworkConfigTest.java b/besu/src/test/java/org/hyperledger/besu/ForkIdsNetworkConfigTest.java index ae338f27ca..fe5077acc6 100644 --- a/besu/src/test/java/org/hyperledger/besu/ForkIdsNetworkConfigTest.java +++ b/besu/src/test/java/org/hyperledger/besu/ForkIdsNetworkConfigTest.java @@ -44,6 +44,7 @@ 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.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; import org.junit.runner.RunWith; @@ -207,4 +208,11 @@ public class ForkIdsNetworkConfigTest { MilestoneStreamingProtocolSchedule::streamMilestoneBlocks); } } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/besu/src/test/java/org/hyperledger/besu/chainimport/JsonBlockImporterTest.java b/besu/src/test/java/org/hyperledger/besu/chainimport/JsonBlockImporterTest.java index 522f268c57..73015afd00 100644 --- a/besu/src/test/java/org/hyperledger/besu/chainimport/JsonBlockImporterTest.java +++ b/besu/src/test/java/org/hyperledger/besu/chainimport/JsonBlockImporterTest.java @@ -410,6 +410,13 @@ public abstract class JsonBlockImporterTest { + genesisConfigFile.getConfigOptions().getConsensusEngine()); } } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } protected Block getBlockAt(final Blockchain blockchain, final long blockNumber) { 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 e140db8c2a..87be2a699e 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/NetworkDeprecationMessageTest.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/NetworkDeprecationMessageTest.java @@ -20,6 +20,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import org.hyperledger.besu.cli.config.NetworkName; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.EnumSource; @@ -45,4 +46,11 @@ class NetworkDeprecationMessageTest { assertThatThrownBy(() -> NetworkDeprecationMessage.generate(network)) .isInstanceOf(AssertionError.class); } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/CliqueProtocolScheduleTest.java b/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/CliqueProtocolScheduleTest.java index 30a3967da9..35f959e45b 100644 --- a/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/CliqueProtocolScheduleTest.java +++ b/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/CliqueProtocolScheduleTest.java @@ -14,8 +14,8 @@ */ package org.hyperledger.besu.consensus.clique; +import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.assertj.core.api.Java6Assertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; diff --git a/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueBlockCreatorTest.java b/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueBlockCreatorTest.java index 7dcbfa34ba..485b2aff79 100644 --- a/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueBlockCreatorTest.java +++ b/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueBlockCreatorTest.java @@ -14,7 +14,7 @@ */ package org.hyperledger.besu.consensus.clique.blockcreation; -import static org.assertj.core.api.Java6Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThat; import static org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider.createInMemoryBlockchain; import static org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider.createInMemoryWorldStateArchive; import static org.mockito.ArgumentMatchers.any; @@ -75,7 +75,6 @@ import java.util.Optional; import com.google.common.collect.Lists; import org.apache.tuweni.bytes.Bytes; -import org.assertj.core.api.Java6Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -98,7 +97,7 @@ public class CliqueBlockCreatorTest { private VoteProvider voteProvider; @BeforeEach - public void setup() { + void setup() { protocolSchedule = CliqueProtocolSchedule.create( GenesisConfigFile.DEFAULT.getConfigOptions(), @@ -160,7 +159,7 @@ public class CliqueBlockCreatorTest { final Block createdBlock = blockCreator.createBlock(5L).getBlock(); - Java6Assertions.assertThat(CliqueHelpers.getProposerOfBlock(createdBlock.getHeader())) + assertThat(CliqueHelpers.getProposerOfBlock(createdBlock.getHeader())) .isEqualTo(proposerAddress); } diff --git a/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/headervalidationrules/CliqueExtraDataValidationRuleTest.java b/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/headervalidationrules/CliqueExtraDataValidationRuleTest.java index 0d30cdf655..afcc7e23c2 100644 --- a/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/headervalidationrules/CliqueExtraDataValidationRuleTest.java +++ b/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/headervalidationrules/CliqueExtraDataValidationRuleTest.java @@ -14,7 +14,7 @@ */ package org.hyperledger.besu.consensus.clique.headervalidationrules; -import static org.assertj.core.api.Java6Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; diff --git a/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/headervalidationrules/VoteValidationRuleTest.java b/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/headervalidationrules/VoteValidationRuleTest.java index fdb6885957..0ba0e5f3c8 100644 --- a/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/headervalidationrules/VoteValidationRuleTest.java +++ b/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/headervalidationrules/VoteValidationRuleTest.java @@ -14,7 +14,7 @@ */ package org.hyperledger.besu.consensus.clique.headervalidationrules; -import static org.assertj.core.api.Java6Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThat; import org.hyperledger.besu.consensus.clique.CliqueBlockInterface; import org.hyperledger.besu.ethereum.core.BlockHeader; @@ -22,6 +22,7 @@ import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture; import java.util.stream.Stream; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -52,4 +53,11 @@ public class VoteValidationRuleTest { assertThat(uut.validate(header, null)).isEqualTo(expectedResult); } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/CliqueProposalsTest.java b/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/CliqueProposalsTest.java index 50dc379b57..cdfbeb6299 100644 --- a/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/CliqueProposalsTest.java +++ b/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/jsonrpc/methods/CliqueProposalsTest.java @@ -14,7 +14,7 @@ */ package org.hyperledger.besu.consensus.clique.jsonrpc.methods; -import static org.assertj.core.api.Java6Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThat; import org.hyperledger.besu.consensus.common.jsonrpc.AbstractVoteProposerMethod; import org.hyperledger.besu.consensus.common.jsonrpc.AbstractVoteProposerMethodTest; diff --git a/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/VoteTest.java b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/VoteTest.java index b01a3a97c6..ec37b1d4bb 100644 --- a/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/VoteTest.java +++ b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/VoteTest.java @@ -14,7 +14,7 @@ */ package org.hyperledger.besu.consensus.common.bft; -import static org.assertj.core.api.Java6Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThat; import org.hyperledger.besu.datatypes.Address; diff --git a/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/jsonrpc/AbstractVoteProposerMethodTest.java b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/jsonrpc/AbstractVoteProposerMethodTest.java index a59bd556e4..eefe1784c8 100644 --- a/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/jsonrpc/AbstractVoteProposerMethodTest.java +++ b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/jsonrpc/AbstractVoteProposerMethodTest.java @@ -14,7 +14,7 @@ */ package org.hyperledger.besu.consensus.common.jsonrpc; -import static org.assertj.core.api.Java6Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; diff --git a/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/BftBlockHashingTest.java b/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/BftBlockHashingTest.java index 7d5362ff7c..1b821c78c9 100644 --- a/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/BftBlockHashingTest.java +++ b/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/BftBlockHashingTest.java @@ -15,7 +15,7 @@ package org.hyperledger.besu.consensus.ibft; import static java.util.Collections.emptyList; -import static org.assertj.core.api.Java6Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThat; import org.hyperledger.besu.consensus.common.bft.BftBlockHashing; import org.hyperledger.besu.consensus.common.bft.BftBlockHeaderFunctions; diff --git a/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftGetPendingVotesTest.java b/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftGetPendingVotesTest.java index ddede6aefe..b3d8cd43cc 100644 --- a/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftGetPendingVotesTest.java +++ b/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/jsonrpc/methods/IbftGetPendingVotesTest.java @@ -14,7 +14,7 @@ */ package org.hyperledger.besu.consensus.ibft.jsonrpc.methods; -import static org.assertj.core.api.Java6Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThat; import org.hyperledger.besu.consensus.common.jsonrpc.AbstractVoteProposerMethod; import org.hyperledger.besu.consensus.common.jsonrpc.AbstractVoteProposerMethodTest; diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/graphql/EthGraphQLHttpBySpecTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/graphql/EthGraphQLHttpBySpecTest.java index 4cd3164600..df620d7c1c 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/graphql/EthGraphQLHttpBySpecTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/graphql/EthGraphQLHttpBySpecTest.java @@ -15,6 +15,7 @@ package org.hyperledger.besu.ethereum.api.graphql; import static com.google.common.base.Preconditions.checkState; +import static org.assertj.core.api.Assertions.assertThat; import java.io.IOException; import java.net.URISyntaxException; @@ -31,6 +32,7 @@ import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response; import org.assertj.core.api.Assertions; +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; @@ -83,4 +85,11 @@ public class EthGraphQLHttpBySpecTest extends AbstractEthGraphQLHttpServiceTest Assertions.assertThat(resp.code()).isEqualTo(expectedStatusCode); } } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceParameterizedTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceParameterizedTest.java index a93575aa8f..a561079e7c 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceParameterizedTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceParameterizedTest.java @@ -27,6 +27,7 @@ import okhttp3.RequestBody; import okhttp3.Response; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; @@ -60,4 +61,11 @@ public class JsonRpcHttpServiceParameterizedTest extends JsonRpcHttpServiceTestB json, null, expectedError.getCode(), expectedError.getMessage()); } } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcErrorTypeConverterTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcErrorTypeConverterTest.java index 8dbee4bf91..a54057f8f4 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcErrorTypeConverterTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcErrorTypeConverterTest.java @@ -22,6 +22,7 @@ import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason; import java.util.Arrays; import java.util.Collection; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; @@ -85,4 +86,11 @@ public class RpcErrorTypeConverterTest { assertThat(JsonRpcErrorConverter.convertTransactionInvalidReason(txInvalidReason)) .isEqualTo(expectedJsonRpcError); } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/bonsai/DebugJsonRpcHttpBySpecTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/bonsai/DebugJsonRpcHttpBySpecTest.java index 0ee3388f4e..e1a13f1a80 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/bonsai/DebugJsonRpcHttpBySpecTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/bonsai/DebugJsonRpcHttpBySpecTest.java @@ -14,9 +14,12 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.bonsai; +import static org.assertj.core.api.Assertions.assertThat; + import org.hyperledger.besu.ethereum.api.jsonrpc.AbstractJsonRpcHttpBySpecTest; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; public class DebugJsonRpcHttpBySpecTest extends AbstractJsonRpcHttpBySpecTest { @@ -33,4 +36,11 @@ public class DebugJsonRpcHttpBySpecTest extends AbstractJsonRpcHttpBySpecTest { "debug/account-at", "debug/batch-send-raw-transaction", "debug/trace-transaction" }); // storageRange and accountRange are not working with bonsai trie } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/bonsai/DebugTraceJsonRpcHttpBySpecTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/bonsai/DebugTraceJsonRpcHttpBySpecTest.java index 37b2cedf7c..fbe3f32196 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/bonsai/DebugTraceJsonRpcHttpBySpecTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/bonsai/DebugTraceJsonRpcHttpBySpecTest.java @@ -14,11 +14,14 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.bonsai; +import static org.assertj.core.api.Assertions.assertThat; + import org.hyperledger.besu.ethereum.api.jsonrpc.AbstractJsonRpcHttpBySpecTest; import org.hyperledger.besu.ethereum.core.BlockchainSetupUtil; import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; public class DebugTraceJsonRpcHttpBySpecTest extends AbstractJsonRpcHttpBySpecTest { @@ -38,4 +41,11 @@ public class DebugTraceJsonRpcHttpBySpecTest extends AbstractJsonRpcHttpBySpecTe public static Object[][] specs() { return AbstractJsonRpcHttpBySpecTest.findSpecFiles(new String[] {"debug/trace-call"}); } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/bonsai/EthByzantiumJsonRpcHttpBySpecTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/bonsai/EthByzantiumJsonRpcHttpBySpecTest.java index 358aeb1554..f1b6b695a8 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/bonsai/EthByzantiumJsonRpcHttpBySpecTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/bonsai/EthByzantiumJsonRpcHttpBySpecTest.java @@ -14,11 +14,14 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.bonsai; +import static org.assertj.core.api.Assertions.assertThat; + import org.hyperledger.besu.ethereum.api.jsonrpc.AbstractJsonRpcHttpBySpecTest; import org.hyperledger.besu.ethereum.core.BlockchainSetupUtil; import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; public class EthByzantiumJsonRpcHttpBySpecTest extends AbstractJsonRpcHttpBySpecTest { @@ -38,4 +41,11 @@ public class EthByzantiumJsonRpcHttpBySpecTest extends AbstractJsonRpcHttpBySpec public static Object[][] specs() { return AbstractJsonRpcHttpBySpecTest.findSpecFiles(new String[] {"eth_latest"}); } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/bonsai/EthJsonRpcHttpBySpecTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/bonsai/EthJsonRpcHttpBySpecTest.java index 9dc7d193c8..1bb5f801eb 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/bonsai/EthJsonRpcHttpBySpecTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/bonsai/EthJsonRpcHttpBySpecTest.java @@ -14,9 +14,12 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.bonsai; +import static org.assertj.core.api.Assertions.assertThat; + import org.hyperledger.besu.ethereum.api.jsonrpc.AbstractJsonRpcHttpBySpecTest; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; public class EthJsonRpcHttpBySpecTest extends AbstractJsonRpcHttpBySpecTest { @@ -30,4 +33,11 @@ public class EthJsonRpcHttpBySpecTest extends AbstractJsonRpcHttpBySpecTest { public static Object[][] specs() { return findSpecFiles(new String[] {"eth"}); } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/bonsai/TraceJsonRpcHttpBySpecTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/bonsai/TraceJsonRpcHttpBySpecTest.java index a3bf6fc51d..51d573ddae 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/bonsai/TraceJsonRpcHttpBySpecTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/bonsai/TraceJsonRpcHttpBySpecTest.java @@ -14,11 +14,14 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.bonsai; +import static org.assertj.core.api.Assertions.assertThat; + import org.hyperledger.besu.ethereum.api.jsonrpc.AbstractJsonRpcHttpBySpecTest; import org.hyperledger.besu.ethereum.core.BlockchainSetupUtil; import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; public class TraceJsonRpcHttpBySpecTest extends AbstractJsonRpcHttpBySpecTest { @@ -52,4 +55,11 @@ public class TraceJsonRpcHttpBySpecTest extends AbstractJsonRpcHttpBySpecTest { "trace/specs/trace-raw-transaction" }); } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/context/ContextKeyTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/context/ContextKeyTest.java index a31bcb96d8..ed2574170e 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/context/ContextKeyTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/context/ContextKeyTest.java @@ -26,6 +26,7 @@ import java.util.function.Supplier; import io.vertx.core.json.JsonObject; import io.vertx.ext.web.RoutingContext; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; @@ -66,4 +67,11 @@ public class ContextKeyTest { private static Supplier supplier(final T value) { return () -> value; } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/forest/DebugJsonRpcHttpBySpecTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/forest/DebugJsonRpcHttpBySpecTest.java index 562b4c2572..bc8d4178ed 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/forest/DebugJsonRpcHttpBySpecTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/forest/DebugJsonRpcHttpBySpecTest.java @@ -14,9 +14,12 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.forest; +import static org.assertj.core.api.Assertions.assertThat; + import org.hyperledger.besu.ethereum.api.jsonrpc.AbstractJsonRpcHttpBySpecTest; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; public class DebugJsonRpcHttpBySpecTest extends AbstractJsonRpcHttpBySpecTest { @@ -37,4 +40,11 @@ public class DebugJsonRpcHttpBySpecTest extends AbstractJsonRpcHttpBySpecTest { "debug/storage-range" }); } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/forest/DebugTraceJsonRpcHttpBySpecTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/forest/DebugTraceJsonRpcHttpBySpecTest.java index 89b79c2af3..cdedc3438b 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/forest/DebugTraceJsonRpcHttpBySpecTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/forest/DebugTraceJsonRpcHttpBySpecTest.java @@ -14,11 +14,14 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.forest; +import static org.assertj.core.api.Assertions.assertThat; + import org.hyperledger.besu.ethereum.api.jsonrpc.AbstractJsonRpcHttpBySpecTest; import org.hyperledger.besu.ethereum.core.BlockchainSetupUtil; import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; public class DebugTraceJsonRpcHttpBySpecTest extends AbstractJsonRpcHttpBySpecTest { @@ -38,4 +41,11 @@ public class DebugTraceJsonRpcHttpBySpecTest extends AbstractJsonRpcHttpBySpecTe public static Object[][] specs() { return AbstractJsonRpcHttpBySpecTest.findSpecFiles(new String[] {"debug/trace-call"}); } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/forest/EthByzantiumJsonRpcHttpBySpecTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/forest/EthByzantiumJsonRpcHttpBySpecTest.java index 1639297992..c7c2d131a1 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/forest/EthByzantiumJsonRpcHttpBySpecTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/forest/EthByzantiumJsonRpcHttpBySpecTest.java @@ -14,11 +14,14 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.forest; +import static org.assertj.core.api.Assertions.assertThat; + import org.hyperledger.besu.ethereum.api.jsonrpc.AbstractJsonRpcHttpBySpecTest; import org.hyperledger.besu.ethereum.core.BlockchainSetupUtil; import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; public class EthByzantiumJsonRpcHttpBySpecTest extends AbstractJsonRpcHttpBySpecTest { @@ -38,4 +41,11 @@ public class EthByzantiumJsonRpcHttpBySpecTest extends AbstractJsonRpcHttpBySpec public static Object[][] specs() { return AbstractJsonRpcHttpBySpecTest.findSpecFiles(new String[] {"eth_latest"}); } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/forest/EthJsonRpcHttpBySpecTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/forest/EthJsonRpcHttpBySpecTest.java index 277f1b89d0..041c0c711e 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/forest/EthJsonRpcHttpBySpecTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/forest/EthJsonRpcHttpBySpecTest.java @@ -14,9 +14,12 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.forest; +import static org.assertj.core.api.Assertions.assertThat; + import org.hyperledger.besu.ethereum.api.jsonrpc.AbstractJsonRpcHttpBySpecTest; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; public class EthJsonRpcHttpBySpecTest extends AbstractJsonRpcHttpBySpecTest { @@ -30,4 +33,11 @@ public class EthJsonRpcHttpBySpecTest extends AbstractJsonRpcHttpBySpecTest { public static Object[][] specs() { return findSpecFiles(new String[] {"eth"}); } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/forest/TraceJsonRpcHttpBySpecTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/forest/TraceJsonRpcHttpBySpecTest.java index d71c28a223..b33be91005 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/forest/TraceJsonRpcHttpBySpecTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/forest/TraceJsonRpcHttpBySpecTest.java @@ -14,11 +14,14 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.forest; +import static org.assertj.core.api.Assertions.assertThat; + import org.hyperledger.besu.ethereum.api.jsonrpc.AbstractJsonRpcHttpBySpecTest; import org.hyperledger.besu.ethereum.core.BlockchainSetupUtil; import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; public class TraceJsonRpcHttpBySpecTest extends AbstractJsonRpcHttpBySpecTest { @@ -52,4 +55,11 @@ public class TraceJsonRpcHttpBySpecTest extends AbstractJsonRpcHttpBySpecTest { "trace/specs/trace-raw-transaction" }); } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceFilterTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceFilterTest.java index 6a9d4da03d..c5c03f6b11 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceFilterTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceFilterTest.java @@ -29,6 +29,7 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import java.util.function.Supplier; +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.CsvSource; @@ -76,4 +77,11 @@ public class TraceFilterTest { final JsonRpcErrorResponse errorResponse = (JsonRpcErrorResponse) response; assertThat(errorResponse.getErrorType()).isEqualTo(RpcErrorType.EXCEEDS_RPC_MAX_BLOCK_RANGE); } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/transaction/pool/PendingPermissionTransactionFilterTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/transaction/pool/PendingPermissionTransactionFilterTest.java index b08e5f7e8d..ada560adb0 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/transaction/pool/PendingPermissionTransactionFilterTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/transaction/pool/PendingPermissionTransactionFilterTest.java @@ -39,6 +39,7 @@ import java.util.List; import java.util.Optional; import java.util.Set; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; @@ -126,4 +127,11 @@ public class PendingPermissionTransactionFilterTest { } return new LinkedHashSet<>(pendingTransactionList); } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/timeout/TimeoutHandlerTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/timeout/TimeoutHandlerTest.java index c8047b806c..2fd96d6b98 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/timeout/TimeoutHandlerTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/timeout/TimeoutHandlerTest.java @@ -14,6 +14,7 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.timeout; +import static org.assertj.core.api.Assertions.assertThat; import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod.ETH_BLOCK_NUMBER; import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod.ETH_GET_LOGS; import static org.mockito.ArgumentMatchers.any; @@ -39,6 +40,7 @@ import io.vertx.core.Handler; import io.vertx.core.Vertx; import io.vertx.core.json.JsonObject; import io.vertx.ext.web.RoutingContext; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; import org.mockito.Mockito; @@ -86,4 +88,11 @@ public class TimeoutHandlerTest { .setTimer(eq(TimeUnit.SECONDS.toMillis(timeoutSec)), any()); verify(ctx, times(timerMustBeSet ? 1 : 0)).addBodyEndHandler(any()); } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/query/BackendQueryTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/query/BackendQueryTest.java index 20eaf656ed..4c5c2679ee 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/query/BackendQueryTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/query/BackendQueryTest.java @@ -20,6 +20,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import java.util.function.Supplier; 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; @@ -52,4 +53,11 @@ public class BackendQueryTest { assertThat(BackendQuery.runIfAlive(() -> wantReturn, alive)).isEqualTo(wantReturn); } } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/HashRateMiningCoordinatorTest.java b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/HashRateMiningCoordinatorTest.java index 985870c6fb..73e122b620 100644 --- a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/HashRateMiningCoordinatorTest.java +++ b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/HashRateMiningCoordinatorTest.java @@ -24,6 +24,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.UUID; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; @@ -62,4 +63,11 @@ public class HashRateMiningCoordinatorTest { assertThat(miningCoordinator.hashesPerSecond()).contains(wantTotalHashrate); } } + + @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/chain/GenesisStateTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/chain/GenesisStateTest.java index ea1eb04414..70c1e64bd1 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 @@ -32,6 +32,7 @@ import java.util.stream.Stream; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.units.bigints.UInt256; import org.bouncycastle.util.encoders.Hex; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -331,4 +332,11 @@ final class GenesisStateTest { Hash.fromHexString( "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")); } + + @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/core/UtilTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/UtilTest.java index f5df655236..39b804abe0 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/UtilTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/UtilTest.java @@ -14,7 +14,7 @@ */ package org.hyperledger.besu.ethereum.core; -import static org.assertj.core.api.Java6Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThat; import org.junit.jupiter.api.Test; diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/BlobTransactionEncodingTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/BlobTransactionEncodingTest.java index b847d0bb72..e53c1b50e0 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/BlobTransactionEncodingTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/BlobTransactionEncodingTest.java @@ -27,6 +27,7 @@ import java.nio.charset.StandardCharsets; import java.util.stream.Stream; import org.apache.tuweni.bytes.Bytes; +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; @@ -117,4 +118,11 @@ public class BlobTransactionEncodingTest { : bytes.toString(); } } + + @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/core/feemarket/BaseFeeMarketBaseFeeTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/feemarket/BaseFeeMarketBaseFeeTest.java index d6d94c8453..e657c5c2e2 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/feemarket/BaseFeeMarketBaseFeeTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/feemarket/BaseFeeMarketBaseFeeTest.java @@ -30,6 +30,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.base.Charsets; import com.google.common.io.Resources; import org.junit.jupiter.api.Disabled; +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; @@ -99,4 +100,11 @@ public class BaseFeeMarketBaseFeeTest { this.expectedBaseFee = expectedBaseFee; } } + + @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/core/feemarket/CoinbaseFeePriceCalculatorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/feemarket/CoinbaseFeePriceCalculatorTest.java index 2706444f83..1da9a689cf 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/feemarket/CoinbaseFeePriceCalculatorTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/feemarket/CoinbaseFeePriceCalculatorTest.java @@ -21,6 +21,7 @@ import org.hyperledger.besu.datatypes.Wei; 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; @@ -54,4 +55,11 @@ public class CoinbaseFeePriceCalculatorTest { assertThat(coinbaseFeePriceCalculator.price(coinbaseFee, transactionGasPrice, baseFee)) .isEqualByComparingTo(expectedPrice); } + + @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/core/feemarket/TransactionPriceCalculatorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/feemarket/TransactionPriceCalculatorTest.java index c23061ac8f..df07fd1f75 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/feemarket/TransactionPriceCalculatorTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/feemarket/TransactionPriceCalculatorTest.java @@ -29,6 +29,7 @@ import java.util.Collections; 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; @@ -146,4 +147,11 @@ public class TransactionPriceCalculatorTest { baseFee)) .isEqualByComparingTo(expectedPrice); } + + @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/forkid/ForkIdBackwardCompatibilityTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/forkid/ForkIdBackwardCompatibilityTest.java index cd28e6e9aa..84c24bc9a2 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/forkid/ForkIdBackwardCompatibilityTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/forkid/ForkIdBackwardCompatibilityTest.java @@ -24,6 +24,7 @@ import java.util.List; import java.util.stream.Stream; import org.apache.tuweni.bytes.Bytes; +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; @@ -99,4 +100,11 @@ public class ForkIdBackwardCompatibilityTest { assertThat(forkIdManager.getForkIdForChainHead()) .isEqualTo(legacyEth64 ? legacyForkId : wantForkId); } + + @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/IntrinsicGasTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/IntrinsicGasTest.java index a6ae23724e..bb9ce2b495 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/IntrinsicGasTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/IntrinsicGasTest.java @@ -14,6 +14,8 @@ */ package org.hyperledger.besu.ethereum.mainnet; +import static org.assertj.core.api.Assertions.assertThat; + import org.hyperledger.besu.ethereum.core.Transaction; import org.hyperledger.besu.ethereum.rlp.RLP; import org.hyperledger.besu.evm.gascalculator.FrontierGasCalculator; @@ -24,6 +26,7 @@ import java.util.stream.Stream; import org.apache.tuweni.bytes.Bytes; import org.assertj.core.api.Assertions; +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; @@ -90,4 +93,11 @@ public class IntrinsicGasTest { gasCalculator.transactionIntrinsicGasCost(t.getPayload(), t.isContractCreation())) .isEqualTo(expectedGas); } + + @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/PragueWithdrawalRequestValidatorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/PragueWithdrawalRequestValidatorTest.java index 1d53b4b19c..8756f85592 100644 --- 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 @@ -28,6 +28,7 @@ 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; @@ -72,4 +73,11 @@ class PragueWithdrawalRequestValidatorTest { 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/RefundSstoreGasTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/RefundSstoreGasTest.java index e98bbc528c..77edb8a76f 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/RefundSstoreGasTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/RefundSstoreGasTest.java @@ -16,6 +16,7 @@ package org.hyperledger.besu.ethereum.mainnet; import static org.apache.tuweni.units.bigints.UInt256.ONE; import static org.apache.tuweni.units.bigints.UInt256.ZERO; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -29,6 +30,7 @@ import java.util.stream.Stream; import org.apache.tuweni.units.bigints.UInt256; import org.assertj.core.api.Assertions; +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; @@ -134,4 +136,11 @@ public class RefundSstoreGasTest { newValue, mockSupplierCurrentValue, mockSupplierForOriginalValue)) .isEqualTo(expectedGasRefund); } + + @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/WithdrawalRequestValidatorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/WithdrawalRequestValidatorTest.java index 43797a6e0d..f93067d94f 100644 --- 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 @@ -29,6 +29,7 @@ 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; @@ -76,4 +77,11 @@ class WithdrawalRequestValidatorTest { 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/headervalidationrules/GasLimitElasticityValidationRuleFixedBaseFeeMarketTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/headervalidationrules/GasLimitElasticityValidationRuleFixedBaseFeeMarketTest.java index 7f29e6f42a..94b58fa690 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/headervalidationrules/GasLimitElasticityValidationRuleFixedBaseFeeMarketTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/headervalidationrules/GasLimitElasticityValidationRuleFixedBaseFeeMarketTest.java @@ -25,6 +25,7 @@ import org.hyperledger.besu.ethereum.mainnet.feemarket.FixedBaseFeeMarket; import java.util.Optional; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; @@ -72,4 +73,11 @@ public class GasLimitElasticityValidationRuleFixedBaseFeeMarketTest { assertThat(uut.validate(header, parent)).isEqualTo(expectedResult); } + + @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/headervalidationrules/GasLimitElasticityValidationRuleTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/headervalidationrules/GasLimitElasticityValidationRuleTest.java index bd69303a05..1f74233445 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/headervalidationrules/GasLimitElasticityValidationRuleTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/headervalidationrules/GasLimitElasticityValidationRuleTest.java @@ -24,6 +24,7 @@ import org.hyperledger.besu.ethereum.mainnet.feemarket.LondonFeeMarket; import java.util.Optional; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; @@ -69,4 +70,11 @@ public class GasLimitElasticityValidationRuleTest { assertThat(uut.validate(header, parent)).isEqualTo(expectedResult); } + + @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/headervalidationrules/GasLimitElasticityValidationRuleZeroBaseFeeMarketTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/headervalidationrules/GasLimitElasticityValidationRuleZeroBaseFeeMarketTest.java index 229b402edc..39462a22cd 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/headervalidationrules/GasLimitElasticityValidationRuleZeroBaseFeeMarketTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/headervalidationrules/GasLimitElasticityValidationRuleZeroBaseFeeMarketTest.java @@ -24,6 +24,7 @@ import org.hyperledger.besu.ethereum.mainnet.feemarket.ZeroBaseFeeMarket; import java.util.Optional; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; @@ -71,4 +72,11 @@ public class GasLimitElasticityValidationRuleZeroBaseFeeMarketTest { assertThat(uut.validate(header, parent)).isEqualTo(expectedResult); } + + @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/headervalidationrules/GasLimitRangeAndDeltaValidationRuleTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/headervalidationrules/GasLimitRangeAndDeltaValidationRuleTest.java index 635f8e1c19..665da47354 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/headervalidationrules/GasLimitRangeAndDeltaValidationRuleTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/headervalidationrules/GasLimitRangeAndDeltaValidationRuleTest.java @@ -23,6 +23,7 @@ import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture; 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; @@ -102,4 +103,11 @@ public class GasLimitRangeAndDeltaValidationRuleTest { assertThat(uut.validate(header, parent)).isEqualTo(expectedResult); } + + @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/headervalidationrules/GasUsageValidationRuleTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/headervalidationrules/GasUsageValidationRuleTest.java index 06dff08046..a06fa0c700 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/headervalidationrules/GasUsageValidationRuleTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/headervalidationrules/GasUsageValidationRuleTest.java @@ -21,6 +21,7 @@ import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture; 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; @@ -48,4 +49,11 @@ public class GasUsageValidationRuleTest { assertThat(uut.validate(header, null)).isEqualTo(expectedResult); } + + @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/headervalidationrules/ProofOfWorkValidationRuleTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/headervalidationrules/ProofOfWorkValidationRuleTest.java index 8d831ab7c4..8f11434d1e 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/headervalidationrules/ProofOfWorkValidationRuleTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/headervalidationrules/ProofOfWorkValidationRuleTest.java @@ -37,6 +37,7 @@ import java.util.Optional; import java.util.stream.Stream; import org.apache.tuweni.units.bigints.UInt256; +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; @@ -216,4 +217,11 @@ public class ProofOfWorkValidationRuleTest { final ProtocolSchedule protocolSchedule = ProtocolScheduleFixture.MAINNET; return ScheduleBasedBlockHeaderFunctions.create(protocolSchedule); } + + @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/util/BlockchainUtilParameterizedTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/util/BlockchainUtilParameterizedTest.java index e4f5780309..af673d10d5 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/util/BlockchainUtilParameterizedTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/util/BlockchainUtilParameterizedTest.java @@ -33,6 +33,7 @@ import java.util.Random; import java.util.stream.Stream; import org.junit.jupiter.api.BeforeAll; +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; @@ -131,4 +132,11 @@ public class BlockchainUtilParameterizedTest { assertThat(maybeAncestorNumber.getAsInt()) .isEqualTo(Math.toIntExact(chainHeight - commonHeader.getNumber())); } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/ChainHeadTrackerTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/ChainHeadTrackerTest.java index b46a109c12..4bad73ebb6 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/ChainHeadTrackerTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/ChainHeadTrackerTest.java @@ -14,6 +14,7 @@ */ package org.hyperledger.besu.ethereum.eth.sync; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; import org.hyperledger.besu.config.GenesisConfigFile; @@ -37,6 +38,7 @@ import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; import java.util.stream.Stream; import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -150,4 +152,11 @@ public class ChainHeadTrackerTest { private ChainState chainHeadState() { return respondingPeer.getEthPeer().chainState(); } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/checkpointsync/CheckPointSyncChainDownloaderTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/checkpointsync/CheckPointSyncChainDownloaderTest.java index 09761081a1..c623b553f1 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/checkpointsync/CheckPointSyncChainDownloaderTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/checkpointsync/CheckPointSyncChainDownloaderTest.java @@ -48,6 +48,7 @@ import java.util.concurrent.CompletableFuture; import java.util.stream.Stream; import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -124,8 +125,10 @@ public class CheckPointSyncChainDownloaderTest { } @AfterEach - public void tearDown() { - ethProtocolManager.stop(); + void tearDown() { + if (ethContext != null) { + ethProtocolManager.stop(); + } } private ChainDownloader downloader( @@ -208,4 +211,11 @@ public class CheckPointSyncChainDownloaderTest { assertThat(localBlockchain.getChainHeadHeader()) .isEqualTo(otherBlockchain.getBlockHeader(pivotBlockNumber).get()); } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastDownloaderFactoryTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastDownloaderFactoryTest.java index e100c03698..b5be361bf4 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastDownloaderFactoryTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastDownloaderFactoryTest.java @@ -48,6 +48,7 @@ import java.util.stream.Stream; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Assumptions; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.params.ParameterizedTest; @@ -254,4 +255,11 @@ public class FastDownloaderFactoryTest { when(fastSyncDir.toFile()).thenReturn(fastSyncDirFile); when(dataDirectory.resolve(anyString())).thenReturn(fastSyncDir); } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncActionsTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncActionsTest.java index d29bb7260e..68caf2182c 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncActionsTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncActionsTest.java @@ -53,6 +53,7 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Stream; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -539,4 +540,11 @@ public class FastSyncActionsTest { pivotBlockSelector, new NoOpMetricsSystem()); } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncChainDownloaderTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncChainDownloaderTest.java index a731185167..f7a8a9ee54 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncChainDownloaderTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncChainDownloaderTest.java @@ -44,6 +44,7 @@ import java.util.concurrent.locks.LockSupport; import java.util.stream.Stream; import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -95,7 +96,9 @@ public class FastSyncChainDownloaderTest { @AfterEach public void tearDown() { - ethProtocolManager.stop(); + if (ethProtocolManager != null) { + ethProtocolManager.stop(); + } } private ChainDownloader downloader( @@ -222,4 +225,11 @@ public class FastSyncChainDownloaderTest { assertThat(localBlockchain.getChainHeadHeader()) .isEqualTo(otherBlockchain.getBlockHeader(pivotBlockNumber).get()); } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncDownloaderTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncDownloaderTest.java index ae252a39f4..e929b72ff9 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncDownloaderTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncDownloaderTest.java @@ -50,6 +50,7 @@ import java.util.function.Supplier; import java.util.stream.Stream; import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -605,4 +606,11 @@ public class FastSyncDownloaderTest { return null; }); } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/PivotBlockConfirmerTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/PivotBlockConfirmerTest.java index 050724ef55..2a8a311084 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/PivotBlockConfirmerTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/PivotBlockConfirmerTest.java @@ -42,6 +42,7 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Stream; import org.apache.tuweni.bytes.Bytes; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -341,4 +342,11 @@ public class PivotBlockConfirmerTest { return RespondingEthPeer.blockchainResponder(mockBlockchain); } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/PivotBlockRetrieverTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/PivotBlockRetrieverTest.java index 41317fdab3..a377ee7827 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/PivotBlockRetrieverTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/PivotBlockRetrieverTest.java @@ -45,6 +45,7 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Stream; import org.apache.tuweni.bytes.Bytes; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -425,4 +426,11 @@ public class PivotBlockRetrieverTest { return RespondingEthPeer.blockchainResponder(mockBlockchain); } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/worldstate/FastWorldDownloadStateTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/worldstate/FastWorldDownloadStateTest.java index 44847ffb93..a808ac7078 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/worldstate/FastWorldDownloadStateTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/worldstate/FastWorldDownloadStateTest.java @@ -43,6 +43,7 @@ import java.util.concurrent.ExecutionException; import java.util.stream.Stream; import org.apache.tuweni.bytes.Bytes; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -265,4 +266,11 @@ public class FastWorldDownloadStateTest { .isInstanceOf(ExecutionException.class) .hasRootCauseInstanceOf(StalledDownloadException.class); } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncChainDownloaderTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncChainDownloaderTest.java index f44c8e2da3..ded65f6a12 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncChainDownloaderTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncChainDownloaderTest.java @@ -55,6 +55,7 @@ import java.util.stream.Stream; import org.awaitility.Awaitility; import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -107,7 +108,9 @@ public class FullSyncChainDownloaderTest { @AfterEach public void tearDown() { - ethProtocolManager.stop(); + if (ethProtocolManager != null) { + ethProtocolManager.stop(); + } } private ChainDownloader downloader(final SynchronizerConfiguration syncConfig) { @@ -499,4 +502,11 @@ public class FullSyncChainDownloaderTest { } return shortChain; } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncChainDownloaderTotalTerminalDifficultyTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncChainDownloaderTotalTerminalDifficultyTest.java index c9f22ec5f0..4eeb3bbc63 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncChainDownloaderTotalTerminalDifficultyTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncChainDownloaderTotalTerminalDifficultyTest.java @@ -39,6 +39,7 @@ import java.util.concurrent.CompletableFuture; import java.util.stream.Stream; import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -91,7 +92,9 @@ public class FullSyncChainDownloaderTotalTerminalDifficultyTest { @AfterEach public void tearDown() { - ethProtocolManager.stop(); + if (ethProtocolManager != null) { + ethProtocolManager.stop(); + } } private ChainDownloader downloader( @@ -179,4 +182,11 @@ public class FullSyncChainDownloaderTotalTerminalDifficultyTest { assertThat(future.isDone()).isFalse(); } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncDownloaderTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncDownloaderTest.java index cb0f399ff8..a44ddc07bb 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncDownloaderTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncDownloaderTest.java @@ -36,6 +36,7 @@ import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; import java.util.stream.Stream; import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -82,7 +83,9 @@ public class FullSyncDownloaderTest { @AfterEach public void tearDown() { - ethProtocolManager.stop(); + if (ethProtocolManager != null) { + ethProtocolManager.stop(); + } } private FullSyncDownloader downloader(final SynchronizerConfiguration syncConfig) { @@ -129,4 +132,11 @@ public class FullSyncDownloaderTest { assertThat(synchronizer.calculateTrailingPeerRequirements()) .isEqualTo(TrailingPeerRequirements.UNRESTRICTED); } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncTargetManagerTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncTargetManagerTest.java index d10be455ea..027bd270d2 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncTargetManagerTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fullsync/FullSyncTargetManagerTest.java @@ -43,6 +43,7 @@ import java.util.concurrent.CompletableFuture; import java.util.stream.Stream; import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -100,7 +101,9 @@ public class FullSyncTargetManagerTest { @AfterEach public void tearDown() { - ethProtocolManager.stop(); + if (ethProtocolManager != null) { + ethProtocolManager.stop(); + } } @ParameterizedTest @@ -180,4 +183,11 @@ public class FullSyncTargetManagerTest { new SyncTarget(bestPeer.getEthPeer(), localBlockchain.getChainHeadHeader())); assertThat(bestPeer.getPeerConnection().isDisconnected()).isFalse(); } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/SnapWorldDownloadStateTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/SnapWorldDownloadStateTest.java index 28298acb9c..d1e90b5eb6 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/SnapWorldDownloadStateTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/SnapWorldDownloadStateTest.java @@ -62,6 +62,7 @@ import java.util.stream.Stream; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; import org.junit.jupiter.api.Assumptions; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -493,4 +494,11 @@ public class SnapWorldDownloadStateTest { .isEmpty(); assertThat(downloadState.isDownloading()).isTrue(); } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/request/heal/StorageTrieNodeHealingRequestTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/request/heal/StorageTrieNodeHealingRequestTest.java index f36a64c876..4f8299f9ac 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/request/heal/StorageTrieNodeHealingRequestTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/request/heal/StorageTrieNodeHealingRequestTest.java @@ -14,6 +14,8 @@ */ package org.hyperledger.besu.ethereum.eth.sync.snapsync.request.heal; +import static org.assertj.core.api.Assertions.assertThat; + import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider; @@ -36,6 +38,7 @@ import java.util.stream.Stream; import org.apache.tuweni.bytes.Bytes; import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.params.ParameterizedTest; @@ -115,4 +118,11 @@ class StorageTrieNodeHealingRequestTest { Assertions.assertThat(request.getExistingData(worldStateStorageCoordinator)).isEmpty(); } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/tasks/DetermineCommonAncestorTaskParameterizedTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/tasks/DetermineCommonAncestorTaskParameterizedTest.java index 71c0bcb544..73d5e5138b 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/tasks/DetermineCommonAncestorTaskParameterizedTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/tasks/DetermineCommonAncestorTaskParameterizedTest.java @@ -51,6 +51,7 @@ import java.util.stream.Stream; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; +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; @@ -174,4 +175,11 @@ public class DetermineCommonAncestorTaskParameterizedTest { assertThat(actualResult.get().getHash()) .isEqualTo(MainnetBlockHeaderFunctions.createHash(commonHeader)); } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/tasks/PersistBlockTaskTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/tasks/PersistBlockTaskTest.java index d789405763..dd5d79b667 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/tasks/PersistBlockTaskTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/tasks/PersistBlockTaskTest.java @@ -40,6 +40,7 @@ import java.util.concurrent.CompletableFuture; import java.util.stream.Stream; import org.awaitility.Awaitility; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -420,4 +421,11 @@ public class PersistBlockTaskTest { assertThat(result.isCancelled()).isTrue(); assertThat(blockchain.contains(nextBlock.getHash())).isFalse(); } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolReplacementHandlerTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolReplacementHandlerTest.java index f57d6fac3e..aca1f202c2 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolReplacementHandlerTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolReplacementHandlerTest.java @@ -30,6 +30,7 @@ import java.util.List; import java.util.Optional; import java.util.stream.Collectors; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; @@ -88,4 +89,11 @@ public class TransactionPoolReplacementHandlerTest { when(pendingTransaction.getTransaction()).thenReturn(transaction); return pendingTransaction; } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionReplacementByFeeMarketRuleTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionReplacementByFeeMarketRuleTest.java index 527b26e251..eb22184a2b 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionReplacementByFeeMarketRuleTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionReplacementByFeeMarketRuleTest.java @@ -24,6 +24,7 @@ import org.hyperledger.besu.util.number.Percentage; import java.util.Collection; import java.util.Optional; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; @@ -107,4 +108,11 @@ public class TransactionReplacementByFeeMarketRuleTest extends AbstractTransacti .shouldReplace(oldTx, newTx, baseFee)) .isEqualTo(expected); } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionReplacementByGasPriceRuleTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionReplacementByGasPriceRuleTest.java index d4f851e190..651666fdd5 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionReplacementByGasPriceRuleTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionReplacementByGasPriceRuleTest.java @@ -24,6 +24,7 @@ import org.hyperledger.besu.util.number.Percentage; import java.util.Collection; import java.util.Optional; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; @@ -84,4 +85,11 @@ public class TransactionReplacementByGasPriceRuleTest extends AbstractTransactio .shouldReplace(oldTx, newTx, baseFee)) .isEqualTo(expected); } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionReplacementRulesTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionReplacementRulesTest.java index a6a5524eed..da7b465583 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionReplacementRulesTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionReplacementRulesTest.java @@ -27,6 +27,7 @@ import org.hyperledger.besu.util.number.Percentage; import java.util.Collection; import java.util.Optional; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; @@ -106,4 +107,11 @@ public class TransactionReplacementRulesTest extends AbstractTransactionReplacem .shouldReplace(oldTx, newTx, mockHeader)) .isEqualTo(expected); } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } 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 6946111e5c..a56222345c 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 @@ -58,6 +58,7 @@ import java.util.Optional; import java.util.OptionalLong; 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; @@ -1622,4 +1623,11 @@ public class LayersTest extends BaseTransactionPoolTest { this.hasPriority = hasPriority; } } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/ethereum/evmtool/src/test/java/org/hyperledger/besu/evmtool/EvmToolSpecTests.java b/ethereum/evmtool/src/test/java/org/hyperledger/besu/evmtool/EvmToolSpecTests.java index 66efb574fe..24cd858ba7 100644 --- a/ethereum/evmtool/src/test/java/org/hyperledger/besu/evmtool/EvmToolSpecTests.java +++ b/ethereum/evmtool/src/test/java/org/hyperledger/besu/evmtool/EvmToolSpecTests.java @@ -45,6 +45,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectReader; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.JsonNodeType; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; @@ -183,4 +184,11 @@ public class EvmToolSpecTests { assertThat(actualNode).isEqualTo(stdoutNode); } } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } 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 66dcf3e85e..cc8958b07c 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 @@ -178,6 +178,7 @@ "0x00a3ca265ebcb825b45f985a16cefb49958ce017": { "code": "0x3373fffffffffffffffffffffffffffffffffffffffe146090573615156028575f545f5260205ff35b366038141561012e5760115f54600182026001905f5b5f82111560595781019083028483029004916001019190603e565b90939004341061012e57600154600101600155600354806003026004013381556001015f3581556001016020359055600101600355005b6003546002548082038060101160a4575060105b5f5b81811460dd5780604c02838201600302600401805490600101805490600101549160601b83528260140152906034015260010160a6565b910180921460ed579060025560f8565b90505f6002555f6003555b5f548061049d141561010757505f5b60015460028282011161011c5750505f610122565b01600290035b5f555f600155604c025ff35b5f5ffd", "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000000000000000000000000000000000000000000e", "0x0000000000000000000000000000000000000000000000000000000000000004": "0x0000000000000000000000000000000000000000000000000000000000000200", "0x0000000000000000000000000000000000000000000000000000000000000006": "0x00000000000000000000000000000001fffffffffffffffe0000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000007": "0x0000000000000000000000000000000000000000000000000000000000000200", @@ -229,31 +230,6 @@ }, "body": "0xf903e5f903e28007830f424094000000000000000000000000000000000000020080b90380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001fffffffffffffffe0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fffffffffffffffe0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005fffffffffffffffe0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007fffffffffffffffe0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009fffffffffffffffe00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bfffffffffffffffe00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000dfffffffffffffffe00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffe000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000026a0963cb6620fe5828cbc93bb7139d3f4501067d76275dff648bf48c3c100ca8dd4a04ac396104a5be4643406718f59a6e74d62a32777f5f6135e55e805e87612013c", "result": { - "stateRoot": "0xdba3aee0733886dac565d2a654d8fac1953fd913261f44b3aa31f153e159e98a", - "txRoot": "0x8521df63211790726b6f1a437bb0fd4b27c00e13e7678d324c4cfddb8d834ad2", - "receiptsRoot": "0x4bd8bd5580caf4ed45f873794ad7ff9d6fd2363ae529269b17b891b68d349d75", - "logsHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "receipts": [ - { - "root": "0x", - "status": "0x1", - "cumulativeGasUsed": "0xe52ba", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "logs": null, - "transactionHash": "0x04a2d3f252dcc98edb684f7f15b572aaf980d0c2eea4c620a9f1ff1d275b2207", - "contractAddress": "0x0000000000000000000000000000000000000000", - "gasUsed": "0xe52ba", - "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "transactionIndex": "0x0" - } - ], - "currentDifficulty": null, - "gasUsed": "0xe52ba", - "currentBaseFee": "0x7", - "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "currentExcessBlobGas": "0x0", - "blobGasUsed": "0x0", "requestsRoot": "0x415d33e444f917658fd3bd6d3d8d88a1f501f9b83ace92ddacac823252c9fa47", "depositRequests": [], "withdrawalRequests": [ @@ -337,7 +313,32 @@ "validatorPubkey": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010", "amount": "0x0000000000000000" } - ] + ], + "stateRoot": "0xf63d7552dc407993393315e99272781d04eedfcf369a1acd3e386d1e6710229d", + "txRoot": "0x8521df63211790726b6f1a437bb0fd4b27c00e13e7678d324c4cfddb8d834ad2", + "receiptsRoot": "0x4bd8bd5580caf4ed45f873794ad7ff9d6fd2363ae529269b17b891b68d349d75", + "logsHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "receipts": [ + { + "root": "0x", + "status": "0x1", + "cumulativeGasUsed": "0xe52ba", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "logs": null, + "transactionHash": "0x04a2d3f252dcc98edb684f7f15b572aaf980d0c2eea4c620a9f1ff1d275b2207", + "contractAddress": "0x0000000000000000000000000000000000000000", + "gasUsed": "0xe52ba", + "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "transactionIndex": "0x0" + } + ], + "currentDifficulty": null, + "gasUsed": "0xe52ba", + "currentBaseFee": "0x7", + "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "currentExcessBlobGas": "0x0", + "blobGasUsed": "0x0" } } } \ No newline at end of file diff --git a/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/discovery/internal/PeerRequirementCombineTest.java b/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/discovery/internal/PeerRequirementCombineTest.java index 5c7a140dc6..7ad7f7c415 100644 --- a/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/discovery/internal/PeerRequirementCombineTest.java +++ b/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/discovery/internal/PeerRequirementCombineTest.java @@ -23,6 +23,7 @@ import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Stream; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; @@ -76,4 +77,11 @@ public class PeerRequirementCombineTest { PeerRequirement combined = PeerRequirement.combine(Collections.emptyList()); assertThat(combined.hasSufficientPeers()).isTrue(); } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/peers/EnodeURLImplTest.java b/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/peers/EnodeURLImplTest.java index b7cc2a0632..cf8fdd6cf0 100644 --- a/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/peers/EnodeURLImplTest.java +++ b/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/peers/EnodeURLImplTest.java @@ -32,6 +32,8 @@ import java.util.stream.Stream; import org.apache.tuweni.bytes.Bytes; import org.assertj.core.api.ThrowableAssert; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.DisabledOnOs; +import org.junit.jupiter.api.condition.OS; import org.mockito.Mockito; public class EnodeURLImplTest { @@ -494,6 +496,9 @@ public class EnodeURLImplTest { } @Test + @DisabledOnOs( + value = OS.MAC, + disabledReason = "canonical lookup may not match dns lookup for local machine") public void toURI_WithHostnameShouldWorkWhenDnsEnabledAndUpdateEnabled() throws UnknownHostException { final String enodeURLString = diff --git a/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/rlpx/connections/netty/TLSContextFactoryTest.java b/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/rlpx/connections/netty/TLSContextFactoryTest.java index 45d228cb40..d7763892c5 100644 --- a/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/rlpx/connections/netty/TLSContextFactoryTest.java +++ b/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/rlpx/connections/netty/TLSContextFactoryTest.java @@ -48,6 +48,7 @@ import io.netty.handler.ssl.SslContext; import io.netty.handler.ssl.SslHandler; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.DisabledOnOs; import org.junit.jupiter.api.condition.OS; import org.junit.jupiter.params.ParameterizedTest; @@ -493,4 +494,11 @@ class TLSContextFactoryTest { return messageHandler != null ? messageHandler.getCause() : Optional.empty(); } } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/evm/src/test/java/org/hyperledger/besu/evm/code/EOFLayoutTest.java b/evm/src/test/java/org/hyperledger/besu/evm/code/EOFLayoutTest.java index 5324d7adf0..145adfb2dd 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/code/EOFLayoutTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/code/EOFLayoutTest.java @@ -20,6 +20,7 @@ import java.util.Arrays; import java.util.Collection; import org.apache.tuweni.bytes.Bytes; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; @@ -361,4 +362,11 @@ public class EOFLayoutTest { assertThat(layout.getCodeSectionCount()).isNotZero(); } } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/evm/src/test/java/org/hyperledger/besu/evm/gascalculator/CancunGasCalculatorTest.java b/evm/src/test/java/org/hyperledger/besu/evm/gascalculator/CancunGasCalculatorTest.java index 917b95b688..ded199bf3b 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/gascalculator/CancunGasCalculatorTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/gascalculator/CancunGasCalculatorTest.java @@ -18,6 +18,7 @@ import static org.assertj.core.api.Assertions.assertThat; import java.util.List; +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; @@ -43,4 +44,11 @@ public class CancunGasCalculatorTest { Arguments.of(targetGasPerBlock, 1, CancunGasCalculator.BLOB_GAS_PER_BLOB), Arguments.of(targetGasPerBlock, 3, targetGasPerBlock)); } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/evm/src/test/java/org/hyperledger/besu/evm/internal/WordsTest.java b/evm/src/test/java/org/hyperledger/besu/evm/internal/WordsTest.java index 30e651436d..871f6ed0b1 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/internal/WordsTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/internal/WordsTest.java @@ -22,6 +22,7 @@ import java.util.Arrays; import java.util.Collection; import org.apache.tuweni.bytes.Bytes; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.api.TestInstance.Lifecycle; import org.junit.jupiter.params.ParameterizedTest; @@ -103,4 +104,11 @@ class WordsTest { void clampedToIntTest(final Bytes theBytes, final int theExpectedInt) { assertThat(clampedToInt(theBytes)).isEqualTo(theExpectedInt); } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operations/ChainIdOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operations/ChainIdOperationTest.java index e8d2c3d02d..969039266d 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operations/ChainIdOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operations/ChainIdOperationTest.java @@ -27,6 +27,7 @@ import java.util.List; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; +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; @@ -67,4 +68,11 @@ class ChainIdOperationTest { final OperationResult result = operation.execute(messageFrame, null); assertThat(result.getGasCost()).isEqualTo(expectedGas); } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operations/ConstantinopleSStoreOperationGasCostTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operations/ConstantinopleSStoreOperationGasCostTest.java index 00edb9c5d1..3cea9300e1 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operations/ConstantinopleSStoreOperationGasCostTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operations/ConstantinopleSStoreOperationGasCostTest.java @@ -23,6 +23,7 @@ import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.evm.testutils.TestCodeExecutor; import org.apache.tuweni.units.bigints.UInt256; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; @@ -73,4 +74,11 @@ public class ConstantinopleSStoreOperationGasCostTest { assertThat(frame.getRemainingGas()).isEqualTo(gasLimit - expectedGasUsed); assertThat(frame.getGasRefund()).isEqualTo(expectedGasRefund); } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operations/LondonSStoreOperationGasCostTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operations/LondonSStoreOperationGasCostTest.java index 1065d5cbd6..f2cf950683 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operations/LondonSStoreOperationGasCostTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operations/LondonSStoreOperationGasCostTest.java @@ -24,6 +24,7 @@ import org.hyperledger.besu.evm.testutils.TestCodeExecutor; import org.apache.tuweni.units.bigints.UInt256; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; @@ -76,4 +77,11 @@ public class LondonSStoreOperationGasCostTest { assertThat(frame.getRemainingGas()).isEqualTo(gasLimit - (expectedGasUsed + 2100)); assertThat(frame.getGasRefund()).isEqualTo(expectedGasRefund); } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operations/MCopyOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operations/MCopyOperationTest.java index a30375723a..2975312920 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operations/MCopyOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operations/MCopyOperationTest.java @@ -27,6 +27,7 @@ import java.util.Arrays; import java.util.Collection; 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; @@ -134,4 +135,11 @@ class MCopyOperationTest { assertThat(frame.readMemory(0, expected.size())).isEqualTo(expected); assertThat(result.getGasCost()).isEqualTo(gasCost); } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operations/SStoreOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operations/SStoreOperationTest.java index e2f14dbdb2..3993d9f81e 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operations/SStoreOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operations/SStoreOperationTest.java @@ -34,6 +34,7 @@ import org.hyperledger.besu.evm.worldstate.WorldUpdater; import java.util.List; import org.apache.tuweni.units.bigints.UInt256; +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; @@ -88,4 +89,11 @@ class SStoreOperationTest { final OperationResult result = operation.execute(frame, null); assertThat(result.getHaltReason()).isEqualTo(expectedHalt); } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operations/SarOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operations/SarOperationTest.java index 460a7294f6..86182e47e3 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operations/SarOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operations/SarOperationTest.java @@ -14,6 +14,7 @@ */ package org.hyperledger.besu.evm.operations; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -27,6 +28,7 @@ import java.util.List; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; +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; @@ -176,4 +178,11 @@ class SarOperationTest { operation.execute(frame, null); verify(frame).pushStackItem(Bytes.fromHexString(expectedResult)); } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operations/SelfDestructOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operations/SelfDestructOperationTest.java index 3b372f03a0..7842174e90 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operations/SelfDestructOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operations/SelfDestructOperationTest.java @@ -36,6 +36,7 @@ import org.hyperledger.besu.evm.operation.SelfDestructOperation; import org.hyperledger.besu.evm.worldstate.WorldUpdater; 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; @@ -176,4 +177,11 @@ public class SelfDestructOperationTest { assertThat(messageFrame.getCreates()).doesNotContain(orignatorAddress); } } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operations/ShlOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operations/ShlOperationTest.java index 7ee283877a..b567cb6302 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operations/ShlOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operations/ShlOperationTest.java @@ -14,6 +14,7 @@ */ package org.hyperledger.besu.evm.operations; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -28,6 +29,7 @@ import java.util.Arrays; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; import org.apache.tuweni.units.bigints.UInt256; +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; @@ -113,4 +115,11 @@ class ShlOperationTest { operation.execute(frame, null); verify(frame).pushStackItem(Bytes.fromHexString(expectedResult)); } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operations/ShrOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operations/ShrOperationTest.java index 16e5ca7631..659c50d35c 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/operations/ShrOperationTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/operations/ShrOperationTest.java @@ -14,6 +14,7 @@ */ package org.hyperledger.besu.evm.operations; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -28,6 +29,7 @@ import java.util.Arrays; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; import org.apache.tuweni.units.bigints.UInt256; +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; @@ -124,4 +126,11 @@ class ShrOperationTest { operation.execute(frame, null); verify(frame).pushStackItem(Bytes.fromHexString(expectedResult)); } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/evm/src/test/java/org/hyperledger/besu/evm/precompile/BLAKE2BFPrecompileContractTest.java b/evm/src/test/java/org/hyperledger/besu/evm/precompile/BLAKE2BFPrecompileContractTest.java index c449f3e082..381e64c015 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/precompile/BLAKE2BFPrecompileContractTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/precompile/BLAKE2BFPrecompileContractTest.java @@ -21,6 +21,7 @@ import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.gascalculator.PetersburgGasCalculator; import org.apache.tuweni.bytes.Bytes; +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; @@ -76,4 +77,11 @@ class BLAKE2BFPrecompileContractTest { .isEqualTo(expectedComputation); assertThat(contract.gasRequirement(input)).isEqualTo(expectedGasUsed); } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/evm/src/test/java/org/hyperledger/besu/evm/precompile/BLS12G1AddPrecompiledContractTest.java b/evm/src/test/java/org/hyperledger/besu/evm/precompile/BLS12G1AddPrecompiledContractTest.java index c85f26b12d..2ad792a410 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/precompile/BLS12G1AddPrecompiledContractTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/precompile/BLS12G1AddPrecompiledContractTest.java @@ -27,6 +27,7 @@ import java.util.stream.Collectors; import com.google.common.io.CharStreams; import org.apache.tuweni.bytes.Bytes; +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; @@ -79,4 +80,11 @@ class BLS12G1AddPrecompiledContractTest { assertThat(contract.gasRequirement(input)).isEqualTo(Long.parseLong(expectedGasUsed)); } } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/evm/src/test/java/org/hyperledger/besu/evm/precompile/BLS12G1MulPrecompiledContractTest.java b/evm/src/test/java/org/hyperledger/besu/evm/precompile/BLS12G1MulPrecompiledContractTest.java index cfadb57bd3..bf0f8a1481 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/precompile/BLS12G1MulPrecompiledContractTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/precompile/BLS12G1MulPrecompiledContractTest.java @@ -28,6 +28,7 @@ import java.util.stream.Collectors; import com.google.common.io.CharStreams; import org.apache.tuweni.bytes.Bytes; +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; @@ -79,4 +80,11 @@ class BLS12G1MulPrecompiledContractTest { assertThat(contract.gasRequirement(input)).isEqualTo(Long.parseLong(expectedGasUsed)); } } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/evm/src/test/java/org/hyperledger/besu/evm/precompile/BLS12G1MultiExpPrecompiledContractTest.java b/evm/src/test/java/org/hyperledger/besu/evm/precompile/BLS12G1MultiExpPrecompiledContractTest.java index 9bd4b6a542..27d45b1dd2 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/precompile/BLS12G1MultiExpPrecompiledContractTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/precompile/BLS12G1MultiExpPrecompiledContractTest.java @@ -28,6 +28,7 @@ import java.util.stream.Collectors; import com.google.common.io.CharStreams; import org.apache.tuweni.bytes.Bytes; +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; @@ -80,4 +81,11 @@ class BLS12G1MultiExpPrecompiledContractTest { assertThat(contract.gasRequirement(input)).isEqualTo(Long.parseLong(expectedGasUsed)); } } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/evm/src/test/java/org/hyperledger/besu/evm/precompile/BLS12G2AddPrecompiledContractTest.java b/evm/src/test/java/org/hyperledger/besu/evm/precompile/BLS12G2AddPrecompiledContractTest.java index 18dcd7ea5b..e98422f785 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/precompile/BLS12G2AddPrecompiledContractTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/precompile/BLS12G2AddPrecompiledContractTest.java @@ -28,6 +28,7 @@ import java.util.stream.Collectors; import com.google.common.io.CharStreams; import org.apache.tuweni.bytes.Bytes; +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; @@ -79,4 +80,11 @@ class BLS12G2AddPrecompiledContractTest { assertThat(contract.gasRequirement(input)).isEqualTo(Long.parseLong(expectedGasUsed)); } } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/evm/src/test/java/org/hyperledger/besu/evm/precompile/BLS12G2MulPrecompiledContractTest.java b/evm/src/test/java/org/hyperledger/besu/evm/precompile/BLS12G2MulPrecompiledContractTest.java index 0dd510273e..32af467747 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/precompile/BLS12G2MulPrecompiledContractTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/precompile/BLS12G2MulPrecompiledContractTest.java @@ -28,6 +28,7 @@ import java.util.stream.Collectors; import com.google.common.io.CharStreams; import org.apache.tuweni.bytes.Bytes; +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; @@ -79,4 +80,11 @@ class BLS12G2MulPrecompiledContractTest { assertThat(contract.gasRequirement(input)).isEqualTo(Long.parseLong(expectedGasUsed)); } } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/evm/src/test/java/org/hyperledger/besu/evm/precompile/BLS12G2MultiExpPrecompiledContractTest.java b/evm/src/test/java/org/hyperledger/besu/evm/precompile/BLS12G2MultiExpPrecompiledContractTest.java index b613bebe80..27ca15076a 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/precompile/BLS12G2MultiExpPrecompiledContractTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/precompile/BLS12G2MultiExpPrecompiledContractTest.java @@ -27,6 +27,7 @@ import java.util.Objects; import com.google.common.io.CharStreams; import org.apache.tuweni.bytes.Bytes; +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; @@ -79,4 +80,11 @@ class BLS12G2MultiExpPrecompiledContractTest { assertThat(contract.gasRequirement(input)).isEqualTo(Long.parseLong(expectedGasUsed)); } } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/evm/src/test/java/org/hyperledger/besu/evm/precompile/BLS12MapFp2ToG2PrecompiledContractTest.java b/evm/src/test/java/org/hyperledger/besu/evm/precompile/BLS12MapFp2ToG2PrecompiledContractTest.java index 05f6b4bfb5..afe2826aec 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/precompile/BLS12MapFp2ToG2PrecompiledContractTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/precompile/BLS12MapFp2ToG2PrecompiledContractTest.java @@ -28,6 +28,7 @@ import java.util.stream.Collectors; import com.google.common.io.CharStreams; import org.apache.tuweni.bytes.Bytes; +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; @@ -80,4 +81,11 @@ class BLS12MapFp2ToG2PrecompiledContractTest { assertThat(contract.gasRequirement(input)).isEqualTo(Long.parseLong(expectedGasUsed)); } } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/evm/src/test/java/org/hyperledger/besu/evm/precompile/BLS12MapFpToG1PrecompiledContractTest.java b/evm/src/test/java/org/hyperledger/besu/evm/precompile/BLS12MapFpToG1PrecompiledContractTest.java index cf83346576..836e295dd5 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/precompile/BLS12MapFpToG1PrecompiledContractTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/precompile/BLS12MapFpToG1PrecompiledContractTest.java @@ -28,6 +28,7 @@ import java.util.stream.Collectors; import com.google.common.io.CharStreams; import org.apache.tuweni.bytes.Bytes; +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; @@ -80,4 +81,11 @@ class BLS12MapFpToG1PrecompiledContractTest { assertThat(contract.gasRequirement(input)).isEqualTo(Long.parseLong(expectedGasUsed)); } } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/evm/src/test/java/org/hyperledger/besu/evm/precompile/BLS12PairingPrecompiledContractTest.java b/evm/src/test/java/org/hyperledger/besu/evm/precompile/BLS12PairingPrecompiledContractTest.java index e5d219dcda..134bc12741 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/precompile/BLS12PairingPrecompiledContractTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/precompile/BLS12PairingPrecompiledContractTest.java @@ -29,6 +29,7 @@ import java.util.stream.Collectors; import com.google.common.collect.Streams; import com.google.common.io.CharStreams; import org.apache.tuweni.bytes.Bytes; +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; @@ -89,4 +90,11 @@ class BLS12PairingPrecompiledContractTest { assertThat(contract.gasRequirement(input)).isEqualTo(Long.parseLong(expectedGasUsed)); } } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/evm/src/test/java/org/hyperledger/besu/evm/precompile/ECRECPrecompiledContractTest.java b/evm/src/test/java/org/hyperledger/besu/evm/precompile/ECRECPrecompiledContractTest.java index bc4026ae64..ac248b947b 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/precompile/ECRECPrecompiledContractTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/precompile/ECRECPrecompiledContractTest.java @@ -22,6 +22,7 @@ import org.hyperledger.besu.evm.gascalculator.SpuriousDragonGasCalculator; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; +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; @@ -355,4 +356,11 @@ class ECRECPrecompiledContractTest { expectedResult == null ? Bytes.EMPTY : Bytes32.fromHexString(expectedResult); assertThat(contract.computePrecompile(input, messageFrame).getOutput()).isEqualTo(expected); } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/evm/src/test/java/org/hyperledger/besu/evm/precompile/KZGPointEvalPrecompileContractTest.java b/evm/src/test/java/org/hyperledger/besu/evm/precompile/KZGPointEvalPrecompileContractTest.java index fb7ce9d397..bbf9b545af 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/precompile/KZGPointEvalPrecompileContractTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/precompile/KZGPointEvalPrecompileContractTest.java @@ -35,6 +35,7 @@ import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; @@ -91,4 +92,11 @@ public class KZGPointEvalPrecompileContractTest { record PrecompileTestParameters( Bytes input, boolean valid, Bytes returnValue, VersionedHash versionedHash) {} + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } diff --git a/evm/src/test/java/org/hyperledger/besu/evm/precompile/MODEXPPrecompiledContractTest.java b/evm/src/test/java/org/hyperledger/besu/evm/precompile/MODEXPPrecompiledContractTest.java index ad2c80a41f..ac4fd9041a 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/precompile/MODEXPPrecompiledContractTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/precompile/MODEXPPrecompiledContractTest.java @@ -22,6 +22,7 @@ import org.hyperledger.besu.evm.gascalculator.BerlinGasCalculator; import org.hyperledger.besu.evm.gascalculator.ByzantiumGasCalculator; import org.apache.tuweni.bytes.Bytes; +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; @@ -181,4 +182,11 @@ class MODEXPPrecompiledContractTest { assertThat(byzantiumContract.gasRequirement(input)).isEqualTo(eip198Gas); assertThat(berlinContract.gasRequirement(input)).isEqualTo(eip2565Gas); } + + @Test + void dryRunDetector() { + assertThat(true) + .withFailMessage("This test is here so gradle --dry-run executes this class") + .isTrue(); + } } From 23123719fb5ec624691f6a4fc34bc9f6ceeedc2e Mon Sep 17 00:00:00 2001 From: Sally MacFarlane Date: Tue, 16 Jul 2024 10:21:16 +1000 Subject: [PATCH 039/259] removed PKI backed QBFT (#7310) * removed PKI backed QBFT Signed-off-by: Sally MacFarlane * changelog Signed-off-by: Sally MacFarlane --------- Signed-off-by: Sally MacFarlane --- CHANGELOG.md | 7 +- .../configuration/BesuNodeConfiguration.java | 8 - .../BesuNodeConfigurationBuilder.java | 10 - .../src/test/resources/pki-certs/README.md | 127 ------------ .../resources/pki-certs/ca_certs/inter_ca.p12 | Bin 3516 -> 0 bytes .../pki-certs/ca_certs/partner1_ca.p12 | Bin 4434 -> 0 bytes .../pki-certs/ca_certs/partner2_ca.p12 | Bin 4434 -> 0 bytes .../resources/pki-certs/ca_certs/root_ca.p12 | Bin 2602 -> 0 bytes .../src/test/resources/pki-certs/create.sh | 190 ------------------ .../src/test/resources/pki-certs/crl/crl.pem | 28 --- .../resources/pki-certs/miner1/miner1.jks | Bin 3227 -> 0 bytes .../resources/pki-certs/miner1/miner1.p12 | Bin 4004 -> 0 bytes .../test/resources/pki-certs/miner1/nss.cfg | 5 - .../resources/pki-certs/miner1/nssdb/cert9.db | Bin 36864 -> 0 bytes .../resources/pki-certs/miner1/nssdb/key4.db | Bin 36864 -> 0 bytes .../pki-certs/miner1/nssdb/pkcs11.txt | 5 - .../pki-certs/miner1/nssdb/secmod.db | 0 .../resources/pki-certs/miner1/nsspin.txt | 1 - .../resources/pki-certs/miner1/truststore.p12 | Bin 1126 -> 0 bytes .../resources/pki-certs/miner2/miner2.jks | Bin 3226 -> 0 bytes .../resources/pki-certs/miner2/miner2.p12 | Bin 4004 -> 0 bytes .../test/resources/pki-certs/miner2/nss.cfg | 5 - .../resources/pki-certs/miner2/nssdb/cert9.db | Bin 36864 -> 0 bytes .../resources/pki-certs/miner2/nssdb/key4.db | Bin 36864 -> 0 bytes .../pki-certs/miner2/nssdb/pkcs11.txt | 5 - .../pki-certs/miner2/nssdb/secmod.db | 0 .../resources/pki-certs/miner2/nsspin.txt | 1 - .../resources/pki-certs/miner2/truststore.p12 | Bin 1126 -> 0 bytes .../resources/pki-certs/miner3/miner3.jks | Bin 3227 -> 0 bytes .../resources/pki-certs/miner3/miner3.p12 | Bin 4004 -> 0 bytes .../test/resources/pki-certs/miner3/nss.cfg | 5 - .../resources/pki-certs/miner3/nssdb/cert9.db | Bin 36864 -> 0 bytes .../resources/pki-certs/miner3/nssdb/key4.db | Bin 36864 -> 0 bytes .../pki-certs/miner3/nssdb/pkcs11.txt | 5 - .../pki-certs/miner3/nssdb/secmod.db | 0 .../resources/pki-certs/miner3/nsspin.txt | 1 - .../resources/pki-certs/miner3/truststore.p12 | Bin 1126 -> 0 bytes .../resources/pki-certs/miner4/miner4.jks | Bin 3226 -> 0 bytes .../resources/pki-certs/miner4/miner4.p12 | Bin 4004 -> 0 bytes .../test/resources/pki-certs/miner4/nss.cfg | 5 - .../resources/pki-certs/miner4/nssdb/cert9.db | Bin 36864 -> 0 bytes .../resources/pki-certs/miner4/nssdb/key4.db | Bin 36864 -> 0 bytes .../pki-certs/miner4/nssdb/pkcs11.txt | 5 - .../pki-certs/miner4/nssdb/secmod.db | 0 .../resources/pki-certs/miner4/nsspin.txt | 1 - .../resources/pki-certs/miner4/truststore.p12 | Bin 1126 -> 0 bytes .../resources/pki-certs/miner5/miner5.jks | Bin 3226 -> 0 bytes .../resources/pki-certs/miner5/miner5.p12 | Bin 4004 -> 0 bytes .../test/resources/pki-certs/miner5/nss.cfg | 5 - .../resources/pki-certs/miner5/nssdb/cert9.db | Bin 36864 -> 0 bytes .../resources/pki-certs/miner5/nssdb/key4.db | Bin 36864 -> 0 bytes .../pki-certs/miner5/nssdb/pkcs11.txt | 5 - .../pki-certs/miner5/nssdb/secmod.db | 0 .../resources/pki-certs/miner5/nsspin.txt | 1 - .../resources/pki-certs/miner5/truststore.p12 | Bin 1126 -> 0 bytes .../resources/pki-certs/miner6/miner6.jks | Bin 3226 -> 0 bytes .../resources/pki-certs/miner6/miner6.p12 | Bin 4004 -> 0 bytes .../test/resources/pki-certs/miner6/nss.cfg | 5 - .../resources/pki-certs/miner6/nssdb/cert9.db | Bin 36864 -> 0 bytes .../resources/pki-certs/miner6/nssdb/key4.db | Bin 36864 -> 0 bytes .../pki-certs/miner6/nssdb/pkcs11.txt | 5 - .../pki-certs/miner6/nssdb/secmod.db | 0 .../resources/pki-certs/miner6/nsspin.txt | 1 - .../resources/pki-certs/miner6/truststore.p12 | Bin 1126 -> 0 bytes .../test/resources/pki-certs/node1/crl.pem | 27 --- .../test/resources/pki-certs/node1/keys.p12 | Bin 6008 -> 0 bytes .../resources/pki-certs/node1/keystore.jks | Bin 6749 -> 0 bytes .../test/resources/pki-certs/node1/nss.cfg | 6 - .../resources/pki-certs/node1/nssdb/cert8.db | Bin 65536 -> 0 bytes .../resources/pki-certs/node1/nssdb/key3.db | Bin 16384 -> 0 bytes .../resources/pki-certs/node1/nssdb/secmod.db | Bin 16384 -> 0 bytes .../test/resources/pki-certs/node1/nsspin.txt | 1 - .../test/resources/pki-certs/node1/ssl-ca.pem | 70 ------- .../test/resources/pki-certs/node1/ssl.pem | 126 ------------ .../resources/pki-certs/node1/truststore.jks | Bin 3135 -> 0 bytes .../test/resources/pki-certs/node2/crl.pem | 27 --- .../test/resources/pki-certs/node2/keys.p12 | Bin 6008 -> 0 bytes .../resources/pki-certs/node2/keystore.jks | Bin 6749 -> 0 bytes .../test/resources/pki-certs/node2/nss.cfg | 6 - .../resources/pki-certs/node2/nssdb/cert8.db | Bin 65536 -> 0 bytes .../resources/pki-certs/node2/nssdb/key3.db | Bin 16384 -> 0 bytes .../resources/pki-certs/node2/nssdb/secmod.db | Bin 16384 -> 0 bytes .../test/resources/pki-certs/node2/nsspin.txt | 1 - .../test/resources/pki-certs/node2/ssl-ca.pem | 70 ------- .../test/resources/pki-certs/node2/ssl.pem | 126 ------------ .../resources/pki-certs/node2/truststore.jks | Bin 3135 -> 0 bytes .../resources/pki-certs/non-validator/crl.pem | 27 --- .../pki-certs/non-validator/keys.p12 | Bin 6056 -> 0 bytes .../pki-certs/non-validator/keystore.jks | Bin 6805 -> 0 bytes .../resources/pki-certs/non-validator/nss.cfg | 6 - .../pki-certs/non-validator/nssdb/cert8.db | Bin 65536 -> 0 bytes .../pki-certs/non-validator/nssdb/key3.db | Bin 16384 -> 0 bytes .../pki-certs/non-validator/nssdb/secmod.db | Bin 16384 -> 0 bytes .../pki-certs/non-validator/nsspin.txt | 1 - .../pki-certs/non-validator/ssl-ca.pem | 70 ------- .../resources/pki-certs/non-validator/ssl.pem | 126 ------------ .../pki-certs/non-validator/truststore.jks | Bin 3135 -> 0 bytes .../resources/pki-certs/nonValidator/crl.pem | 27 --- .../resources/pki-certs/nonValidator/keys.p12 | Bin 6046 -> 0 bytes .../pki-certs/nonValidator/keystore.jks | Bin 6795 -> 0 bytes .../resources/pki-certs/nonValidator/nss.cfg | 6 - .../pki-certs/nonValidator/nssdb/cert8.db | Bin 65536 -> 0 bytes .../pki-certs/nonValidator/nssdb/key3.db | Bin 16384 -> 0 bytes .../pki-certs/nonValidator/nssdb/secmod.db | Bin 16384 -> 0 bytes .../pki-certs/nonValidator/nsspin.txt | 1 - .../pki-certs/nonValidator/ssl-ca.pem | 70 ------- .../resources/pki-certs/nonValidator/ssl.pem | 126 ------------ .../pki-certs/nonValidator/truststore.jks | Bin 3135 -> 0 bytes .../pki-certs/truststore/truststore.p12 | Bin 5894 -> 0 bytes .../resources/pki-certs/validator/crl.pem | 27 --- .../resources/pki-certs/validator/keys.p12 | Bin 6032 -> 0 bytes .../pki-certs/validator/keystore.jks | Bin 6773 -> 0 bytes .../resources/pki-certs/validator/nss.cfg | 6 - .../pki-certs/validator/nssdb/cert8.db | Bin 65536 -> 0 bytes .../pki-certs/validator/nssdb/key3.db | Bin 16384 -> 0 bytes .../pki-certs/validator/nssdb/secmod.db | Bin 16384 -> 0 bytes .../resources/pki-certs/validator/nsspin.txt | 1 - .../resources/pki-certs/validator/ssl-ca.pem | 70 ------- .../resources/pki-certs/validator/ssl.pem | 126 ------------ .../pki-certs/validator/truststore.jks | Bin 3135 -> 0 bytes .../resources/pki-certs/validator1/crl.pem | 27 --- .../resources/pki-certs/validator1/keys.p12 | Bin 6034 -> 0 bytes .../pki-certs/validator1/keystore.jks | Bin 6783 -> 0 bytes .../resources/pki-certs/validator1/nss.cfg | 6 - .../pki-certs/validator1/nssdb/cert8.db | Bin 65536 -> 0 bytes .../pki-certs/validator1/nssdb/key3.db | Bin 16384 -> 0 bytes .../pki-certs/validator1/nssdb/secmod.db | Bin 16384 -> 0 bytes .../resources/pki-certs/validator1/nsspin.txt | 1 - .../resources/pki-certs/validator1/ssl-ca.pem | 70 ------- .../resources/pki-certs/validator1/ssl.pem | 126 ------------ .../pki-certs/validator1/truststore.jks | Bin 3135 -> 0 bytes .../resources/pki-certs/validator2/crl.pem | 27 --- .../resources/pki-certs/validator2/keys.p12 | Bin 6034 -> 0 bytes .../pki-certs/validator2/keystore.jks | Bin 6783 -> 0 bytes .../resources/pki-certs/validator2/nss.cfg | 6 - .../pki-certs/validator2/nssdb/cert8.db | Bin 65536 -> 0 bytes .../pki-certs/validator2/nssdb/key3.db | Bin 16384 -> 0 bytes .../pki-certs/validator2/nssdb/secmod.db | Bin 16384 -> 0 bytes .../resources/pki-certs/validator2/nsspin.txt | 1 - .../resources/pki-certs/validator2/ssl-ca.pem | 70 ------- .../resources/pki-certs/validator2/ssl.pem | 126 ------------ .../pki-certs/validator2/truststore.jks | Bin 3135 -> 0 bytes .../resources/pki-certs/validator3/crl.pem | 27 --- .../resources/pki-certs/validator3/keys.p12 | Bin 6034 -> 0 bytes .../pki-certs/validator3/keystore.jks | Bin 6783 -> 0 bytes .../resources/pki-certs/validator3/nss.cfg | 6 - .../pki-certs/validator3/nssdb/cert8.db | Bin 65536 -> 0 bytes .../pki-certs/validator3/nssdb/key3.db | Bin 16384 -> 0 bytes .../pki-certs/validator3/nssdb/secmod.db | Bin 16384 -> 0 bytes .../resources/pki-certs/validator3/nsspin.txt | 1 - .../resources/pki-certs/validator3/ssl-ca.pem | 70 ------- .../resources/pki-certs/validator3/ssl.pem | 126 ------------ .../pki-certs/validator3/truststore.jks | Bin 3135 -> 0 bytes .../resources/pki-certs/validator4/crl.pem | 27 --- .../resources/pki-certs/validator4/keys.p12 | Bin 6034 -> 0 bytes .../pki-certs/validator4/keystore.jks | Bin 6783 -> 0 bytes .../resources/pki-certs/validator4/nss.cfg | 6 - .../pki-certs/validator4/nssdb/cert8.db | Bin 65536 -> 0 bytes .../pki-certs/validator4/nssdb/key3.db | Bin 16384 -> 0 bytes .../pki-certs/validator4/nssdb/secmod.db | Bin 16384 -> 0 bytes .../resources/pki-certs/validator4/nsspin.txt | 1 - .../resources/pki-certs/validator4/ssl-ca.pem | 70 ------- .../resources/pki-certs/validator4/ssl.pem | 126 ------------ .../pki-certs/validator4/truststore.jks | Bin 3135 -> 0 bytes .../org/hyperledger/besu/cli/BesuCommand.java | 18 -- .../unstable/PkiBlockCreationOptions.java | 164 --------------- .../controller/BesuControllerBuilder.java | 17 -- ...onsensusScheduleBesuControllerBuilder.java | 10 - .../controller/QbftBesuControllerBuilder.java | 10 +- .../TransitionBesuControllerBuilder.java | 8 - .../besu/cli/CommandTestAbstract.java | 22 -- .../hyperledger/besu/cli/PkiOptionsTest.java | 98 --------- .../qbft/support/TestContextBuilder.java | 2 +- .../besu/consensus/qbft/QbftContext.java | 19 +- .../blockcreation/PkiQbftBlockCreator.java | 179 ----------------- .../QbftBlockCreatorFactory.java | 18 -- .../pki/DefaultKeyStoreWrapperProvider.java | 96 --------- .../qbft/pki/KeyStoreWrapperProvider.java | 29 --- .../pki/PkiBlockCreationConfiguration.java | 68 ------- ...PkiBlockCreationConfigurationProvider.java | 87 -------- .../qbft/pki/PkiQbftBlockHashing.java | 48 ----- .../qbft/pki/PkiQbftBlockHeaderFunctions.java | 37 ---- .../consensus/qbft/pki/PkiQbftExtraData.java | 77 ------- .../qbft/pki/PkiQbftExtraDataCodec.java | 95 --------- .../validation/ProposalPayloadValidator.java | 76 +------ .../qbft/validation/ProposalValidator.java | 2 +- .../ProposalPayloadValidatorTest.java | 131 +----------- 187 files changed, 17 insertions(+), 3800 deletions(-) delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/README.md delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/ca_certs/inter_ca.p12 delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/ca_certs/partner1_ca.p12 delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/ca_certs/partner2_ca.p12 delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/ca_certs/root_ca.p12 delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/create.sh delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/crl/crl.pem delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner1/miner1.jks delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner1/miner1.p12 delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner1/nss.cfg delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner1/nssdb/cert9.db delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner1/nssdb/key4.db delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner1/nssdb/pkcs11.txt delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner1/nssdb/secmod.db delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner1/nsspin.txt delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner1/truststore.p12 delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner2/miner2.jks delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner2/miner2.p12 delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner2/nss.cfg delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner2/nssdb/cert9.db delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner2/nssdb/key4.db delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner2/nssdb/pkcs11.txt delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner2/nssdb/secmod.db delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner2/nsspin.txt delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner2/truststore.p12 delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner3/miner3.jks delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner3/miner3.p12 delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner3/nss.cfg delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner3/nssdb/cert9.db delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner3/nssdb/key4.db delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner3/nssdb/pkcs11.txt delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner3/nssdb/secmod.db delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner3/nsspin.txt delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner3/truststore.p12 delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner4/miner4.jks delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner4/miner4.p12 delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner4/nss.cfg delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner4/nssdb/cert9.db delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner4/nssdb/key4.db delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner4/nssdb/pkcs11.txt delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner4/nssdb/secmod.db delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner4/nsspin.txt delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner4/truststore.p12 delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner5/miner5.jks delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner5/miner5.p12 delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner5/nss.cfg delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner5/nssdb/cert9.db delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner5/nssdb/key4.db delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner5/nssdb/pkcs11.txt delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner5/nssdb/secmod.db delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner5/nsspin.txt delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner5/truststore.p12 delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner6/miner6.jks delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner6/miner6.p12 delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner6/nss.cfg delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner6/nssdb/cert9.db delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner6/nssdb/key4.db delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner6/nssdb/pkcs11.txt delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner6/nssdb/secmod.db delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner6/nsspin.txt delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/miner6/truststore.p12 delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/node1/crl.pem delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/node1/keys.p12 delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/node1/keystore.jks delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/node1/nss.cfg delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/node1/nssdb/cert8.db delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/node1/nssdb/key3.db delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/node1/nssdb/secmod.db delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/node1/nsspin.txt delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/node1/ssl-ca.pem delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/node1/ssl.pem delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/node1/truststore.jks delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/node2/crl.pem delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/node2/keys.p12 delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/node2/keystore.jks delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/node2/nss.cfg delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/node2/nssdb/cert8.db delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/node2/nssdb/key3.db delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/node2/nssdb/secmod.db delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/node2/nsspin.txt delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/node2/ssl-ca.pem delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/node2/ssl.pem delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/node2/truststore.jks delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/non-validator/crl.pem delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/non-validator/keys.p12 delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/non-validator/keystore.jks delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/non-validator/nss.cfg delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/non-validator/nssdb/cert8.db delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/non-validator/nssdb/key3.db delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/non-validator/nssdb/secmod.db delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/non-validator/nsspin.txt delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/non-validator/ssl-ca.pem delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/non-validator/ssl.pem delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/non-validator/truststore.jks delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/nonValidator/crl.pem delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/nonValidator/keys.p12 delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/nonValidator/keystore.jks delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/nonValidator/nss.cfg delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/nonValidator/nssdb/cert8.db delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/nonValidator/nssdb/key3.db delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/nonValidator/nssdb/secmod.db delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/nonValidator/nsspin.txt delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/nonValidator/ssl-ca.pem delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/nonValidator/ssl.pem delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/nonValidator/truststore.jks delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/truststore/truststore.p12 delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator/crl.pem delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator/keys.p12 delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator/keystore.jks delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator/nss.cfg delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator/nssdb/cert8.db delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator/nssdb/key3.db delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator/nssdb/secmod.db delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator/nsspin.txt delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator/ssl-ca.pem delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator/ssl.pem delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator/truststore.jks delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator1/crl.pem delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator1/keys.p12 delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator1/keystore.jks delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator1/nss.cfg delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator1/nssdb/cert8.db delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator1/nssdb/key3.db delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator1/nssdb/secmod.db delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator1/nsspin.txt delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator1/ssl-ca.pem delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator1/ssl.pem delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator1/truststore.jks delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator2/crl.pem delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator2/keys.p12 delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator2/keystore.jks delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator2/nss.cfg delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator2/nssdb/cert8.db delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator2/nssdb/key3.db delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator2/nssdb/secmod.db delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator2/nsspin.txt delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator2/ssl-ca.pem delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator2/ssl.pem delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator2/truststore.jks delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator3/crl.pem delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator3/keys.p12 delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator3/keystore.jks delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator3/nss.cfg delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator3/nssdb/cert8.db delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator3/nssdb/key3.db delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator3/nssdb/secmod.db delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator3/nsspin.txt delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator3/ssl-ca.pem delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator3/ssl.pem delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator3/truststore.jks delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator4/crl.pem delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator4/keys.p12 delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator4/keystore.jks delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator4/nss.cfg delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator4/nssdb/cert8.db delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator4/nssdb/key3.db delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator4/nssdb/secmod.db delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator4/nsspin.txt delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator4/ssl-ca.pem delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator4/ssl.pem delete mode 100644 acceptance-tests/tests/src/test/resources/pki-certs/validator4/truststore.jks delete mode 100644 besu/src/main/java/org/hyperledger/besu/cli/options/unstable/PkiBlockCreationOptions.java delete mode 100644 besu/src/test/java/org/hyperledger/besu/cli/PkiOptionsTest.java delete mode 100644 consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/blockcreation/PkiQbftBlockCreator.java delete mode 100644 consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/pki/DefaultKeyStoreWrapperProvider.java delete mode 100644 consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/pki/KeyStoreWrapperProvider.java delete mode 100644 consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/pki/PkiBlockCreationConfiguration.java delete mode 100644 consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/pki/PkiBlockCreationConfigurationProvider.java delete mode 100644 consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/pki/PkiQbftBlockHashing.java delete mode 100644 consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/pki/PkiQbftBlockHeaderFunctions.java delete mode 100644 consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/pki/PkiQbftExtraData.java delete mode 100644 consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/pki/PkiQbftExtraDataCodec.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 70714d2055..e2b3ea072b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,14 +3,15 @@ ## Next release ### Breaking Changes -- Removed deprecated sync modes (X_SNAP and X_CHECKPOINT). Use SNAP and CHECKPOINT instead [#7309](https://github.com/hyperledger/besu/pull/7309) +- Remove deprecated sync modes (X_SNAP and X_CHECKPOINT). Use SNAP and CHECKPOINT instead [#7309](https://github.com/hyperledger/besu/pull/7309) +- Remove PKI-backed QBFT (deprecated in 24.5.1) Other forms of QBFT remain unchanged. [#7293](https://github.com/hyperledger/besu/pull/7293) ### Additions and Improvements - `--Xsnapsync-bft-enabled` option enables experimental support for snap sync with IBFT/QBFT permissioned Bonsai-DB chains [#7140](https://github.com/hyperledger/besu/pull/7140) - Add support to load external profiles using `--profile` [#7265](https://github.com/hyperledger/besu/issues/7265) - `privacy-nonce-always-increments` option enables private transactions to always increment the nonce, even if the transaction is invalid [#6593](https://github.com/hyperledger/besu/pull/6593) -- Added `block-test` subcommand to the evmtool which runs blockchain reference tests [#7293](https://github.com/hyperledger/besu/pull/7293) -- implement gnark-crypto for eip-2537 [#7316](https://github.com/hyperledger/besu/pull/7316) +- Add `block-test` subcommand to the evmtool which runs blockchain reference tests [#7310](https://github.com/hyperledger/besu/pull/7310) +- Implement gnark-crypto for eip-2537 [#7316](https://github.com/hyperledger/besu/pull/7316) ### Bug fixes diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeConfiguration.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeConfiguration.java index d1e398f721..7bffe9d775 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeConfiguration.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeConfiguration.java @@ -28,7 +28,6 @@ import org.hyperledger.besu.ethereum.p2p.rlpx.connections.netty.TLSConfiguration import org.hyperledger.besu.ethereum.permissioning.PermissioningConfiguration; import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration; -import org.hyperledger.besu.pki.config.PkiKeyStoreConfiguration; import org.hyperledger.besu.tests.acceptance.dsl.node.configuration.genesis.GenesisConfigurationProvider; import java.nio.file.Path; @@ -70,7 +69,6 @@ public class BesuNodeConfiguration { private final List runCommand; private final NetworkName network; private final Optional keyPair; - private final Optional pkiKeyStoreConfiguration; private final boolean strictTxReplayProtectionEnabled; private final Map environment; @@ -107,7 +105,6 @@ public class BesuNodeConfiguration { final Optional privacyParameters, final List runCommand, final Optional keyPair, - final Optional pkiKeyStoreConfiguration, final boolean strictTxReplayProtectionEnabled, final Map environment) { this.name = name; @@ -142,7 +139,6 @@ public class BesuNodeConfiguration { this.privacyParameters = privacyParameters; this.runCommand = runCommand; this.keyPair = keyPair; - this.pkiKeyStoreConfiguration = pkiKeyStoreConfiguration; this.strictTxReplayProtectionEnabled = strictTxReplayProtectionEnabled; this.environment = environment; } @@ -275,10 +271,6 @@ public class BesuNodeConfiguration { return keyPair; } - public Optional getPkiKeyStoreConfiguration() { - return pkiKeyStoreConfiguration; - } - public boolean isStrictTxReplayProtectionEnabled() { return strictTxReplayProtectionEnabled; } diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeConfigurationBuilder.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeConfigurationBuilder.java index 1a9a16f36f..86fb8ab5ca 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeConfigurationBuilder.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeConfigurationBuilder.java @@ -41,7 +41,6 @@ import org.hyperledger.besu.ethereum.p2p.rlpx.connections.netty.TLSConfiguration import org.hyperledger.besu.ethereum.permissioning.PermissioningConfiguration; import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration; -import org.hyperledger.besu.pki.config.PkiKeyStoreConfiguration; import org.hyperledger.besu.tests.acceptance.dsl.node.configuration.genesis.GenesisConfigurationProvider; import org.hyperledger.besu.tests.acceptance.dsl.node.configuration.pki.PKCS11Utils; @@ -96,7 +95,6 @@ public class BesuNodeConfigurationBuilder { private Optional privacyParameters = Optional.empty(); private List runCommand = new ArrayList<>(); private Optional keyPair = Optional.empty(); - private Optional pkiKeyStoreConfiguration = Optional.empty(); private Boolean strictTxReplayProtectionEnabled = false; private Map environment = new HashMap<>(); @@ -429,13 +427,6 @@ public class BesuNodeConfigurationBuilder { return this; } - public BesuNodeConfigurationBuilder pkiBlockCreationEnabled( - final PkiKeyStoreConfiguration pkiKeyStoreConfiguration) { - this.pkiKeyStoreConfiguration = Optional.of(pkiKeyStoreConfiguration); - - return this; - } - public BesuNodeConfigurationBuilder discoveryEnabled(final boolean discoveryEnabled) { this.discoveryEnabled = discoveryEnabled; return this; @@ -549,7 +540,6 @@ public class BesuNodeConfigurationBuilder { privacyParameters, runCommand, keyPair, - pkiKeyStoreConfiguration, strictTxReplayProtectionEnabled, environment); } diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/README.md b/acceptance-tests/tests/src/test/resources/pki-certs/README.md deleted file mode 100644 index 25b23db203..0000000000 --- a/acceptance-tests/tests/src/test/resources/pki-certs/README.md +++ /dev/null @@ -1,127 +0,0 @@ -See `ethereum/p2p/src/test/resources/keys/README.md` which describes the details on how the -certificates are created. The same CA are used to create miner1-miner6. - -For `PkiQbftAcceptanceTest`: -`miner1`-`miner5` are signed with `partner1_ca` and `miner6` is signed with `partner2_ca`. -`miner5` and `miner6` are revoked and added in the crl list. - -Sample shell script that can be executed to recreate the certificates -~~~ -#! /bin/sh - -names=("partner1:miner1" "partner1:miner2" "partner1:miner3" "partner1:miner4" "partner1:miner5" "partner2:miner6") -crls=("partner1:miner5" "partner2:miner6") -KEY_ALG="EC -groupname secp256r1" -#KEY_ALG="RSA -keysize 2048" - -########## -CA_CERTS_PATH=./ca_certs -ROOT_CA_KS=$CA_CERTS_PATH/root_ca.p12 -INTER_CA_KS=$CA_CERTS_PATH/inter_ca.p12 -CRL_DIR=./crl - -keytool -exportcert -keystore $ROOT_CA_KS -storepass test123 -alias root_ca -rfc -file $CA_CERTS_PATH/root_ca.pem - -echo "Generating miner keystores..." -### Generate client keystores -for name in "${names[@]}" -do - IFS=':' read -r -a array <<< "$name" - partner=${array[0]} - client=${array[1]} - - PARTNER_CA_KEYSTORE="$CA_CERTS_PATH/${partner}_ca.p12" - CLIENT_PATH="./${client}" - KEYSTORE_PATH="./$CLIENT_PATH/${client}.p12" - NSSDB_PATH="${CLIENT_PATH}/nssdb" - - echo "$PARTNER_CA_KEYSTORE" - - mkdir -p $NSSDB_PATH - - echo "Generating keystore for Partner $partner Client $client" - keytool -genkeypair -keystore $KEYSTORE_PATH -storepass test123 -alias ${client} \ - -keyalg $KEY_ALG -validity 36500 \ - -dname "CN=localhost, OU=${partner}" \ - -ext san=dns:localhost,ip:127.0.0.1 - - echo "Creating CSR for $client and signing it with ${partner}_ca" - keytool -storepass test123 -keystore $KEYSTORE_PATH -certreq -alias ${client} \ - | keytool -storepass test123 -keystore $PARTNER_CA_KEYSTORE -gencert -alias "${partner}_ca" -ext ku:c=digitalSignature,nonRepudiation,keyEncipherment -ext eku=sA,cA \ - -rfc > "${CLIENT_PATH}/${client}.pem" - - echo "Concat root_ca.pem to ${client}.pem" - cat "${CA_CERTS_PATH}/root_ca.pem" >> "${CLIENT_PATH}/${client}.pem" - - echo "Importing signed $client.pem CSR into $KEYSTORE_PATH" - keytool -keystore $KEYSTORE_PATH -importcert -alias $client \ - -storepass test123 -noprompt -file "${CLIENT_PATH}/${client}.pem" - - echo "Converting p12 to jks" - keytool -importkeystore -srckeystore $KEYSTORE_PATH -srcstoretype PKCS12 -destkeystore "$CLIENT_PATH/${client}.jks" -deststoretype JKS -srcstorepass test123 -deststorepass test123 -srcalias $client -destalias $client -srckeypass test123 -destkeypass test123 -noprompt - - echo "Initialize nss" - echo "test123" > ${CLIENT_PATH}/nsspin.txt - certutil -N -d sql:${NSSDB_PATH} -f "${CLIENT_PATH}/nsspin.txt" - # hack to make Java SunPKCS11 work with new sql version of nssdb - touch ${NSSDB_PATH}/secmod.db - - pk12util -i $KEYSTORE_PATH -d sql:${NSSDB_PATH} -k ${CLIENT_PATH}/nsspin.txt -W test123 - echo "Fixing truststores in sql:${NSSDB_PATH}" - certutil -M -n "CN=root.ca.besu.com" -t CT,C,C -d sql:"$NSSDB_PATH" -f ${CLIENT_PATH}/nsspin.txt - certutil -M -n "CN=inter.ca.besu.com" -t CT,C,C -d sql:"$NSSDB_PATH" -f ${CLIENT_PATH}/nsspin.txt - certutil -M -n "CN=${partner}.ca.besu.com" -t CT,C,C -d sql:"$NSSDB_PATH" -f ${CLIENT_PATH}/nsspin.txt - - certutil -d sql:"$NSSDB_PATH" -f nsspin.txt -L - - echo "Creating pkcs11 nss config file" - cat <${CLIENT_PATH}/nss.cfg -name = NSScrypto-${partner}-${client} -nssSecmodDirectory = ./src/test/resources/pki-certs/${client}/nssdb -nssDbMode = readOnly -nssModule = keystore -showInfo = true -EOF - - # remove pem files - rm "${CLIENT_PATH}/${client}.pem" - - # create truststore - echo "Creating truststore ..." - keytool -exportcert -keystore $ROOT_CA_KS -storepass test123 -alias root_ca -rfc | keytool -import -trustcacerts -alias root_ca -keystore "${CLIENT_PATH}/truststore.p12" -storepass test123 -noprompt - keytool -exportcert -keystore $INTER_CA_KS -storepass test123 -alias inter_ca -rfc | keytool -import -trustcacerts -alias inter_ca -keystore "${CLIENT_PATH}/truststore.p12" -storepass test123 -noprompt - keytool -exportcert -keystore $PARTNER_CA_KEYSTORE -storepass test123 -alias "${partner}_ca" -rfc | keytool -import -trustcacerts -alias "${partner}_ca" -keystore "${CLIENT_PATH}/truststore.p12" -storepass test123 -noprompt - -done -rm $CA_CERTS_PATH/root_ca.pem -echo "Keystores and nss database created" - -## create crl list -mkdir -p $CRL_DIR -rm $CRL_DIR/crl.pem - -for crl in "${crls[@]}" -do - IFS=':' read -r -a array <<< "$crl" - partner=${array[0]} - client=${array[1]} - - echo "Exporting CA certificate and private key" - openssl pkcs12 -nodes -in "$CA_CERTS_PATH/${partner}_ca.p12" -out "$CRL_DIR/${partner}_ca_key.pem" -passin pass:test123 -nocerts - openssl pkcs12 -nodes -in "$CA_CERTS_PATH/${partner}_ca.p12" -out "$CRL_DIR/${partner}_ca.pem" -passin pass:test123 -nokeys - - echo "Export $client certificate" - openssl pkcs12 -nodes -in "./${client}/${client}.p12" -out "$CRL_DIR/${client}.pem" -passin pass:test123 -nokeys - - ## On Mac, use gnutls-certtool, on Linux use certtool - echo "Creating crl" - printf '365\n\n' | gnutls-certtool --generate-crl --load-ca-privkey "$CRL_DIR/${partner}_ca_key.pem" --load-ca-certificate "$CRL_DIR/${partner}_ca.pem" \ - --load-certificate "$CRL_DIR/${client}.pem" >> $CRL_DIR/crl.pem - - rm "$CRL_DIR/${partner}_ca_key.pem" - rm "$CRL_DIR/${partner}_ca.pem" - rm "$CRL_DIR/${client}.pem" - -done - -~~~ diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/ca_certs/inter_ca.p12 b/acceptance-tests/tests/src/test/resources/pki-certs/ca_certs/inter_ca.p12 deleted file mode 100644 index a6e945c2f0638ca5380ba1bb5e378d4eb63bc4f9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3516 zcma)9c{CJ`w>KD!O!h=Fl(B{xvdb2ceb-nrWQobXRCa?Q!x$pjWzX0~M)sXh3?*dA z)?_I{vM;~hdGCC`=l%8GANSmIKg<2|bI*mL!Hv`a8W+Arm*MxX(96`+!YtGPei#!S!+&q21_7yHSLr}Vj4r^1h87@3 z%aStPz)5(JZ6?GKXX~8onM#YM9WASP?EVDNp!-y;Bu+Wva?{3wrlk79-B**={OOXq zDkDMaQE-})F{%TPE@zW^!FU4U!zCW>J1qVvdB(Gc3Y3I_s^srE>NL6H3N7r?jGE;KZklYB=|k5Zm~%_y%Z6}81KU2(9R%`;1&L>MzOCN}4CagmrFY9k zxm`t}k)%JeWu^3z0}vBF5%R%$toSK~+6RBFwXNJTKBMBgRrzrndoyH$`KT+{xpIO< z7|R&T>}GOcrxaRKombwx+|nXT?(e1bqXTVD;Ba+yZ zu-P>q4otuKK*PLL`0^tco>)Hm-jad`A^HU)H;My_US>9U^VtuE)!eJpV_e^qK!%7M z-i7eI5#EIYu9#mxmHo7OL?Nml-CEx#vq!z}!ABzCF-i=KArfA*M#4Lep7n)~I~SuQ ztYJ~U4#~#rH`f~tclM#A#dWh@9LpzLjI(FrE#Q3KynrzCQ7E=SrS7QEV~YCH?qU7Q<%ikyjPR*J$QkFPKBX4WjL(#ZI4j+t%*4I<}%IJj`yTr zM^bug)}lYYCXv9Baw2FYzLOt6cb~An*wAyQ32LTFuI! z$Kh#)#uIn-smIqweVD+1q*gW7x2TIC+?}ZfN8uUUwKFWW&iI+_JH)D2upg-v;#X6 z9q-!{vUx;2mqIW3ASc_;{x?Q{#FfF%O#cf-zINwzh?S_)&F+KAv(;-eud0-|pn{eJ zBGPNDVOVVR1+8-FQE<+?Q{vj#X8Dzz!=)#vmTx<~6sU)$HO3^psXFUL1esADzKABH z@zKfy>IEdFH^j-A(qAf7Y~1+x>A~^U_j}pv*Coi&N+T~zR!v^{G&aRpmlCXx2@&OD zq3>4mTtJHU6nZL_WqnoB#wV#y?d{+c54E|-D{kb^6*pZWW zc73RIxE2iZPh5gH;B0&>RPIz>Q~^{jRDM(rR1c^eVFLdOIN=<$Y!>dGF8pvg1sS-a ztcrP$z zF2#CW3wmkJD5{WM23Iy6@yo7We$*-+VX!XjMXh)@Myr8uUW|`q(AA&uD=GeJPETCF^S4Q?z+e%!a zsknp?8V^mu^n4qv`$dGau6sMfDy@J5d|{t4PYLDcSbSvmzO-!R23K1=ZV+*03S``m zBb%pu=C9JC#iDXNtn?|r`<~o&KhE=r`~!h{qy?U}XD95#l%F;{ap2&+kRf)IfH%fF zzIq#@qb9KUo?bXwDJ?C?F7G-WnE$9t!1C0%Md({4-QZPZuy$p~{tG}C(eceVGY@q(1$$|I+Sfd(#>1E7rY7Hvo2U>H?2mvwRL$oe7cCo(dKT0DETK zW0czGAP93*YKvC5F<)$CL)%F7^RU^Xsn&9ekYcY$+hb~#C60D|c>!|Z7VtguSXr@2 zro0dz-Ipr*X9YGDAk*8)VO<@;cAO8hNuE;vyq!lin;IE)NJ2URaDfUCxt0oBi;20`z?OT|NiiAK}U2m1a zZ%4A{|9p={sIa+c)HnA*KVjE&KZ;f=TOfJIjL-J5ns0I|QtzhN05bIok#8b!?-=Ua zr^bke?SV;epUI^;jR`%B=i43r2J@t7Pz0Ph!=$x;>f6CJoD^~ujY7CNKSTn<>_HS6 zsETNKwnbgfiutDpwvV;p;7Il{9v-dGE2td9KV&t{XyJ&x`?Q}#@w)rvwwT%rSwW4^ z>jXRQlaXp@;@2w>uIH`?qkd3vBdPx8U@7~- z)!m0bDC`<9>aGWNSsw5fwaS=#nIw~_m`*d+K02pM++A~(UyL}ja`KyFM+hfZ%rosM zASk9AE9U?oHV;JVBQ{fv?Zl;xjk}MOd9!l|t3_58Z;O2`4wHE}`YX>|{7&?SP3uHz-(u7h*jLn^hlFVf;| zFiYaD+lMskXAeCOWL=K#InBDkD8@a8hLT4K4Obv!|4pPWBz*X~ybmTFXPBjD`RmE?= zp{ww0UhV6bg0^91?T7DPVwh^4}SUcpI}4naiT%d2?jW@| z^h-s2ff=nHMjYnT;gqYV-r(^YvE1X!+ne`&lujH_R)WGAgWNuAV)ykumj};$ zcE#ItI?o-7a-Uv&w@I?T@C%G^6(Mk?l)kq`iF`(%81(&7-=R)<8DFc$NxVZSSdG8( zo1U-mx%g6A+-0cYjTw1xLI${I7ABh2NDt`=0=H?Q;h*VpcliA>&kj}v=X4mKrRgX} zZ<34)rp%0yL)iv15xT9$&%ywL0w2i>^!%l6Nnc-VIZ)4IFWCX&SScMh<|lc)2mCLL z*2pGD&!q4>nx$~z2%NV&QIm8zn@7Cm!i>1fM0rRB*SwE~qC$ug9p`h21Asiie?!wc zEtT=5i+4I&(hVt4SeS>yBnoS|M-?X#5^{h-+6WI=!jG73CwX}Yo0Hv*B@V28R_mkL zmD?W*9DpnY-UxHj$c<{X40~l#G&sj-;T=wEN;7p@d3Gv!G53wy-TvFY8U$9r{&GL& zLjdOdX<}loU?T5T`=7o|gQn$$)Axtlfbi+4;N}@A?o$(9i$Ke*xx|UEw1!L;t_&;B zr(|E&n;pp^O9L_K-+fI8cv6p0zRTfe&zjc&Uj{}B_EbMVLbO-eqDgu-aS&z*gTui8 zd^FSmAQdhDe$9|C&C32Zy9`uJuyL!|eiyZ$5*|L!`qel3@cSW>mP7b1;8)vq%6fie S=hf#40hqa&9*+My!T$k)Pi9R3 diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/ca_certs/partner1_ca.p12 b/acceptance-tests/tests/src/test/resources/pki-certs/ca_certs/partner1_ca.p12 deleted file mode 100644 index fc89f3e90f462e3f4f2511e054c7dbf2aa0221a7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4434 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 diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/ca_certs/partner2_ca.p12 b/acceptance-tests/tests/src/test/resources/pki-certs/ca_certs/partner2_ca.p12 deleted file mode 100644 index c9fe71867920fff04f279af62effe2389cbf5305..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4434 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 diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/ca_certs/root_ca.p12 b/acceptance-tests/tests/src/test/resources/pki-certs/ca_certs/root_ca.p12 deleted file mode 100644 index 8fc62a23aceb2d9899743d385bb80e53aeb31e9d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2602 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 diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/create.sh b/acceptance-tests/tests/src/test/resources/pki-certs/create.sh deleted file mode 100644 index efc59a09c7..0000000000 --- a/acceptance-tests/tests/src/test/resources/pki-certs/create.sh +++ /dev/null @@ -1,190 +0,0 @@ -#! /bin/sh -## -## 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 -## - -set -e - -names=("partner1:miner1" "partner1:miner2" "partner1:miner3" "partner1:miner4" "partner1:miner5" "partner2:miner6") -crls=("partner1:miner5" "partner2:miner6") -KEY_ALG="EC -groupname secp256r1" -#KEY_ALG="RSA -keysize 2048" - -########## -CA_CERTS_PATH=./ca_certs -ROOT_CA_KS=$CA_CERTS_PATH/root_ca.p12 -INTER_CA_KS=$CA_CERTS_PATH/inter_ca.p12 -PARTNER1_CA_KS=$CA_CERTS_PATH/partner1_ca.p12 -PARTNER2_CA_KS=$CA_CERTS_PATH/partner2_ca.p12 -CRL_DIR=./crl - -mkdir $CA_CERTS_PATH - -keytool -genkeypair -alias root_ca -dname "CN=root.ca.besu.com" -ext bc:c -keyalg RSA -keysize 2048 \ --sigalg SHA256WithRSA -validity 36500 \ --storepass test123 \ --keystore $ROOT_CA_KS - -keytool -exportcert -keystore $ROOT_CA_KS -storepass test123 -alias root_ca -rfc -file $CA_CERTS_PATH/root_ca.pem - -keytool -genkeypair -alias inter_ca -dname "CN=inter.ca.besu.com" \ --ext bc:c=ca:true,pathlen:1 -ext ku:c=dS,kCS,cRLs \ --keyalg RSA -sigalg SHA256WithRSA -validity 36500 \ --storepass test123 \ --keystore $INTER_CA_KS - -keytool -exportcert -keystore $INTER_CA_KS -storepass test123 -alias inter_ca -rfc -file $CA_CERTS_PATH/inter_ca.pem - -keytool -genkeypair -alias partner1_ca -dname "CN=partner1.ca.besu.com" \ --ext bc:c=ca:true,pathlen:0 -ext ku:c=dS,kCS,cRLs \ --keyalg RSA -sigalg SHA256WithRSA -validity 36500 \ --storepass test123 \ --keystore $PARTNER1_CA_KS - -keytool -exportcert -keystore $PARTNER1_CA_KS -storepass test123 -alias partner1_ca -rfc -file $CA_CERTS_PATH/partner1_ca.pem - -keytool -genkeypair -alias partner2_ca -dname "CN=partner2.ca.besu.com" \ --ext bc:c=ca:true,pathlen:0 -ext ku:c=dS,kCS,cRLs \ --keyalg RSA -sigalg SHA256WithRSA -validity 36500 \ --storepass test123 \ --keystore $PARTNER2_CA_KS - -keytool -exportcert -keystore $PARTNER2_CA_KS -storepass test123 -alias partner2_ca -rfc -file $CA_CERTS_PATH/partner2_ca.pem - -keytool -storepass test123 -keystore $INTER_CA_KS -certreq -alias inter_ca \ -| keytool -storepass test123 -keystore $ROOT_CA_KS -gencert -validity 36500 -alias root_ca \ --ext bc:c=ca:true,pathlen:1 -ext ku:c=dS,kCS,cRLs -rfc > $CA_CERTS_PATH/inter_ca.pem - -cat $CA_CERTS_PATH/root_ca.pem >> $CA_CERTS_PATH/inter_ca.pem - -keytool -keystore $INTER_CA_KS -importcert -alias inter_ca \ --storepass test123 -noprompt -file $CA_CERTS_PATH/inter_ca.pem - -keytool -storepass test123 -keystore $PARTNER1_CA_KS -certreq -alias partner1_ca \ -| keytool -storepass test123 -keystore $INTER_CA_KS -gencert -validity 36500 -alias inter_ca \ --ext bc:c=ca:true,pathlen:0 -ext ku:c=dS,kCS,cRLs -rfc > $CA_CERTS_PATH/partner1_ca.pem - -keytool -storepass test123 -keystore $PARTNER2_CA_KS -certreq -alias partner2_ca \ -| keytool -storepass test123 -keystore $INTER_CA_KS -gencert -validity 36500 -alias inter_ca \ --ext bc:c=ca:true,pathlen:0 -ext ku:c=dS,kCS,cRLs -rfc > $CA_CERTS_PATH/partner2_ca.pem - -cat $CA_CERTS_PATH/inter_ca.pem >> $CA_CERTS_PATH/partner1_ca.pem -cat $CA_CERTS_PATH/inter_ca.pem >> $CA_CERTS_PATH/partner2_ca.pem - -keytool -keystore $PARTNER1_CA_KS -importcert -alias partner1_ca \ --storepass test123 -noprompt -file $CA_CERTS_PATH/partner1_ca.pem - -keytool -keystore $PARTNER2_CA_KS -importcert -alias partner2_ca \ --storepass test123 -noprompt -file $CA_CERTS_PATH/partner2_ca.pem - -echo "Generating miner keystores..." -### Generate client keystores -for name in "${names[@]}" -do - IFS=':' read -r -a array <<< "$name" - partner=${array[0]} - client=${array[1]} - - PARTNER_CA_KEYSTORE="$CA_CERTS_PATH/${partner}_ca.p12" - CLIENT_PATH="./${client}" - KEYSTORE_PATH="./$CLIENT_PATH/${client}.p12" - NSSDB_PATH="${CLIENT_PATH}/nssdb" - - echo "$PARTNER_CA_KEYSTORE" - - mkdir -p $NSSDB_PATH - - echo "Generating keystore for Partner $partner Client $client" - keytool -genkeypair -keystore $KEYSTORE_PATH -storepass test123 -alias ${client} \ - -keyalg $KEY_ALG -validity 36500 \ - -dname "CN=localhost, OU=${partner}" \ - -ext san=dns:localhost,ip:127.0.0.1 - - echo "Creating CSR for $client and signing it with ${partner}_ca" - keytool -storepass test123 -keystore $KEYSTORE_PATH -certreq -alias ${client} \ - | keytool -storepass test123 -keystore $PARTNER_CA_KEYSTORE -gencert -validity 36500 -alias "${partner}_ca" -ext ku:c=digitalSignature,nonRepudiation,keyEncipherment -ext eku=sA,cA \ - -rfc > "${CLIENT_PATH}/${client}.pem" - - echo "Concat root_ca.pem to ${client}.pem" - cat "${CA_CERTS_PATH}/root_ca.pem" >> "${CLIENT_PATH}/${client}.pem" - - echo "Importing signed $client.pem CSR into $KEYSTORE_PATH" - keytool -keystore $KEYSTORE_PATH -importcert -alias $client \ - -storepass test123 -noprompt -file "${CLIENT_PATH}/${client}.pem" - - echo "Converting p12 to jks" - keytool -importkeystore -srckeystore $KEYSTORE_PATH -srcstoretype PKCS12 -destkeystore "$CLIENT_PATH/${client}.jks" -deststoretype JKS -srcstorepass test123 -deststorepass test123 -srcalias $client -destalias $client -srckeypass test123 -destkeypass test123 -noprompt - - echo "Initialize nss" - echo "test123" > ${CLIENT_PATH}/nsspin.txt - certutil -N -d sql:${NSSDB_PATH} -f "${CLIENT_PATH}/nsspin.txt" - # hack to make Java SunPKCS11 work with new sql version of nssdb - touch ${NSSDB_PATH}/secmod.db - - pk12util -i $KEYSTORE_PATH -d sql:${NSSDB_PATH} -k ${CLIENT_PATH}/nsspin.txt -W test123 - echo "Fixing truststores in sql:${NSSDB_PATH}" - certutil -M -n "CN=root.ca.besu.com" -t CT,C,C -d sql:"$NSSDB_PATH" -f ${CLIENT_PATH}/nsspin.txt - certutil -M -n "CN=inter.ca.besu.com" -t u,u,u -d sql:"$NSSDB_PATH" -f ${CLIENT_PATH}/nsspin.txt - certutil -M -n "CN=${partner}.ca.besu.com" -t u,u,u -d sql:"$NSSDB_PATH" -f ${CLIENT_PATH}/nsspin.txt - - certutil -d sql:"$NSSDB_PATH" -f nsspin.txt -L - - echo "Creating pkcs11 nss config file" - cat <${CLIENT_PATH}/nss.cfg -name = NSScrypto-${partner}-${client} -nssSecmodDirectory = ./src/test/resources/pki-certs/${client}/nssdb -nssDbMode = readOnly -nssModule = keystore -showInfo = true -EOF - - # remove pem files - rm "${CLIENT_PATH}/${client}.pem" - - # create truststore - echo "Creating truststore ..." - keytool -exportcert -keystore $ROOT_CA_KS -storepass test123 -alias root_ca -rfc | keytool -import -trustcacerts -alias root_ca -keystore "${CLIENT_PATH}/truststore.p12" -storepass test123 -noprompt -## keytool -exportcert -keystore $INTER_CA_KS -storepass test123 -alias inter_ca -rfc | keytool -import -trustcacerts -alias inter_ca -keystore "${CLIENT_PATH}/truststore.p12" -storepass test123 -noprompt -## keytool -exportcert -keystore $PARTNER_CA_KEYSTORE -storepass test123 -alias "${partner}_ca" -rfc | keytool -import -trustcacerts -alias "${partner}_ca" -keystore "${CLIENT_PATH}/truststore.p12" -storepass test123 -noprompt - -done -rm $CA_CERTS_PATH/root_ca.pem -echo "Keystores and nss database created" - -## create crl list -mkdir -p $CRL_DIR -## rm $CRL_DIR/crl.pem - -for crl in "${crls[@]}" -do - IFS=':' read -r -a array <<< "$crl" - partner=${array[0]} - client=${array[1]} - - echo "Exporting CA certificate and private key" - openssl pkcs12 -nodes -in "$CA_CERTS_PATH/${partner}_ca.p12" -out "$CRL_DIR/${partner}_ca_key.pem" -passin pass:test123 -nocerts - openssl pkcs12 -nodes -in "$CA_CERTS_PATH/${partner}_ca.p12" -out "$CRL_DIR/${partner}_ca.pem" -passin pass:test123 -nokeys - - echo "Export $client certificate" - openssl pkcs12 -nodes -in "./${client}/${client}.p12" -out "$CRL_DIR/${client}.pem" -passin pass:test123 -nokeys - - ## On Mac, use gnutls-certtool, on Linux use certtool - echo "Creating crl" - printf '365\n\n' | gnutls-certtool --generate-crl --load-ca-privkey "$CRL_DIR/${partner}_ca_key.pem" --load-ca-certificate "$CRL_DIR/${partner}_ca.pem" \ - --load-certificate "$CRL_DIR/${client}.pem" >> $CRL_DIR/crl.pem - - rm "$CRL_DIR/${partner}_ca_key.pem" - rm "$CRL_DIR/${partner}_ca.pem" - rm "$CRL_DIR/${client}.pem" -done diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/crl/crl.pem b/acceptance-tests/tests/src/test/resources/pki-certs/crl/crl.pem deleted file mode 100644 index 763d01c19d..0000000000 --- a/acceptance-tests/tests/src/test/resources/pki-certs/crl/crl.pem +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN X509 CRL----- -MIICGzCCAQMCAQEwDQYJKoZIhvcNAQELBQAwHzEdMBsGA1UEAxMUcGFydG5lcjEu -Y2EuYmVzdS5jb20XDTIzMDUwNDEwMTUzNVoXDTI0MDUwMzEwMTUzNVowbTAZAghF -KUAnwQI0rxcNMjMwNTA0MTAxNTM1WjAZAggBqEW2S0yD7hcNMjMwNTA0MTAxNTM1 -WjAZAghxoeavxdMy8xcNMjMwNTA0MTAxNTM1WjAaAgkAgWKzx/tKZWkXDTIzMDUw -NDEwMTUzNVqgQTA/MB8GA1UdIwQYMBaAFJcP76nbNK50KG5jmh6CvsxlAhJjMBwG -A1UdFAQVAhNkU4XHFwNbgBqsTIFexJjuzEvyMA0GCSqGSIb3DQEBCwUAA4IBAQB2 -fhAhVwRBtHdwqhGjRlgbz4i6E0CtoL/02Vazib1OiRAXCkyFJL04U3FGcrPa89Dt -ClZE0G38+Jw0Be0tEpn9A8doSbLr73w1GqW3BqNTw/qjbc6R2x28A1VIVPwV6bZH -5P59YtDV+SjSPNxqkwRMyXqGZ2WIMwUS3u47Es9vMsjChXUJWU6W+jf3LYO/dt+V -7xSchRpljhBtMB8MIoXILBq9uOSFalLmy94YzK2Rw1ZG2SVy2QZ6ZXHvZ/omLbPL -kd4oAiN7L0OLOkFVHyb9bVP6DUWfXxSxBdszbQzHCy74NEsFUC0xqq0xpxwQRRfD -codJtbEVJraSsSBkB78n ------END X509 CRL----- ------BEGIN X509 CRL----- -MIICGzCCAQMCAQEwDQYJKoZIhvcNAQELBQAwHzEdMBsGA1UEAxMUcGFydG5lcjIu -Y2EuYmVzdS5jb20XDTIzMDUwNDEwMTUzNVoXDTI0MDUwMzEwMTUzNVowbTAZAggF -p9b0zZl1RxcNMjMwNTA0MTAxNTM1WjAZAgh7MQ7e4x/GbRcNMjMwNTA0MTAxNTM1 -WjAZAghxoeavxdMy8xcNMjMwNTA0MTAxNTM1WjAaAgkAgWKzx/tKZWkXDTIzMDUw -NDEwMTUzNVqgQTA/MB8GA1UdIwQYMBaAFJuQMv8IsgbJS8FfPZZx+hSgj7PBMBwG -A1UdFAQVAhNkU4XHGmnm4OkmS4KBFW1nS4csMA0GCSqGSIb3DQEBCwUAA4IBAQB2 -43mCjuMmB+MXpl+Axn3b/4V2f0HmbUFhF/andWKUwzC47HoQ+WzXoTV0xisHGCgH -SYlrLdWd+pFh24H7TrKgqvmwtVmUFwm6DphXW3AHvaePWIrAy7L5ZrdOQB9TZPC1 -Ly+6x0oKoueiHodWivLQx+CJVbPAzxFEVh0JjecoFw8Tf9FGTqy8jJRdno9HgKDg -BB7w7kPGF7xoaAbukwTXFz7f1nep44oqge+leEc398tdFDxmwralXAUB0A2v/vDG -cSZTr+fyTri+zHjQzeq6//y2GF7S56KSyBXDXTJrvqtuijiVHTzQku+pbVNNrid5 -LgCJI7Phj2Q8k26z0+JJ ------END X509 CRL----- diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/miner1/miner1.jks b/acceptance-tests/tests/src/test/resources/pki-certs/miner1/miner1.jks deleted file mode 100644 index df9dfad4b5dd2f0b891cae035e1d19444f0913de..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3227 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 QjT$@usqm`wOaG_;1?O7-y#N3J diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/miner1/miner1.p12 b/acceptance-tests/tests/src/test/resources/pki-certs/miner1/miner1.p12 deleted file mode 100644 index baba59128aae2a961e6b1af9decea6ffdd241300..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4004 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 diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/miner1/nss.cfg b/acceptance-tests/tests/src/test/resources/pki-certs/miner1/nss.cfg deleted file mode 100644 index d76bd9c163..0000000000 --- a/acceptance-tests/tests/src/test/resources/pki-certs/miner1/nss.cfg +++ /dev/null @@ -1,5 +0,0 @@ -name = NSScrypto-partner1-miner1 -nssSecmodDirectory = ./src/test/resources/pki-certs/miner1/nssdb -nssDbMode = readOnly -nssModule = keystore -showInfo = true diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/miner1/nssdb/cert9.db b/acceptance-tests/tests/src/test/resources/pki-certs/miner1/nssdb/cert9.db deleted file mode 100644 index 33e83d02b71d03eaa6c38f795823d384e1cd3d35..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36864 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 U*V_@F3hC$sy}7=gmKebQ0ObKytpET3 diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/miner1/nssdb/key4.db b/acceptance-tests/tests/src/test/resources/pki-certs/miner1/nssdb/key4.db deleted file mode 100644 index 03a4a5e5b86910715a5db5d5d99b80bd8b442a81..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36864 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 p+7JuA~I(+~&*%4@*4 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 diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/miner2/nss.cfg b/acceptance-tests/tests/src/test/resources/pki-certs/miner2/nss.cfg deleted file mode 100644 index 995d452fc4..0000000000 --- a/acceptance-tests/tests/src/test/resources/pki-certs/miner2/nss.cfg +++ /dev/null @@ -1,5 +0,0 @@ -name = NSScrypto-partner1-miner2 -nssSecmodDirectory = ./src/test/resources/pki-certs/miner2/nssdb -nssDbMode = readOnly -nssModule = keystore -showInfo = true diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/miner2/nssdb/cert9.db b/acceptance-tests/tests/src/test/resources/pki-certs/miner2/nssdb/cert9.db deleted file mode 100644 index 21d6ea184107e60752f60c91b43be1b1327d1302..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36864 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 diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/miner3/miner3.jks b/acceptance-tests/tests/src/test/resources/pki-certs/miner3/miner3.jks deleted file mode 100644 index 79ee2cb0ecc44eb7cf4c08171acb77db25627dfb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3227 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 U7k@7OlWzLEnYFYJUK_~&0K?b-cmMzZ diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/miner3/miner3.p12 b/acceptance-tests/tests/src/test/resources/pki-certs/miner3/miner3.p12 deleted file mode 100644 index c7e42d1af69677fbdda29b508457a4c77f64ddcc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4004 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 diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/miner3/nss.cfg b/acceptance-tests/tests/src/test/resources/pki-certs/miner3/nss.cfg deleted file mode 100644 index 65e04bccbf..0000000000 --- a/acceptance-tests/tests/src/test/resources/pki-certs/miner3/nss.cfg +++ /dev/null @@ -1,5 +0,0 @@ -name = NSScrypto-partner1-miner3 -nssSecmodDirectory = ./src/test/resources/pki-certs/miner3/nssdb -nssDbMode = readOnly -nssModule = keystore -showInfo = true diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/miner3/nssdb/cert9.db b/acceptance-tests/tests/src/test/resources/pki-certs/miner3/nssdb/cert9.db deleted file mode 100644 index 5b295bcda9ab458a518e5255a688503e86575f81..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36864 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 diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/miner3/nssdb/pkcs11.txt b/acceptance-tests/tests/src/test/resources/pki-certs/miner3/nssdb/pkcs11.txt deleted file mode 100644 index c4368a178f..0000000000 --- a/acceptance-tests/tests/src/test/resources/pki-certs/miner3/nssdb/pkcs11.txt +++ /dev/null @@ -1,5 +0,0 @@ -library= -name=NSS Internal PKCS #11 Module -parameters=configdir='sql:./miner3/nssdb' certPrefix='' keyPrefix='' secmod='secmod.db' flags= updatedir='' updateCertPrefix='' updateKeyPrefix='' updateid='' updateTokenDescription='' -NSS=Flags=internal,critical trustOrder=75 cipherOrder=100 slotParams=(1={slotFlags=[ECC,RSA,DSA,DH,RC2,RC4,DES,RANDOM,SHA1,MD5,MD2,SSL,TLS,AES,Camellia,SEED,SHA256,SHA512] askpw=any timeout=30}) - diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/miner3/nssdb/secmod.db b/acceptance-tests/tests/src/test/resources/pki-certs/miner3/nssdb/secmod.db deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/miner3/nsspin.txt b/acceptance-tests/tests/src/test/resources/pki-certs/miner3/nsspin.txt deleted file mode 100644 index 5271a52680..0000000000 --- a/acceptance-tests/tests/src/test/resources/pki-certs/miner3/nsspin.txt +++ /dev/null @@ -1 +0,0 @@ -test123 diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/miner3/truststore.p12 b/acceptance-tests/tests/src/test/resources/pki-certs/miner3/truststore.p12 deleted file mode 100644 index 028424cebdf8e53db3c9b018ae0b324b56352a56..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1126 zcmV-s1eyCVf&^j$0Ru3C1PlfVDuzgg_YDCD0ic2d{RDyo`7nY5^)P}1@dgPhhDe6@ z4FLxRpn?P9FoFZ#0s#Opf&&LNQU+thDZTr0|Wso1Q5=F?w)25f2`pSws*~ujbng<17P4v{NMV#l_e_M2nzm0vP@%` zFjWphE88&)X{Xq`o0QA;=&AiX`S=llxH$J*ZX+(tC$c?gh#m;e4=Xo3kn;yO`-KMAQolV+`vfy zF>u118cPkS!J^6PR~d}XZNx@jTsE%Eb@=Doowg7`K?n>f#&8CxK+9G>cMo$lZ;Z=o z=|}Ym1CNE9?cO1JPp;|;MpJnA9r1Fs27y6vkOra2aD!KLB>pUV$g{`Z&%t z`M3dfb~S~})^5&9gMj2;Kv2g*InmLXI!*i^r(Ts2R7zs6$SWvg0rZl}-~$`!n3tTX zQjl#>7IvJ3sOE)rgWN8NS-GQ@q)<}hD^Y8+aqGjn=?<=Tj;ya+Nf#6)C2AH9rgTR{ zpupZfphl`DOkkABCt8_lj^n zdP>Un3Z1rfJ!^+dfT1u=FflL<1_@w>NC9O71OfpC00bZuj$jg#_Af|-I!ll3k*)r> szqZAYjcCRE&gh?g#yCj?6!(kQl=+!N7V=~=MG{1qwp*jJ=K=yJ5CeJ<_5c6? diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/miner4/miner4.jks b/acceptance-tests/tests/src/test/resources/pki-certs/miner4/miner4.jks deleted file mode 100644 index 6cde7b1a0bafe370fa8c6480adc3ccab33e3ac18..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3226 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 Zp?~oPk8mGD-i{QZPB4_~8*GUI{4YLqO@sgd diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/miner4/nssdb/key4.db b/acceptance-tests/tests/src/test/resources/pki-certs/miner4/nssdb/key4.db deleted file mode 100644 index 127bbd567e9732c176dce7c3a75f62d4c6c25899..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36864 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 Q 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 WO&;MshP)gpLY-hJ*EiS_1Nfh$%TR0p diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/miner5/nssdb/key4.db b/acceptance-tests/tests/src/test/resources/pki-certs/miner5/nssdb/key4.db deleted file mode 100644 index e366aa9e27204b6e11311f91083a09eb9ab4d299..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36864 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 UPr!D?Pkui_GA7&5hQ65iKapuQjsO4v diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/miner5/nssdb/pkcs11.txt b/acceptance-tests/tests/src/test/resources/pki-certs/miner5/nssdb/pkcs11.txt deleted file mode 100644 index bd574fbdc7..0000000000 --- a/acceptance-tests/tests/src/test/resources/pki-certs/miner5/nssdb/pkcs11.txt +++ /dev/null @@ -1,5 +0,0 @@ -library= -name=NSS Internal PKCS #11 Module -parameters=configdir='sql:./miner5/nssdb' certPrefix='' keyPrefix='' secmod='secmod.db' flags= updatedir='' updateCertPrefix='' updateKeyPrefix='' updateid='' updateTokenDescription='' -NSS=Flags=internal,critical trustOrder=75 cipherOrder=100 slotParams=(1={slotFlags=[ECC,RSA,DSA,DH,RC2,RC4,DES,RANDOM,SHA1,MD5,MD2,SSL,TLS,AES,Camellia,SEED,SHA256,SHA512] askpw=any timeout=30}) - diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/miner5/nssdb/secmod.db b/acceptance-tests/tests/src/test/resources/pki-certs/miner5/nssdb/secmod.db deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/miner5/nsspin.txt b/acceptance-tests/tests/src/test/resources/pki-certs/miner5/nsspin.txt deleted file mode 100644 index 5271a52680..0000000000 --- a/acceptance-tests/tests/src/test/resources/pki-certs/miner5/nsspin.txt +++ /dev/null @@ -1 +0,0 @@ -test123 diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/miner5/truststore.p12 b/acceptance-tests/tests/src/test/resources/pki-certs/miner5/truststore.p12 deleted file mode 100644 index 7d54dfe7f6d1ed45b5cb8ac5ae5e8046819fcb9f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1126 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 T8@sDhVAdh!A+gZ4T6O9VovHCl diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/miner6/miner6.p12 b/acceptance-tests/tests/src/test/resources/pki-certs/miner6/miner6.p12 deleted file mode 100644 index 8df1575b0e3a939e925148f1b3e36f132f58f83c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4004 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 diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/miner6/nss.cfg b/acceptance-tests/tests/src/test/resources/pki-certs/miner6/nss.cfg deleted file mode 100644 index 60a2e65bc4..0000000000 --- a/acceptance-tests/tests/src/test/resources/pki-certs/miner6/nss.cfg +++ /dev/null @@ -1,5 +0,0 @@ -name = NSScrypto-partner2-miner6 -nssSecmodDirectory = ./src/test/resources/pki-certs/miner6/nssdb -nssDbMode = readOnly -nssModule = keystore -showInfo = true diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/miner6/nssdb/cert9.db b/acceptance-tests/tests/src/test/resources/pki-certs/miner6/nssdb/cert9.db deleted file mode 100644 index 8bc1ba42f15efaef2bac73ad65811099cba0b0e9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36864 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 V;Xb~4J5r=N!Pi`0e@hJDe*vndG710y diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/miner6/nssdb/key4.db b/acceptance-tests/tests/src/test/resources/pki-certs/miner6/nssdb/key4.db deleted file mode 100644 index aa078f69b7d74b24028ca91d68009f3702a9b02a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36864 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 J&<4Ml_#a_$6!icA diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/miner6/nssdb/pkcs11.txt b/acceptance-tests/tests/src/test/resources/pki-certs/miner6/nssdb/pkcs11.txt deleted file mode 100644 index a47ca829b2..0000000000 --- a/acceptance-tests/tests/src/test/resources/pki-certs/miner6/nssdb/pkcs11.txt +++ /dev/null @@ -1,5 +0,0 @@ -library= -name=NSS Internal PKCS #11 Module -parameters=configdir='sql:./miner6/nssdb' certPrefix='' keyPrefix='' secmod='secmod.db' flags= updatedir='' updateCertPrefix='' updateKeyPrefix='' updateid='' updateTokenDescription='' -NSS=Flags=internal,critical trustOrder=75 cipherOrder=100 slotParams=(1={slotFlags=[ECC,RSA,DSA,DH,RC2,RC4,DES,RANDOM,SHA1,MD5,MD2,SSL,TLS,AES,Camellia,SEED,SHA256,SHA512] askpw=any timeout=30}) - diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/miner6/nssdb/secmod.db b/acceptance-tests/tests/src/test/resources/pki-certs/miner6/nssdb/secmod.db deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/miner6/nsspin.txt b/acceptance-tests/tests/src/test/resources/pki-certs/miner6/nsspin.txt deleted file mode 100644 index 5271a52680..0000000000 --- a/acceptance-tests/tests/src/test/resources/pki-certs/miner6/nsspin.txt +++ /dev/null @@ -1 +0,0 @@ -test123 diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/miner6/truststore.p12 b/acceptance-tests/tests/src/test/resources/pki-certs/miner6/truststore.p12 deleted file mode 100644 index bb56eecd08a7a2a501832acfe6bc4c347d74e218..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1126 zcmV-s1eyCVf&^j$0Ru3C1PlfVDuzgg_YDCD0ic2d{RDyo`7nY5^)P}1@dgPhhDe6@ z4FLxRpn?P9FoFZ#0s#Opf&&LNQU+thDZTr0|Wso1Q2sHS96?4gecm=3lqFrmB)aB17J4`?`1hJP*4S%kCe{8B>`yN z4 zUE$b?Rz@kqye4m^AH#Ni&&BXxkfSoGJC#)zhZ?rAb^KZ1|K4h(ACjLg#_ZDSf=T({|{o{%g9 zQC3S3FJvkBaWy9w!A2w<%g#DYxe53}*^vW>UaWnOyw;Q6DI7t~zxoJJ?X>B81(9g? zHy?7TyxQJ!o0C+09;s)~!`#J3OEeyE!9xzSCcq8!kT}0NLc`1!TYoRte6tiS8BLx5 z;(XgcP*y$|?wgb(71W2p=GbxZWs^@cy3f9O8nz=3(*Cu_I9WoU8=|j%OwnrR&<<`U zz%ZFoHgyK>^yFbj0lE7LbTN*s#Cv@2uu)fhiLZO(#rV;V?sAx`t=%{rg08%VF@aS7 z;)IyKnSvp&tQvOu<;$ssg*0c~oq{h{y(Kp&*)_yVke#4joQ^jK^`6V(+XN|-8*ZMN z)2|$+$yX@0EwU^^V!z_t5Jae_2eI7-5*X%Bw;qd;at}Ho+LZcnI?N-$y@93bXI3W0Xo^S9tkvFtebPi+ zUD(S_$eG5Gf4y?OW@t6Rfws{5i(-M$0LLOr>bI(T091&9c28l$H!>+VgB1V&37Wel z3V{TBE$t*P)sT2E=X*vY)~!G%UaA1I15_I-XMnSZj7NW9BVjoqgQZAMfmC*si71j$ zanwk4-6LhVVNrH5(;ZrFgrkM07ORL7d9PubyYvO7Cw{Z0GgFGa{%*>qe7BP|B1fMe zD56`AT#DBJrPB~v4~P_^0~AL;!49{ks86#cEFuu`L?FA1khlQF@;B#20%^rNC9O71OfpC00bZoH4!(i%gEG#YVCl4cJ&0~ s2tPw26Y2?Z5^=WKQ|Iag6d@(bPYJ>ZO{Qbqu_k_7`mSbZ-~s|C5FGOOJ^%m! diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/node1/crl.pem b/acceptance-tests/tests/src/test/resources/pki-certs/node1/crl.pem deleted file mode 100644 index 8ced006c91..0000000000 --- a/acceptance-tests/tests/src/test/resources/pki-certs/node1/crl.pem +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN X509 CRL----- -MIICBDCB7QIBATANBgkqhkiG9w0BAQsFADCBgTELMAkGA1UEBhMCVVMxCzAJBgNV -BAgMAkNBMQwwCgYDVQQHDANTRk8xCzAJBgNVBAoMAk1DMQ0wCwYDVQQLDARyb290 -MRMwEQYDVQQDDApwYXJ0bmVyYWNhMSYwJAYJKoZIhvcNAQkBFhdwYXJ0bmVyYWNh -QHBhcnRuZXJhLmNvbRcNMjEwNzA5MTkxMjM1WhcNMjIwNzA5MTkxMjM1WjAnMCUC -FF9rJlU9U6JdFIeK/xRojaoxHdc5Fw0yMTA3MDkxOTEyMzVaoA4wDDAKBgNVHRQE -AwIBADANBgkqhkiG9w0BAQsFAAOCAQEAfByR//FGHSsVQbaS51d59o82XocOGnnT -p1hjceqtLGv3bhiebVrsRCOB5TsvE/r2IbB/yHYTe3+LJisIUqBxblQ6xK6IM+qA -3fY646YnPT5pvdZAPZ2BCN/xP3xqGffFKapQ9cz0/36YE3vaEoUDlC2VHK0OXI0t -4CLwAmiptUT2GW4Bk1RtokAsFiUNwNIOlRX5bywUNwkG7EuitR90QSGH3l/vyii2 -0c1Fm9He9MskwipjXpJKKb+t+m1pdpOVkSjRfjmVqi4BZwWlnQjELSLywhJ+WZG2 -Z1NgRjzPXotFKK+YD97Kx1L260A1eUZ46zSq73oUZr0EDZRnNJTr6A== ------END X509 CRL----- ------BEGIN X509 CRL----- -MIICLDCCARQCAQEwDQYJKoZIhvcNAQELBQAwgYExCzAJBgNVBAYTAlVTMQswCQYD -VQQIDAJDQTEMMAoGA1UEBwwDU0ZPMQswCQYDVQQKDAJNQzENMAsGA1UECwwEcm9v -dDETMBEGA1UEAwwKcGFydG5lcmJjYTEmMCQGCSqGSIb3DQEJARYXcGFydG5lcmJj -YUBwYXJ0bmVyYi5jb20XDTIxMDcwOTE5MTIzNVoXDTIyMDcwOTE5MTIzNVowTjAl -AhQTZhDgbKuvX7iLRUBBTiWXBPKM1xcNMjEwNzA5MTkxMjM1WjAlAhRfayZVPVOi -XRSHiv8UaI2qMR3XORcNMjEwNzA5MTkxMjM1WqAOMAwwCgYDVR0UBAMCAQEwDQYJ -KoZIhvcNAQELBQADggEBAMIltmJ036f1BmK/baISJTZTu7PKZgSZMNORnpFT8KvC -s2GNRor5bGp5qvD6LHvsx92YVppCC6xd/beCFBtdyYifqw5xtOvqLQKuqCfxruLz -EqYjKXE/3v8VdyU71J7kFqi0U0Gy4/h/YCL92e5KNbATlmcn5ToyI2EBIEfBfV08 -mm7FBXvbHRzqhfrnCNEjBWBWz3zkJMc9Rib26eCCofYIDkY2HvYSN78YgrnMmD6O -hWOXrPoxArxvmDr5rG4vCadqbQYRkkCAOP0hBeMiB0SAcO2W2LNNAmHWXX7FvU3n -ZRZUX31WoVjhNeEQtNBb2mPYBXHQzLC66qYm1p97afc= ------END X509 CRL----- diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/node1/keys.p12 b/acceptance-tests/tests/src/test/resources/pki-certs/node1/keys.p12 deleted file mode 100644 index 1aeb2fec791cc42aa3d6c9f2390440f0963e7f9c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6008 zcmY+IWl$6hyM`B7KvqIvX`~xjN z?>lqO`Of+A%rkReGxyK?$Hfy$=7o-i!4pa*f`!8op%ihAhlY)o7fQwn3?*azCuZac zC2ao>!paLJtokP^M@Iwv^NRjM(0Hh^K>yuM?m?~+{3XU7|;HcDd*_Bv28AlV1r1su%Wy-x8^5)C*XVlJNwKWcg zZd-EO1g*|-@D6bp6()9gd0s{|4E=q_Wo$HJ2fq`0b=IVf70$=4?~qBl>)6tIwuul1 zH0_la?ZxwyX?wCPv9;t=M^kYNJTeWTd5~bP9!xjNFQ*|?NW}d zSnMcT?Bl7Njr?&A+&(y(kTOP2b-@~)`-ImIj94M8usWk(zWI9*O zQhkv%RxU4p7NeI;)jhh;bsu$I^Q~`>mVpqduYkTVK#hZKzTUZ+0SDI|YX)vVJ>$-G zDHzic&z@n@qsjh&&!#H!^K<&toUB|AqzxqYi`3lt1N_Hp6M*Re3L`&}UJ%l7Oez@6 z?2Mnoy;)HZWXnZl|1rrBXP>e*B^_q>f|$%~POI}%IgIslw-@XM(@9>n+H&aDo~ z3G65HbhX}F>_qOvxQl#-{(7|!JbT+J?Ubd^$jN|;01oJ)LAobPcq-vw-3D8sFzT`l z$falPU+i(1ytwPqC@A_9~BV-VR z@EJ7@JUN3KRC4kDqt#&)W#ABQBMxg7KjZaN#)8QP8S5)20Kpkyi(v?*_+)HRyH_rO z@q~0ldFL;8opu&3N>b4FP-nt?`$fw4y6x6$P0jO+sr9{lc$g!>`b6?O6ijg}XN%}1 zZV5$;x!gcSpbR^^Np>cw{4CyD$HEM$>Bzj;^Y#j17!-x?vB(1Pi9Q=YmXM-3_8284 zd31P=iQg=B=Z8}wU}9V$9?>AVhBPzJtc5PJ=?@sldDM8-St-Z+Zs*YwFkO#3pqym# zj9K_~8PVp^k8|I<&DNPT*gwZpV&A1Ug6C_a1}1!t0w!CdmZ$@sT+21WQtgg6EU#lm zjC}O;@Ru5GZceiDtELOap~A&%D~fBsTp719iORI13VjcAi2inyH{Wz~pI12!4HiK# z3B+A{zw^~G*4au0@=)8PgzxLn%1}s_&hP)Wo{NeOk(o9F_n75(hQw*u<_9o!nVTKX z?hq&2h!dnIDOuO;(NM6W2jSl!2}b!j@Z z6)vxMN1x!U)px-^9W$CZ=8DC$Y7QPn7rJ)5E&P=U_fxFlLoc%aOwoU?@z?YMM$t6* znyPs}^2OX$2naj_F3Z!DPHhZY9C<-_$ebY}!|u<%+I&KlZ8KL(gs>rzc>3ee#6-D( zd`qkO7!2OI#XH~>Oos>BxKPA3>tKa{yL6rKunxVwz6QL|7q~QoDb8CnQb}%1Tefk@ zoQvbCQZ)cC&RHo{ZSRXCx@|R4K(z;Jd~4f!mr?R46L}<@bw~H+RYBgN+o!@TA92;_ zt6(hPMf{9YqZqd$tvj|gexA|k<12M(u~suyw*3$c5$^pql-Ch26!q^q$u8y zfy{8<=7SOC;rsSL&aK4um=6j8-&dPa%Sa`@ujj76`AGCG0A2cV)9v%d?<$VJrz4i? zyq5$oK$B6vDbojc?E1%Sg29@xG%T$BAy}iJHircf%%dG^Sv^ox17VP+&SOd9D=1>%-Cl^LgFJZ*4XoS5xH2Cj=C|LfiFgo%FFg>JJP#e z^_`6_nlr5SKiLkI4Iw|1WQ^9M{5NjM#`esR3?;t`uXy&fc9hHYCmZjoM(>>+DB;*XXthLnASbu#;Yg!$Q8}H8FoM}Ns zuPOMc8uTLY4upgB%aDg&1lWk-1qEE?f2q_cU_Yx3p})9y1i7=PYn@hCq8t|_K*-Bl zPe~)q=>MAO<~jen@^G&dY^@i@`p3pMBNYS<0B;Z>aE%Is`RUH=NQ#tAN*Zl zGtdfIPS0P`TRXMEk{eBTmP{Oqe?#$tcPN#&|ElBQh;0SIaHcccv?D+ezAXjwf`uDV$eJTdA+QH(_u)GOY4j*-1-i72?IosW(+E5@`}Z|n zrnVVFB{%1MGVO(SX@QwVHl@}cw$mY1Yt`FaboAE@Kh|!>&qZRlC~{wm%&pFXvHB{qJ{S^i_)&QNV1G zq7n5HsOZyV=hJkdoZc;{g=1;?lPK%h9w?g}D@KEqXN1_TnY(!{RNwHlxP0F}w@mPb zu7^%=;&WN#*m)F&08Jj{E%&g43O}%5y;>F8vlZOInq8&lC#a`p$BgfJ7WNR6rrc9cAPp&7Uw$=~QeHvC-uAAYgSl)W@b3@zI(PaZGn;uI z#L0a^Rjro>M&)tT&XqrA^qH)EFLX3SB|$TQ0;4$LeJ^iT5|xK}5al!G==SJbY*%)Z zr^PVA7V#pdH-;2nQjFtwimOL98X=W#n-VoJOY%sA-t}QcrhN^m12t2947hheZJ)8= z0s)rv$FqwNYVTOoW$V<-G9RaTo!Q_%0Jp%lXL)8!f}+5v%^R6(O6qZ&L;oXBfAxBc z-4pXJ-+HxC1zxSf88%f>k+|HAi@XoQ7cmYm59e4#3&7>$S;W6bMcT%fhwbRlZ>8A? zkeIR_zwbBXer9y)raO=1{tSc=hN}h#kOoB%LYJLVT9pye7Qu?8Ju4z)B=~QSBy8U3 z0>>n=d0xZ?8{JGot-t-zprg49)=^Nw@58Il8VmhGR>8o(t6t=gC*c*cPGZPW=o}?C z5Scl{vp4$Fa(c(ma)``8lophM}0Wvt+O)aSR9pfMIt5O5cER%0OWVJ_xBzb7E_(@ z@kM$TqbMjRb$Ra5CtW+mJ{_jP`qAe(8H{$Sp6|B+GICS=Ywx$F+51%QnqO`byr|*> zUM0wxlGlU!CQ;j_EP)K7Y7&Hh0`y)QLe?lf;=3=)-IUCeg+?NH;FIe8*zKg*>qre} zv!BMC>VWsGTY_}t9bXqY`wtXu^qiI%5=OoSQ{ZDJ+}AxiUvra|ro~>p_Oym@Oy)c+ zbFTwu23dCaKff{`&On8&Dl0$lp~#eF7r3Iqtefvphs#RPL<`lizja*n8VBy0dHpBHrXCn8RlPRON?&(Dl!`~Ua2~H9x!N=Xb5GPgQd`WtFJ7SFE?~b zU~1I!t*jqUSy}rDwZ*){Byzn)$UDo#6!zh0=Z_9cdkn7N{$pJD!o+)P#=S5S`o+#p^%K{``8*n!8A1DO;&6%(Uc-;q`}$k# z36Y=Q(F(@&2#s$TdnQ}I_de(0a$L-Mk3jB9g&$$jBeVaqL(|D+cuRrU*`1aoMAUPJ zuW<{z{l@IG{2u4RLN&JFR{TvE&ho-LazJT9E{p*4mCSIFq%NgE024v&=uK3=z%zWh zPnMr7tlEC-+%uhrV^MGF>-dNt&Ts{})8XWdjw>kc3)1I2hY$7n` ztj>*0otTbd%+q^K;oDsRw=3HwxV9_I28A;<@P$=jX)1G#QV?p-GoO$vq^52PN0K{h(bo(hgOAO zZLHh@Ilq>wP?taEPRExwW?gIIYuXbVi<}r^SS`(gTiFARsI|1a6WVl@P^}$rgNXBOH_S;NZfxI2oZ*_;pyc4CVCDJk$?ALG;mXR zHP+zZ^kifs?g{k(MbN+3ejQ|YVDXlLB9rf}-%d4n2hX)RqyhROZq~YX(!*}8t9w|h ztbaTq1h?-`3;7wz2f$nsuk|@e>-V*{Q8q&GPX{cjo-i71AixS{_!N0QD61rm7$8`p zt8w6^rtnx7FB)-6w4YOJO}{!jky)shM^o{3o@09$*pvM936DS+XK&{ewpZ^qX!_Bc|tMG z{*S213&m6ihGPC3%l~uISkM1Q+knu}^Fo0~JfXn7|7UYB{08a{*xfJ z{7i$Bp|OBOl)&4xO0*!FI~U9!w8jXlcXE6wDLRoU($%@msT$}Uc(qRSEI5b5p#`yN zmPl-jt-F2pbxH3npO4GAHoXw6P`N-SfiEw(Tt6Rq78t>c5lQ4>>Qz5v(qK+=AFmu!Pim-2aDebymTFEp8P12RR~p(;D%i@gGw zx7uVU4VUK^M0T%Uq4L^m9OWBMMY~gvJ<1;q`SZ2qXMmBzYxQ3D`D`5RliK=?8%7c@MxHiyJ+QpJg$ zlr%_cxbptyny`dJ>!bxcg;IdXlY{5Yxk@M%LaE*KGOQ+<^RVv+&MuHZZSLC*PL$gN6+{$p41l5cNq@(|bvO708UYZ$Or5#Pii7=bNiWM-LzEYq#NNL;~|fT#XP|t_0z3 zB3pN2;;W39uF2bGhI2Iv@=h75`fKww*sHYqC7Gh|@`=~#LzFaHsJaaX7L_&3fk5r_ zu5I_F2d=6g6`<>G%ds;qdYm(*u~sy(h9Z=@)z$16f6n7~tQ(!tCv6AhhGa+B%hj6Y zZ}cIN;0wP>OPUCDf*n(fYGG%Ww1DbiVk45G?yRd7Vh%NDP9Wa;!>UmRvftMyfxQG7 zw}rFw-ali10>Mgl^vObTiFG6HWseDI&QJLy;sdfkYJJne6Dxi!`r1@0-XfJ2i?*Cu zhyvbKj%Dvf=~?n}e{8MGBE?)^=l<#A)L3$Q-h<6;C@|s}I_)T@o?-XZ#!S2R!f(ld zYwQWUJ6lP#_aShBV2!o;faa9XqY|_OnHnmpszW?3sCanV#e=1tuyMtu<~}u|S-P)3 zPP|F(oI>Qgqvmuj;R}rETO#oS{>rez44`CQ^Wpgeq9^Q4K{A@rnL`_4KfJp+bz4S} zVBA3WrM8`XYgm?GKp^di0vj^(NFefrp)Q({SBi(?f7cNQ%!^9{0=NR+0qg+w0A3!( z{~!`xQXn`$up-7h^~<{IL3_zWBCUwM%o}kYULJZL94t&ud<=9-OaKtv?a9)p0JS>O dp(@$^(QUOHyjA21dVbB1IAx4~V5yW9Tv*1fy6 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 Q5C8!X009sHf&WI}Uo4sy9{>OV diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/node1/nssdb/key3.db b/acceptance-tests/tests/src/test/resources/pki-certs/node1/nssdb/key3.db deleted file mode 100644 index 0b103995be1baae63b6a94d6559514d93a489105..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI$c{J2(9{}**G-Db@#ubWAOtOrvESDKsx`ZKexr{B#9VELkLbg%%HK8$HvJ)ap z7_=x{lOan)S+9&sdAnKa9Z7W4`~LC%{r=H=?m5r*oacPM=XsuUzTflt=Q-zrkRoIV zg7!fWVibY|zm^a`1i`+hy#=BEQ+z%DwgLZ^za2q{y_y~n&H0-5V(-r0`tE`H_dMUd zFK7q^fB+Bx0zd!=00AHX1b_e#00KbZ?;?PLwlE(tD;OrG7Q?_W1a9!scyI820RaSn z01yBIKmZ5;0U+=l1>g`eAkgE2Dx?yN;Huz|XoWpgOgGh0C3xrnL-?+6voQWRHzf z-}@Shh;~Zw>e`+iU9S8gfXg z?c=cNQ+T|W-iB`6!gkPu=osgYfFl1swLiS>WJ8iG730+W^Pa9g9rZb3vf{6T_LFmk zON=(j`sBkj{Pil|=x6Zhh!(5mlflWKUcKoHgBnBe`oHj{oyK!K6p`LBMLXV6Jv#+Z zSm*C(_?)<(x0UqeUL`}_;)SsUc{E-?F>Wc5;e>k3uT?0wfFUF<4${NJerVnvoFa=H zEPA2Cb~2u5IGmkPahy@X@#wm#U;j4n%0@0hxgip@J;V+yR^dBjyNaHW_}L`91X(88 zbv;Od7JV;i(R+TvMWmY|>7rh|@n~jJPivIQ!yKs@wYon3fpnU-W%EzSGfo>GbP6{a z_`;Ejvl3+4c5{WVq({o!<&6!w}EKflr4=KLC!*@PdJAB5yLjH_xpc;d966FZ1J5hSXnNoRF zbzAg|jBL7K1HEh7Fm;7Xvushck&(@|HVybQOP3+)Oh+|6wih!W=#7%}5qsx=ef3-( zp=sVIBl=#7S5tS5nkno0+G!!{bJXNiMf{6^G_E!IVMoyev+k^BPh&N0ZiPZ~R;ryr zzK<~Bjw7-fd#1{agfX|Q))^8O3Z`XIa*N@0RjZs&EzwtrzvD8@{Tn&)TPG5eKl}O= z9aFQNk9HW{w0I_=s+7e_YapJ*+UR9c@}B0vT)p^t{#B3)o4vePU&=hx!6ifz>-%Bk z`fbPb&caiKY!Z%SC7xf;s;)C^&une$|KMrbLUrE{A2VBbXjWJz&~(DblJ%gH z*;uL9^MwMlIoNHipQ#2?OIs+_T%xmuQyw0!hpl>DTgoA&@*xm%#nwOsKWKJop*Jp7|;?Rmwfr$)76!Bp^n@%xG?W|Jh%gDU9 zlDO*8d*@37pQJnuW59#@62FLdgip>q*!@X8tuVLEFVcK^+&#WbKr2h2v1HJ}vT-e+p75awwbr?A z(4YfLV&^p9Zk?S~stt*kvn=Oo{&dVg!c=9luirvrYuxk+VNmY5+u4Ub8$!gHvGfx! zcV-POm_?6=t!ImJo@Kmx`*Vl#=DQs^Dxsk&-uiwi4X0^2#^xz&x}EH=j`cd6hjMcs zTE~8hZ6a}qJW7J}cFFNrCG)uGJDtWmy*;Ku0d8#Ye z5c;FjNV^Qry3ERQCePs2#T3%HuGcOIz1;=uwOh(ZBCzfF3OhlVtuvb!N6 zn7DC3ZVn!ImqHE>4hy7uD7$-IaQB7VUZ4hh2L}9I{wctmKmZ5;0U!VbfB+Bx0zd!= u00AHX1c1Q*F0k_*|FuCYAOHk_01yBIKmZ5;0U!VbfB+Bx0zlyZBk&iY2!oRV diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/node1/nssdb/secmod.db b/acceptance-tests/tests/src/test/resources/pki-certs/node1/nssdb/secmod.db deleted file mode 100644 index 08102e23979aed56fbaeb5c47e07822df06d387d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI&ze)o!9Ki9PRcZ&RE^Zlel7WliW+=zQ1fB*srAbn3Ip&3(^PBXj>VNKH72weOW}Baa@8gJJ5c*;EIaDN=i@L3=Gv8PNHit(=Nn zzV9t}@yOUKlZHt&&7#=mE9F1@r^BW1o^bB!pR(!MpGyh?2q1s}0tg_000IagfB*sr H{C9ybXU9$v diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/node1/nsspin.txt b/acceptance-tests/tests/src/test/resources/pki-certs/node1/nsspin.txt deleted file mode 100644 index 5271a52680..0000000000 --- a/acceptance-tests/tests/src/test/resources/pki-certs/node1/nsspin.txt +++ /dev/null @@ -1 +0,0 @@ -test123 diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/node1/ssl-ca.pem b/acceptance-tests/tests/src/test/resources/pki-certs/node1/ssl-ca.pem deleted file mode 100644 index 61a8f5230e..0000000000 --- a/acceptance-tests/tests/src/test/resources/pki-certs/node1/ssl-ca.pem +++ /dev/null @@ -1,70 +0,0 @@ ------BEGIN CERTIFICATE----- -MIID8DCCAtigAwIBAgIUcATI/N49JsZyAuyS8gfW6BppdBEwDQYJKoZIhvcNAQEL -BQAweDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMQwwCgYDVQQHDANTRk8xCzAJ -BgNVBAoMAk1DMQ0wCwYDVQQLDARyb290MRAwDgYDVQQDDAdpbnRlcmNhMSAwHgYJ -KoZIhvcNAQkBFhFpbnRlcmNhQGFkbWluLmNvbTAgFw0yMTA3MDkxOTExNTRaGA8y -MTIxMDYxNTE5MTE1NFowgYExCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEMMAoG -A1UEBwwDU0ZPMQswCQYDVQQKDAJNQzENMAsGA1UECwwEcm9vdDETMBEGA1UEAwwK -cGFydG5lcmFjYTEmMCQGCSqGSIb3DQEJARYXcGFydG5lcmFjYUBwYXJ0bmVyYS5j -b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDccGhUDD8T8m6e2x13 -B0LgCDR8F2vlfAw9FN/tXOKKU3DpagJk0CAutL6YFFYs9MXg8D6bZx+w0iXUnaN/ -6rjIC1LFs79AizpEaoFWDzcVI66ItSW1Swu3ts0I1kK7EGgAMba0TDTnssfrtuPw -rOA2TOdVX03owOE+gaaPonIQlnew5+NNGhbW+P/5ix1IQXhyuNjV/uu3VEJBGNTh -cAuMGdjvglFuz4zyFon4kNRcQvghs5ztjs2h5ZNHjEo6YtNIdJuRS/XOXII9MfPN -plcwJArWTM3yEATNBtdc5FypOSI6cO/Pl+SVEf4kKmnzJQZWOSGiDXbpm938hGVw -ByZPAgMBAAGjZjBkMB0GA1UdDgQWBBQhpkZg+Ktqh6sFCjtm9HE+9bLJ3TAfBgNV -HSMEGDAWgBTdAXu8aBbvkvxYD5Ss9/Ml5VgohjASBgNVHRMBAf8ECDAGAQH/AgEA -MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAQEAIggdc0DCxEiNaKak -/xbc7uGiGBb+UzBTjk4BmX9kEFrZf4XEaHzsptltqcQDCVtzcbFFFxMYhv/w/1g/ -WMNuUhL0mmGIGMxfoqkg50tNyuHW6aSrBXErel9WthGXAhUSzdHgkWxl3pe2wgda -qIcSwTCFgOeVWTZRdKWqKNPHirBglJHUpMgLo0qa0Ug1hxiyOQRt2yXLpe/mH3pG -cozhrEDYQMOcDhYTpPwM2Bl+TsRPpxFaV4QDfiOyvUDFLMM0dyhl2pukjay/Xpp2 -+6Tsnaa+Ui0sDcM3A36Q07+E4Vugxjzfb9a36Eg4XE+Jg3jDA8UOqjeFg9gkK3aY -NaI0qQ== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIID6jCCAtKgAwIBAgIUYdazVD+VnI7jBu7xLaW+npfwHJIwDQYJKoZIhvcNAQEL -BQAwfDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMQwwCgYDVQQHDANTRk8xCzAJ -BgNVBAoMAk1DMQ0wCwYDVQQLDARyb290MRUwEwYDVQQDDAxyb290Y2EuYWRtaW4x -HzAdBgkqhkiG9w0BCQEWEHJvb3RjYUBhZG1pbi5jb20wIBcNMjEwNzA5MTkxMTU0 -WhgPMjEyMTA2MTUxOTExNTRaMHgxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEM -MAoGA1UEBwwDU0ZPMQswCQYDVQQKDAJNQzENMAsGA1UECwwEcm9vdDEQMA4GA1UE -AwwHaW50ZXJjYTEgMB4GCSqGSIb3DQEJARYRaW50ZXJjYUBhZG1pbi5jb20wggEi -MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ8QgVwEjy3CgJFvET7tYNBw97 -4i33EHQT4ZuayGCJ+ADY3ZFpsw2M1IPlbAguqfBkcLd8TAjWNRAdsm9ubGlIcTZr -7LNle3gvc7qEP4qg0i6M7D06CDqtBaIJ1PMTJchOouGU9ntBe+h0qg8tzpiqJdIw -jIOPRWW98Hw9KgF6++2jtlcOW1IxiFSWqf0Mpc81qKukcxnsHjvdxmBp/Z1vL42E -m5xNOGXoxpjq8NygSuVDhQ/bZUnmHLmvv9MXe9Ob52rlzea/YafLpOeNGSA1aCxm -Fx0lcoXWp4xpoyJn9St7vmH3t7quBKdqt54zwcuHjhgZPSR6RikodKHtsl8TAgMB -AAGjZjBkMB0GA1UdDgQWBBTdAXu8aBbvkvxYD5Ss9/Ml5VgohjAfBgNVHSMEGDAW -gBSMsBNO3UGBteMZOTq5fDPG2aPx8DASBgNVHRMBAf8ECDAGAQH/AgEBMA4GA1Ud -DwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAQEA0hJCtrCI9Mf47+y3pvsTjiaT -TZwpNE0cdxHjpcCHJWX2jmGbqqA6wvQ7yy4PFarmnFOoW3hQFeiLgpz9X86YTRzF -8dj3Q2MKXf6i6/iW+Y96GFqurshKp7wV25wfzWwLXcVCiM1xYPWYSyGsZAGotu4M -c7uolVABjJu5nci9mBxVmaYV5oT1mxrvq3dCPm2AvmVFNWPNRbMSAuT5B7FUDvWG -xvd1aDFduqL0iLAcrTifMIYI3XL4pBSIlL78dgY45WL6616EF3mHhW/Y4k4PNq1I -Fz08Q3y99ilhzeAci1jv6KBVHiALZNFFtYjd10KX95qnF9SomBjCTPsQ9PTC5g== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIID2zCCAsOgAwIBAgIUdxRGMrv1ONRI/dJXUHa3isjVXuwwDQYJKoZIhvcNAQEL -BQAwfDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMQwwCgYDVQQHDANTRk8xCzAJ -BgNVBAoMAk1DMQ0wCwYDVQQLDARyb290MRUwEwYDVQQDDAxyb290Y2EuYWRtaW4x -HzAdBgkqhkiG9w0BCQEWEHJvb3RjYUBhZG1pbi5jb20wIBcNMjEwNzA5MTkxMTU0 -WhgPMjEyMTA2MTUxOTExNTRaMHwxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEM -MAoGA1UEBwwDU0ZPMQswCQYDVQQKDAJNQzENMAsGA1UECwwEcm9vdDEVMBMGA1UE -AwwMcm9vdGNhLmFkbWluMR8wHQYJKoZIhvcNAQkBFhByb290Y2FAYWRtaW4uY29t -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Bqlx+ngRZfWjktX6urJ -Tpg2//n3uMW8Gp55SVq+lbpkNXuA3W0uTlom/2fsnzmMmBAJUvv/NaLcFSN++0/d -fYGVhogxjlRoyaXa4sdFPg2ocM+lCHLGhWpYuVdTWPknikTOVNbh9z94SLRfrP8N -kuxGNZNktnVm+QJmrCLmjvnPvQlcP/WqFYehFM26NaRzswOhLLRU1YK8aVlh9Vto -PGSTPtZK60XwTfyCj/zEvHqpbGbKJPp7W0rpxl7ehPQIzGQt5IMH3zKrqLm4/pt+ -XFEVqy724sstthS73bvXguWxBLOzuMze8CbI6SJpcHaH8HO5pfFMPyE5N5l2x9Co -uQIDAQABo1MwUTAdBgNVHQ4EFgQUjLATTt1BgbXjGTk6uXwzxtmj8fAwHwYDVR0j -BBgwFoAUjLATTt1BgbXjGTk6uXwzxtmj8fAwDwYDVR0TAQH/BAUwAwEB/zANBgkq -hkiG9w0BAQsFAAOCAQEAL9/7YtxIbuTt7dgH1KOMb/y6P3Qb79fTVZTx073E2ZBj -OfSuMGUhKC30LWQXCQEsY4WpugJ4cS0NsArSYsO5XWguqgjYlWL6poOmYhGvj7ou -oi44oYqcPm6EbvLrAKdI67bkbSPLzgs+6TrxTyXHzPKFBqGBnuHaFKjgb4hGiPmd -JWKrh3fbTtuLjqSHd0Gey2uBNFql4LhPutdsCUhSOD3BibAeTbXyln70AgpTCoWT -9Qr9Ux6HYIiAHSDBzzuN8EcrlnAm9RO4zRyUVwxDsHoNsOUwybn50IM66p83HuiY -h/iX5uNjaFAADfRR4rQOwb6MLreVH2XYUSiz4M/ijg== ------END CERTIFICATE----- diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/node1/ssl.pem b/acceptance-tests/tests/src/test/resources/pki-certs/node1/ssl.pem deleted file mode 100644 index 291b730311..0000000000 --- a/acceptance-tests/tests/src/test/resources/pki-certs/node1/ssl.pem +++ /dev/null @@ -1,126 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCw8JqVhfSxCPC+ -8UKvPAGHyZOzqrXd3SyrdYQnUKP2NkAhbXpJMNnIyk41+dVJxzjNJ9RiSr3D8hJH -3NOMLtj93UROtp7Az1PdnpPRjeHsT7kt9+79J3I4r6eEU7uhfig2UNPJBaKxqoht -MyBoGJgIYl3O8SD6grFV40cFfCFOWFgKi+Q+U7I0uMl/y+eXw1/g8DBwGPxhhw9Z -est7Ov3Qnk4x2np8Ejh6hl+dAqubojjLFdWrs2goQXrkE+qLEM2jze49L6gL5FwJ -brMkyewsaF6xVKfptMw9EK92NFzQuCUF8SXq548FzYHkiVVNweheBD7+4iCOpi0b -eiC4N6RXAgMBAAECggEABx01aeuf4fpVC6hRoRANk7MUIDYt58S7xg0MijQg04Zs -36syLn0rVHpl2J+55qR+8Si3zlfo91blS0RisRE1IkfiNjP7gA8V9SQqF1PYEJNI -A8QjNMSAQC031Ac11RFodn6bdUqntvL/VzymAelzO2sREH/7bncQwD5KHbtW73pm -un5CvnP6dHQTHX+AVDuH6yOdukuyNM+2Xn8J+PAIRsPn9yENgmvzWIW8UOvKj2Ox -4ckkT7zkihwyf8BnztNizdxSlR+ebsvP76C2gAULXoYjJlI7XxvQ1/qhma0yXhGx -I/fBBmK5rz84DabblgS0mOc2ul/nlhJI5kQSHr/PQQKBgQDVLnoJUOCa/R+s9zOn -WcUu38C8JYsj1J1PqHEOkoTim8gD3JxxCEuHLLFMSxMp4umGa3oYxut6HmgdQaym -mYPCKr0oWYDhZ8M0zwKFGTGjhGv/gkRQKdYk7IV5ASKEijRHwxfMBL9Qbc0+G0xO -/CQgJ4GsQ8neGfrDavzfsnt79wKBgQDUeqApjX0bQXTRYMyJU926N7vasyW+2kFd -KE2aUxgdEm1LG1ZDaCuPi7YZYH+J9krKISLehUJRCa4rmu6L0JjWHJAZNDQdKi2E -jNfQUWU9hoQHs3J/c8e63MmgUy7K16gt7oelRtlyL2A5NXnqvTv8U0kw7+KJkxda -et0Cke9CoQKBgBo6SJtizu9imwYNt9YsDj1xG+ZJ/C9hViVZxOcVEbJLljUbbEff -zGMKFZocVnQ9zZtTF8d6mbgBi6+lx9cLZhF6bqFLObcBrBuQKHA1pEzI2vypizwN -maIbU2SKxjNmSX5Wu1PHdb4wdCLi+uVw0gT+t055XJmtupNWU1w2OkkLAoGATdFD -SzSYdxz37Z7oCft/Hy4+TJCD6GwCuF2EXlrEYBFZmcI/S5yhJ4dhf9XJn/tl1LVi -EeD4Mrm64hlx+B7DetcnJzPpSi0iUoNKnu7Qh0H2pONhsa/znEo0RdVxM7Tb0Uak -wzE5fgo/0XP2XLRFfdn62kNg0kXerbKFsuVDnUECgYARX+jedlHmj1aY6ldhoRGf -5/RAfYAH2f0NbS4oAiRvchjydN9EjCVp8KoF7m9ToaLqPFgHP8zIjYsk7B49jXZr -DjtyMERpjMsBoRbjSKyD1glm1UQeoavgiorPz0w9QDYBstlhH/d0ejfEBCpGk5/2 -YxMs98KdYA62DUkmuaiySQ== ------END PRIVATE KEY----- ------BEGIN CERTIFICATE----- -MIIEszCCA5ugAwIBAgIUX2smVT1Tol0Uh4r/FGiNqjEd1zgwDQYJKoZIhvcNAQEL -BQAwgYExCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEMMAoGA1UEBwwDU0ZPMQsw -CQYDVQQKDAJNQzENMAsGA1UECwwEcm9vdDETMBEGA1UEAwwKcGFydG5lcmFjYTEm -MCQGCSqGSIb3DQEJARYXcGFydG5lcmFjYUBwYXJ0bmVyYS5jb20wIBcNMjEwNzA5 -MTkxMjA4WhgPMjEyMTA2MTUxOTEyMDhaMHcxCzAJBgNVBAYTAlVTMQswCQYDVQQI -DAJDQTEMMAoGA1UEBwwDU0ZPMQswCQYDVQQKDAJNQzENMAsGA1UECwwEcm9vdDEO -MAwGA1UEAwwFbm9kZTExITAfBgkqhkiG9w0BCQEWEm5vZGUxQHBhcnRuZXJhLmNv -bTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALDwmpWF9LEI8L7xQq88 -AYfJk7Oqtd3dLKt1hCdQo/Y2QCFtekkw2cjKTjX51UnHOM0n1GJKvcPyEkfc04wu -2P3dRE62nsDPU92ek9GN4exPuS337v0ncjivp4RTu6F+KDZQ08kForGqiG0zIGgY -mAhiXc7xIPqCsVXjRwV8IU5YWAqL5D5TsjS4yX/L55fDX+DwMHAY/GGHD1l6y3s6 -/dCeTjHaenwSOHqGX50Cq5uiOMsV1auzaChBeuQT6osQzaPN7j0vqAvkXAlusyTJ -7CxoXrFUp+m0zD0Qr3Y0XNC4JQXxJernjwXNgeSJVU3B6F4EPv7iII6mLRt6ILg3 -pFcCAwEAAaOCASgwggEkMBEGCWCGSAGG+EIBAQQEAwIGwDAdBgNVHQ4EFgQUAWkS -lH1KF5emjGJvHhaERb3a7DIwCQYDVR0TBAIwADAOBgNVHQ8BAf8EBAMCBeAwHQYD -VR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMIG1BgNVHSMEga0wgaqAFCGmRmD4 -q2qHqwUKO2b0cT71ssndoXykejB4MQswCQYDVQQGEwJVUzELMAkGA1UECAwCQ0Ex -DDAKBgNVBAcMA1NGTzELMAkGA1UECgwCTUMxDTALBgNVBAsMBHJvb3QxEDAOBgNV -BAMMB2ludGVyY2ExIDAeBgkqhkiG9w0BCQEWEWludGVyY2FAYWRtaW4uY29tghRw -BMj83j0mxnIC7JLyB9boGml0ETANBgkqhkiG9w0BAQsFAAOCAQEAWq/10HjhRI3A -OOs2JTrG5Xpzz7E8rpH45XQE0ecB1I9Zcm5bnHx+WdIo5GtxvFzGF3EtlAaxDlcM -iE1u1bfrwEF6qr0nQc8q+wHfnNdb1lqqFlXrhoerLBVrChwqkGbxILUQ+mPFhSQd -a2791g8SS/jLM3lnf9bFp7AdzJCqg7Ly0BEkIpfVsuZn0HgfYf7JG68B05RdU7/v -Hw5wGTbEmukODWZtAYRFBnKT4pq5G30heNjATjkmaWeoImJNSPgyoPzYJsYJMUNC -GYj3Ap0ueY6LbsNXst61jUGeBtCcWDa3uRg8Hl7j1dz4USPTJwBEEuSSN3CzjJuI -VGvgw1MPpQ== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIID8DCCAtigAwIBAgIUcATI/N49JsZyAuyS8gfW6BppdBEwDQYJKoZIhvcNAQEL -BQAweDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMQwwCgYDVQQHDANTRk8xCzAJ -BgNVBAoMAk1DMQ0wCwYDVQQLDARyb290MRAwDgYDVQQDDAdpbnRlcmNhMSAwHgYJ -KoZIhvcNAQkBFhFpbnRlcmNhQGFkbWluLmNvbTAgFw0yMTA3MDkxOTExNTRaGA8y -MTIxMDYxNTE5MTE1NFowgYExCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEMMAoG -A1UEBwwDU0ZPMQswCQYDVQQKDAJNQzENMAsGA1UECwwEcm9vdDETMBEGA1UEAwwK -cGFydG5lcmFjYTEmMCQGCSqGSIb3DQEJARYXcGFydG5lcmFjYUBwYXJ0bmVyYS5j -b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDccGhUDD8T8m6e2x13 -B0LgCDR8F2vlfAw9FN/tXOKKU3DpagJk0CAutL6YFFYs9MXg8D6bZx+w0iXUnaN/ -6rjIC1LFs79AizpEaoFWDzcVI66ItSW1Swu3ts0I1kK7EGgAMba0TDTnssfrtuPw -rOA2TOdVX03owOE+gaaPonIQlnew5+NNGhbW+P/5ix1IQXhyuNjV/uu3VEJBGNTh -cAuMGdjvglFuz4zyFon4kNRcQvghs5ztjs2h5ZNHjEo6YtNIdJuRS/XOXII9MfPN -plcwJArWTM3yEATNBtdc5FypOSI6cO/Pl+SVEf4kKmnzJQZWOSGiDXbpm938hGVw -ByZPAgMBAAGjZjBkMB0GA1UdDgQWBBQhpkZg+Ktqh6sFCjtm9HE+9bLJ3TAfBgNV -HSMEGDAWgBTdAXu8aBbvkvxYD5Ss9/Ml5VgohjASBgNVHRMBAf8ECDAGAQH/AgEA -MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAQEAIggdc0DCxEiNaKak -/xbc7uGiGBb+UzBTjk4BmX9kEFrZf4XEaHzsptltqcQDCVtzcbFFFxMYhv/w/1g/ -WMNuUhL0mmGIGMxfoqkg50tNyuHW6aSrBXErel9WthGXAhUSzdHgkWxl3pe2wgda -qIcSwTCFgOeVWTZRdKWqKNPHirBglJHUpMgLo0qa0Ug1hxiyOQRt2yXLpe/mH3pG -cozhrEDYQMOcDhYTpPwM2Bl+TsRPpxFaV4QDfiOyvUDFLMM0dyhl2pukjay/Xpp2 -+6Tsnaa+Ui0sDcM3A36Q07+E4Vugxjzfb9a36Eg4XE+Jg3jDA8UOqjeFg9gkK3aY -NaI0qQ== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIID6jCCAtKgAwIBAgIUYdazVD+VnI7jBu7xLaW+npfwHJIwDQYJKoZIhvcNAQEL -BQAwfDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMQwwCgYDVQQHDANTRk8xCzAJ -BgNVBAoMAk1DMQ0wCwYDVQQLDARyb290MRUwEwYDVQQDDAxyb290Y2EuYWRtaW4x -HzAdBgkqhkiG9w0BCQEWEHJvb3RjYUBhZG1pbi5jb20wIBcNMjEwNzA5MTkxMTU0 -WhgPMjEyMTA2MTUxOTExNTRaMHgxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEM -MAoGA1UEBwwDU0ZPMQswCQYDVQQKDAJNQzENMAsGA1UECwwEcm9vdDEQMA4GA1UE -AwwHaW50ZXJjYTEgMB4GCSqGSIb3DQEJARYRaW50ZXJjYUBhZG1pbi5jb20wggEi -MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ8QgVwEjy3CgJFvET7tYNBw97 -4i33EHQT4ZuayGCJ+ADY3ZFpsw2M1IPlbAguqfBkcLd8TAjWNRAdsm9ubGlIcTZr -7LNle3gvc7qEP4qg0i6M7D06CDqtBaIJ1PMTJchOouGU9ntBe+h0qg8tzpiqJdIw -jIOPRWW98Hw9KgF6++2jtlcOW1IxiFSWqf0Mpc81qKukcxnsHjvdxmBp/Z1vL42E -m5xNOGXoxpjq8NygSuVDhQ/bZUnmHLmvv9MXe9Ob52rlzea/YafLpOeNGSA1aCxm -Fx0lcoXWp4xpoyJn9St7vmH3t7quBKdqt54zwcuHjhgZPSR6RikodKHtsl8TAgMB -AAGjZjBkMB0GA1UdDgQWBBTdAXu8aBbvkvxYD5Ss9/Ml5VgohjAfBgNVHSMEGDAW -gBSMsBNO3UGBteMZOTq5fDPG2aPx8DASBgNVHRMBAf8ECDAGAQH/AgEBMA4GA1Ud -DwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAQEA0hJCtrCI9Mf47+y3pvsTjiaT -TZwpNE0cdxHjpcCHJWX2jmGbqqA6wvQ7yy4PFarmnFOoW3hQFeiLgpz9X86YTRzF -8dj3Q2MKXf6i6/iW+Y96GFqurshKp7wV25wfzWwLXcVCiM1xYPWYSyGsZAGotu4M -c7uolVABjJu5nci9mBxVmaYV5oT1mxrvq3dCPm2AvmVFNWPNRbMSAuT5B7FUDvWG -xvd1aDFduqL0iLAcrTifMIYI3XL4pBSIlL78dgY45WL6616EF3mHhW/Y4k4PNq1I -Fz08Q3y99ilhzeAci1jv6KBVHiALZNFFtYjd10KX95qnF9SomBjCTPsQ9PTC5g== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIID2zCCAsOgAwIBAgIUdxRGMrv1ONRI/dJXUHa3isjVXuwwDQYJKoZIhvcNAQEL -BQAwfDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMQwwCgYDVQQHDANTRk8xCzAJ -BgNVBAoMAk1DMQ0wCwYDVQQLDARyb290MRUwEwYDVQQDDAxyb290Y2EuYWRtaW4x -HzAdBgkqhkiG9w0BCQEWEHJvb3RjYUBhZG1pbi5jb20wIBcNMjEwNzA5MTkxMTU0 -WhgPMjEyMTA2MTUxOTExNTRaMHwxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEM -MAoGA1UEBwwDU0ZPMQswCQYDVQQKDAJNQzENMAsGA1UECwwEcm9vdDEVMBMGA1UE -AwwMcm9vdGNhLmFkbWluMR8wHQYJKoZIhvcNAQkBFhByb290Y2FAYWRtaW4uY29t -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Bqlx+ngRZfWjktX6urJ -Tpg2//n3uMW8Gp55SVq+lbpkNXuA3W0uTlom/2fsnzmMmBAJUvv/NaLcFSN++0/d -fYGVhogxjlRoyaXa4sdFPg2ocM+lCHLGhWpYuVdTWPknikTOVNbh9z94SLRfrP8N -kuxGNZNktnVm+QJmrCLmjvnPvQlcP/WqFYehFM26NaRzswOhLLRU1YK8aVlh9Vto -PGSTPtZK60XwTfyCj/zEvHqpbGbKJPp7W0rpxl7ehPQIzGQt5IMH3zKrqLm4/pt+ -XFEVqy724sstthS73bvXguWxBLOzuMze8CbI6SJpcHaH8HO5pfFMPyE5N5l2x9Co -uQIDAQABo1MwUTAdBgNVHQ4EFgQUjLATTt1BgbXjGTk6uXwzxtmj8fAwHwYDVR0j -BBgwFoAUjLATTt1BgbXjGTk6uXwzxtmj8fAwDwYDVR0TAQH/BAUwAwEB/zANBgkq -hkiG9w0BAQsFAAOCAQEAL9/7YtxIbuTt7dgH1KOMb/y6P3Qb79fTVZTx073E2ZBj -OfSuMGUhKC30LWQXCQEsY4WpugJ4cS0NsArSYsO5XWguqgjYlWL6poOmYhGvj7ou -oi44oYqcPm6EbvLrAKdI67bkbSPLzgs+6TrxTyXHzPKFBqGBnuHaFKjgb4hGiPmd -JWKrh3fbTtuLjqSHd0Gey2uBNFql4LhPutdsCUhSOD3BibAeTbXyln70AgpTCoWT -9Qr9Ux6HYIiAHSDBzzuN8EcrlnAm9RO4zRyUVwxDsHoNsOUwybn50IM66p83HuiY -h/iX5uNjaFAADfRR4rQOwb6MLreVH2XYUSiz4M/ijg== ------END CERTIFICATE----- diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/node1/truststore.jks b/acceptance-tests/tests/src/test/resources/pki-certs/node1/truststore.jks deleted file mode 100644 index d707235c76a31f1e2287e068289c8af1be79d11a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3135 zcmc(hcTiJ%7ROU40TNoME?rJsVDgD9ALy9!v0SbWx0qO972P{fW#E1<91(DuW z1Pw*OLiJ%p0b>+UdPf2Vfk)eb@?>3S+@0MS|G4wJ=X`%N_ssYH&gXa5rq`xHAP|K0 zKsQ&28x8~lhm&uiO+oDTC=8&-9$(-$obNdEOTF0csyCsA)xM7jC- z05YP8eP}=(&_rvZ(HK<+F}{6hRzeMp`JDK{^~HeYwi^a!2SH=Nd>|kO%ngYFgF*Bi z`7PspMya%_KbO_= zIwq$_cxTkIMejeNQxZt%BpZ(>`ELeVjC2r1{_Xj&z~*=_`x-lI`=!4p{`Aa-*1w<| zhP~rlwvM zcl0=jzobJmnKWXUt;C#LX}lj^?Ct)C{GSnyCgaV=-o`OuPw^^4v7GPrl@`@hucb#h zSqhh;J`S|0P=xOF-g^}@e4DMZvij*;hGOfuoTq;Xkr7mrKWnNhtEqk^q~&>04Fn1X zfpe_^OV*Eu+Dh`WiLeQg%aP{2`q6g>#Wl5RBKJ4H&Yfid(i`$lHZeft)VDYAZEQe- z!Ru`70F$wtqzw7&Y1?l(kV%qN9_mB zGJf83*o^Uds*4COTFgQ-S}o*0gVYYV-bb{a^u z_8<3x;GfH&?$oCV9Z_aB^)YnPk4u+#D0E%RJvmX`%45}3`9SZC)=ys1NBGo*citr3 zRk(YIr;0*_(G2eKdw|fCJEp3m6)lsLK}K1hn(3&mv)S0gex2xob2)+hmqW`(2hDbf z&=%L1&PZbQ!vd@6FV`lkYz*|py88Wj$l~;w7)#%F@|?)&#q(WG28*(l8PiGB?BPp4 zlTEZ-JF&s(7Y@xobBfVMf1noF0rK25Q|cT)8Afp)1b9~9y0r*pEjOX${w&M-1!JaAQd7kNPW?F!JF_lmGYR=p@=B> z2#7y5n)0ifWpI9pQfEtIxl8heuDn*BT$8IWuo$9Pg(jO%w?bR~%!qWjaUi+BOpmVD zkijd0%v*ue#iPs{EeZu3?BbwNJ1gq+nv@$ z9U67M^Fds{V^;IQcYd_0F|3A@#p&3v251v+iF$l2U4BnU8YV}zcoPd-ZTD#^*iZSw zg!e2aOt6^H@tFxYTBVI{N=DKk$NO28{QAsPhQ!6MZ2iHv?)RsHAIGfk(ctwgO!y&o zu1ASWWET0JhT!Cj7*JW@4@UN^WRrACL;I<~jYzA0zZ5#)3=uRGy`k zD0Bei*mFjNI!2`SZgBYWbS}k?*U<`1vbkKm3eRuH6qV)$iBCx#=xuiKT)pPE_iS8x zhM5LotT}Ch(UWB|Y#7hiP55O*qUP3vPSJ?Y^ii*2>c|6JVO!qlS#cSRhqAkIp^|H>y#k zAY^EX^R^A|d_wcWZyxBQwK+^uxx@{P>p%jmH*hgeh?HEv62hS|?E2^Au{hD+iSd5) z0dqdJ8(2~8gNBiHA9vxXeG+HvXU4K@rDS;UFO2SzdS4l&E?g}X?J7zWdu+PQ&tyIx ad19|6ani4`UFgV#Hu}TctF4B1qW=V(G>y^# diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/node2/crl.pem b/acceptance-tests/tests/src/test/resources/pki-certs/node2/crl.pem deleted file mode 100644 index 8ced006c91..0000000000 --- a/acceptance-tests/tests/src/test/resources/pki-certs/node2/crl.pem +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN X509 CRL----- -MIICBDCB7QIBATANBgkqhkiG9w0BAQsFADCBgTELMAkGA1UEBhMCVVMxCzAJBgNV -BAgMAkNBMQwwCgYDVQQHDANTRk8xCzAJBgNVBAoMAk1DMQ0wCwYDVQQLDARyb290 -MRMwEQYDVQQDDApwYXJ0bmVyYWNhMSYwJAYJKoZIhvcNAQkBFhdwYXJ0bmVyYWNh -QHBhcnRuZXJhLmNvbRcNMjEwNzA5MTkxMjM1WhcNMjIwNzA5MTkxMjM1WjAnMCUC -FF9rJlU9U6JdFIeK/xRojaoxHdc5Fw0yMTA3MDkxOTEyMzVaoA4wDDAKBgNVHRQE -AwIBADANBgkqhkiG9w0BAQsFAAOCAQEAfByR//FGHSsVQbaS51d59o82XocOGnnT -p1hjceqtLGv3bhiebVrsRCOB5TsvE/r2IbB/yHYTe3+LJisIUqBxblQ6xK6IM+qA -3fY646YnPT5pvdZAPZ2BCN/xP3xqGffFKapQ9cz0/36YE3vaEoUDlC2VHK0OXI0t -4CLwAmiptUT2GW4Bk1RtokAsFiUNwNIOlRX5bywUNwkG7EuitR90QSGH3l/vyii2 -0c1Fm9He9MskwipjXpJKKb+t+m1pdpOVkSjRfjmVqi4BZwWlnQjELSLywhJ+WZG2 -Z1NgRjzPXotFKK+YD97Kx1L260A1eUZ46zSq73oUZr0EDZRnNJTr6A== ------END X509 CRL----- ------BEGIN X509 CRL----- -MIICLDCCARQCAQEwDQYJKoZIhvcNAQELBQAwgYExCzAJBgNVBAYTAlVTMQswCQYD -VQQIDAJDQTEMMAoGA1UEBwwDU0ZPMQswCQYDVQQKDAJNQzENMAsGA1UECwwEcm9v -dDETMBEGA1UEAwwKcGFydG5lcmJjYTEmMCQGCSqGSIb3DQEJARYXcGFydG5lcmJj -YUBwYXJ0bmVyYi5jb20XDTIxMDcwOTE5MTIzNVoXDTIyMDcwOTE5MTIzNVowTjAl -AhQTZhDgbKuvX7iLRUBBTiWXBPKM1xcNMjEwNzA5MTkxMjM1WjAlAhRfayZVPVOi -XRSHiv8UaI2qMR3XORcNMjEwNzA5MTkxMjM1WqAOMAwwCgYDVR0UBAMCAQEwDQYJ -KoZIhvcNAQELBQADggEBAMIltmJ036f1BmK/baISJTZTu7PKZgSZMNORnpFT8KvC -s2GNRor5bGp5qvD6LHvsx92YVppCC6xd/beCFBtdyYifqw5xtOvqLQKuqCfxruLz -EqYjKXE/3v8VdyU71J7kFqi0U0Gy4/h/YCL92e5KNbATlmcn5ToyI2EBIEfBfV08 -mm7FBXvbHRzqhfrnCNEjBWBWz3zkJMc9Rib26eCCofYIDkY2HvYSN78YgrnMmD6O -hWOXrPoxArxvmDr5rG4vCadqbQYRkkCAOP0hBeMiB0SAcO2W2LNNAmHWXX7FvU3n -ZRZUX31WoVjhNeEQtNBb2mPYBXHQzLC66qYm1p97afc= ------END X509 CRL----- diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/node2/keys.p12 b/acceptance-tests/tests/src/test/resources/pki-certs/node2/keys.p12 deleted file mode 100644 index 5b3aa85caa4c2318b88d436a057fe6c1028b7a40..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6008 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 diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/node2/keystore.jks b/acceptance-tests/tests/src/test/resources/pki-certs/node2/keystore.jks deleted file mode 100644 index 90b5e93ec75351ca331567a3c7015202667cbbdc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6749 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 diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/node2/nss.cfg b/acceptance-tests/tests/src/test/resources/pki-certs/node2/nss.cfg deleted file mode 100644 index a0db3bdc99..0000000000 --- a/acceptance-tests/tests/src/test/resources/pki-certs/node2/nss.cfg +++ /dev/null @@ -1,6 +0,0 @@ - -name = NSScrypto-node2 -nssSecmodDirectory = ./src/test/resources/pki-certs/node2/nssdb -nssDbMode = readOnly -nssModule = keystore - diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/node2/nssdb/cert8.db b/acceptance-tests/tests/src/test/resources/pki-certs/node2/nssdb/cert8.db deleted file mode 100644 index 10555edf0d7d8ccb38cf07295888fdf5e61db5d9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 65536 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 BkJ|tM diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/node2/nssdb/secmod.db b/acceptance-tests/tests/src/test/resources/pki-certs/node2/nssdb/secmod.db deleted file mode 100644 index ebbf2f030645a70640c155267e97f878374109ac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI&ze)o!9Ki9PRcZ&RE^Z45$G#X7ao5V@hw6QklO`E2= z=c&*n*==I_(aiTeH8l4>gVcoMSo>btHuC8HC>W%^noe|(nIg5f9JE*RlmVUJ*~+QN z<@?@p7Y~iSG-;SblPrpDzEb|ff7)O8?g^)^{weF8{kfnZfB*srAb}P;PF&&gpl~?{`jre9!ZJp3ig6^F8n9dA+{R$H|YA5C{ay zdSGiU)X^RS0YVdQ8JR%Xtg(1dl~s8OM#6f*Na!D#Fem_p3Iq%2Dc+q^d91(OX=NHj zjcjY+O0v&dYUZ zaRs0KLU2p?q6z)ih?H0oF42PUAouw|i>?N$z^5aZ)2}(k-MY%k+$9 zpR*~vA1+u)7vw9!&z($f8!&_WNFKesLrZ4JhnkM~70I3GGG3`KFgR4gv2s{BX} zKWZjejD0`QrcfbpmwxwYp#$yqBsq1Adx%+GUwM(^Y%_+3$|3 zjGLhIW;q3hf|D>8AnzDcSPc#FRX~*>IvxI~I!3@2arUG*EaXMyIq=;|s>WtxRkGqK z8eY*}vu_~z`fnbXEczc)#bG=Evfp*SwM*SPm= zVoqGJ)|IxC5xZ@2`zuYVpL%fVA5u|o_^m|3sC+gxoB>6cBVsPjA(qW0;_OIg#HAWK z_MV&mWoN37>>Q?&CYEf4)F}x?l?;Oqs^%X>sf}OVBQcsD_aSX$(2-yYK{3n*?(j6! zC19y3lFmJ5a%KG;1Bq+obGUg0IQy;RZ{qv~|FXwAh8OV*SB*eINgjb?y95dg29nKIv&aJe(9LvC&L?pF`cCrthKuY=%?tp8o6$ zIWD0Y%-e1h2bwsbz~l|Uydr0`+Wqzc(nCM*R)$J=95w90i7lLV@}Y(qa(3f+#cz9i zdARBODxaJvb0&uD@~@88jL+=ECQPWSajM;5%jSCg4kOcQoc${KJyDA|8c>8*XiqPa z=>!v^l60MGr^D2D0HKSM*D9=dY!Bf`7O92H$lMNmL2-`%rU{9?^kzG^<;&i?&P9_c zMk>yu&FSOQFER~=bz;!H&Id-ss&3VH2@|`>uib}fBlY(AZ8@*cZIZ$h#!N)2ssi6WcSw}$F%mkY?6ynO=m34IsPX#@InfLKEi zn!2!LjZVJKd?zz(Ef@QJ^!fimpA%$fp$`Rswfz!Duj&BK`j^Fib!^vc(8;e|Q9@$0 ze3+V`<}G3pWiJ|0w(m9)3+5Zly%#6r{65j1T$HKS$k^M4MGF>f=3<+f zfdt&K>TCw7MC^vjRWO#5?)M=_fRtRf6vVDF?6C0Wc(m}TxESxA0b{iC4SiwtpLN1& z-*304^^2Xgo*K=xl#t?f`b)Q*M1QKC#>~hUeq4|)(rCEI%V0E)tl0qJWA7K>J14SI}-*|^2%Z%?TGK$TUisr8EJ%$9*ah6DrbglaY>=4cFsU)v=2UV zghti!&*-aNp(Kr}`!^}Q10Irhw?(!!9hJ`@)JC)qnpB8skkItg?c#$Kl?aUp;fP%7 zsc?TsfJR>K|K@y9Xc}5 z5t|r+htH-mjLGhOB;jgFC8lHoVuI?{)T>@qngcX5-VG`F?q94V-ruvcjeLoG`WA0> zsrkJ#_Yb4uyMpZs*~qf557GGdrKj?j;Y@2Pj(tlDr`)9jDX3p06ohGaJo00RCN1&o z|I)%Yz44z~fc!UFxNYz8Q$WfShSa!DUEtZK>x$=8C|zt%tkbRS2C*EI+~L7+v9k9^ zRis5BmXbKF1uoZe2#5BcuG6Mru4yxdA?IJMybko2ZJZ}8H$JlMsOl&soK_F&jS6y@ z?$bD#w_90gpQyR(6MdwlWVFG4(s5&|kk-YnqlVA&6vFHGvG>z6Z`a!~DM6zd4HvAFEClD-e94Ip0-yZN1j+|W($#l$4g@!cEpaI zj=H)mm)}ti kwVH=SglZ2XPE{h7S2mT`vHgYK;sQ6`12Zgv$2T@~ diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/non-validator/crl.pem b/acceptance-tests/tests/src/test/resources/pki-certs/non-validator/crl.pem deleted file mode 100644 index 8ced006c91..0000000000 --- a/acceptance-tests/tests/src/test/resources/pki-certs/non-validator/crl.pem +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN X509 CRL----- -MIICBDCB7QIBATANBgkqhkiG9w0BAQsFADCBgTELMAkGA1UEBhMCVVMxCzAJBgNV -BAgMAkNBMQwwCgYDVQQHDANTRk8xCzAJBgNVBAoMAk1DMQ0wCwYDVQQLDARyb290 -MRMwEQYDVQQDDApwYXJ0bmVyYWNhMSYwJAYJKoZIhvcNAQkBFhdwYXJ0bmVyYWNh -QHBhcnRuZXJhLmNvbRcNMjEwNzA5MTkxMjM1WhcNMjIwNzA5MTkxMjM1WjAnMCUC -FF9rJlU9U6JdFIeK/xRojaoxHdc5Fw0yMTA3MDkxOTEyMzVaoA4wDDAKBgNVHRQE -AwIBADANBgkqhkiG9w0BAQsFAAOCAQEAfByR//FGHSsVQbaS51d59o82XocOGnnT -p1hjceqtLGv3bhiebVrsRCOB5TsvE/r2IbB/yHYTe3+LJisIUqBxblQ6xK6IM+qA -3fY646YnPT5pvdZAPZ2BCN/xP3xqGffFKapQ9cz0/36YE3vaEoUDlC2VHK0OXI0t -4CLwAmiptUT2GW4Bk1RtokAsFiUNwNIOlRX5bywUNwkG7EuitR90QSGH3l/vyii2 -0c1Fm9He9MskwipjXpJKKb+t+m1pdpOVkSjRfjmVqi4BZwWlnQjELSLywhJ+WZG2 -Z1NgRjzPXotFKK+YD97Kx1L260A1eUZ46zSq73oUZr0EDZRnNJTr6A== ------END X509 CRL----- ------BEGIN X509 CRL----- -MIICLDCCARQCAQEwDQYJKoZIhvcNAQELBQAwgYExCzAJBgNVBAYTAlVTMQswCQYD -VQQIDAJDQTEMMAoGA1UEBwwDU0ZPMQswCQYDVQQKDAJNQzENMAsGA1UECwwEcm9v -dDETMBEGA1UEAwwKcGFydG5lcmJjYTEmMCQGCSqGSIb3DQEJARYXcGFydG5lcmJj -YUBwYXJ0bmVyYi5jb20XDTIxMDcwOTE5MTIzNVoXDTIyMDcwOTE5MTIzNVowTjAl -AhQTZhDgbKuvX7iLRUBBTiWXBPKM1xcNMjEwNzA5MTkxMjM1WjAlAhRfayZVPVOi -XRSHiv8UaI2qMR3XORcNMjEwNzA5MTkxMjM1WqAOMAwwCgYDVR0UBAMCAQEwDQYJ -KoZIhvcNAQELBQADggEBAMIltmJ036f1BmK/baISJTZTu7PKZgSZMNORnpFT8KvC -s2GNRor5bGp5qvD6LHvsx92YVppCC6xd/beCFBtdyYifqw5xtOvqLQKuqCfxruLz -EqYjKXE/3v8VdyU71J7kFqi0U0Gy4/h/YCL92e5KNbATlmcn5ToyI2EBIEfBfV08 -mm7FBXvbHRzqhfrnCNEjBWBWz3zkJMc9Rib26eCCofYIDkY2HvYSN78YgrnMmD6O -hWOXrPoxArxvmDr5rG4vCadqbQYRkkCAOP0hBeMiB0SAcO2W2LNNAmHWXX7FvU3n -ZRZUX31WoVjhNeEQtNBb2mPYBXHQzLC66qYm1p97afc= ------END X509 CRL----- diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/non-validator/keys.p12 b/acceptance-tests/tests/src/test/resources/pki-certs/non-validator/keys.p12 deleted file mode 100644 index 30115f1a0dbef1486dbad765b6140e423d331f59..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6056 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 diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/non-validator/keystore.jks b/acceptance-tests/tests/src/test/resources/pki-certs/non-validator/keystore.jks deleted file mode 100644 index 310fbb591cae578e711de9c0f237e9477d3b2f07..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6805 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 F{syT2m diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/non-validator/nssdb/secmod.db b/acceptance-tests/tests/src/test/resources/pki-certs/non-validator/nssdb/secmod.db deleted file mode 100644 index 1320aa6f1c3153aaeecbb09c1958d0207995b3a3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI&ze>YE9Ki9PRcZ&RE^Z z(ASW9Nh(?t$5Q0`gX8Xg_sjkH%#rG0AR-l!ofnYW4e_ns8&+D6VBkq9!0tg_000IagfB*srAb`N{0##A6SosIM;|fF9%H+{i zx2rBprV|sy>bleJs*_erUD|LOYghH$w`LFx!zl5+us1$yG@5!gu}Ri6)|}o3aTErb zO`0Z6!=9)5I?1jRJ&0z$=c$pt`KenOom3l>g_0@FZ_Rz%<-g44j*{3Y% zeBZ51MQ*>(Pj2i;n{%D^lW3Af*5oVYfB28P3*SBE*tH+=*Yn>O1Of;kfB*srAb-_HV8%Aqu0328({Fl=t?UoaJhEhq2gP87>^ulp8OuzXXd#MZ-z!nJ zqQ%;yNug;9W#46Jgon68d2+j*)4k{3bNb_VzQ51s{XOURIq%>1^ZI_)X4YmvAP|K0 zKsQ&2D;@*_hf{8fCxO`P&{#l&rMv}*&>nyYY0QE`zz~RFsG!lly9?^wxR0H-heE0o z+Fl%;29WHWyW?^3i%2k-n+*g+Vz>cLcBl=E9R;zm+6v$Zh=Cpk0dQ?790;hDk@=Ry zg@BkEV2}X!hQy741^W2~V}t-g>5Gv9B>wsuCs>&8lc>8XqFw!b z0BI5AJ`A7+Xkauj7_5rDDDOTDE1`7X%Q&To57{45IJI zZ=L8jOr<3rw4I!MY?h|FzPwn|d~ZkQiC^s-QtI5W5vTfm&}Q}u>&K?AX;9MmI4xJ! zu{pg$JEK<2`~DG~5>Lh?T6;Xse?8c0sEsW0@5qM-w#0ea)!JIwE&n~?=cm@RfkmA# z+-;|_b>xLT6&bD zg-|K_!(h8|mEhgJyDy0&w_uf(HBa6!6xt?aJ^e#SjG)^5ITIZj4YkW5tTAy6;~ zoNEPGuzobuMuG<>3=^c3qs;pBqVEieX=v6){?zg+ca8x_ZOA)eqJZ$JZ*Sn;*nk3q z*I{e`l(lTPopnxGwu3=?->$gy;(Ui^X6PK zR4=prc(jUret(U5-AivyoTa+f!_(!Grg!EqMKK{tE;GRn*Lor4-ls6wu#DEMe9`65TmSL)nv@Z$#nd|fOd32QcfV>rO@)RA=4eg zw59dsGZHwxu)rGni?yk0YkfV@?g4*piWq&CXyMyInHN62bgtV`e@Uh?VgAAES?^}%}_;V=fexfxj342iRE*fPg`pr%Hl%g9|X$r569y;oZc7EL ztVcoKx^VBifgDlcH7md>(F}a~q#K|8tCMj}9+A@puY8J|pqvgt0k;fAP@?hcjCDI5 zyGCD20p=AvS@elhPOC$x@ zGkAnid8-JzSd>|lc_F{OZ7eiuXGOhkvr?lbO`-;kNg5Wn!1tv~qI{r*(&*S z@|^%BCdrUc&xq984Gv$K$*r>Gaj?XYtuGaSMC5m1i%Ro?#HJ zhN(JXyd`at(VJyFVi3pML-=)6y!Ph(E|G|?^f9jy>gauZVSC=#Suts>hmyO9gnVEe zt&rlGD|>8VPecQLvAXUCtkA1E^QVXHq(o6MExB-`U5dfkGZjv#Z_(hJ&Hmkq;NNKg z{!eJoDWG3fPG+_)%}!Srte_GVE}CZSQZW?|ym^kkXyD3qWG!cE>C$pixTyV&8*Rpg_k?;fq^RE9N1FA? z)Bxv&w1YBbZs4M-cZi_7MJb2Cl=RxGZS`s5HkS*8Mq?M!cg&WC>TCO)Y9JV5U8#nZ z0+8Wlj$76|3-K+Bzk6Vg)a5YA<>J@XuL1G!zQCnCL2`1#Y6!dfh|8Z-M`J}!kmCI4 zgJ!&{*Ks0R2Mi+XKkUL&`^C@L&5mc;NJ?|NJvY2V?t7`9x_G5fq`N3h^pVL5ACviL abX6T8^ZrCv>DcurR5h5SPtc1v_J0EFZ;aOf diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/nonValidator/crl.pem b/acceptance-tests/tests/src/test/resources/pki-certs/nonValidator/crl.pem deleted file mode 100644 index 8ced006c91..0000000000 --- a/acceptance-tests/tests/src/test/resources/pki-certs/nonValidator/crl.pem +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN X509 CRL----- -MIICBDCB7QIBATANBgkqhkiG9w0BAQsFADCBgTELMAkGA1UEBhMCVVMxCzAJBgNV -BAgMAkNBMQwwCgYDVQQHDANTRk8xCzAJBgNVBAoMAk1DMQ0wCwYDVQQLDARyb290 -MRMwEQYDVQQDDApwYXJ0bmVyYWNhMSYwJAYJKoZIhvcNAQkBFhdwYXJ0bmVyYWNh -QHBhcnRuZXJhLmNvbRcNMjEwNzA5MTkxMjM1WhcNMjIwNzA5MTkxMjM1WjAnMCUC -FF9rJlU9U6JdFIeK/xRojaoxHdc5Fw0yMTA3MDkxOTEyMzVaoA4wDDAKBgNVHRQE -AwIBADANBgkqhkiG9w0BAQsFAAOCAQEAfByR//FGHSsVQbaS51d59o82XocOGnnT -p1hjceqtLGv3bhiebVrsRCOB5TsvE/r2IbB/yHYTe3+LJisIUqBxblQ6xK6IM+qA -3fY646YnPT5pvdZAPZ2BCN/xP3xqGffFKapQ9cz0/36YE3vaEoUDlC2VHK0OXI0t -4CLwAmiptUT2GW4Bk1RtokAsFiUNwNIOlRX5bywUNwkG7EuitR90QSGH3l/vyii2 -0c1Fm9He9MskwipjXpJKKb+t+m1pdpOVkSjRfjmVqi4BZwWlnQjELSLywhJ+WZG2 -Z1NgRjzPXotFKK+YD97Kx1L260A1eUZ46zSq73oUZr0EDZRnNJTr6A== ------END X509 CRL----- ------BEGIN X509 CRL----- -MIICLDCCARQCAQEwDQYJKoZIhvcNAQELBQAwgYExCzAJBgNVBAYTAlVTMQswCQYD -VQQIDAJDQTEMMAoGA1UEBwwDU0ZPMQswCQYDVQQKDAJNQzENMAsGA1UECwwEcm9v -dDETMBEGA1UEAwwKcGFydG5lcmJjYTEmMCQGCSqGSIb3DQEJARYXcGFydG5lcmJj -YUBwYXJ0bmVyYi5jb20XDTIxMDcwOTE5MTIzNVoXDTIyMDcwOTE5MTIzNVowTjAl -AhQTZhDgbKuvX7iLRUBBTiWXBPKM1xcNMjEwNzA5MTkxMjM1WjAlAhRfayZVPVOi -XRSHiv8UaI2qMR3XORcNMjEwNzA5MTkxMjM1WqAOMAwwCgYDVR0UBAMCAQEwDQYJ -KoZIhvcNAQELBQADggEBAMIltmJ036f1BmK/baISJTZTu7PKZgSZMNORnpFT8KvC -s2GNRor5bGp5qvD6LHvsx92YVppCC6xd/beCFBtdyYifqw5xtOvqLQKuqCfxruLz -EqYjKXE/3v8VdyU71J7kFqi0U0Gy4/h/YCL92e5KNbATlmcn5ToyI2EBIEfBfV08 -mm7FBXvbHRzqhfrnCNEjBWBWz3zkJMc9Rib26eCCofYIDkY2HvYSN78YgrnMmD6O -hWOXrPoxArxvmDr5rG4vCadqbQYRkkCAOP0hBeMiB0SAcO2W2LNNAmHWXX7FvU3n -ZRZUX31WoVjhNeEQtNBb2mPYBXHQzLC66qYm1p97afc= ------END X509 CRL----- diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/nonValidator/keys.p12 b/acceptance-tests/tests/src/test/resources/pki-certs/nonValidator/keys.p12 deleted file mode 100644 index 0f5879ff1c0eca2567f5f417547e3778cd2add23..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6046 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�Buv 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 HtH8eiS_q!X diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/nonValidator/nssdb/secmod.db b/acceptance-tests/tests/src/test/resources/pki-certs/nonValidator/nssdb/secmod.db deleted file mode 100644 index 1d70f9b3a97264b7b49982a0dd894a43314ed59d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 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 diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/validator/crl.pem b/acceptance-tests/tests/src/test/resources/pki-certs/validator/crl.pem deleted file mode 100644 index 8ced006c91..0000000000 --- a/acceptance-tests/tests/src/test/resources/pki-certs/validator/crl.pem +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN X509 CRL----- -MIICBDCB7QIBATANBgkqhkiG9w0BAQsFADCBgTELMAkGA1UEBhMCVVMxCzAJBgNV -BAgMAkNBMQwwCgYDVQQHDANTRk8xCzAJBgNVBAoMAk1DMQ0wCwYDVQQLDARyb290 -MRMwEQYDVQQDDApwYXJ0bmVyYWNhMSYwJAYJKoZIhvcNAQkBFhdwYXJ0bmVyYWNh -QHBhcnRuZXJhLmNvbRcNMjEwNzA5MTkxMjM1WhcNMjIwNzA5MTkxMjM1WjAnMCUC -FF9rJlU9U6JdFIeK/xRojaoxHdc5Fw0yMTA3MDkxOTEyMzVaoA4wDDAKBgNVHRQE -AwIBADANBgkqhkiG9w0BAQsFAAOCAQEAfByR//FGHSsVQbaS51d59o82XocOGnnT -p1hjceqtLGv3bhiebVrsRCOB5TsvE/r2IbB/yHYTe3+LJisIUqBxblQ6xK6IM+qA -3fY646YnPT5pvdZAPZ2BCN/xP3xqGffFKapQ9cz0/36YE3vaEoUDlC2VHK0OXI0t -4CLwAmiptUT2GW4Bk1RtokAsFiUNwNIOlRX5bywUNwkG7EuitR90QSGH3l/vyii2 -0c1Fm9He9MskwipjXpJKKb+t+m1pdpOVkSjRfjmVqi4BZwWlnQjELSLywhJ+WZG2 -Z1NgRjzPXotFKK+YD97Kx1L260A1eUZ46zSq73oUZr0EDZRnNJTr6A== ------END X509 CRL----- ------BEGIN X509 CRL----- -MIICLDCCARQCAQEwDQYJKoZIhvcNAQELBQAwgYExCzAJBgNVBAYTAlVTMQswCQYD -VQQIDAJDQTEMMAoGA1UEBwwDU0ZPMQswCQYDVQQKDAJNQzENMAsGA1UECwwEcm9v -dDETMBEGA1UEAwwKcGFydG5lcmJjYTEmMCQGCSqGSIb3DQEJARYXcGFydG5lcmJj -YUBwYXJ0bmVyYi5jb20XDTIxMDcwOTE5MTIzNVoXDTIyMDcwOTE5MTIzNVowTjAl -AhQTZhDgbKuvX7iLRUBBTiWXBPKM1xcNMjEwNzA5MTkxMjM1WjAlAhRfayZVPVOi -XRSHiv8UaI2qMR3XORcNMjEwNzA5MTkxMjM1WqAOMAwwCgYDVR0UBAMCAQEwDQYJ -KoZIhvcNAQELBQADggEBAMIltmJ036f1BmK/baISJTZTu7PKZgSZMNORnpFT8KvC -s2GNRor5bGp5qvD6LHvsx92YVppCC6xd/beCFBtdyYifqw5xtOvqLQKuqCfxruLz -EqYjKXE/3v8VdyU71J7kFqi0U0Gy4/h/YCL92e5KNbATlmcn5ToyI2EBIEfBfV08 -mm7FBXvbHRzqhfrnCNEjBWBWz3zkJMc9Rib26eCCofYIDkY2HvYSN78YgrnMmD6O -hWOXrPoxArxvmDr5rG4vCadqbQYRkkCAOP0hBeMiB0SAcO2W2LNNAmHWXX7FvU3n -ZRZUX31WoVjhNeEQtNBb2mPYBXHQzLC66qYm1p97afc= ------END X509 CRL----- diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/validator/keys.p12 b/acceptance-tests/tests/src/test/resources/pki-certs/validator/keys.p12 deleted file mode 100644 index c3be57147fe26d8a513c90423b409425b7f9ed0e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6032 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 C>~C%W diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/validator/keystore.jks b/acceptance-tests/tests/src/test/resources/pki-certs/validator/keystore.jks deleted file mode 100644 index 4fb942a9e0f1a55765b331f784473df9271af34b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6773 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 J0LYQ~{{o6$?4tkx diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/validator/nss.cfg b/acceptance-tests/tests/src/test/resources/pki-certs/validator/nss.cfg deleted file mode 100644 index f3849919ca..0000000000 --- a/acceptance-tests/tests/src/test/resources/pki-certs/validator/nss.cfg +++ /dev/null @@ -1,6 +0,0 @@ - -name = NSScrypto-validator -nssSecmodDirectory = ./src/test/resources/pki-certs/validator/nssdb -nssDbMode = readOnly -nssModule = keystore - diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/validator/nssdb/cert8.db b/acceptance-tests/tests/src/test/resources/pki-certs/validator/nssdb/cert8.db deleted file mode 100644 index f1aa64c06cae6ebc6fa426cc3fe372cebe220e26..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 65536 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 J5MaB&e*ngi^fUkf diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/validator/nssdb/key3.db b/acceptance-tests/tests/src/test/resources/pki-certs/validator/nssdb/key3.db deleted file mode 100644 index cb2eb74985dcd253546ee476487162909ca25d0e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI%Yc$mB8UXMa#&u-aC__@oRxT^Tl)*`pkr3LsXUJ__W;D!*C_9%O36-63zs4|f zja-r;a=%k1w+?b2B*KI(htBzMKA#Vrwby!|wVw4n>;JxMJ@5K``mgteaEm!WAP^1+ z1lA9M2<^2H0SE-TSN0Ra`=4fS{l^E+AN9u)1h(H(Zw5~8)&1Dtv!6dbc>jH#pFS51 z1Oh++2mk>f00e*l5C8%|00;m9Anz9CqM3Pe649&vv!cR>IFAOHk_01yBI zKmZ5;0U!VbfB+Bx0zXHf z3KUT~{iL3fxG13p=UT8-NrJ%T!}P=02cQC6P)=!6bGyZG=D>!U|MGHmf00e-*|0KW(;rDeQ zx;s1gkjN0_5ZH$DN$&steN;xmL@lm&rq*bRl?RR2MN_Yq+He=B=@HB58CSipEojUo#0G}!0z>9uX)jE&o zw`r+;9~q^rOItHT2ROGVT`~`>P|GM(Z(I2VgqKc+?dRLU^7xihxAP>F7ya`pa7|5eJ^#oM+j67BDdf!*eQ(;9zh$2&Bg>7}(-Jr2 zC6oROSC3IbPLTHs4Hp*Z`Kb5wW|v-*ik5upgX##HYMCHcKHhHb1)F7%=6+8R5*pOv zi1#z6g=NV_Te#|(DcJ9(hbmGn5p>lX>h~(sgc`GRzXutnw6&if9Xk};&TS*#5nr>u zLJ88auBjwSKB_bnXp!$4;-$+vE14y$YYGDt2d`H>sV`p9D*HK4nPJ6Q52uWJ(YDqvoAH zERSOPQ{fGFHc4;+@~Bm&2x3Xh{Zu94kMeTEjH0>>-T*P}1{pltr88;io2OtzYof-L zU;pyOai1xzGCi7ojh!5|{+SoS17&SrPqfSw^84!Jj+-`-9Gd>Z(b#=LNZ!oYFfGmR zT~)F5GKM*l*M8Atz=vB#!B-Jp^^s~rm{4!LVA-R%(mTXil-o00Nwdq0qu|ce?r0r_lv0y>%kINT*6Oj3ZKQevL((19pRX`@ zWQ4`hH904IvobBtZ6UK`xY(={S!yX*5i>zie=xvwKJ3)jZs$Rk4eeauLm!ezTALrt zKH!o#tvP#g+m&TOUW93vb;QmT8;WsScE2+bXAaGeNlDond#>R`rbImdc-Ru|A+}oe zM1}aIP29$Wf3~<4qlVEk&Fy{8IGjNbXpZ3->rlFSui)e_cw z=MG_tGyDkJzOkfOe=(>len(ijbw$4K-W=bCn5+1BK(EmvddO&KDfjsZ5;=K(yNgjm zV?`o=H#Ts6+`-gL*!nggI`c%izB2NmoHMTDt8e%jr)LaIp0Mw;4-#xLv$ZSd>$$1s zvs>$_W45(oJ~FyS3+_whRvrmqli1?N_UQ8JG3#}ad;d6>8OC8YSn#&(BbG+kl#0td zCt4XjCxCg=OwN{gMYSbi=PWd_{OhEWq^RP0zB`4r*_frPUCozPkVFP|So(C4UxH4{ zj$>D{F1I<*YLD3t>35zt%p7_3O8&@)vU^yD!&?+OLmiH$5O|c&R?OSuH{7`$sG}#pJKO z#)`w@B{I-H#3TW7yOsT2fp7-H2Hi(HQm{IzG{0qBV#sHA;md^fz^(0|NUNC3oP*)f z7L=?Sg~3GQ?vB~3iL{a+yR)w)RVQ6%MsTP5bc9QM9DCuy%n4ckZX;OPC06?wO)uRo z;llMyxEK%VcMH!{*p5l(a`p*jAL}xL(72H7E2U&K&fShly>9WFn%sd=r_{k%W=Aq^o@?jl+-HC(KmZ5;0U!VbfB+Bx0zd!=00AHX1c1Q*QQ%)< C_@u-D diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/validator/nssdb/secmod.db b/acceptance-tests/tests/src/test/resources/pki-certs/validator/nssdb/secmod.db deleted file mode 100644 index c51600ebfcfe5e2003875fe46a053ccba4c7dd09..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 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 T;=|Iy)!Bv=_7WNZH3t44NI<;k diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/validator1/nss.cfg b/acceptance-tests/tests/src/test/resources/pki-certs/validator1/nss.cfg deleted file mode 100644 index b908a6800f..0000000000 --- a/acceptance-tests/tests/src/test/resources/pki-certs/validator1/nss.cfg +++ /dev/null @@ -1,6 +0,0 @@ - -name = NSScrypto-validator1 -nssSecmodDirectory = ./src/test/resources/pki-certs/validator1/nssdb -nssDbMode = readOnly -nssModule = keystore - diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/validator1/nssdb/cert8.db b/acceptance-tests/tests/src/test/resources/pki-certs/validator1/nssdb/cert8.db deleted file mode 100644 index c9633c714184d2e157136369f26fd5eba4a63c5d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 65536 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 BLAn3{ diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/validator1/nssdb/key3.db b/acceptance-tests/tests/src/test/resources/pki-certs/validator1/nssdb/key3.db deleted file mode 100644 index 2b98e97f3b00199635526bf32492b92a9a270515..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 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 E0sNwjEC2ui diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/validator1/nssdb/secmod.db b/acceptance-tests/tests/src/test/resources/pki-certs/validator1/nssdb/secmod.db deleted file mode 100644 index bc3748fac0570558d7936a34046ac8664a8ce093..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 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 BZI}Q6 diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/validator2/keystore.jks b/acceptance-tests/tests/src/test/resources/pki-certs/validator2/keystore.jks deleted file mode 100644 index 414b903e13363bff556f75c2610ff1d0a4af736b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6783 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 diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/validator3/crl.pem b/acceptance-tests/tests/src/test/resources/pki-certs/validator3/crl.pem deleted file mode 100644 index 8ced006c91..0000000000 --- a/acceptance-tests/tests/src/test/resources/pki-certs/validator3/crl.pem +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN X509 CRL----- -MIICBDCB7QIBATANBgkqhkiG9w0BAQsFADCBgTELMAkGA1UEBhMCVVMxCzAJBgNV -BAgMAkNBMQwwCgYDVQQHDANTRk8xCzAJBgNVBAoMAk1DMQ0wCwYDVQQLDARyb290 -MRMwEQYDVQQDDApwYXJ0bmVyYWNhMSYwJAYJKoZIhvcNAQkBFhdwYXJ0bmVyYWNh -QHBhcnRuZXJhLmNvbRcNMjEwNzA5MTkxMjM1WhcNMjIwNzA5MTkxMjM1WjAnMCUC -FF9rJlU9U6JdFIeK/xRojaoxHdc5Fw0yMTA3MDkxOTEyMzVaoA4wDDAKBgNVHRQE -AwIBADANBgkqhkiG9w0BAQsFAAOCAQEAfByR//FGHSsVQbaS51d59o82XocOGnnT -p1hjceqtLGv3bhiebVrsRCOB5TsvE/r2IbB/yHYTe3+LJisIUqBxblQ6xK6IM+qA -3fY646YnPT5pvdZAPZ2BCN/xP3xqGffFKapQ9cz0/36YE3vaEoUDlC2VHK0OXI0t -4CLwAmiptUT2GW4Bk1RtokAsFiUNwNIOlRX5bywUNwkG7EuitR90QSGH3l/vyii2 -0c1Fm9He9MskwipjXpJKKb+t+m1pdpOVkSjRfjmVqi4BZwWlnQjELSLywhJ+WZG2 -Z1NgRjzPXotFKK+YD97Kx1L260A1eUZ46zSq73oUZr0EDZRnNJTr6A== ------END X509 CRL----- ------BEGIN X509 CRL----- -MIICLDCCARQCAQEwDQYJKoZIhvcNAQELBQAwgYExCzAJBgNVBAYTAlVTMQswCQYD -VQQIDAJDQTEMMAoGA1UEBwwDU0ZPMQswCQYDVQQKDAJNQzENMAsGA1UECwwEcm9v -dDETMBEGA1UEAwwKcGFydG5lcmJjYTEmMCQGCSqGSIb3DQEJARYXcGFydG5lcmJj -YUBwYXJ0bmVyYi5jb20XDTIxMDcwOTE5MTIzNVoXDTIyMDcwOTE5MTIzNVowTjAl -AhQTZhDgbKuvX7iLRUBBTiWXBPKM1xcNMjEwNzA5MTkxMjM1WjAlAhRfayZVPVOi -XRSHiv8UaI2qMR3XORcNMjEwNzA5MTkxMjM1WqAOMAwwCgYDVR0UBAMCAQEwDQYJ -KoZIhvcNAQELBQADggEBAMIltmJ036f1BmK/baISJTZTu7PKZgSZMNORnpFT8KvC -s2GNRor5bGp5qvD6LHvsx92YVppCC6xd/beCFBtdyYifqw5xtOvqLQKuqCfxruLz -EqYjKXE/3v8VdyU71J7kFqi0U0Gy4/h/YCL92e5KNbATlmcn5ToyI2EBIEfBfV08 -mm7FBXvbHRzqhfrnCNEjBWBWz3zkJMc9Rib26eCCofYIDkY2HvYSN78YgrnMmD6O -hWOXrPoxArxvmDr5rG4vCadqbQYRkkCAOP0hBeMiB0SAcO2W2LNNAmHWXX7FvU3n -ZRZUX31WoVjhNeEQtNBb2mPYBXHQzLC66qYm1p97afc= ------END X509 CRL----- diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/validator3/keys.p12 b/acceptance-tests/tests/src/test/resources/pki-certs/validator3/keys.p12 deleted file mode 100644 index b36ede08e5ab569a284ff976e23079b00c827f1f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6034 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 uauZ>o(_#XE6w>Q;(y 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�?O8?s2jl&ezK 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 HzQ8{LKjB5t diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/validator3/nssdb/key3.db b/acceptance-tests/tests/src/test/resources/pki-certs/validator3/nssdb/key3.db deleted file mode 100644 index 6414460a69c30d002e7d87ea579da8e887572e0e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI$XHe5y769;nAdpZbbe8hKClEjg(j*WR5ETT1)I}gDL~7_gqS6BR=tVk6e~J_< zQlu{~is5b{68xAX5CjNkM3BM5$6XLyCY`<9R6_|EbA;eq`3JU_fIXb1#= z01yBIKmZ5;0U!VbfB+Bx0zlxeB7lSrQ2VGAR4u9!m4(XUNM;FUNoM&90tf&BAOHk_ z01yBIK;Xv+FhXoWL=Tc9F~HkT8B(CYcNL_W*-qcPa&PYhjGYO_s2~XE)!&YHLY+$R z)=~F9JniCuP8F(NV}QZn6nM`A5!+tDt3AGakBAJr48=`m%jnqrpF5(r-{=s!m7iw^ z_qSp1eZ_t(}Jzx$i;d!}Cp_@1xwJ3>){N_I>~7pF)SCU&OkzH*bCVdOoA()vaF zv*WK_qUcnyFY9_2Tq0#xW^!<`hczz-r*2XH{lE`@&A9S59tYt%T z-OcJ!cT-D1koC;eO>0wKT1b=fE*B+*qH1Q-)xRMyQ-J)%fKNIA`N!Nm^Xnj(75;L6d!upnC1^4!~q~66XKIJHz7u!=~P^)P(a!DxU>Eji_JX zeic3*UUQn&R{m7EwzzU5Mz(90Unv(Wi)ixtrE(+BLhR4ZUT?E@x*SzLokIRdBoxnz z4KFrQYO3F1mUHr>9Rv#D>^@42QxvZz5%e(W4b5)wnn-y8l+bbdYmw~EoTA!`pd%H& zwzt0}XV|RhCFFl((C6hZ5hGxDLV9pH^cNpI)s@y0{A?d))xFBim|Ji=|B1ezw<(f7 zI-8!TuM{;YTzOHWgr9R1Up1k?_AG_TL=cumqb!LYwCcV*K^PLcT+I;38$i13UsX7O zJ9k7Iy}jnC(RqY>bzULj!t`p5mFJ^nXTyUX(gs!6t(`e`Z#$dpAmO`!r`~3w?pK@M z>MP}mn7RMLBAO(Mn=-$S5*pf3+gF$6d=_aVtr@n~-4n=VPI5WS$uNsc_#(+@6?cZ0 z$61lf04*M1h_jcBd3W)}p=!5gM<u) zo@?Mhm1&o>4`{shGm6{|y+w2P^9*8hERDVwWy z`GH&sU6XP3%z;VhgXUqbvv(R1*JOmL8Lrgv)|Rsfnnd_?*tm;smaA4(hxAjvLu6gA z5H8n?uRNh=f>k`Az;4Zzw$SWxQr2>1jHyE{xv+kHumRgx4xyjQ-@`o%4Z*F$3ACZ< zSXYVMNy)9%@wvc%tUpw+=!(Ae2fe_uo3F+clBsJJnLdSU!1@ula@|WC1uJY*)I9u} zaAjGcU5|SOd&g>1Z}94x{60mlPQ%EeZ5USZ64+{~@hXh&hUy#z;j_jXCgU^v6Ze#L zrq)PE?3EBsDfm{*aOX(2|LQqa`(SgP>?F1s`(b;SZBn27$v}>sg=7|(F>QgVSE9S4 z$Zj`Xzw4G-9=l(RX8%!M?At|O<00`wl)-v1Cn+9rgyIt8QA029J1$%_DLJL{r;{}8 zL!N1?t8sBZRfszZmG-5Na9fUiX%-^bg|>!tP|Ih|C>Si>54%h2HEO0JJ_i}zl$X2C zJf~^3auq#|EDF6zck%GPN%X+@6FmYLd0{sDt+K2`6IfxP8oPtP*+g{pYb8Vf{Zh=Q z5Oa(a3sb9>4u+RS?a)3%e}A&KpCiV>)yct~(bCD!pXBZJSNW#^a{>V%00e*l5C8%| z00;m9AOHk_01yBI|GU7^kNMXIU4Q@(00KY&2mk>f00e*l5C8%|00;nq|D(Xa0Hkz_ A$^ZZW diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/validator3/nssdb/secmod.db b/acceptance-tests/tests/src/test/resources/pki-certs/validator3/nssdb/secmod.db deleted file mode 100644 index 75bd6e3d96d9b279614832801245ccc20f2996cf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI&O-jQ+6u|LkmD+_=H||6RTx8c$+zDCLjTEI&FOVkF5}GC@Nu@44hI`K;u6qEl zpvO?^Bva8Mx-3Qh1CRN7c{B4{N2-UOh*U&&o<$DKQ1(Q&Ojm@|mIJe2E^L>5xn+~? zIVs+ADQzLg#xm zyA+ywpPyVOBORaX%umBf9wu?IWB2h9mghqw7=f|zMvt100IagfB*srAb diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/validator3/nsspin.txt b/acceptance-tests/tests/src/test/resources/pki-certs/validator3/nsspin.txt deleted file mode 100644 index 5271a52680..0000000000 --- a/acceptance-tests/tests/src/test/resources/pki-certs/validator3/nsspin.txt +++ /dev/null @@ -1 +0,0 @@ -test123 diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/validator3/ssl-ca.pem b/acceptance-tests/tests/src/test/resources/pki-certs/validator3/ssl-ca.pem deleted file mode 100644 index a5fdc343f5..0000000000 --- a/acceptance-tests/tests/src/test/resources/pki-certs/validator3/ssl-ca.pem +++ /dev/null @@ -1,70 +0,0 @@ ------BEGIN CERTIFICATE----- -MIID8DCCAtigAwIBAgIUcATI/N49JsZyAuyS8gfW6BppdBMwDQYJKoZIhvcNAQEL -BQAweDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMQwwCgYDVQQHDANTRk8xCzAJ -BgNVBAoMAk1DMQ0wCwYDVQQLDARyb290MRAwDgYDVQQDDAdpbnRlcmNhMSAwHgYJ -KoZIhvcNAQkBFhFpbnRlcmNhQGFkbWluLmNvbTAgFw0yMTA3MDkxOTEyMThaGA8y -MTIxMDYxNTE5MTIxOFowgYExCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEMMAoG -A1UEBwwDU0ZPMQswCQYDVQQKDAJNQzENMAsGA1UECwwEcm9vdDETMBEGA1UEAwwK -cGFydG5lcmNjYTEmMCQGCSqGSIb3DQEJARYXcGFydG5lcmNjYUBwYXJ0bmVyYy5j -b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC+31Xz+vdtagGGF4Zs -JPzLNkPRWUZ2aB2nB6O3GFFItRERIeKQQ809jpuWb+3nPwmHgAeu/5KDuHExXUp3 -zsq/pBhjmIxysN/tSB0ZWgnDZj0T/O1cFxmFPSIQi2YqN9ex/k1P0A/bPLYid6sp -BrMB2oDuemjG9OL8zwWxTWFstwMZgh+PUoLv4xPt3vnv8hiBvMxIRe2IjseFRvR9 -zoaxAW94oeLPngPgWanUZvU+hL0BR2h0RZbsmPciw4K7PzHKCfOnDcJN3/k32GuQ -1ETYXVqBZstMwZ/yUAZzHDUFuungfM/VyuVVqjV1Njmi1ulrZNaLj3pe+x0WwrXq -VbgfAgMBAAGjZjBkMB0GA1UdDgQWBBRoOd/JgcA/UZW816OxlkI45xhLJDAfBgNV -HSMEGDAWgBTdAXu8aBbvkvxYD5Ss9/Ml5VgohjASBgNVHRMBAf8ECDAGAQH/AgEA -MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAQEAbIUXWJ1SU2cwnGfJ -gor9Y3QX8q3bLRBQ6nuVXUhyHtOKnecEYY+6cvTgAy4tcaEbTrmXnIwwddzWXR5c -IEgpem6t9tJqjvDZ3SMmlIf57L/rKp1rQQXmOBm2fBy86zC6RChYMshf9LQ3pCeZ -kESZ+WzHqmTDe2vpe3AaZTsGy+HucyVv5Ha5WLATFMPSMbY76sMbFDEr8viskCNm -JzDvYbqHMfZUJu4eiWiRJ8v6GY1HJ8SJrFUz2ry6WNYiizoEABHC8VrWV+Kss1Vq -MiFfAZND4wBS5TZmaKi4BQt/+cnUAX0ej6wYSug/+Atz9DSu/b+AsEZ5tXnxDMGO -vqwj8g== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIID6jCCAtKgAwIBAgIUYdazVD+VnI7jBu7xLaW+npfwHJIwDQYJKoZIhvcNAQEL -BQAwfDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMQwwCgYDVQQHDANTRk8xCzAJ -BgNVBAoMAk1DMQ0wCwYDVQQLDARyb290MRUwEwYDVQQDDAxyb290Y2EuYWRtaW4x -HzAdBgkqhkiG9w0BCQEWEHJvb3RjYUBhZG1pbi5jb20wIBcNMjEwNzA5MTkxMTU0 -WhgPMjEyMTA2MTUxOTExNTRaMHgxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEM -MAoGA1UEBwwDU0ZPMQswCQYDVQQKDAJNQzENMAsGA1UECwwEcm9vdDEQMA4GA1UE -AwwHaW50ZXJjYTEgMB4GCSqGSIb3DQEJARYRaW50ZXJjYUBhZG1pbi5jb20wggEi -MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ8QgVwEjy3CgJFvET7tYNBw97 -4i33EHQT4ZuayGCJ+ADY3ZFpsw2M1IPlbAguqfBkcLd8TAjWNRAdsm9ubGlIcTZr -7LNle3gvc7qEP4qg0i6M7D06CDqtBaIJ1PMTJchOouGU9ntBe+h0qg8tzpiqJdIw -jIOPRWW98Hw9KgF6++2jtlcOW1IxiFSWqf0Mpc81qKukcxnsHjvdxmBp/Z1vL42E -m5xNOGXoxpjq8NygSuVDhQ/bZUnmHLmvv9MXe9Ob52rlzea/YafLpOeNGSA1aCxm -Fx0lcoXWp4xpoyJn9St7vmH3t7quBKdqt54zwcuHjhgZPSR6RikodKHtsl8TAgMB -AAGjZjBkMB0GA1UdDgQWBBTdAXu8aBbvkvxYD5Ss9/Ml5VgohjAfBgNVHSMEGDAW -gBSMsBNO3UGBteMZOTq5fDPG2aPx8DASBgNVHRMBAf8ECDAGAQH/AgEBMA4GA1Ud -DwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAQEA0hJCtrCI9Mf47+y3pvsTjiaT -TZwpNE0cdxHjpcCHJWX2jmGbqqA6wvQ7yy4PFarmnFOoW3hQFeiLgpz9X86YTRzF -8dj3Q2MKXf6i6/iW+Y96GFqurshKp7wV25wfzWwLXcVCiM1xYPWYSyGsZAGotu4M -c7uolVABjJu5nci9mBxVmaYV5oT1mxrvq3dCPm2AvmVFNWPNRbMSAuT5B7FUDvWG -xvd1aDFduqL0iLAcrTifMIYI3XL4pBSIlL78dgY45WL6616EF3mHhW/Y4k4PNq1I -Fz08Q3y99ilhzeAci1jv6KBVHiALZNFFtYjd10KX95qnF9SomBjCTPsQ9PTC5g== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIID2zCCAsOgAwIBAgIUdxRGMrv1ONRI/dJXUHa3isjVXuwwDQYJKoZIhvcNAQEL -BQAwfDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMQwwCgYDVQQHDANTRk8xCzAJ -BgNVBAoMAk1DMQ0wCwYDVQQLDARyb290MRUwEwYDVQQDDAxyb290Y2EuYWRtaW4x -HzAdBgkqhkiG9w0BCQEWEHJvb3RjYUBhZG1pbi5jb20wIBcNMjEwNzA5MTkxMTU0 -WhgPMjEyMTA2MTUxOTExNTRaMHwxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEM -MAoGA1UEBwwDU0ZPMQswCQYDVQQKDAJNQzENMAsGA1UECwwEcm9vdDEVMBMGA1UE -AwwMcm9vdGNhLmFkbWluMR8wHQYJKoZIhvcNAQkBFhByb290Y2FAYWRtaW4uY29t -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Bqlx+ngRZfWjktX6urJ -Tpg2//n3uMW8Gp55SVq+lbpkNXuA3W0uTlom/2fsnzmMmBAJUvv/NaLcFSN++0/d -fYGVhogxjlRoyaXa4sdFPg2ocM+lCHLGhWpYuVdTWPknikTOVNbh9z94SLRfrP8N -kuxGNZNktnVm+QJmrCLmjvnPvQlcP/WqFYehFM26NaRzswOhLLRU1YK8aVlh9Vto -PGSTPtZK60XwTfyCj/zEvHqpbGbKJPp7W0rpxl7ehPQIzGQt5IMH3zKrqLm4/pt+ -XFEVqy724sstthS73bvXguWxBLOzuMze8CbI6SJpcHaH8HO5pfFMPyE5N5l2x9Co -uQIDAQABo1MwUTAdBgNVHQ4EFgQUjLATTt1BgbXjGTk6uXwzxtmj8fAwHwYDVR0j -BBgwFoAUjLATTt1BgbXjGTk6uXwzxtmj8fAwDwYDVR0TAQH/BAUwAwEB/zANBgkq -hkiG9w0BAQsFAAOCAQEAL9/7YtxIbuTt7dgH1KOMb/y6P3Qb79fTVZTx073E2ZBj -OfSuMGUhKC30LWQXCQEsY4WpugJ4cS0NsArSYsO5XWguqgjYlWL6poOmYhGvj7ou -oi44oYqcPm6EbvLrAKdI67bkbSPLzgs+6TrxTyXHzPKFBqGBnuHaFKjgb4hGiPmd -JWKrh3fbTtuLjqSHd0Gey2uBNFql4LhPutdsCUhSOD3BibAeTbXyln70AgpTCoWT -9Qr9Ux6HYIiAHSDBzzuN8EcrlnAm9RO4zRyUVwxDsHoNsOUwybn50IM66p83HuiY -h/iX5uNjaFAADfRR4rQOwb6MLreVH2XYUSiz4M/ijg== ------END CERTIFICATE----- diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/validator3/ssl.pem b/acceptance-tests/tests/src/test/resources/pki-certs/validator3/ssl.pem deleted file mode 100644 index 474187b0e2..0000000000 --- a/acceptance-tests/tests/src/test/resources/pki-certs/validator3/ssl.pem +++ /dev/null @@ -1,126 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDW0t2JaCSa2iXy -7Njgdb7vpTBUxYV44tueVscVtVEAKbe9HN0iOro3cmHymmujuxmqXJA4bHK8OqeX -fsWoyhnK17aRXhRGUNHcd7OTLSsmWgLsTCQ3syfYrC1G8Dbgggdw7gp/KXDfHRLc -WZY/1H2JSH0QJwTyiNPE1Jhz7Dw2YHlTE5iOC95g02ABXI7LLiB1DvTkjwkBT9bk -Bcokx8OgX/aUScV4OJsMcog+zf2bic/lcU/SI/wPSu95EGmLB/0PER8TOCbp+GTk -Q1CiIkL1ZSjW6JtRwGhPoc3JGhKED5P+y1t6LHdE3wBbX37AfcPJqd4vMErlkn98 -1spNvckHAgMBAAECggEBALhlG5/ccr8wzS4tuyNALnqJsmixexX+tEC/f/fUQQkA -xiRf6Dh/bGQ3nHefsRFDgo5HEcw82mdTeZOCT6vIfkcszhsNRB3vNZQmc0+7j7RF -wwiNevEMqQFFGUAw5Qnk0vpOeVgZfDcnP49AnsV/YZo7TI5Wz9pXNF9ZlNq8Rhrt -NYTF92vzWfrCskQnYL2Tn29qUTWIvsqq6wt7oR0NKwTfbm4420ZGbpAKgtVWsnXN -13nRhAgB7aNEAAXn9FsRjn/aVaOLWv8rfL7AnWx/DREMOBOKNUIW7mkT4xwNFrnl -kVS4mjnMRVtMG+/xK781E9voJ+2GYXiCE3ldEY1ZhDECgYEA9I7ej9ZWYLwnf6jS -IsRDWLwqLsy5upHv88zeqGTNR/kiO8On5+GMaFT93II53TQk+gLBTdmUYR1jYdq+ -raR9nOSVjV35kE747NZIhqRGkMCJg3qLLF7haK5bvynAD60dIpme6IiDEKLjgPmr -k2CQo0rPIASed+vXpdYVYGVsaMUCgYEA4N/cLv/Mi59tAdFNUaxyIAVgFD++bG1r -RkJmhYcCqj563kIRhqd+YtWhtedeBMTrmMBztd/1p1qjUmnB/drhvl60J+4WoULR -1YSA1hLOz25iGTBEPJH05115hD4OC7o2R88NdC4TYizIqzSbyuYIw3kTLGDzO9b9 -wYaR4+TdD1sCgYEAo8a985O1uwimZw6200OeWmGA2mCODQzIpfvQLPN8qjOEooNw -AZEBx6kLbU3k1GekT63iqHEKtlLJCHJGeeELojNOmCKUC/lnKKyEW27ONwhJzzwU -0f0kdUc29/lMvvLO7Sn1yoIJS+3Z77jEF2l203Q465dMTMErZMrO/ARQKoUCgYBW -n0T0wcpsGjxmT9al2HSZyxhIlIlowPlqthdB5lDrfWfdB7wyj4CK19oT9Qztb2GF -lNS9wYiiL7LsAxscC12b9GUXYIpNEi08P29VhyctFkspgsM2Rc799K7jdvf4IoHY -RXTcRQdocPHXqUs97ECB87ikBrCLY3SaQJkgHT/eMwKBgGRqRCW3J+DHaGYVrfFh -jTtVnMAw+eNMrfEzbueav8XYFDA035lHANMaW1ImCEnGcNxTKTNHYlEI+GJGlf3j -nLyFxHt2t7t3EH+Z1TRBpTWcI9NIBA9suGSwHF6JSYYoP/XycknvHR3CKnptVqEh -2BvRskmyqDqlJ3or8iilBVG4 ------END PRIVATE KEY----- ------BEGIN CERTIFICATE----- -MIIEvjCCA6agAwIBAgIUeHwvCYkMzLzluPyGlFa5V/lmFnowDQYJKoZIhvcNAQEL -BQAwgYExCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEMMAoGA1UEBwwDU0ZPMQsw -CQYDVQQKDAJNQzENMAsGA1UECwwEcm9vdDETMBEGA1UEAwwKcGFydG5lcmNjYTEm -MCQGCSqGSIb3DQEJARYXcGFydG5lcmNjYUBwYXJ0bmVyYy5jb20wIBcNMjEwNzA5 -MTkxMjE4WhgPMjEyMTA2MTUxOTEyMThaMIGBMQswCQYDVQQGEwJVUzELMAkGA1UE -CAwCQ0ExDDAKBgNVBAcMA1NGTzELMAkGA1UECgwCTUMxDTALBgNVBAsMBHJvb3Qx -EzARBgNVBAMMCnZhbGlkYXRvcjMxJjAkBgkqhkiG9w0BCQEWF3ZhbGlkYXRvcjNA -cGFydG5lcmMuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1tLd -iWgkmtol8uzY4HW+76UwVMWFeOLbnlbHFbVRACm3vRzdIjq6N3Jh8ppro7sZqlyQ -OGxyvDqnl37FqMoZyte2kV4URlDR3Hezky0rJloC7EwkN7Mn2KwtRvA24IIHcO4K -fylw3x0S3FmWP9R9iUh9ECcE8ojTxNSYc+w8NmB5UxOYjgveYNNgAVyOyy4gdQ70 -5I8JAU/W5AXKJMfDoF/2lEnFeDibDHKIPs39m4nP5XFP0iP8D0rveRBpiwf9DxEf -Ezgm6fhk5ENQoiJC9WUo1uibUcBoT6HNyRoShA+T/stbeix3RN8AW19+wH3Dyane -LzBK5ZJ/fNbKTb3JBwIDAQABo4IBKDCCASQwEQYJYIZIAYb4QgEBBAQDAgbAMB0G -A1UdDgQWBBSl7BsGlNKcg8bg/9K/Pt6beFmUbDAJBgNVHRMEAjAAMA4GA1UdDwEB -/wQEAwIF4DAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwgbUGA1UdIwSB -rTCBqoAUaDnfyYHAP1GVvNejsZZCOOcYSyShfKR6MHgxCzAJBgNVBAYTAlVTMQsw -CQYDVQQIDAJDQTEMMAoGA1UEBwwDU0ZPMQswCQYDVQQKDAJNQzENMAsGA1UECwwE -cm9vdDEQMA4GA1UEAwwHaW50ZXJjYTEgMB4GCSqGSIb3DQEJARYRaW50ZXJjYUBh -ZG1pbi5jb22CFHAEyPzePSbGcgLskvIH1ugaaXQTMA0GCSqGSIb3DQEBCwUAA4IB -AQAM49KuL0GR6f9O6bS8YkPNcNcOP3y5AbGzV08boCHcnL0iJmSyUoYwD4ksEj+Z -41YcBOGtPE++MR27LvpMXV6wMoJvmg4G97M1Oql+fs+eZnKyWRuQSWoCLUpsh5Cq -j9QUHv95xUyadH3HSQnDHd2Khhsu60MEqF6wuyU+EsjoNp5Ejsmk0DDWobXPwA8K -WaqyleZOjA52HeRwAeextO9Zvv4yJX/I/DeGf3LTPz8IAE0rLXROpEj31rX0CeKA -BPiBVVn0qRTeimjm9G22AUwKKBNCta2plMkbq2shHAKTXWzI72aW6kHHG35zdXWV -qnQZrcVShlqsexiZAGRfKqsb ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIID8DCCAtigAwIBAgIUcATI/N49JsZyAuyS8gfW6BppdBMwDQYJKoZIhvcNAQEL -BQAweDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMQwwCgYDVQQHDANTRk8xCzAJ -BgNVBAoMAk1DMQ0wCwYDVQQLDARyb290MRAwDgYDVQQDDAdpbnRlcmNhMSAwHgYJ -KoZIhvcNAQkBFhFpbnRlcmNhQGFkbWluLmNvbTAgFw0yMTA3MDkxOTEyMThaGA8y -MTIxMDYxNTE5MTIxOFowgYExCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEMMAoG -A1UEBwwDU0ZPMQswCQYDVQQKDAJNQzENMAsGA1UECwwEcm9vdDETMBEGA1UEAwwK -cGFydG5lcmNjYTEmMCQGCSqGSIb3DQEJARYXcGFydG5lcmNjYUBwYXJ0bmVyYy5j -b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC+31Xz+vdtagGGF4Zs -JPzLNkPRWUZ2aB2nB6O3GFFItRERIeKQQ809jpuWb+3nPwmHgAeu/5KDuHExXUp3 -zsq/pBhjmIxysN/tSB0ZWgnDZj0T/O1cFxmFPSIQi2YqN9ex/k1P0A/bPLYid6sp -BrMB2oDuemjG9OL8zwWxTWFstwMZgh+PUoLv4xPt3vnv8hiBvMxIRe2IjseFRvR9 -zoaxAW94oeLPngPgWanUZvU+hL0BR2h0RZbsmPciw4K7PzHKCfOnDcJN3/k32GuQ -1ETYXVqBZstMwZ/yUAZzHDUFuungfM/VyuVVqjV1Njmi1ulrZNaLj3pe+x0WwrXq -VbgfAgMBAAGjZjBkMB0GA1UdDgQWBBRoOd/JgcA/UZW816OxlkI45xhLJDAfBgNV -HSMEGDAWgBTdAXu8aBbvkvxYD5Ss9/Ml5VgohjASBgNVHRMBAf8ECDAGAQH/AgEA -MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAQEAbIUXWJ1SU2cwnGfJ -gor9Y3QX8q3bLRBQ6nuVXUhyHtOKnecEYY+6cvTgAy4tcaEbTrmXnIwwddzWXR5c -IEgpem6t9tJqjvDZ3SMmlIf57L/rKp1rQQXmOBm2fBy86zC6RChYMshf9LQ3pCeZ -kESZ+WzHqmTDe2vpe3AaZTsGy+HucyVv5Ha5WLATFMPSMbY76sMbFDEr8viskCNm -JzDvYbqHMfZUJu4eiWiRJ8v6GY1HJ8SJrFUz2ry6WNYiizoEABHC8VrWV+Kss1Vq -MiFfAZND4wBS5TZmaKi4BQt/+cnUAX0ej6wYSug/+Atz9DSu/b+AsEZ5tXnxDMGO -vqwj8g== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIID6jCCAtKgAwIBAgIUYdazVD+VnI7jBu7xLaW+npfwHJIwDQYJKoZIhvcNAQEL -BQAwfDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMQwwCgYDVQQHDANTRk8xCzAJ -BgNVBAoMAk1DMQ0wCwYDVQQLDARyb290MRUwEwYDVQQDDAxyb290Y2EuYWRtaW4x -HzAdBgkqhkiG9w0BCQEWEHJvb3RjYUBhZG1pbi5jb20wIBcNMjEwNzA5MTkxMTU0 -WhgPMjEyMTA2MTUxOTExNTRaMHgxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEM -MAoGA1UEBwwDU0ZPMQswCQYDVQQKDAJNQzENMAsGA1UECwwEcm9vdDEQMA4GA1UE -AwwHaW50ZXJjYTEgMB4GCSqGSIb3DQEJARYRaW50ZXJjYUBhZG1pbi5jb20wggEi -MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ8QgVwEjy3CgJFvET7tYNBw97 -4i33EHQT4ZuayGCJ+ADY3ZFpsw2M1IPlbAguqfBkcLd8TAjWNRAdsm9ubGlIcTZr -7LNle3gvc7qEP4qg0i6M7D06CDqtBaIJ1PMTJchOouGU9ntBe+h0qg8tzpiqJdIw -jIOPRWW98Hw9KgF6++2jtlcOW1IxiFSWqf0Mpc81qKukcxnsHjvdxmBp/Z1vL42E -m5xNOGXoxpjq8NygSuVDhQ/bZUnmHLmvv9MXe9Ob52rlzea/YafLpOeNGSA1aCxm -Fx0lcoXWp4xpoyJn9St7vmH3t7quBKdqt54zwcuHjhgZPSR6RikodKHtsl8TAgMB -AAGjZjBkMB0GA1UdDgQWBBTdAXu8aBbvkvxYD5Ss9/Ml5VgohjAfBgNVHSMEGDAW -gBSMsBNO3UGBteMZOTq5fDPG2aPx8DASBgNVHRMBAf8ECDAGAQH/AgEBMA4GA1Ud -DwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAQEA0hJCtrCI9Mf47+y3pvsTjiaT -TZwpNE0cdxHjpcCHJWX2jmGbqqA6wvQ7yy4PFarmnFOoW3hQFeiLgpz9X86YTRzF -8dj3Q2MKXf6i6/iW+Y96GFqurshKp7wV25wfzWwLXcVCiM1xYPWYSyGsZAGotu4M -c7uolVABjJu5nci9mBxVmaYV5oT1mxrvq3dCPm2AvmVFNWPNRbMSAuT5B7FUDvWG -xvd1aDFduqL0iLAcrTifMIYI3XL4pBSIlL78dgY45WL6616EF3mHhW/Y4k4PNq1I -Fz08Q3y99ilhzeAci1jv6KBVHiALZNFFtYjd10KX95qnF9SomBjCTPsQ9PTC5g== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIID2zCCAsOgAwIBAgIUdxRGMrv1ONRI/dJXUHa3isjVXuwwDQYJKoZIhvcNAQEL -BQAwfDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMQwwCgYDVQQHDANTRk8xCzAJ -BgNVBAoMAk1DMQ0wCwYDVQQLDARyb290MRUwEwYDVQQDDAxyb290Y2EuYWRtaW4x -HzAdBgkqhkiG9w0BCQEWEHJvb3RjYUBhZG1pbi5jb20wIBcNMjEwNzA5MTkxMTU0 -WhgPMjEyMTA2MTUxOTExNTRaMHwxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEM -MAoGA1UEBwwDU0ZPMQswCQYDVQQKDAJNQzENMAsGA1UECwwEcm9vdDEVMBMGA1UE -AwwMcm9vdGNhLmFkbWluMR8wHQYJKoZIhvcNAQkBFhByb290Y2FAYWRtaW4uY29t -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Bqlx+ngRZfWjktX6urJ -Tpg2//n3uMW8Gp55SVq+lbpkNXuA3W0uTlom/2fsnzmMmBAJUvv/NaLcFSN++0/d -fYGVhogxjlRoyaXa4sdFPg2ocM+lCHLGhWpYuVdTWPknikTOVNbh9z94SLRfrP8N -kuxGNZNktnVm+QJmrCLmjvnPvQlcP/WqFYehFM26NaRzswOhLLRU1YK8aVlh9Vto -PGSTPtZK60XwTfyCj/zEvHqpbGbKJPp7W0rpxl7ehPQIzGQt5IMH3zKrqLm4/pt+ -XFEVqy724sstthS73bvXguWxBLOzuMze8CbI6SJpcHaH8HO5pfFMPyE5N5l2x9Co -uQIDAQABo1MwUTAdBgNVHQ4EFgQUjLATTt1BgbXjGTk6uXwzxtmj8fAwHwYDVR0j -BBgwFoAUjLATTt1BgbXjGTk6uXwzxtmj8fAwDwYDVR0TAQH/BAUwAwEB/zANBgkq -hkiG9w0BAQsFAAOCAQEAL9/7YtxIbuTt7dgH1KOMb/y6P3Qb79fTVZTx073E2ZBj -OfSuMGUhKC30LWQXCQEsY4WpugJ4cS0NsArSYsO5XWguqgjYlWL6poOmYhGvj7ou -oi44oYqcPm6EbvLrAKdI67bkbSPLzgs+6TrxTyXHzPKFBqGBnuHaFKjgb4hGiPmd -JWKrh3fbTtuLjqSHd0Gey2uBNFql4LhPutdsCUhSOD3BibAeTbXyln70AgpTCoWT -9Qr9Ux6HYIiAHSDBzzuN8EcrlnAm9RO4zRyUVwxDsHoNsOUwybn50IM66p83HuiY -h/iX5uNjaFAADfRR4rQOwb6MLreVH2XYUSiz4M/ijg== ------END CERTIFICATE----- diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/validator3/truststore.jks b/acceptance-tests/tests/src/test/resources/pki-certs/validator3/truststore.jks deleted file mode 100644 index 7acd9015b86e4783c78910745adfd67669b33948..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3135 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 E04*k+`2YX_ diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/validator4/keystore.jks b/acceptance-tests/tests/src/test/resources/pki-certs/validator4/keystore.jks deleted file mode 100644 index ef941f664e3204b1e88dd30ae9700ad9a78723bc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6783 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 NY(1`phJgyp`wtkv+35fP diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/validator4/nss.cfg b/acceptance-tests/tests/src/test/resources/pki-certs/validator4/nss.cfg deleted file mode 100644 index c114f78b09..0000000000 --- a/acceptance-tests/tests/src/test/resources/pki-certs/validator4/nss.cfg +++ /dev/null @@ -1,6 +0,0 @@ - -name = NSScrypto-validator4 -nssSecmodDirectory = ./src/test/resources/pki-certs/validator4/nssdb -nssDbMode = readOnly -nssModule = keystore - diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/validator4/nssdb/cert8.db b/acceptance-tests/tests/src/test/resources/pki-certs/validator4/nssdb/cert8.db deleted file mode 100644 index 7c94b589ac7f804ea94a3acc1ff7f6ba5fbbd512..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 65536 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 diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/validator4/nssdb/key3.db b/acceptance-tests/tests/src/test/resources/pki-certs/validator4/nssdb/key3.db deleted file mode 100644 index 0b60173dbf93ac79ab3e94a15e363711706b2d58..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI$XHe7G769;n2)zXnLL%h>x&%cq6om+)Axjk$3*GFahiD)YLRE^0Qdim%42S|E z(i9NIAi|1*1dv`9gG&cP2Vp59_{8@^9ddMmUm+3&d&PbA^7iket2Kd z5C{MPAOHk_01yBIKmZ5;0U!VbfWY5HKoHtMtRtoom55?QIwD;>Q7Bj_QRpiOAOHk_ z01yBIKmZ5;fgd9PheQHgC}ejRI+dmaVIz50v8wzc2X30(ToZ$d^1orzIr#6c84r6# zHG@Z=SLjaFsO?@R?S6OJ`j##!(7~qu4%iN z>#QX()%RatlWf!!s;EB2ERyh>U$Q9?6P`1@cpjC?!31dJKWU2Q39xIJMuf@!D|D??WvrFbp@vbddxK@-wJF!t zB&mJ0@cE|)Z57!{w>;7g z&L;e`8@6HZSVFXCb{HxKLt+HXBTUJ9#ZZq;u4JnW4rwG6epR;DxjxrC`VFP>)`oC!5&eNd~C=!Fr((;g^9G9O{8X!z4yNUo}t#IUS!3g z$mY*&f6P;l*`-7^JPw%Lc0HYuDI261;`G<)Sk^G^_5B$2;U2X~9B*84JT~dK#pv)2 zn#F}I@_J6eG`qJ;f}RaSySA`~9rk5kYjg_9zkS$5PKT$6LbP7kE59}%XFZ=FpwKl- z8V*)`{*db5?74_*X?!mowt1q@y@A1H6v`VnGRrX>@KURZGc2s?-@2esp z(w|Lb$QMOLDHNobU!~F_I$gQ_#Ht$+EmhpR4`%qv6wOr00@8{p+l6g%nVIT$!&ftO zR92Jr)GauCE$G>1O>6AF#~Q-OJ0039w>I?xuT**DWXC(ziJbPtvl-8$Vn0hH4DF2= zTfe1yvu@7`1FWIBDC0|0J^f{W%rx{eJ*4)Vtvnp6UgRDt{o>oW($Hod$I+as+d!3DwpYolMU-?GtI3i? zjoUS`I?1&s(IUGtqpGuJ4RVtN(b?%w$s`m+W)e7OT?4#E91)p-TcK+Xf|_L&=uBE5p0>Lyhu>jqf08)N!^{T zJ?q0Ca~CzHR`?7V@9_(UM4`I6P}KcgD0H|KOp-G|n8X`iy4Ev2w#7c@)jY9l2Kw)p z!pD95<1`wkf00e*l5C8%|00;m9AOHk_01)^;3j7OA CEQufh diff --git a/acceptance-tests/tests/src/test/resources/pki-certs/validator4/nssdb/secmod.db b/acceptance-tests/tests/src/test/resources/pki-certs/validator4/nssdb/secmod.db deleted file mode 100644 index 346dc33e6916bb2023054dc994582c9fa3527709..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI&O-jQ+6u|LkmD+_=H||6RTx8c$a3y3_H&T>By+E2wOK6&uB$c}G816lXxb6YG zf*wPulT1a6=&}^~4?O1U<;~1*9jP9AB2p3Ac@{Y^L)jDAGF=f;TMo>Axv*XK<(5sl zkMCa0TG5J}BG%q&_C9Mrmje+%009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{ z1Q6I1fr`BD&+AY1d3{rE#61u|009ILKmY**5I_I{1Q7UDpejnooQv)$O!<>ZH|Dmq{>NIMv*;;ykX|5>BJP#WqoHkX|L3=37zlN z>{4jzeSUJCjC6diGd~R{d6>k-j{Oh+VRzx0cO0Ae(f)e-`+|l50tg_000IagfB*sr LAb?c5GZ@U+#vY=g<;nCLPa{SMkth3BuBgV$h{D*SjEb=)%Z)5$DY6W* zMA>P3lG3C{LLstcH+sgF?HS6G+wGq2IrpB^AHVbceLwH-Ils?&|Gw|n_q#NIzovA2n6trD0IIF;jqTwKvlNV1=3*cAPxHH1`G;7p~61GdP-GOD$V+fO@~dr z%fjnl9~}izoZLG?^h0J)0Km%u0sXMNAU7w>3eJg!T3M`35J;$w78VKetSDSan1!Cn zn#6;I8tGtBAn%IAi-dbnC|+0*5WO;mA(1OnA^}4nxj4CEH-gfCe~lXu75FUfTNN=x ziVG+!hEl?Udq7pJDi({|Z6nUFgk=|$vA8dVpWGh}*tFg-fCB=f0sIh<2Jk>>003!| z%zQG`t((viWpH?S_^ENC^77nF`QvKI)U&_Y)W%hka8&#7ln0^H{F z%eeFokfgr*5IDsdT}C9t%ecPwAis-6Bp zm^$LPmlUhfa&SbKX|zC#UiiJ*H^I`vSSTl=A2mODQ{lC9}e`Nt0 z0G8n#AdEe%x1GID*|r0aU0w6`9r~_)V`FVx%{L<`3zeE)8zx#`SzVcYRrC9se-c$$ z1t3{&n<7h*B*qQwBnIbHLeID>qKbH$>>pLwIbw1VZE^OWvI4X01q-7qG3gkUwD4pN z*C5xABam$UkIa`z%)Jc64`1ISGng1Un=sHzbToyaSY|zU_#V_o zV9Me)lH1I-m2@}uM6D*D$Bp3OG#gkdhRUNMUP%n2HA;L&2>j=c!qe!r(Tn$A<`0|xOywI*`}Gpj}yg>o)9YI`1< zQ1uUeJ71tFo@(rGzr!z5Of?N%Wx*L7>!Vqm)YagSbG|<-b~%m-t9i3;VOI>%#k#Fm z;jHgoD}z%<;-$<|qGaBs79Bdkol`$*mUyX1t>xGsopG(rA{1#FxwuYs1H{0@duw3c z&Y=3VU}}#==+b^c;UpXL{glS}{pOJz9@*Y4LOaD|#zgts=69&b6j#r0bqY2{Fa+WF zI0Su9mUez6a>!xQno+`#r>VV?*$z}i)fUNE+Y5o;1z}bgd$TypJ z6$|oRc%RPdM?z6dOzj~9K9k#}x^<}7w_9fPIv@$e5l~LxgZM0<#nkMRW&e3AVX(zXtUDb$7zTzvI(0W4+Ad<$W| zPtBPb<4Rhz4;OL87n|5~J`YY{81W5{ALyQZuG|>NBbS_pFXU~%ih8^|VO(}dmwJ!U zmWKddi4eK3|FL5mx9B8#yamO@Pwi2h5%5C4Pr6or{NgO6t@E-|2`ZvFu-_Sh$zhV* z%KQuwEjR(`Vv4J?lfJw1snHTL^~^5M${@|~8%>yqQFS~5pU;ub-TWt7zTP7!eq)ORi!1sqX-M=f`fA9_Bk@jt#Sn&sjufHsa`c8J-fOGHRW5 z$DI~aD7zwql9G*7$b)r>!_1Bw2m5t``P<3A4M6)E*KiBeWqvqT1hrjjHl@_e*4 zT>NXvx;P?3w?qiqH^+6`l5Z-cZsxQj)~+(06;>pbuW}s>L3Db|W(bE}sa^2qROz?> zG;%aZ>}+T-rLD)9UpZf2OntA8U(NJ(0;5~%lJ&&k4J#R0UeX`Bcf&ecwG(EpWs5b_ j6U84I&I_ allocatedPorts = new HashSet<>(); - private final PkiBlockCreationConfigurationProvider pkiBlockCreationConfigProvider; private final Supplier genesisConfigFileSupplier = Suppliers.memoize(this::readGenesisConfigFile); private final Supplier genesisConfigOptionsSupplier = @@ -906,8 +902,6 @@ public class BesuCommand implements DefaultCommandValues, Runnable { @Mixin private P2PTLSConfigOptions p2pTLSConfigOptions; - @Mixin private PkiBlockCreationOptions pkiBlockCreationOptions; - // Plugins Configuration Option Group @CommandLine.ArgGroup(validate = false) PluginsConfigurationOptions pluginsConfigurationOptions = new PluginsConfigurationOptions(); @@ -972,7 +966,6 @@ public class BesuCommand implements DefaultCommandValues, Runnable { new SecurityModuleServiceImpl(), new PermissioningServiceImpl(), new PrivacyPluginServiceImpl(), - new PkiBlockCreationConfigurationProvider(), new RpcEndpointServiceImpl(), new TransactionSelectionServiceImpl(), new TransactionPoolValidatorServiceImpl(), @@ -995,7 +988,6 @@ public class BesuCommand implements DefaultCommandValues, Runnable { * @param securityModuleService instance of SecurityModuleServiceImpl * @param permissioningService instance of PermissioningServiceImpl * @param privacyPluginService instance of PrivacyPluginServiceImpl - * @param pkiBlockCreationConfigProvider instance of PkiBlockCreationConfigurationProvider * @param rpcEndpointServiceImpl instance of RpcEndpointServiceImpl * @param transactionSelectionServiceImpl instance of TransactionSelectionServiceImpl * @param transactionValidatorServiceImpl instance of TransactionValidatorServiceImpl @@ -1016,7 +1008,6 @@ public class BesuCommand implements DefaultCommandValues, Runnable { final SecurityModuleServiceImpl securityModuleService, final PermissioningServiceImpl permissioningService, final PrivacyPluginServiceImpl privacyPluginService, - final PkiBlockCreationConfigurationProvider pkiBlockCreationConfigProvider, final RpcEndpointServiceImpl rpcEndpointServiceImpl, final TransactionSelectionServiceImpl transactionSelectionServiceImpl, final TransactionPoolValidatorServiceImpl transactionValidatorServiceImpl, @@ -1037,7 +1028,6 @@ public class BesuCommand implements DefaultCommandValues, Runnable { this.privacyPluginService = privacyPluginService; this.pluginCommonConfiguration = new BesuConfigurationImpl(); besuPluginContext.addService(BesuConfiguration.class, pluginCommonConfiguration); - this.pkiBlockCreationConfigProvider = pkiBlockCreationConfigProvider; this.rpcEndpointServiceImpl = rpcEndpointServiceImpl; this.transactionSelectionServiceImpl = transactionSelectionServiceImpl; this.transactionValidatorServiceImpl = transactionValidatorServiceImpl; @@ -1556,7 +1546,6 @@ public class BesuCommand implements DefaultCommandValues, Runnable { validateApiOptions(); validateConsensusSyncCompatibilityOptions(); p2pTLSConfigOptions.checkP2PTLSOptionsDependencies(logger, commandLine); - pkiBlockCreationOptions.checkPkiBlockCreationOptionsDependencies(logger, commandLine); } private void validateConsensusSyncCompatibilityOptions() { @@ -1910,7 +1899,6 @@ public class BesuCommand implements DefaultCommandValues, Runnable { .metricsSystem(metricsSystem.get()) .messagePermissioningProviders(permissioningService.getMessagePermissioningProviders()) .privacyParameters(privacyParameters()) - .pkiBlockCreationConfiguration(maybePkiBlockCreationConfiguration()) .clock(Clock.systemUTC()) .isRevertReasonEnabled(isRevertReasonEnabled) .storageProvider(storageProvider) @@ -2182,12 +2170,6 @@ public class BesuCommand implements DefaultCommandValues, Runnable { return keyValueStorageProvider(keyValueStorageName); } - private Optional maybePkiBlockCreationConfiguration() { - return pkiBlockCreationOptions - .asDomainConfig(commandLine) - .map(pkiBlockCreationConfigProvider::load); - } - private SynchronizerConfiguration buildSyncConfig() { return unstableSynchronizerOptions .toDomainObject() diff --git a/besu/src/main/java/org/hyperledger/besu/cli/options/unstable/PkiBlockCreationOptions.java b/besu/src/main/java/org/hyperledger/besu/cli/options/unstable/PkiBlockCreationOptions.java deleted file mode 100644 index 64fe8effb4..0000000000 --- a/besu/src/main/java/org/hyperledger/besu/cli/options/unstable/PkiBlockCreationOptions.java +++ /dev/null @@ -1,164 +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 static java.util.Arrays.asList; -import static org.hyperledger.besu.cli.DefaultCommandValues.MANDATORY_FILE_FORMAT_HELP; - -import org.hyperledger.besu.cli.util.CommandLineUtils; -import org.hyperledger.besu.pki.config.PkiKeyStoreConfiguration; - -import java.nio.file.Path; -import java.util.Optional; - -import org.slf4j.Logger; -import picocli.CommandLine; -import picocli.CommandLine.Option; -import picocli.CommandLine.ParameterException; - -/** The Pki block creation Cli options. */ -public class PkiBlockCreationOptions { - - /** The pki block creation enabled. */ - @Option( - names = {"--Xpki-block-creation-enabled"}, - hidden = true, - description = "Enable PKI integration (default: ${DEFAULT-VALUE})") - Boolean enabled = false; - - /** The Key store type. */ - @Option( - names = {"--Xpki-block-creation-keystore-type"}, - hidden = true, - paramLabel = "", - description = "PKI service keystore type. Required if PKI Block Creation is enabled.") - @SuppressWarnings({"FieldCanBeFinal", "FieldMayBeFinal"}) - String keyStoreType = PkiKeyStoreConfiguration.DEFAULT_KEYSTORE_TYPE; - - /** The Key store file. */ - @Option( - names = {"--Xpki-block-creation-keystore-file"}, - hidden = true, - paramLabel = MANDATORY_FILE_FORMAT_HELP, - description = "Keystore containing key/certificate for PKI Block Creation.") - Path keyStoreFile = null; - - /** The Key store password file. */ - @Option( - names = {"--Xpki-block-creation-keystore-password-file"}, - hidden = true, - paramLabel = MANDATORY_FILE_FORMAT_HELP, - description = - "File containing password to unlock keystore for PKI Integration. Required if PKI Block Creation is enabled.") - Path keyStorePasswordFile = null; - - /** The Certificate alias. */ - @Option( - names = {"--Xpki-block-creation-keystore-certificate-alias"}, - hidden = true, - paramLabel = "", - description = - "Alias of the certificate that will be included in the blocks proposed by this validator.") - @SuppressWarnings({"FieldCanBeFinal", "FieldMayBeFinal"}) - String certificateAlias = PkiKeyStoreConfiguration.DEFAULT_CERTIFICATE_ALIAS; - - /** The Trust store type. */ - @Option( - names = {"--Xpki-block-creation-truststore-type"}, - hidden = true, - paramLabel = "", - description = "PKI Integration truststore type.") - @SuppressWarnings({"FieldCanBeFinal", "FieldMayBeFinal"}) - String trustStoreType = PkiKeyStoreConfiguration.DEFAULT_KEYSTORE_TYPE; - - /** The Trust store file. */ - @Option( - names = {"--Xpki-block-creation-truststore-file"}, - hidden = true, - paramLabel = MANDATORY_FILE_FORMAT_HELP, - description = "Truststore containing trusted certificates for PKI Block Creation.") - Path trustStoreFile = null; - - /** The Trust store password file. */ - @Option( - names = {"--Xpki-block-creation-truststore-password-file"}, - hidden = true, - paramLabel = MANDATORY_FILE_FORMAT_HELP, - description = "File containing password to unlock truststore for PKI Block Creation.") - Path trustStorePasswordFile = null; - - /** The Crl file. */ - @Option( - names = {"--Xpki-block-creation-crl-file"}, - hidden = true, - paramLabel = MANDATORY_FILE_FORMAT_HELP, - description = "File with all CRLs for PKI Block Creation.") - Path crlFile = null; - - /** Default Constructor. */ - PkiBlockCreationOptions() {} - - /** - * As domain config optional. - * - * @param commandLine the command line - * @return the optional - */ - public Optional asDomainConfig(final CommandLine commandLine) { - if (!enabled) { - return Optional.empty(); - } - - if (keyStoreFile == null) { - throw new ParameterException( - commandLine, "KeyStore file is required when PKI Block Creation is enabled"); - } - - if (keyStorePasswordFile == null) { - throw new ParameterException( - commandLine, - "File containing password to unlock keystore is required when PKI Block Creation is enabled"); - } - - return Optional.of( - new PkiKeyStoreConfiguration.Builder() - .withKeyStoreType(keyStoreType) - .withKeyStorePath(keyStoreFile) - .withKeyStorePasswordPath(keyStorePasswordFile) - .withCertificateAlias(certificateAlias) - .withTrustStoreType(trustStoreType) - .withTrustStorePath(trustStoreFile) - .withTrustStorePasswordPath(trustStorePasswordFile) - .withCrlFilePath(crlFile) - .build()); - } - - /** - * Check pki block creation options dependencies. - * - * @param logger the logger - * @param commandLine the command line - */ - public void checkPkiBlockCreationOptionsDependencies( - final Logger logger, final CommandLine commandLine) { - CommandLineUtils.checkOptionDependencies( - logger, - commandLine, - "--Xpki-block-creation-enabled", - !enabled, - asList( - "--Xpki-block-creation-keystore-file", "--Xpki-block-creation-keystore-password-file")); - } -} 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 73bc76608b..8f26909a51 100644 --- a/besu/src/main/java/org/hyperledger/besu/controller/BesuControllerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/controller/BesuControllerBuilder.java @@ -23,7 +23,6 @@ import org.hyperledger.besu.config.GenesisConfigOptions; import org.hyperledger.besu.consensus.merge.MergeContext; import org.hyperledger.besu.consensus.merge.UnverifiedForkchoiceSupplier; import org.hyperledger.besu.consensus.qbft.BFTPivotSelectorFromPeers; -import org.hyperledger.besu.consensus.qbft.pki.PkiBlockCreationConfiguration; import org.hyperledger.besu.cryptoservices.NodeKey; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.ConsensusContext; @@ -150,10 +149,6 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides /** The Privacy parameters. */ protected PrivacyParameters privacyParameters; - /** The Pki block creation configuration. */ - protected Optional pkiBlockCreationConfiguration = - Optional.empty(); - /** The Data directory. */ protected Path dataDirectory; @@ -348,18 +343,6 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides return this; } - /** - * Pki block creation configuration besu controller builder. - * - * @param pkiBlockCreationConfiguration the pki block creation configuration - * @return the besu controller builder - */ - public BesuControllerBuilder pkiBlockCreationConfiguration( - final Optional pkiBlockCreationConfiguration) { - this.pkiBlockCreationConfiguration = pkiBlockCreationConfiguration; - return this; - } - /** * Data directory besu controller builder. * diff --git a/besu/src/main/java/org/hyperledger/besu/controller/ConsensusScheduleBesuControllerBuilder.java b/besu/src/main/java/org/hyperledger/besu/controller/ConsensusScheduleBesuControllerBuilder.java index af59a7625d..f669332202 100644 --- a/besu/src/main/java/org/hyperledger/besu/controller/ConsensusScheduleBesuControllerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/controller/ConsensusScheduleBesuControllerBuilder.java @@ -23,7 +23,6 @@ import org.hyperledger.besu.consensus.common.ForksSchedule; import org.hyperledger.besu.consensus.common.MigratingContext; import org.hyperledger.besu.consensus.common.MigratingMiningCoordinator; import org.hyperledger.besu.consensus.common.MigratingProtocolContext; -import org.hyperledger.besu.consensus.qbft.pki.PkiBlockCreationConfiguration; import org.hyperledger.besu.cryptoservices.NodeKey; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.ConsensusContext; @@ -330,15 +329,6 @@ public class ConsensusScheduleBesuControllerBuilder extends BesuControllerBuilde return super.privacyParameters(privacyParameters); } - @Override - public BesuControllerBuilder pkiBlockCreationConfiguration( - final Optional pkiBlockCreationConfiguration) { - besuControllerBuilderSchedule - .values() - .forEach(b -> b.pkiBlockCreationConfiguration(pkiBlockCreationConfiguration)); - return super.pkiBlockCreationConfiguration(pkiBlockCreationConfiguration); - } - @Override public BesuControllerBuilder dataDirectory(final Path dataDirectory) { besuControllerBuilderSchedule.values().forEach(b -> b.dataDirectory(dataDirectory)); 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 030173acb0..4a5f592e23 100644 --- a/besu/src/main/java/org/hyperledger/besu/controller/QbftBesuControllerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/controller/QbftBesuControllerBuilder.java @@ -52,7 +52,6 @@ import org.hyperledger.besu.consensus.qbft.QbftProtocolScheduleBuilder; import org.hyperledger.besu.consensus.qbft.blockcreation.QbftBlockCreatorFactory; import org.hyperledger.besu.consensus.qbft.jsonrpc.QbftJsonRpcMethods; import org.hyperledger.besu.consensus.qbft.payload.MessageFactory; -import org.hyperledger.besu.consensus.qbft.pki.PkiQbftExtraDataCodec; import org.hyperledger.besu.consensus.qbft.protocol.Istanbul100SubProtocol; import org.hyperledger.besu.consensus.qbft.statemachine.QbftBlockHeightManagerFactory; import org.hyperledger.besu.consensus.qbft.statemachine.QbftController; @@ -113,11 +112,7 @@ public class QbftBesuControllerBuilder extends BftBesuControllerBuilder { protected Supplier bftExtraDataCodec() { return Suppliers.memoize( () -> { - if (pkiBlockCreationConfiguration.isPresent()) { - return new PkiQbftExtraDataCodec(); - } else { - return new QbftExtraDataCodec(); - } + return new QbftExtraDataCodec(); }); } @@ -393,8 +388,7 @@ public class QbftBesuControllerBuilder extends BftBesuControllerBuilder { new ForkingValidatorProvider( blockchain, qbftForksSchedule, blockValidatorProvider, transactionValidatorProvider); - return new QbftContext( - validatorProvider, epochManager, bftBlockInterface().get(), pkiBlockCreationConfiguration); + return new QbftContext(validatorProvider, epochManager, bftBlockInterface().get()); } private BftValidatorOverrides convertBftForks(final List bftForks) { diff --git a/besu/src/main/java/org/hyperledger/besu/controller/TransitionBesuControllerBuilder.java b/besu/src/main/java/org/hyperledger/besu/controller/TransitionBesuControllerBuilder.java index 4f084f3c13..cdf5413fff 100644 --- a/besu/src/main/java/org/hyperledger/besu/controller/TransitionBesuControllerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/controller/TransitionBesuControllerBuilder.java @@ -21,7 +21,6 @@ import org.hyperledger.besu.consensus.merge.TransitionBackwardSyncContext; import org.hyperledger.besu.consensus.merge.TransitionContext; import org.hyperledger.besu.consensus.merge.TransitionProtocolSchedule; import org.hyperledger.besu.consensus.merge.blockcreation.TransitionCoordinator; -import org.hyperledger.besu.consensus.qbft.pki.PkiBlockCreationConfiguration; import org.hyperledger.besu.cryptoservices.NodeKey; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.ConsensusContext; @@ -350,13 +349,6 @@ public class TransitionBesuControllerBuilder extends BesuControllerBuilder { return propagateConfig(z -> z.privacyParameters(privacyParameters)); } - @Override - public BesuControllerBuilder pkiBlockCreationConfiguration( - final Optional pkiBlockCreationConfiguration) { - super.pkiBlockCreationConfiguration(pkiBlockCreationConfiguration); - return propagateConfig(z -> z.pkiBlockCreationConfiguration(pkiBlockCreationConfiguration)); - } - @Override public BesuControllerBuilder dataDirectory(final Path dataDirectory) { super.dataDirectory(dataDirectory); 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 f620c729b6..c92a3a5bda 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/CommandTestAbstract.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/CommandTestAbstract.java @@ -45,8 +45,6 @@ import org.hyperledger.besu.cli.options.unstable.NetworkingOptions; import org.hyperledger.besu.cli.options.unstable.SynchronizerOptions; import org.hyperledger.besu.components.BesuComponent; import org.hyperledger.besu.config.GenesisConfigOptions; -import org.hyperledger.besu.consensus.qbft.pki.PkiBlockCreationConfiguration; -import org.hyperledger.besu.consensus.qbft.pki.PkiBlockCreationConfigurationProvider; import org.hyperledger.besu.controller.BesuController; import org.hyperledger.besu.controller.BesuControllerBuilder; import org.hyperledger.besu.controller.NoopPluginServiceFactory; @@ -74,7 +72,6 @@ import org.hyperledger.besu.ethereum.storage.StorageProvider; import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration; -import org.hyperledger.besu.pki.config.PkiKeyStoreConfiguration; import org.hyperledger.besu.plugin.services.PicoCLIOptions; import org.hyperledger.besu.plugin.services.StorageService; import org.hyperledger.besu.plugin.services.TransactionSelectionService; @@ -235,9 +232,6 @@ public abstract class CommandTestAbstract { @Mock(lenient = true) protected BesuComponent mockBesuComponent; - @Mock protected PkiBlockCreationConfigurationProvider mockPkiBlockCreationConfigProvider; - @Mock protected PkiBlockCreationConfiguration mockPkiBlockCreationConfiguration; - @Captor protected ArgumentCaptor> bytesCollectionCollector; @Captor protected ArgumentCaptor pathArgumentCaptor; @Captor protected ArgumentCaptor stringArgumentCaptor; @@ -252,7 +246,6 @@ public abstract class CommandTestAbstract { @Captor protected ArgumentCaptor storageProviderArgumentCaptor; @Captor protected ArgumentCaptor ethProtocolConfigurationArgumentCaptor; @Captor protected ArgumentCaptor dataStorageConfigurationArgumentCaptor; - @Captor protected ArgumentCaptor pkiKeyStoreConfigurationArgumentCaptor; @Captor protected ArgumentCaptor> @@ -281,8 +274,6 @@ public abstract class CommandTestAbstract { when(mockControllerBuilder.messagePermissioningProviders(any())) .thenReturn(mockControllerBuilder); when(mockControllerBuilder.privacyParameters(any())).thenReturn(mockControllerBuilder); - when(mockControllerBuilder.pkiBlockCreationConfiguration(any())) - .thenReturn(mockControllerBuilder); when(mockControllerBuilder.clock(any())).thenReturn(mockControllerBuilder); when(mockControllerBuilder.isRevertReasonEnabled(false)).thenReturn(mockControllerBuilder); when(mockControllerBuilder.storageProvider(any())).thenReturn(mockControllerBuilder); @@ -390,10 +381,6 @@ public abstract class CommandTestAbstract { .when(mockBesuPluginContext.getService(TransactionSelectionService.class)) .thenReturn(Optional.of(txSelectionService)); - lenient() - .doReturn(mockPkiBlockCreationConfiguration) - .when(mockPkiBlockCreationConfigProvider) - .load(pkiKeyStoreConfigurationArgumentCaptor.capture()); when(mockBesuComponent.getBesuCommandLogger()).thenReturn(mockLogger); } @@ -489,7 +476,6 @@ public abstract class CommandTestAbstract { environment, storageService, securityModuleService, - mockPkiBlockCreationConfigProvider, privacyPluginService); case PORT_CHECK: return new TestBesuCommand( @@ -503,7 +489,6 @@ public abstract class CommandTestAbstract { environment, storageService, securityModuleService, - mockPkiBlockCreationConfigProvider, privacyPluginService); default: return new TestBesuCommandWithoutPortCheck( @@ -517,7 +502,6 @@ public abstract class CommandTestAbstract { environment, storageService, securityModuleService, - mockPkiBlockCreationConfigProvider, privacyPluginService); } } @@ -558,7 +542,6 @@ public abstract class CommandTestAbstract { final Map environment, final StorageServiceImpl storageService, final SecurityModuleServiceImpl securityModuleService, - final PkiBlockCreationConfigurationProvider pkiBlockCreationConfigProvider, final PrivacyPluginServiceImpl privacyPluginService) { super( besuComponent, @@ -573,7 +556,6 @@ public abstract class CommandTestAbstract { securityModuleService, new PermissioningServiceImpl(), privacyPluginService, - pkiBlockCreationConfigProvider, rpcEndpointServiceImpl, new TransactionSelectionServiceImpl(), new TransactionPoolValidatorServiceImpl(), @@ -659,7 +641,6 @@ public abstract class CommandTestAbstract { final Map environment, final StorageServiceImpl storageService, final SecurityModuleServiceImpl securityModuleService, - final PkiBlockCreationConfigurationProvider pkiBlockCreationConfigProvider, final PrivacyPluginServiceImpl privacyPluginService) { super( besuComponent, @@ -672,7 +653,6 @@ public abstract class CommandTestAbstract { environment, storageService, securityModuleService, - pkiBlockCreationConfigProvider, privacyPluginService); } @@ -695,7 +675,6 @@ public abstract class CommandTestAbstract { final Map environment, final StorageServiceImpl storageService, final SecurityModuleServiceImpl securityModuleService, - final PkiBlockCreationConfigurationProvider pkiBlockCreationConfigProvider, final PrivacyPluginServiceImpl privacyPluginService) { super( context, @@ -708,7 +687,6 @@ public abstract class CommandTestAbstract { environment, storageService, securityModuleService, - pkiBlockCreationConfigProvider, privacyPluginService); } diff --git a/besu/src/test/java/org/hyperledger/besu/cli/PkiOptionsTest.java b/besu/src/test/java/org/hyperledger/besu/cli/PkiOptionsTest.java deleted file mode 100644 index 12da66342b..0000000000 --- a/besu/src/test/java/org/hyperledger/besu/cli/PkiOptionsTest.java +++ /dev/null @@ -1,98 +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.cli; - -import static java.nio.charset.StandardCharsets.UTF_8; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.verifyNoInteractions; - -import org.hyperledger.besu.pki.config.PkiKeyStoreConfiguration; - -import java.io.File; -import java.nio.file.Path; - -import org.apache.commons.io.FileUtils; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.io.TempDir; - -public class PkiOptionsTest extends CommandTestAbstract { - - @Test - public void pkiBlockCreationIsDisabledByDefault() { - parseCommand(); - - verifyNoInteractions(mockPkiBlockCreationConfigProvider); - } - - @Test - public void pkiBlockCreationKeyStoreFileRequired() { - parseCommand( - "--Xpki-block-creation-enabled", - "--Xpki-block-creation-keystore-password-file", - "/tmp/pwd"); - - assertThat(commandErrorOutput.toString(UTF_8)) - .contains("KeyStore file is required when PKI Block Creation is enabled"); - } - - @Test - public void pkiBlockCreationPasswordFileRequired() { - parseCommand( - "--Xpki-block-creation-enabled", "--Xpki-block-creation-keystore-file", "/tmp/keystore"); - - assertThat(commandErrorOutput.toString(UTF_8)) - .contains( - "File containing password to unlock keystore is required when PKI Block Creation is enabled"); - } - - @Test - public void pkiBlockCreationFullConfig(final @TempDir Path pkiTempFolder) throws Exception { - // Create temp file with password - final File pwdFile = pkiTempFolder.resolve("pwd").toFile(); - FileUtils.writeStringToFile(pwdFile, "foo", UTF_8); - - parseCommand( - "--Xpki-block-creation-enabled", - "--Xpki-block-creation-keystore-type", - "JKS", - "--Xpki-block-creation-keystore-file", - "/tmp/keystore", - "--Xpki-block-creation-keystore-password-file", - pwdFile.getAbsolutePath(), - "--Xpki-block-creation-keystore-certificate-alias", - "anAlias", - "--Xpki-block-creation-truststore-type", - "JKS", - "--Xpki-block-creation-truststore-file", - "/tmp/truststore", - "--Xpki-block-creation-truststore-password-file", - pwdFile.getAbsolutePath(), - "--Xpki-block-creation-crl-file", - "/tmp/crl"); - - final PkiKeyStoreConfiguration pkiKeyStoreConfig = - pkiKeyStoreConfigurationArgumentCaptor.getValue(); - - assertThat(pkiKeyStoreConfig).isNotNull(); - assertThat(pkiKeyStoreConfig.getKeyStoreType()).isEqualTo("JKS"); - assertThat(pkiKeyStoreConfig.getKeyStorePath()).isEqualTo(Path.of("/tmp/keystore")); - assertThat(pkiKeyStoreConfig.getKeyStorePassword()).isEqualTo("foo"); - assertThat(pkiKeyStoreConfig.getCertificateAlias()).isEqualTo("anAlias"); - assertThat(pkiKeyStoreConfig.getTrustStoreType()).isEqualTo("JKS"); - assertThat(pkiKeyStoreConfig.getTrustStorePath()).isEqualTo(Path.of("/tmp/truststore")); - assertThat(pkiKeyStoreConfig.getTrustStorePassword()).isEqualTo("foo"); - assertThat(pkiKeyStoreConfig.getCrlFilePath()).hasValue(Path.of("/tmp/crl")); - } -} diff --git a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/TestContextBuilder.java b/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/TestContextBuilder.java index 7a014986a2..48b6daad0a 100644 --- a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/TestContextBuilder.java +++ b/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/TestContextBuilder.java @@ -458,7 +458,7 @@ public class TestContextBuilder { new ProtocolContext( blockChain, worldStateArchive, - new QbftContext(validatorProvider, epochManager, blockInterface, Optional.empty()), + new QbftContext(validatorProvider, epochManager, blockInterface), new BadBlockManager()); final TransactionPoolConfiguration poolConf = diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/QbftContext.java b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/QbftContext.java index f89f4990be..68e8b7f1af 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/QbftContext.java +++ b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/QbftContext.java @@ -18,38 +18,21 @@ import org.hyperledger.besu.consensus.common.EpochManager; import org.hyperledger.besu.consensus.common.bft.BftBlockInterface; import org.hyperledger.besu.consensus.common.bft.BftContext; import org.hyperledger.besu.consensus.common.validator.ValidatorProvider; -import org.hyperledger.besu.consensus.qbft.pki.PkiBlockCreationConfiguration; - -import java.util.Optional; /** The Qbft context. */ public class QbftContext extends BftContext { - private final Optional pkiBlockCreationConfiguration; - /** * Instantiates a new Qbft context. * * @param validatorProvider the validator provider * @param epochManager the epoch manager * @param blockInterface the block interface - * @param pkiBlockCreationConfiguration the pki block creation configuration */ public QbftContext( final ValidatorProvider validatorProvider, final EpochManager epochManager, - final BftBlockInterface blockInterface, - final Optional pkiBlockCreationConfiguration) { + final BftBlockInterface blockInterface) { super(validatorProvider, epochManager, blockInterface); - this.pkiBlockCreationConfiguration = pkiBlockCreationConfiguration; - } - - /** - * Gets pki block creation configuration. - * - * @return the pki block creation configuration - */ - public Optional getPkiBlockCreationConfiguration() { - return pkiBlockCreationConfiguration; } } diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/blockcreation/PkiQbftBlockCreator.java b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/blockcreation/PkiQbftBlockCreator.java deleted file mode 100644 index b3811a8aa3..0000000000 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/blockcreation/PkiQbftBlockCreator.java +++ /dev/null @@ -1,179 +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.consensus.qbft.blockcreation; - -import static com.google.common.base.Preconditions.checkArgument; - -import org.hyperledger.besu.consensus.common.bft.BftBlockHeaderFunctions; -import org.hyperledger.besu.consensus.common.bft.BftExtraData; -import org.hyperledger.besu.consensus.common.bft.BftExtraDataCodec; -import org.hyperledger.besu.consensus.common.bft.BftProtocolSchedule; -import org.hyperledger.besu.consensus.qbft.pki.PkiBlockCreationConfiguration; -import org.hyperledger.besu.consensus.qbft.pki.PkiQbftBlockHeaderFunctions; -import org.hyperledger.besu.consensus.qbft.pki.PkiQbftExtraData; -import org.hyperledger.besu.consensus.qbft.pki.PkiQbftExtraDataCodec; -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.ethereum.blockcreation.BlockCreationTiming; -import org.hyperledger.besu.ethereum.blockcreation.BlockCreator; -import org.hyperledger.besu.ethereum.core.Block; -import org.hyperledger.besu.ethereum.core.BlockHeader; -import org.hyperledger.besu.ethereum.core.BlockHeaderBuilder; -import org.hyperledger.besu.ethereum.core.Transaction; -import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; -import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; -import org.hyperledger.besu.ethereum.mainnet.WithdrawalsValidator; -import org.hyperledger.besu.pki.cms.CmsCreator; - -import java.util.Collections; -import java.util.List; -import java.util.Optional; - -import com.google.common.annotations.VisibleForTesting; -import org.apache.tuweni.bytes.Bytes; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** The Pki qbft block creator. */ -public class PkiQbftBlockCreator implements BlockCreator { - - private static final Logger LOG = LoggerFactory.getLogger(PkiQbftBlockCreator.class); - - private final BlockCreator blockCreator; - private final PkiQbftExtraDataCodec pkiQbftExtraDataCodec; - private final CmsCreator cmsCreator; - private final BlockHeader parentHeader; - private final ProtocolSchedule protocolSchedule; - - /** - * Instantiates a new Pki qbft block creator. - * - * @param blockCreator the block creator - * @param pkiBlockCreationConfiguration the pki block creation configuration - * @param pkiQbftExtraDataCodec the pki qbft extra data codec - * @param parentHeader the block header of the parent block - * @param protocolSchedule the protocol schedule (the type of block can vary based on the current - * protocol spec) - */ - public PkiQbftBlockCreator( - final BlockCreator blockCreator, - final PkiBlockCreationConfiguration pkiBlockCreationConfiguration, - final BftExtraDataCodec pkiQbftExtraDataCodec, - final BlockHeader parentHeader, - final ProtocolSchedule protocolSchedule) { - this( - blockCreator, - new CmsCreator( - pkiBlockCreationConfiguration.getKeyStore(), - pkiBlockCreationConfiguration.getCertificateAlias()), - pkiQbftExtraDataCodec, - parentHeader, - protocolSchedule); - } - - /** - * Instantiates a new Pki qbft block creator. - * - * @param blockCreator the block creator - * @param cmsCreator the cms creator - * @param bftExtraDataCodec the bft extra data codec - * @param parentHeader the block header of the parent block - * @param protocolSchedule the protocol schedule (the type of block can vary based on the current - * protocol spec) - */ - @VisibleForTesting - public PkiQbftBlockCreator( - final BlockCreator blockCreator, - final CmsCreator cmsCreator, - final BftExtraDataCodec bftExtraDataCodec, - final BlockHeader parentHeader, - final ProtocolSchedule protocolSchedule) { - this.blockCreator = blockCreator; - this.cmsCreator = cmsCreator; - this.protocolSchedule = protocolSchedule; - this.parentHeader = parentHeader; - - checkArgument( - bftExtraDataCodec instanceof PkiQbftExtraDataCodec, - "PkiQbftBlockCreator must use PkiQbftExtraDataCodec"); - this.pkiQbftExtraDataCodec = (PkiQbftExtraDataCodec) bftExtraDataCodec; - } - - @Override - public BlockCreationResult createBlock(final long timestamp) { - ProtocolSpec protocolSpec = - ((BftProtocolSchedule) protocolSchedule) - .getByBlockNumberOrTimestamp(parentHeader.getNumber() + 1, timestamp); - - final BlockCreationResult blockCreationResult; - if (protocolSpec.getWithdrawalsValidator() instanceof WithdrawalsValidator.AllowedWithdrawals) { - blockCreationResult = blockCreator.createEmptyWithdrawalsBlock(timestamp); - } else { - blockCreationResult = blockCreator.createBlock(timestamp); - } - return replaceCmsInBlock(blockCreationResult); - } - - @Override - public BlockCreationResult createBlock( - final List transactions, final List ommers, final long timestamp) { - final BlockCreationResult blockCreationResult = - blockCreator.createBlock(transactions, ommers, timestamp); - return replaceCmsInBlock(blockCreationResult); - } - - @Override - public BlockCreationResult createBlock( - final Optional> maybeTransactions, - final Optional> maybeOmmers, - final long timestamp) { - return createBlock( - maybeTransactions.orElse(Collections.emptyList()), - maybeOmmers.orElse(Collections.emptyList()), - timestamp); - } - - @Override - public BlockCreationResult createEmptyWithdrawalsBlock(final long timestamp) { - final BlockCreationResult blockCreationResult = - blockCreator.createEmptyWithdrawalsBlock(timestamp); - return replaceCmsInBlock(blockCreationResult); - } - - private BlockCreationResult replaceCmsInBlock(final BlockCreationResult blockCreationResult) { - final Block block = blockCreationResult.getBlock(); - final BlockHeader blockHeader = block.getHeader(); - final Hash hashWithoutCms = - PkiQbftBlockHeaderFunctions.forCmsSignature(pkiQbftExtraDataCodec).hash(block.getHeader()); - - final Bytes cms = cmsCreator.create(hashWithoutCms); - - final BftExtraData previousExtraData = pkiQbftExtraDataCodec.decode(blockHeader); - final BftExtraData substituteExtraData = new PkiQbftExtraData(previousExtraData, cms); - final Bytes substituteExtraDataBytes = pkiQbftExtraDataCodec.encode(substituteExtraData); - - final BlockHeaderBuilder headerBuilder = BlockHeaderBuilder.fromHeader(blockHeader); - headerBuilder - .extraData(substituteExtraDataBytes) - .blockHeaderFunctions(BftBlockHeaderFunctions.forCommittedSeal(pkiQbftExtraDataCodec)); - final BlockHeader newHeader = headerBuilder.buildBlockHeader(); - - LOG.debug("Created CMS with signed hash {} for block {}", hashWithoutCms, newHeader.getHash()); - - return new BlockCreationResult( - new Block(newHeader, block.getBody()), - blockCreationResult.getTransactionSelectionResults(), - new BlockCreationTiming()); - } -} diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/blockcreation/QbftBlockCreatorFactory.java b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/blockcreation/QbftBlockCreatorFactory.java index 9cbc64e787..10f61713d9 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/blockcreation/QbftBlockCreatorFactory.java +++ b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/blockcreation/QbftBlockCreatorFactory.java @@ -20,10 +20,8 @@ import org.hyperledger.besu.consensus.common.ForksSchedule; import org.hyperledger.besu.consensus.common.bft.BftExtraData; import org.hyperledger.besu.consensus.common.bft.BftExtraDataCodec; import org.hyperledger.besu.consensus.common.bft.blockcreation.BftBlockCreatorFactory; -import org.hyperledger.besu.consensus.qbft.QbftContext; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.ethereum.ProtocolContext; -import org.hyperledger.besu.ethereum.blockcreation.BlockCreator; import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.MiningParameters; import org.hyperledger.besu.ethereum.eth.manager.EthScheduler; @@ -69,22 +67,6 @@ public class QbftBlockCreatorFactory extends BftBlockCreatorFactory extraDataCodec.encodeWithoutCms(bftExtraData), extraDataCodec)); - } -} diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/pki/PkiQbftBlockHeaderFunctions.java b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/pki/PkiQbftBlockHeaderFunctions.java deleted file mode 100644 index df567c2c2c..0000000000 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/pki/PkiQbftBlockHeaderFunctions.java +++ /dev/null @@ -1,37 +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.consensus.qbft.pki; - -import org.hyperledger.besu.consensus.common.bft.BftBlockHeaderFunctions; -import org.hyperledger.besu.ethereum.core.BlockHeaderFunctions; - -/** The Pki qbft block header functions. */ -public class PkiQbftBlockHeaderFunctions { - /** Default constructor */ - private PkiQbftBlockHeaderFunctions() {} - - /** - * Create block header functions for cms signature. - * - * @param bftExtraDataCodec the bft extra data codec - * @return the block header functions - */ - public static BlockHeaderFunctions forCmsSignature( - final PkiQbftExtraDataCodec bftExtraDataCodec) { - return new BftBlockHeaderFunctions( - h -> new PkiQbftBlockHashing(bftExtraDataCodec).calculateHashOfBftBlockForCmsSignature(h), - bftExtraDataCodec); - } -} diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/pki/PkiQbftExtraData.java b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/pki/PkiQbftExtraData.java deleted file mode 100644 index 8d047c79e6..0000000000 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/pki/PkiQbftExtraData.java +++ /dev/null @@ -1,77 +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.consensus.qbft.pki; - -import org.hyperledger.besu.consensus.common.bft.BftExtraData; -import org.hyperledger.besu.consensus.common.bft.Vote; -import org.hyperledger.besu.crypto.SECPSignature; -import org.hyperledger.besu.datatypes.Address; - -import java.util.Collection; -import java.util.Optional; - -import org.apache.tuweni.bytes.Bytes; - -/** The Pki Qbft extra data. */ -public class PkiQbftExtraData extends BftExtraData { - - private final Bytes cms; - - /** - * Instantiates a new Pki Qbft extra data. - * - * @param vanityData the vanity data - * @param seals the seals - * @param vote the vote - * @param round the round - * @param validators the validators - * @param cms the cms - */ - public PkiQbftExtraData( - final Bytes vanityData, - final Collection seals, - final Optional vote, - final int round, - final Collection